aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/clang/include/clang
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm-project/clang/include/clang')
-rw-r--r--contrib/llvm-project/clang/include/clang/APINotes/APINotesManager.h175
-rw-r--r--contrib/llvm-project/clang/include/clang/APINotes/APINotesOptions.h34
-rw-r--r--contrib/llvm-project/clang/include/clang/APINotes/APINotesReader.h200
-rw-r--r--contrib/llvm-project/clang/include/clang/APINotes/APINotesWriter.h110
-rw-r--r--contrib/llvm-project/clang/include/clang/APINotes/APINotesYAMLCompiler.h11
-rw-r--r--contrib/llvm-project/clang/include/clang/APINotes/Types.h226
-rw-r--r--contrib/llvm-project/clang/include/clang/ARCMigrate/ARCMT.h2
-rw-r--r--contrib/llvm-project/clang/include/clang/ARCMigrate/ARCMTActions.h2
-rw-r--r--contrib/llvm-project/clang/include/clang/ARCMigrate/FileRemapper.h16
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/APNumericStorage.h71
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/APValue.h16
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/ASTConcept.h146
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/ASTConsumer.h6
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/ASTContext.h477
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/ASTDiagnostic.h7
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/ASTDumper.h1
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/ASTFwd.h5
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/ASTImportError.h50
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/ASTImporter.h52
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/ASTImporterLookupTable.h5
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/ASTImporterSharedState.h26
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/ASTLambda.h20
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/ASTNodeTraverser.h67
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/ASTStructuralEquivalence.h18
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/ASTTypeTraits.h101
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/ASTUnresolvedSet.h7
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/AbstractBasicReader.h21
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/AbstractBasicWriter.h21
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/AbstractTypeReader.h7
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/AbstractTypeWriter.h4
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/Attr.h57
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/AttrIterator.h1
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/BuiltinTypes.def3
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/CXXInheritance.h4
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/CXXRecordDeclDefinitionBits.def3
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/CanonicalType.h3
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/CharUnits.h13
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/Comment.h330
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/CommentCommands.td113
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/CommentHTMLTags.td6
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/CommentLexer.h3
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/CommentParser.h5
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/CommentSema.h24
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/CommentVisitor.h5
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/ComparisonCategories.h14
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/ComputeDependence.h14
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/CurrentSourceLocExprScope.h13
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/Decl.h706
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/DeclBase.h372
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/DeclCXX.h462
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/DeclContextInternals.h13
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/DeclFriend.h11
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/DeclObjC.h156
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/DeclObjCCommon.h6
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/DeclOpenMP.h34
-rwxr-xr-xcontrib/llvm-project/clang/include/clang/AST/DeclTemplate.h397
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/DeclarationName.h46
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/DependenceFlags.h24
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/DependentDiagnostic.h2
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/Expr.h908
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/ExprCXX.h568
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/ExprConcepts.h228
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/ExprObjC.h60
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/ExprOpenMP.h4
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/ExternalASTMerger.h2
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/ExternalASTSource.h14
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/FormatString.h30
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/GlobalDecl.h9
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/IgnoreExpr.h8
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/JSONNodeDumper.h25
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/LambdaCapture.h8
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/LexicallyOrderedRecursiveASTVisitor.h6
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/LocInfoType.h6
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/Mangle.h61
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/MangleNumberingContext.h10
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/NSAPI.h16
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/NestedNameSpecifier.h4
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/NonTrivialTypeVisitor.h4
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/ODRDiagsEmitter.h203
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/ODRHash.h17
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/OSLog.h4
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/OpenMPClause.h1744
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/OperationKinds.def9
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/ParentMapContext.h20
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/PrettyDeclStackTrace.h1
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/PrettyPrinter.h85
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/PropertiesBase.td158
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/QualTypeNames.h2
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/Randstruct.h35
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/RawCommentList.h29
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/RecursiveASTVisitor.h468
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/Redeclarable.h5
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/Stmt.h403
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/StmtCXX.h39
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/StmtObjC.h41
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/StmtOpenMP.h1145
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/TemplateArgumentVisitor.h2
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/TemplateBase.h197
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/TemplateName.h169
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/TextNodeDumper.h17
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/Type.h1137
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/TypeLoc.h316
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/TypeOrdering.h1
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/TypeProperties.td118
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/UnresolvedSet.h14
-rw-r--r--contrib/llvm-project/clang/include/clang/AST/VTableBuilder.h4
-rw-r--r--contrib/llvm-project/clang/include/clang/ASTMatchers/ASTMatchFinder.h11
-rw-r--r--contrib/llvm-project/clang/include/clang/ASTMatchers/ASTMatchers.h965
-rw-r--r--contrib/llvm-project/clang/include/clang/ASTMatchers/ASTMatchersInternal.h209
-rw-r--r--contrib/llvm-project/clang/include/clang/ASTMatchers/Dynamic/Diagnostics.h10
-rw-r--r--contrib/llvm-project/clang/include/clang/ASTMatchers/Dynamic/Parser.h18
-rw-r--r--contrib/llvm-project/clang/include/clang/ASTMatchers/Dynamic/Registry.h8
-rw-r--r--contrib/llvm-project/clang/include/clang/ASTMatchers/Dynamic/VariantValue.h16
-rw-r--r--contrib/llvm-project/clang/include/clang/Analysis/Analyses/CalledOnceCheck.h5
-rw-r--r--contrib/llvm-project/clang/include/clang/Analysis/Analyses/Consumed.h11
-rw-r--r--contrib/llvm-project/clang/include/clang/Analysis/Analyses/Dominators.h4
-rw-r--r--contrib/llvm-project/clang/include/clang/Analysis/Analyses/ExprMutationAnalyzer.h2
-rw-r--r--contrib/llvm-project/clang/include/clang/Analysis/Analyses/IntervalPartition.h123
-rw-r--r--contrib/llvm-project/clang/include/clang/Analysis/Analyses/PostOrderCFGView.h10
-rw-r--r--contrib/llvm-project/clang/include/clang/Analysis/Analyses/ReachableCode.h8
-rw-r--r--contrib/llvm-project/clang/include/clang/Analysis/Analyses/ThreadSafety.h17
-rw-r--r--contrib/llvm-project/clang/include/clang/Analysis/Analyses/ThreadSafetyCommon.h68
-rw-r--r--contrib/llvm-project/clang/include/clang/Analysis/Analyses/ThreadSafetyTIL.h37
-rw-r--r--contrib/llvm-project/clang/include/clang/Analysis/Analyses/ThreadSafetyTraverse.h5
-rw-r--r--contrib/llvm-project/clang/include/clang/Analysis/Analyses/ThreadSafetyUtil.h10
-rw-r--r--contrib/llvm-project/clang/include/clang/Analysis/Analyses/UnsafeBufferUsage.h122
-rw-r--r--contrib/llvm-project/clang/include/clang/Analysis/Analyses/UnsafeBufferUsageGadgets.def46
-rw-r--r--contrib/llvm-project/clang/include/clang/Analysis/AnalysisDeclContext.h8
-rw-r--r--contrib/llvm-project/clang/include/clang/Analysis/AnalysisDiagnostic.h14
-rw-r--r--contrib/llvm-project/clang/include/clang/Analysis/AnyCall.h23
-rw-r--r--contrib/llvm-project/clang/include/clang/Analysis/BodyFarm.h12
-rw-r--r--contrib/llvm-project/clang/include/clang/Analysis/CFG.h143
-rw-r--r--contrib/llvm-project/clang/include/clang/Analysis/CFGStmtMap.h2
-rw-r--r--contrib/llvm-project/clang/include/clang/Analysis/CallGraph.h2
-rw-r--r--contrib/llvm-project/clang/include/clang/Analysis/CloneDetection.h20
-rw-r--r--contrib/llvm-project/clang/include/clang/Analysis/ConstructionContext.h77
-rw-r--r--contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/Arena.h152
-rw-r--r--contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/CFGMatchSwitch.h98
-rw-r--r--contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/ControlFlowContext.h79
-rw-r--r--contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/DataflowAnalysis.h332
-rw-r--r--contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/DataflowAnalysisContext.h304
-rw-r--r--contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h739
-rw-r--r--contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/DataflowLattice.h31
-rw-r--r--contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/DataflowValues.h2
-rw-r--r--contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/DataflowWorklist.h35
-rw-r--r--contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/DebugSupport.h36
-rw-r--r--contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/Formula.h147
-rw-r--r--contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/Logger.h91
-rw-r--r--contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/MapLattice.h143
-rw-r--r--contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/MatchSwitch.h174
-rw-r--r--contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/Models/ChromiumCheckModel.h38
-rw-r--r--contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/Models/UncheckedOptionalAccessModel.h80
-rw-r--r--contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/NoopAnalysis.h41
-rw-r--r--contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/NoopLattice.h41
-rw-r--r--contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/RecordOps.h68
-rw-r--r--contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/SimplifyConstraints.h49
-rw-r--r--contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/Solver.h98
-rw-r--r--contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/StorageLocation.h181
-rw-r--r--contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/Transfer.h61
-rw-r--r--contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.h159
-rw-r--r--contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/Value.h231
-rw-r--r--contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/WatchedLiteralsSolver.h58
-rw-r--r--contrib/llvm-project/clang/include/clang/Analysis/IssueHash.h4
-rw-r--r--contrib/llvm-project/clang/include/clang/Analysis/MacroExpansionContext.h12
-rw-r--r--contrib/llvm-project/clang/include/clang/Analysis/PathDiagnostic.h41
-rw-r--r--contrib/llvm-project/clang/include/clang/Analysis/ProgramPoint.h82
-rw-r--r--contrib/llvm-project/clang/include/clang/Analysis/RetainSummaryManager.h22
-rw-r--r--contrib/llvm-project/clang/include/clang/Analysis/SelectorExtras.h6
-rw-r--r--contrib/llvm-project/clang/include/clang/Analysis/Support/BumpVector.h9
-rw-r--r--contrib/llvm-project/clang/include/clang/Basic/AArch64SVEACLETypes.def12
-rw-r--r--contrib/llvm-project/clang/include/clang/Basic/AddressSpaces.h6
-rw-r--r--contrib/llvm-project/clang/include/clang/Basic/AlignedAllocation.h12
-rw-r--r--contrib/llvm-project/clang/include/clang/Basic/Attr.td1059
-rw-r--r--contrib/llvm-project/clang/include/clang/Basic/AttrDocs.td1949
-rw-r--r--contrib/llvm-project/clang/include/clang/Basic/AttrSubjectMatchRules.h11
-rw-r--r--contrib/llvm-project/clang/include/clang/Basic/AttributeCommonInfo.h170
-rw-r--r--contrib/llvm-project/clang/include/clang/Basic/Attributes.h26
-rw-r--r--contrib/llvm-project/clang/include/clang/Basic/BuiltinHeaders.def43
-rw-r--r--contrib/llvm-project/clang/include/clang/Basic/Builtins.def1335
-rw-r--r--contrib/llvm-project/clang/include/clang/Basic/Builtins.h107
-rw-r--r--contrib/llvm-project/clang/include/clang/Basic/BuiltinsAArch64.def355
-rw-r--r--contrib/llvm-project/clang/include/clang/Basic/BuiltinsAArch64NeonSVEBridge.def39
-rw-r--r--contrib/llvm-project/clang/include/clang/Basic/BuiltinsAArch64NeonSVEBridge_cg.def39
-rw-r--r--contrib/llvm-project/clang/include/clang/Basic/BuiltinsAMDGPU.def241
-rw-r--r--contrib/llvm-project/clang/include/clang/Basic/BuiltinsARM.def248
-rw-r--r--contrib/llvm-project/clang/include/clang/Basic/BuiltinsHexagon.def22
-rw-r--r--contrib/llvm-project/clang/include/clang/Basic/BuiltinsHexagonDep.def184
-rw-r--r--contrib/llvm-project/clang/include/clang/Basic/BuiltinsHexagonMapCustomDep.def196
-rw-r--r--contrib/llvm-project/clang/include/clang/Basic/BuiltinsLoongArch.def28
-rw-r--r--contrib/llvm-project/clang/include/clang/Basic/BuiltinsLoongArchBase.def58
-rw-r--r--contrib/llvm-project/clang/include/clang/Basic/BuiltinsLoongArchLASX.def988
-rw-r--r--contrib/llvm-project/clang/include/clang/Basic/BuiltinsLoongArchLSX.def959
-rw-r--r--contrib/llvm-project/clang/include/clang/Basic/BuiltinsNEON.def1
-rw-r--r--contrib/llvm-project/clang/include/clang/Basic/BuiltinsNVPTX.def312
-rw-r--r--contrib/llvm-project/clang/include/clang/Basic/BuiltinsPPC.def1464
-rw-r--r--contrib/llvm-project/clang/include/clang/Basic/BuiltinsRISCV.def114
-rw-r--r--contrib/llvm-project/clang/include/clang/Basic/BuiltinsRISCVVector.def22
-rw-r--r--contrib/llvm-project/clang/include/clang/Basic/BuiltinsSME.def21
-rw-r--r--contrib/llvm-project/clang/include/clang/Basic/BuiltinsSVE.def2
-rw-r--r--contrib/llvm-project/clang/include/clang/Basic/BuiltinsSystemZ.def46
-rw-r--r--contrib/llvm-project/clang/include/clang/Basic/BuiltinsVE.def32
-rw-r--r--contrib/llvm-project/clang/include/clang/Basic/BuiltinsVEVL.gen.def1257
-rw-r--r--contrib/llvm-project/clang/include/clang/Basic/BuiltinsWebAssembly.def64
-rw-r--r--contrib/llvm-project/clang/include/clang/Basic/BuiltinsX86.def1237
-rw-r--r--contrib/llvm-project/clang/include/clang/Basic/BuiltinsX86_64.def51
-rw-r--r--contrib/llvm-project/clang/include/clang/Basic/CLWarnings.h26
-rw-r--r--contrib/llvm-project/clang/include/clang/Basic/CharInfo.h62
-rw-r--r--contrib/llvm-project/clang/include/clang/Basic/CodeGenOptions.def173
-rw-r--r--contrib/llvm-project/clang/include/clang/Basic/CodeGenOptions.h123
-rw-r--r--contrib/llvm-project/clang/include/clang/Basic/Cuda.h40
-rw-r--r--contrib/llvm-project/clang/include/clang/Basic/CustomizableOptional.h280
-rw-r--r--contrib/llvm-project/clang/include/clang/Basic/DarwinSDKInfo.h62
-rw-r--r--contrib/llvm-project/clang/include/clang/Basic/DebugInfoOptions.h60
-rw-r--r--contrib/llvm-project/clang/include/clang/Basic/DebugOptions.def146
-rw-r--r--contrib/llvm-project/clang/include/clang/Basic/DeclNodes.td6
-rw-r--r--contrib/llvm-project/clang/include/clang/Basic/Diagnostic.h97
-rw-r--r--contrib/llvm-project/clang/include/clang/Basic/Diagnostic.td19
-rw-r--r--contrib/llvm-project/clang/include/clang/Basic/DiagnosticAST.h2
-rw-r--r--contrib/llvm-project/clang/include/clang/Basic/DiagnosticASTKinds.td462
-rw-r--r--contrib/llvm-project/clang/include/clang/Basic/DiagnosticAnalysis.h2
-rw-r--r--contrib/llvm-project/clang/include/clang/Basic/DiagnosticAnalysisKinds.td11
-rw-r--r--contrib/llvm-project/clang/include/clang/Basic/DiagnosticCategories.h8
-rw-r--r--contrib/llvm-project/clang/include/clang/Basic/DiagnosticComment.h2
-rw-r--r--contrib/llvm-project/clang/include/clang/Basic/DiagnosticCommentKinds.td4
-rw-r--r--contrib/llvm-project/clang/include/clang/Basic/DiagnosticCommonKinds.td148
-rw-r--r--contrib/llvm-project/clang/include/clang/Basic/DiagnosticCrossTU.h2
-rw-r--r--contrib/llvm-project/clang/include/clang/Basic/DiagnosticCrossTUKinds.td4
-rw-r--r--contrib/llvm-project/clang/include/clang/Basic/DiagnosticDocs.td15
-rw-r--r--contrib/llvm-project/clang/include/clang/Basic/DiagnosticDriver.h2
-rw-r--r--contrib/llvm-project/clang/include/clang/Basic/DiagnosticDriverKinds.td447
-rw-r--r--contrib/llvm-project/clang/include/clang/Basic/DiagnosticError.h15
-rw-r--r--contrib/llvm-project/clang/include/clang/Basic/DiagnosticFrontend.h2
-rw-r--r--contrib/llvm-project/clang/include/clang/Basic/DiagnosticFrontendKinds.td78
-rw-r--r--contrib/llvm-project/clang/include/clang/Basic/DiagnosticGroups.td306
-rw-r--r--contrib/llvm-project/clang/include/clang/Basic/DiagnosticIDs.h63
-rw-r--r--contrib/llvm-project/clang/include/clang/Basic/DiagnosticLex.h2
-rw-r--r--contrib/llvm-project/clang/include/clang/Basic/DiagnosticLexKinds.td194
-rw-r--r--contrib/llvm-project/clang/include/clang/Basic/DiagnosticOptions.def4
-rw-r--r--contrib/llvm-project/clang/include/clang/Basic/DiagnosticOptions.h16
-rw-r--r--contrib/llvm-project/clang/include/clang/Basic/DiagnosticParse.h2
-rw-r--r--contrib/llvm-project/clang/include/clang/Basic/DiagnosticParseKinds.td283
-rw-r--r--contrib/llvm-project/clang/include/clang/Basic/DiagnosticRefactoring.h2
-rw-r--r--contrib/llvm-project/clang/include/clang/Basic/DiagnosticSema.h2
-rw-r--r--contrib/llvm-project/clang/include/clang/Basic/DiagnosticSemaKinds.td1624
-rw-r--r--contrib/llvm-project/clang/include/clang/Basic/DiagnosticSerialization.h2
-rw-r--r--contrib/llvm-project/clang/include/clang/Basic/DiagnosticSerializationKinds.td272
-rw-r--r--contrib/llvm-project/clang/include/clang/Basic/DirectoryEntry.h137
-rw-r--r--contrib/llvm-project/clang/include/clang/Basic/ExceptionSpecificationType.h5
-rw-r--r--contrib/llvm-project/clang/include/clang/Basic/FPOptions.def12
-rw-r--r--contrib/llvm-project/clang/include/clang/Basic/Features.def28
-rw-r--r--contrib/llvm-project/clang/include/clang/Basic/FileEntry.h178
-rw-r--r--contrib/llvm-project/clang/include/clang/Basic/FileManager.h49
-rw-r--r--contrib/llvm-project/clang/include/clang/Basic/FileSystemStatCache.h3
-rw-r--r--contrib/llvm-project/clang/include/clang/Basic/HLSLRuntime.h66
-rw-r--r--contrib/llvm-project/clang/include/clang/Basic/HeaderInclude.h73
-rw-r--r--contrib/llvm-project/clang/include/clang/Basic/IdentifierTable.h440
-rw-r--r--contrib/llvm-project/clang/include/clang/Basic/JsonSupport.h24
-rw-r--r--contrib/llvm-project/clang/include/clang/Basic/LLVM.h9
-rw-r--r--contrib/llvm-project/clang/include/clang/Basic/Lambda.h2
-rw-r--r--contrib/llvm-project/clang/include/clang/Basic/LangOptions.def130
-rw-r--r--contrib/llvm-project/clang/include/clang/Basic/LangOptions.h333
-rw-r--r--contrib/llvm-project/clang/include/clang/Basic/LangStandard.h38
-rw-r--r--contrib/llvm-project/clang/include/clang/Basic/LangStandards.def102
-rw-r--r--contrib/llvm-project/clang/include/clang/Basic/Linkage.h61
-rw-r--r--contrib/llvm-project/clang/include/clang/Basic/MSP430Target.def3
-rw-r--r--contrib/llvm-project/clang/include/clang/Basic/MakeSupport.h23
-rw-r--r--contrib/llvm-project/clang/include/clang/Basic/Module.h254
-rw-r--r--contrib/llvm-project/clang/include/clang/Basic/NoSanitizeList.h2
-rw-r--r--contrib/llvm-project/clang/include/clang/Basic/ObjCRuntime.h52
-rw-r--r--contrib/llvm-project/clang/include/clang/Basic/OpenACCKinds.h401
-rw-r--r--contrib/llvm-project/clang/include/clang/Basic/OpenCLExtensionTypes.def8
-rw-r--r--contrib/llvm-project/clang/include/clang/Basic/OpenCLExtensions.def8
-rw-r--r--contrib/llvm-project/clang/include/clang/Basic/OpenCLOptions.h9
-rw-r--r--contrib/llvm-project/clang/include/clang/Basic/OpenMPKinds.def81
-rw-r--r--contrib/llvm-project/clang/include/clang/Basic/OpenMPKinds.h96
-rw-r--r--contrib/llvm-project/clang/include/clang/Basic/OperatorKinds.def4
-rw-r--r--contrib/llvm-project/clang/include/clang/Basic/OperatorPrecedence.h2
-rw-r--r--contrib/llvm-project/clang/include/clang/Basic/ParsedAttrInfo.h168
-rw-r--r--contrib/llvm-project/clang/include/clang/Basic/PartialDiagnostic.h7
-rw-r--r--contrib/llvm-project/clang/include/clang/Basic/PlistSupport.h3
-rw-r--r--contrib/llvm-project/clang/include/clang/Basic/PragmaKinds.h12
-rw-r--r--contrib/llvm-project/clang/include/clang/Basic/ProfileList.h33
-rw-r--r--contrib/llvm-project/clang/include/clang/Basic/RISCVVTypes.def385
-rw-r--r--contrib/llvm-project/clang/include/clang/Basic/Sanitizers.def8
-rw-r--r--contrib/llvm-project/clang/include/clang/Basic/Sanitizers.h13
-rw-r--r--contrib/llvm-project/clang/include/clang/Basic/Sarif.h513
-rw-r--r--contrib/llvm-project/clang/include/clang/Basic/SourceLocation.h36
-rw-r--r--contrib/llvm-project/clang/include/clang/Basic/SourceManager.h280
-rw-r--r--contrib/llvm-project/clang/include/clang/Basic/SourceMgrAdapter.h85
-rw-r--r--contrib/llvm-project/clang/include/clang/Basic/Specifiers.h84
-rw-r--r--contrib/llvm-project/clang/include/clang/Basic/Stack.h2
-rw-r--r--contrib/llvm-project/clang/include/clang/Basic/StmtNodes.td23
-rw-r--r--contrib/llvm-project/clang/include/clang/Basic/SyncScope.h142
-rw-r--r--contrib/llvm-project/clang/include/clang/Basic/TargetBuiltins.h60
-rw-r--r--contrib/llvm-project/clang/include/clang/Basic/TargetCXXABI.h6
-rw-r--r--contrib/llvm-project/clang/include/clang/Basic/TargetID.h29
-rw-r--r--contrib/llvm-project/clang/include/clang/Basic/TargetInfo.h347
-rw-r--r--contrib/llvm-project/clang/include/clang/Basic/TargetOSMacros.def55
-rw-r--r--contrib/llvm-project/clang/include/clang/Basic/TargetOptions.h38
-rw-r--r--contrib/llvm-project/clang/include/clang/Basic/Thunk.h8
-rw-r--r--contrib/llvm-project/clang/include/clang/Basic/TokenKinds.def188
-rw-r--r--contrib/llvm-project/clang/include/clang/Basic/TokenKinds.h18
-rw-r--r--contrib/llvm-project/clang/include/clang/Basic/TransformTypeTraits.def29
-rw-r--r--contrib/llvm-project/clang/include/clang/Basic/TypeNodes.td8
-rw-r--r--contrib/llvm-project/clang/include/clang/Basic/TypeTraits.h4
-rw-r--r--contrib/llvm-project/clang/include/clang/Basic/Version.h3
-rw-r--r--contrib/llvm-project/clang/include/clang/Basic/Visibility.h28
-rw-r--r--contrib/llvm-project/clang/include/clang/Basic/WebAssemblyReferenceTypes.def40
-rw-r--r--contrib/llvm-project/clang/include/clang/Basic/X86Target.def110
-rw-r--r--contrib/llvm-project/clang/include/clang/Basic/arm_bf16.td2
-rw-r--r--contrib/llvm-project/clang/include/clang/Basic/arm_fp16.td2
-rw-r--r--contrib/llvm-project/clang/include/clang/Basic/arm_neon.td130
-rw-r--r--contrib/llvm-project/clang/include/clang/Basic/arm_neon_incl.td1
-rw-r--r--contrib/llvm-project/clang/include/clang/Basic/arm_sme.td676
-rw-r--r--contrib/llvm-project/clang/include/clang/Basic/arm_sve.td2243
-rw-r--r--contrib/llvm-project/clang/include/clang/Basic/arm_sve_sme_incl.td295
-rw-r--r--contrib/llvm-project/clang/include/clang/Basic/riscv_sifive_vector.td211
-rw-r--r--contrib/llvm-project/clang/include/clang/Basic/riscv_vector.td3482
-rw-r--r--contrib/llvm-project/clang/include/clang/Basic/riscv_vector_common.td713
-rw-r--r--contrib/llvm-project/clang/include/clang/CodeGen/BackendUtil.h12
-rw-r--r--contrib/llvm-project/clang/include/clang/CodeGen/CGFunctionInfo.h54
-rw-r--r--contrib/llvm-project/clang/include/clang/CodeGen/CodeGenABITypes.h8
-rw-r--r--contrib/llvm-project/clang/include/clang/CodeGen/CodeGenAction.h5
-rw-r--r--contrib/llvm-project/clang/include/clang/CodeGen/ConstantInitBuilder.h7
-rw-r--r--contrib/llvm-project/clang/include/clang/CodeGen/ModuleBuilder.h12
-rw-r--r--contrib/llvm-project/clang/include/clang/CodeGen/ObjectFilePCHContainerOperations.h6
-rw-r--r--contrib/llvm-project/clang/include/clang/CodeGen/SwiftCallingConv.h1
-rw-r--r--contrib/llvm-project/clang/include/clang/CrossTU/CrossTranslationUnit.h28
-rw-r--r--contrib/llvm-project/clang/include/clang/DirectoryWatcher/DirectoryWatcher.h2
-rw-r--r--contrib/llvm-project/clang/include/clang/Driver/Action.h77
-rw-r--r--contrib/llvm-project/clang/include/clang/Driver/ClangOptionDocs.td6
-rw-r--r--contrib/llvm-project/clang/include/clang/Driver/Compilation.h41
-rw-r--r--contrib/llvm-project/clang/include/clang/Driver/Distro.h13
-rw-r--r--contrib/llvm-project/clang/include/clang/Driver/Driver.h262
-rw-r--r--contrib/llvm-project/clang/include/clang/Driver/Job.h49
-rw-r--r--contrib/llvm-project/clang/include/clang/Driver/Multilib.h134
-rw-r--r--contrib/llvm-project/clang/include/clang/Driver/MultilibBuilder.h134
-rw-r--r--contrib/llvm-project/clang/include/clang/Driver/OffloadBundler.h126
-rw-r--r--contrib/llvm-project/clang/include/clang/Driver/Options.h37
-rw-r--r--contrib/llvm-project/clang/include/clang/Driver/Options.td5140
-rw-r--r--contrib/llvm-project/clang/include/clang/Driver/Phases.h3
-rw-r--r--contrib/llvm-project/clang/include/clang/Driver/SanitizerArgs.h32
-rw-r--r--contrib/llvm-project/clang/include/clang/Driver/Tool.h1
-rw-r--r--contrib/llvm-project/clang/include/clang/Driver/ToolChain.h176
-rw-r--r--contrib/llvm-project/clang/include/clang/Driver/Types.def26
-rw-r--r--contrib/llvm-project/clang/include/clang/Driver/Types.h19
-rw-r--r--contrib/llvm-project/clang/include/clang/Driver/Util.h1
-rw-r--r--contrib/llvm-project/clang/include/clang/Driver/XRayArgs.h9
-rw-r--r--contrib/llvm-project/clang/include/clang/ExtractAPI/API.h1675
-rw-r--r--contrib/llvm-project/clang/include/clang/ExtractAPI/APIIgnoresList.h76
-rw-r--r--contrib/llvm-project/clang/include/clang/ExtractAPI/AvailabilityInfo.h76
-rw-r--r--contrib/llvm-project/clang/include/clang/ExtractAPI/DeclarationFragments.h454
-rw-r--r--contrib/llvm-project/clang/include/clang/ExtractAPI/ExtractAPIActionBase.h54
-rw-r--r--contrib/llvm-project/clang/include/clang/ExtractAPI/ExtractAPIVisitor.h1426
-rw-r--r--contrib/llvm-project/clang/include/clang/ExtractAPI/FrontendActions.h95
-rw-r--r--contrib/llvm-project/clang/include/clang/ExtractAPI/Serialization/SerializerBase.h314
-rw-r--r--contrib/llvm-project/clang/include/clang/ExtractAPI/Serialization/SymbolGraphSerializer.h243
-rw-r--r--contrib/llvm-project/clang/include/clang/ExtractAPI/TypedefUnderlyingTypeResolver.h48
-rwxr-xr-xcontrib/llvm-project/clang/include/clang/Format/Format.h3334
-rw-r--r--contrib/llvm-project/clang/include/clang/Frontend/ASTConsumers.h6
-rw-r--r--contrib/llvm-project/clang/include/clang/Frontend/ASTUnit.h55
-rw-r--r--contrib/llvm-project/clang/include/clang/Frontend/CommandLineSourceLoc.h9
-rw-r--r--contrib/llvm-project/clang/include/clang/Frontend/CompilerInstance.h142
-rw-r--r--contrib/llvm-project/clang/include/clang/Frontend/CompilerInvocation.h357
-rw-r--r--contrib/llvm-project/clang/include/clang/Frontend/DependencyOutputOptions.h19
-rw-r--r--contrib/llvm-project/clang/include/clang/Frontend/FrontendAction.h17
-rw-r--r--contrib/llvm-project/clang/include/clang/Frontend/FrontendActions.h28
-rw-r--r--contrib/llvm-project/clang/include/clang/Frontend/FrontendOptions.h142
-rw-r--r--contrib/llvm-project/clang/include/clang/Frontend/LayoutOverrideSource.h6
-rw-r--r--contrib/llvm-project/clang/include/clang/Frontend/MigratorOptions.h4
-rw-r--r--contrib/llvm-project/clang/include/clang/Frontend/MultiplexConsumer.h2
-rw-r--r--contrib/llvm-project/clang/include/clang/Frontend/PCHContainerOperations.h4
-rw-r--r--contrib/llvm-project/clang/include/clang/Frontend/PrecompiledPreamble.h94
-rw-r--r--contrib/llvm-project/clang/include/clang/Frontend/PreprocessorOutputOptions.h20
-rw-r--r--contrib/llvm-project/clang/include/clang/Frontend/SARIFDiagnostic.h74
-rw-r--r--contrib/llvm-project/clang/include/clang/Frontend/SARIFDiagnosticPrinter.h76
-rw-r--r--contrib/llvm-project/clang/include/clang/Frontend/SerializedDiagnosticPrinter.h1
-rw-r--r--contrib/llvm-project/clang/include/clang/Frontend/SerializedDiagnostics.h4
-rw-r--r--contrib/llvm-project/clang/include/clang/Frontend/TextDiagnostic.h3
-rw-r--r--contrib/llvm-project/clang/include/clang/Frontend/TextDiagnosticPrinter.h1
-rw-r--r--contrib/llvm-project/clang/include/clang/Frontend/Utils.h83
-rw-r--r--contrib/llvm-project/clang/include/clang/Frontend/VerifyDiagnosticConsumer.h163
-rw-r--r--contrib/llvm-project/clang/include/clang/Index/IndexSymbol.h2
-rw-r--r--contrib/llvm-project/clang/include/clang/Index/IndexingOptions.h4
-rw-r--r--contrib/llvm-project/clang/include/clang/IndexSerialization/SerializablePathCollection.h9
-rw-r--r--contrib/llvm-project/clang/include/clang/Interpreter/CodeCompletion.h49
-rw-r--r--contrib/llvm-project/clang/include/clang/Interpreter/Interpreter.h102
-rw-r--r--contrib/llvm-project/clang/include/clang/Interpreter/Value.h208
-rw-r--r--contrib/llvm-project/clang/include/clang/Lex/DependencyDirectivesScanner.h140
-rw-r--r--contrib/llvm-project/clang/include/clang/Lex/DependencyDirectivesSourceMinimizer.h112
-rw-r--r--contrib/llvm-project/clang/include/clang/Lex/DirectoryLookup.h21
-rw-r--r--contrib/llvm-project/clang/include/clang/Lex/HeaderMap.h31
-rw-r--r--contrib/llvm-project/clang/include/clang/Lex/HeaderSearch.h386
-rw-r--r--contrib/llvm-project/clang/include/clang/Lex/HeaderSearchOptions.h73
-rw-r--r--contrib/llvm-project/clang/include/clang/Lex/Lexer.h140
-rw-r--r--contrib/llvm-project/clang/include/clang/Lex/LiteralSupport.h56
-rw-r--r--contrib/llvm-project/clang/include/clang/Lex/MacroInfo.h58
-rw-r--r--contrib/llvm-project/clang/include/clang/Lex/ModuleLoader.h5
-rw-r--r--contrib/llvm-project/clang/include/clang/Lex/ModuleMap.h187
-rw-r--r--contrib/llvm-project/clang/include/clang/Lex/MultipleIncludeOpt.h6
-rw-r--r--contrib/llvm-project/clang/include/clang/Lex/PPCallbacks.h116
-rw-r--r--contrib/llvm-project/clang/include/clang/Lex/Pragma.h7
-rw-r--r--contrib/llvm-project/clang/include/clang/Lex/PreprocessingRecord.h26
-rw-r--r--contrib/llvm-project/clang/include/clang/Lex/Preprocessor.h706
-rw-r--r--contrib/llvm-project/clang/include/clang/Lex/PreprocessorExcludedConditionalDirectiveSkipMapping.h30
-rw-r--r--contrib/llvm-project/clang/include/clang/Lex/PreprocessorLexer.h21
-rw-r--r--contrib/llvm-project/clang/include/clang/Lex/PreprocessorOptions.h33
-rw-r--r--contrib/llvm-project/clang/include/clang/Lex/Token.h23
-rw-r--r--contrib/llvm-project/clang/include/clang/Lex/VariadicMacroSupport.h5
-rw-r--r--contrib/llvm-project/clang/include/clang/Parse/LoopHint.h18
-rw-r--r--contrib/llvm-project/clang/include/clang/Parse/Parser.h831
-rw-r--r--contrib/llvm-project/clang/include/clang/Parse/RAIIObjectsForParser.h51
-rw-r--r--contrib/llvm-project/clang/include/clang/Rewrite/Core/RewriteRope.h4
-rw-r--r--contrib/llvm-project/clang/include/clang/Sema/AnalysisBasedWarnings.h6
-rw-r--r--contrib/llvm-project/clang/include/clang/Sema/CleanupInfo.h4
-rw-r--r--contrib/llvm-project/clang/include/clang/Sema/CodeCompleteConsumer.h146
-rw-r--r--contrib/llvm-project/clang/include/clang/Sema/DeclSpec.h174
-rw-r--r--contrib/llvm-project/clang/include/clang/Sema/DelayedDiagnostic.h4
-rw-r--r--contrib/llvm-project/clang/include/clang/Sema/Designator.h201
-rw-r--r--contrib/llvm-project/clang/include/clang/Sema/EnterExpressionEvaluationContext.h69
-rw-r--r--contrib/llvm-project/clang/include/clang/Sema/ExternalSemaSource.h7
-rw-r--r--contrib/llvm-project/clang/include/clang/Sema/HLSLExternalSemaSource.h55
-rw-r--r--contrib/llvm-project/clang/include/clang/Sema/IdentifierResolver.h14
-rw-r--r--contrib/llvm-project/clang/include/clang/Sema/Initialization.h47
-rw-r--r--contrib/llvm-project/clang/include/clang/Sema/Lookup.h134
-rw-r--r--contrib/llvm-project/clang/include/clang/Sema/MultiplexExternalSemaSource.h20
-rw-r--r--contrib/llvm-project/clang/include/clang/Sema/Overload.h118
-rw-r--r--contrib/llvm-project/clang/include/clang/Sema/Ownership.h276
-rw-r--r--contrib/llvm-project/clang/include/clang/Sema/ParsedAttr.h343
-rw-r--r--contrib/llvm-project/clang/include/clang/Sema/ParsedTemplate.h9
-rw-r--r--contrib/llvm-project/clang/include/clang/Sema/RISCVIntrinsicManager.h41
-rw-r--r--contrib/llvm-project/clang/include/clang/Sema/Scope.h92
-rw-r--r--contrib/llvm-project/clang/include/clang/Sema/ScopeInfo.h99
-rw-r--r--contrib/llvm-project/clang/include/clang/Sema/Sema.h2893
-rw-r--r--contrib/llvm-project/clang/include/clang/Sema/SemaConcept.h17
-rw-r--r--contrib/llvm-project/clang/include/clang/Sema/SemaLambda.h5
-rw-r--r--contrib/llvm-project/clang/include/clang/Sema/Template.h147
-rw-r--r--contrib/llvm-project/clang/include/clang/Sema/TemplateDeduction.h45
-rw-r--r--contrib/llvm-project/clang/include/clang/Sema/TemplateInstCallback.h4
-rw-r--r--contrib/llvm-project/clang/include/clang/Sema/TypoCorrection.h12
-rw-r--r--contrib/llvm-project/clang/include/clang/Sema/Weak.h39
-rw-r--r--contrib/llvm-project/clang/include/clang/Serialization/ASTBitCodes.h80
-rw-r--r--contrib/llvm-project/clang/include/clang/Serialization/ASTReader.h298
-rw-r--r--contrib/llvm-project/clang/include/clang/Serialization/ASTRecordReader.h31
-rw-r--r--contrib/llvm-project/clang/include/clang/Serialization/ASTRecordWriter.h19
-rw-r--r--contrib/llvm-project/clang/include/clang/Serialization/ASTWriter.h193
-rw-r--r--contrib/llvm-project/clang/include/clang/Serialization/GlobalModuleIndex.h16
-rw-r--r--contrib/llvm-project/clang/include/clang/Serialization/InMemoryModuleCache.h1
-rw-r--r--contrib/llvm-project/clang/include/clang/Serialization/ModuleFile.h47
-rw-r--r--contrib/llvm-project/clang/include/clang/Serialization/ModuleFileExtension.h27
-rw-r--r--contrib/llvm-project/clang/include/clang/Serialization/ModuleManager.h18
-rw-r--r--contrib/llvm-project/clang/include/clang/Serialization/PCHContainerOperations.h19
-rw-r--r--contrib/llvm-project/clang/include/clang/Serialization/SourceLocationEncoding.h163
-rw-r--r--contrib/llvm-project/clang/include/clang/Serialization/TypeBitCodes.def6
-rw-r--r--contrib/llvm-project/clang/include/clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h8
-rw-r--r--contrib/llvm-project/clang/include/clang/StaticAnalyzer/Checkers/CheckerBase.td9
-rw-r--r--contrib/llvm-project/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td256
-rw-r--r--contrib/llvm-project/clang/include/clang/StaticAnalyzer/Checkers/LocalCheckers.h27
-rw-r--r--contrib/llvm-project/clang/include/clang/StaticAnalyzer/Checkers/MPIFunctionClassifier.h4
-rw-r--r--contrib/llvm-project/clang/include/clang/StaticAnalyzer/Checkers/SValExplainer.h49
-rw-r--r--contrib/llvm-project/clang/include/clang/StaticAnalyzer/Checkers/Taint.h128
-rw-r--r--contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/Analyses.def8
-rw-r--r--contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/AnalyzerOptions.def74
-rw-r--r--contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h74
-rw-r--r--contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h34
-rw-r--r--contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitors.h145
-rw-r--r--contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/BugReporter/BugSuppression.h53
-rw-r--r--contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/BugReporter/BugType.h35
-rw-r--r--contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/BugReporter/CommonBugCategories.h2
-rw-r--r--contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/Checker.h57
-rw-r--r--contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/CheckerManager.h14
-rw-r--r--contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathDiagnosticConsumers.h1
-rw-r--r--contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/APSIntType.h4
-rw-r--r--contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h27
-rw-r--r--contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CallDescription.h257
-rw-r--r--contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h430
-rw-r--r--contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h26
-rw-r--r--contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerHelpers.h12
-rw-r--r--contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ConstraintManager.h149
-rw-r--r--contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h38
-rw-r--r--contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/DynamicExtent.h5
-rw-r--r--contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/DynamicType.h3
-rw-r--r--contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/DynamicTypeInfo.h2
-rw-r--r--contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h17
-rw-r--r--contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h213
-rw-r--r--contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/FunctionSummary.h7
-rw-r--r--contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/LoopUnrolling.h1
-rw-r--r--contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h150
-rw-r--r--contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h128
-rw-r--r--contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h108
-rw-r--r--contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/RangedConstraintManager.h112
-rw-r--r--contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/Regions.def1
-rw-r--r--contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SMTConstraintManager.h23
-rw-r--r--contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SMTConv.h28
-rw-r--r--contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h134
-rw-r--r--contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SValVisitor.h55
-rw-r--r--contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.def38
-rw-r--r--contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h443
-rw-r--r--contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SimpleConstraintManager.h21
-rw-r--r--contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h19
-rw-r--r--contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SymExpr.h7
-rw-r--r--contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h133
-rw-r--r--contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/Symbols.def2
-rw-r--r--contrib/llvm-project/clang/include/clang/StaticAnalyzer/Frontend/AnalysisConsumer.h4
-rw-r--r--contrib/llvm-project/clang/include/clang/StaticAnalyzer/Frontend/FrontendActions.h3
-rw-r--r--contrib/llvm-project/clang/include/clang/StaticAnalyzer/Frontend/ModelConsumer.h4
-rw-r--r--contrib/llvm-project/clang/include/clang/Support/RISCVVIntrinsicUtils.h570
-rw-r--r--contrib/llvm-project/clang/include/clang/Testing/CommandLineArgs.h7
-rw-r--r--contrib/llvm-project/clang/include/clang/Testing/TestAST.h103
-rw-r--r--contrib/llvm-project/clang/include/clang/Testing/TestClangConfig.h2
-rw-r--r--contrib/llvm-project/clang/include/clang/Tooling/ASTDiff/ASTDiff.h33
-rw-r--r--contrib/llvm-project/clang/include/clang/Tooling/ASTDiff/ASTDiffInternal.h4
-rw-r--r--contrib/llvm-project/clang/include/clang/Tooling/AllTUsExecution.h3
-rw-r--r--contrib/llvm-project/clang/include/clang/Tooling/CommonOptionsParser.h2
-rw-r--r--contrib/llvm-project/clang/include/clang/Tooling/CompilationDatabase.h2
-rw-r--r--contrib/llvm-project/clang/include/clang/Tooling/Core/Replacement.h17
-rw-r--r--contrib/llvm-project/clang/include/clang/Tooling/DependencyScanning/DependencyScanningFilesystem.h437
-rw-r--r--contrib/llvm-project/clang/include/clang/Tooling/DependencyScanning/DependencyScanningService.h61
-rw-r--r--contrib/llvm-project/clang/include/clang/Tooling/DependencyScanning/DependencyScanningTool.h190
-rw-r--r--contrib/llvm-project/clang/include/clang/Tooling/DependencyScanning/DependencyScanningWorker.h84
-rw-r--r--contrib/llvm-project/clang/include/clang/Tooling/DependencyScanning/ModuleDepCollector.h251
-rw-r--r--contrib/llvm-project/clang/include/clang/Tooling/DiagnosticsYaml.h3
-rw-r--r--contrib/llvm-project/clang/include/clang/Tooling/FixIt.h2
-rw-r--r--contrib/llvm-project/clang/include/clang/Tooling/Inclusions/HeaderAnalysis.h46
-rw-r--r--contrib/llvm-project/clang/include/clang/Tooling/Inclusions/HeaderIncludes.h46
-rw-r--r--contrib/llvm-project/clang/include/clang/Tooling/Inclusions/IncludeStyle.h6
-rw-r--r--contrib/llvm-project/clang/include/clang/Tooling/Inclusions/StandardLibrary.h158
-rw-r--r--contrib/llvm-project/clang/include/clang/Tooling/Refactoring/ASTSelection.h17
-rw-r--r--contrib/llvm-project/clang/include/clang/Tooling/Refactoring/AtomicChange.h8
-rw-r--r--contrib/llvm-project/clang/include/clang/Tooling/Refactoring/Extract/Extract.h18
-rw-r--r--contrib/llvm-project/clang/include/clang/Tooling/Refactoring/Extract/SourceExtraction.h6
-rw-r--r--contrib/llvm-project/clang/include/clang/Tooling/Refactoring/Lookup.h6
-rw-r--r--contrib/llvm-project/clang/include/clang/Tooling/Refactoring/RecursiveSymbolVisitor.h15
-rw-r--r--contrib/llvm-project/clang/include/clang/Tooling/Refactoring/RefactoringAction.h6
-rw-r--r--contrib/llvm-project/clang/include/clang/Tooling/Refactoring/RefactoringActionRule.h7
-rw-r--r--contrib/llvm-project/clang/include/clang/Tooling/Refactoring/RefactoringActionRuleRequirements.h8
-rw-r--r--contrib/llvm-project/clang/include/clang/Tooling/Refactoring/RefactoringActionRules.h10
-rw-r--r--contrib/llvm-project/clang/include/clang/Tooling/Refactoring/RefactoringActionRulesInternal.h18
-rw-r--r--contrib/llvm-project/clang/include/clang/Tooling/Refactoring/RefactoringOption.h6
-rw-r--r--contrib/llvm-project/clang/include/clang/Tooling/Refactoring/RefactoringOptionVisitor.h12
-rw-r--r--contrib/llvm-project/clang/include/clang/Tooling/Refactoring/RefactoringOptions.h15
-rw-r--r--contrib/llvm-project/clang/include/clang/Tooling/Refactoring/RefactoringResultConsumer.h6
-rw-r--r--contrib/llvm-project/clang/include/clang/Tooling/Refactoring/RefactoringRuleContext.h6
-rw-r--r--contrib/llvm-project/clang/include/clang/Tooling/Refactoring/Rename/RenamingAction.h7
-rw-r--r--contrib/llvm-project/clang/include/clang/Tooling/Refactoring/Rename/SymbolName.h6
-rw-r--r--contrib/llvm-project/clang/include/clang/Tooling/Refactoring/Rename/SymbolOccurrences.h8
-rw-r--r--contrib/llvm-project/clang/include/clang/Tooling/Refactoring/Rename/USRFinder.h6
-rw-r--r--contrib/llvm-project/clang/include/clang/Tooling/Refactoring/Rename/USRFindingAction.h7
-rw-r--r--contrib/llvm-project/clang/include/clang/Tooling/Refactoring/Rename/USRLocFinder.h6
-rw-r--r--contrib/llvm-project/clang/include/clang/Tooling/ReplacementsYaml.h3
-rw-r--r--contrib/llvm-project/clang/include/clang/Tooling/StandaloneExecution.h3
-rw-r--r--contrib/llvm-project/clang/include/clang/Tooling/Syntax/BuildTree.h22
-rw-r--r--contrib/llvm-project/clang/include/clang/Tooling/Syntax/Mutations.h6
-rw-r--r--contrib/llvm-project/clang/include/clang/Tooling/Syntax/Nodes.h7
-rw-r--r--contrib/llvm-project/clang/include/clang/Tooling/Syntax/TokenBufferTokenManager.h70
-rw-r--r--contrib/llvm-project/clang/include/clang/Tooling/Syntax/TokenManager.h47
-rw-r--r--contrib/llvm-project/clang/include/clang/Tooling/Syntax/Tokens.h10
-rw-r--r--contrib/llvm-project/clang/include/clang/Tooling/Syntax/Tree.h68
-rw-r--r--contrib/llvm-project/clang/include/clang/Tooling/Tooling.h31
-rw-r--r--contrib/llvm-project/clang/include/clang/Tooling/Transformer/MatchConsumer.h6
-rw-r--r--contrib/llvm-project/clang/include/clang/Tooling/Transformer/Parsing.h6
-rw-r--r--contrib/llvm-project/clang/include/clang/Tooling/Transformer/RangeSelector.h8
-rw-r--r--contrib/llvm-project/clang/include/clang/Tooling/Transformer/RewriteRule.h159
-rw-r--r--contrib/llvm-project/clang/include/clang/Tooling/Transformer/SourceCode.h68
-rw-r--r--contrib/llvm-project/clang/include/clang/Tooling/Transformer/SourceCodeBuilders.h58
-rw-r--r--contrib/llvm-project/clang/include/clang/Tooling/Transformer/Stencil.h32
-rw-r--r--contrib/llvm-project/clang/include/clang/Tooling/Transformer/Transformer.h180
-rw-r--r--contrib/llvm-project/clang/include/clang/module.modulemap182
568 files changed, 61493 insertions, 19892 deletions
diff --git a/contrib/llvm-project/clang/include/clang/APINotes/APINotesManager.h b/contrib/llvm-project/clang/include/clang/APINotes/APINotesManager.h
new file mode 100644
index 000000000000..18375c9e51a1
--- /dev/null
+++ b/contrib/llvm-project/clang/include/clang/APINotes/APINotesManager.h
@@ -0,0 +1,175 @@
+//===--- APINotesManager.h - Manage API Notes Files -------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_APINOTES_APINOTESMANAGER_H
+#define LLVM_CLANG_APINOTES_APINOTESMANAGER_H
+
+#include "clang/Basic/Module.h"
+#include "clang/Basic/SourceLocation.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/PointerUnion.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/VersionTuple.h"
+#include <memory>
+#include <string>
+
+namespace clang {
+
+class DirectoryEntry;
+class FileEntry;
+class LangOptions;
+class SourceManager;
+
+namespace api_notes {
+
+class APINotesReader;
+
+/// The API notes manager helps find API notes associated with declarations.
+///
+/// API notes are externally-provided annotations for declarations that can
+/// introduce new attributes (covering availability, nullability of
+/// parameters/results, and so on) for specific declarations without directly
+/// modifying the headers that contain those declarations.
+///
+/// The API notes manager is responsible for finding and loading the
+/// external API notes files that correspond to a given header. Its primary
+/// operation is \c findAPINotes(), which finds the API notes reader that
+/// provides information about the declarations at that location.
+class APINotesManager {
+ using ReaderEntry = llvm::PointerUnion<DirectoryEntryRef, APINotesReader *>;
+
+ SourceManager &SM;
+
+ /// Whether to implicitly search for API notes files based on the
+ /// source file from which an entity was declared.
+ bool ImplicitAPINotes;
+
+ /// The Swift version to use when interpreting versioned API notes.
+ llvm::VersionTuple SwiftVersion;
+
+ enum ReaderKind : unsigned { Public = 0, Private = 1 };
+
+ /// API notes readers for the current module.
+ ///
+ /// There can be up to two of these, one for public headers and one
+ /// for private headers.
+ ///
+ /// Not using std::unique_ptr to store these, since the reader pointers are
+ /// also stored in llvm::PointerUnion below.
+ APINotesReader *CurrentModuleReaders[2] = {nullptr, nullptr};
+
+ /// A mapping from header file directories to the API notes reader for
+ /// that directory, or a redirection to another directory entry that may
+ /// have more information, or NULL to indicate that there is no API notes
+ /// reader for this directory.
+ llvm::DenseMap<const DirectoryEntry *, ReaderEntry> Readers;
+
+ /// Load the API notes associated with the given file, whether it is
+ /// the binary or source form of API notes.
+ ///
+ /// \returns the API notes reader for this file, or null if there is
+ /// a failure.
+ std::unique_ptr<APINotesReader> loadAPINotes(FileEntryRef APINotesFile);
+
+ /// Load the API notes associated with the given buffer, whether it is
+ /// the binary or source form of API notes.
+ ///
+ /// \returns the API notes reader for this file, or null if there is
+ /// a failure.
+ std::unique_ptr<APINotesReader> loadAPINotes(StringRef Buffer);
+
+ /// Load the given API notes file for the given header directory.
+ ///
+ /// \param HeaderDir The directory at which we
+ ///
+ /// \returns true if an error occurred.
+ bool loadAPINotes(const DirectoryEntry *HeaderDir, FileEntryRef APINotesFile);
+
+ /// Look for API notes in the given directory.
+ ///
+ /// This might find either a binary or source API notes.
+ OptionalFileEntryRef findAPINotesFile(DirectoryEntryRef Directory,
+ StringRef FileName,
+ bool WantPublic = true);
+
+ /// Attempt to load API notes for the given framework. A framework will have
+ /// the API notes file under either {FrameworkPath}/APINotes,
+ /// {FrameworkPath}/Headers or {FrameworkPath}/PrivateHeaders, while a
+ /// library will have the API notes simply in its directory.
+ ///
+ /// \param FrameworkPath The path to the framework.
+ /// \param Public Whether to load the public API notes. Otherwise, attempt
+ /// to load the private API notes.
+ ///
+ /// \returns the header directory entry (e.g., for Headers or PrivateHeaders)
+ /// for which the API notes were successfully loaded, or NULL if API notes
+ /// could not be loaded for any reason.
+ OptionalDirectoryEntryRef loadFrameworkAPINotes(llvm::StringRef FrameworkPath,
+ llvm::StringRef FrameworkName,
+ bool Public);
+
+public:
+ APINotesManager(SourceManager &SM, const LangOptions &LangOpts);
+ ~APINotesManager();
+
+ /// Set the Swift version to use when filtering API notes.
+ void setSwiftVersion(llvm::VersionTuple Version) {
+ this->SwiftVersion = Version;
+ }
+
+ /// Load the API notes for the current module.
+ ///
+ /// \param M The current module.
+ /// \param LookInModule Whether to look inside the module itself.
+ /// \param SearchPaths The paths in which we should search for API notes
+ /// for the current module.
+ ///
+ /// \returns true if API notes were successfully loaded, \c false otherwise.
+ bool loadCurrentModuleAPINotes(Module *M, bool LookInModule,
+ ArrayRef<std::string> SearchPaths);
+
+ /// Get FileEntry for the APINotes of the module that is currently being
+ /// compiled.
+ ///
+ /// \param M The current module.
+ /// \param LookInModule Whether to look inside the directory of the current
+ /// module.
+ /// \param SearchPaths The paths in which we should search for API
+ /// notes for the current module.
+ ///
+ /// \returns a vector of FileEntry where APINotes files are.
+ llvm::SmallVector<FileEntryRef, 2>
+ getCurrentModuleAPINotes(Module *M, bool LookInModule,
+ ArrayRef<std::string> SearchPaths);
+
+ /// Load Compiled API notes for current module.
+ ///
+ /// \param Buffers Array of compiled API notes.
+ ///
+ /// \returns true if API notes were successfully loaded, \c false otherwise.
+ bool loadCurrentModuleAPINotesFromBuffer(ArrayRef<StringRef> Buffers);
+
+ /// Retrieve the set of API notes readers for the current module.
+ ArrayRef<APINotesReader *> getCurrentModuleReaders() const {
+ bool HasPublic = CurrentModuleReaders[ReaderKind::Public];
+ bool HasPrivate = CurrentModuleReaders[ReaderKind::Private];
+ assert((!HasPrivate || HasPublic) && "private module requires public module");
+ if (!HasPrivate && !HasPublic)
+ return {};
+ return ArrayRef(CurrentModuleReaders).slice(0, HasPrivate ? 2 : 1);
+ }
+
+ /// Find the API notes readers that correspond to the given source location.
+ llvm::SmallVector<APINotesReader *, 2> findAPINotes(SourceLocation Loc);
+};
+
+} // end namespace api_notes
+} // end namespace clang
+
+#endif
diff --git a/contrib/llvm-project/clang/include/clang/APINotes/APINotesOptions.h b/contrib/llvm-project/clang/include/clang/APINotes/APINotesOptions.h
new file mode 100644
index 000000000000..e8b8a9ed2261
--- /dev/null
+++ b/contrib/llvm-project/clang/include/clang/APINotes/APINotesOptions.h
@@ -0,0 +1,34 @@
+//===--- APINotesOptions.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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_APINOTES_APINOTESOPTIONS_H
+#define LLVM_CLANG_APINOTES_APINOTESOPTIONS_H
+
+#include "llvm/Support/VersionTuple.h"
+#include <string>
+#include <vector>
+
+namespace clang {
+
+/// Tracks various options which control how API notes are found and handled.
+class APINotesOptions {
+public:
+ /// The Swift version which should be used for API notes.
+ llvm::VersionTuple SwiftVersion;
+
+ /// The set of search paths where we API notes can be found for particular
+ /// modules.
+ ///
+ /// The API notes in this directory are stored as <ModuleName>.apinotes, and
+ /// are only applied when building the module <ModuleName>.
+ std::vector<std::string> ModuleSearchPaths;
+};
+
+} // namespace clang
+
+#endif // LLVM_CLANG_APINOTES_APINOTESOPTIONS_H
diff --git a/contrib/llvm-project/clang/include/clang/APINotes/APINotesReader.h b/contrib/llvm-project/clang/include/clang/APINotes/APINotesReader.h
new file mode 100644
index 000000000000..1c5aab095955
--- /dev/null
+++ b/contrib/llvm-project/clang/include/clang/APINotes/APINotesReader.h
@@ -0,0 +1,200 @@
+//===--- APINotesReader.h - API Notes Reader --------------------*- 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 the \c APINotesReader class that reads source API notes
+// data providing additional information about source code as a separate input,
+// such as the non-nil/nilable annotations for method parameters.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_APINOTES_READER_H
+#define LLVM_CLANG_APINOTES_READER_H
+
+#include "clang/APINotes/Types.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/VersionTuple.h"
+#include <memory>
+
+namespace clang {
+namespace api_notes {
+
+/// A class that reads API notes data from a binary file that was written by
+/// the \c APINotesWriter.
+class APINotesReader {
+ class Implementation;
+ std::unique_ptr<Implementation> Implementation;
+
+ APINotesReader(llvm::MemoryBuffer *InputBuffer,
+ llvm::VersionTuple SwiftVersion, bool &Failed);
+
+public:
+ /// Create a new API notes reader from the given member buffer, which
+ /// contains the contents of a binary API notes file.
+ ///
+ /// \returns the new API notes reader, or null if an error occurred.
+ static std::unique_ptr<APINotesReader>
+ Create(std::unique_ptr<llvm::MemoryBuffer> InputBuffer,
+ llvm::VersionTuple SwiftVersion);
+
+ ~APINotesReader();
+
+ APINotesReader(const APINotesReader &) = delete;
+ APINotesReader &operator=(const APINotesReader &) = delete;
+
+ /// Captures the completed versioned information for a particular part of
+ /// API notes, including both unversioned API notes and each versioned API
+ /// note for that particular entity.
+ template <typename T> class VersionedInfo {
+ /// The complete set of results.
+ llvm::SmallVector<std::pair<llvm::VersionTuple, T>, 1> Results;
+
+ /// The index of the result that is the "selected" set based on the desired
+ /// Swift version, or null if nothing matched.
+ std::optional<unsigned> Selected;
+
+ public:
+ /// Form an empty set of versioned information.
+ VersionedInfo(std::nullopt_t) : Selected(std::nullopt) {}
+
+ /// Form a versioned info set given the desired version and a set of
+ /// results.
+ VersionedInfo(
+ llvm::VersionTuple Version,
+ llvm::SmallVector<std::pair<llvm::VersionTuple, T>, 1> Results);
+
+ /// Retrieve the selected index in the result set.
+ std::optional<unsigned> getSelected() const { return Selected; }
+
+ /// Return the number of versioned results we know about.
+ unsigned size() const { return Results.size(); }
+
+ /// Access all versioned results.
+ const std::pair<llvm::VersionTuple, T> *begin() const {
+ assert(!Results.empty());
+ return Results.begin();
+ }
+ const std::pair<llvm::VersionTuple, T> *end() const {
+ return Results.end();
+ }
+
+ /// Access a specific versioned result.
+ const std::pair<llvm::VersionTuple, T> &operator[](unsigned index) const {
+ assert(index < Results.size());
+ return Results[index];
+ }
+ };
+
+ /// Look for the context ID of the given Objective-C class.
+ ///
+ /// \param Name The name of the class we're looking for.
+ ///
+ /// \returns The ID, if known.
+ std::optional<ContextID> lookupObjCClassID(llvm::StringRef Name);
+
+ /// Look for information regarding the given Objective-C class.
+ ///
+ /// \param Name The name of the class we're looking for.
+ ///
+ /// \returns The information about the class, if known.
+ VersionedInfo<ObjCContextInfo> lookupObjCClassInfo(llvm::StringRef Name);
+
+ /// Look for the context ID of the given Objective-C protocol.
+ ///
+ /// \param Name The name of the protocol we're looking for.
+ ///
+ /// \returns The ID of the protocol, if known.
+ std::optional<ContextID> lookupObjCProtocolID(llvm::StringRef Name);
+
+ /// Look for information regarding the given Objective-C protocol.
+ ///
+ /// \param Name The name of the protocol we're looking for.
+ ///
+ /// \returns The information about the protocol, if known.
+ VersionedInfo<ObjCContextInfo> lookupObjCProtocolInfo(llvm::StringRef Name);
+
+ /// Look for information regarding the given Objective-C property in
+ /// the given context.
+ ///
+ /// \param CtxID The ID that references the context we are looking for.
+ /// \param Name The name of the property we're looking for.
+ /// \param IsInstance Whether we are looking for an instance property (vs.
+ /// a class property).
+ ///
+ /// \returns Information about the property, if known.
+ VersionedInfo<ObjCPropertyInfo>
+ lookupObjCProperty(ContextID CtxID, llvm::StringRef Name, bool IsInstance);
+
+ /// Look for information regarding the given Objective-C method in
+ /// the given context.
+ ///
+ /// \param CtxID The ID that references the context we are looking for.
+ /// \param Selector The selector naming the method we're looking for.
+ /// \param IsInstanceMethod Whether we are looking for an instance method.
+ ///
+ /// \returns Information about the method, if known.
+ VersionedInfo<ObjCMethodInfo> lookupObjCMethod(ContextID CtxID,
+ ObjCSelectorRef Selector,
+ bool IsInstanceMethod);
+
+ /// Look for information regarding the given global variable.
+ ///
+ /// \param Name The name of the global variable.
+ ///
+ /// \returns information about the global variable, if known.
+ VersionedInfo<GlobalVariableInfo>
+ lookupGlobalVariable(llvm::StringRef Name,
+ std::optional<Context> Ctx = std::nullopt);
+
+ /// Look for information regarding the given global function.
+ ///
+ /// \param Name The name of the global function.
+ ///
+ /// \returns information about the global function, if known.
+ VersionedInfo<GlobalFunctionInfo>
+ lookupGlobalFunction(llvm::StringRef Name,
+ std::optional<Context> Ctx = std::nullopt);
+
+ /// Look for information regarding the given enumerator.
+ ///
+ /// \param Name The name of the enumerator.
+ ///
+ /// \returns information about the enumerator, if known.
+ VersionedInfo<EnumConstantInfo> lookupEnumConstant(llvm::StringRef Name);
+
+ /// Look for information regarding the given tag
+ /// (struct/union/enum/C++ class).
+ ///
+ /// \param Name The name of the tag.
+ ///
+ /// \returns information about the tag, if known.
+ VersionedInfo<TagInfo> lookupTag(llvm::StringRef Name,
+ std::optional<Context> Ctx = std::nullopt);
+
+ /// Look for information regarding the given typedef.
+ ///
+ /// \param Name The name of the typedef.
+ ///
+ /// \returns information about the typedef, if known.
+ VersionedInfo<TypedefInfo>
+ lookupTypedef(llvm::StringRef Name,
+ std::optional<Context> Ctx = std::nullopt);
+
+ /// Look for the context ID of the given C++ namespace.
+ ///
+ /// \param Name The name of the class we're looking for.
+ ///
+ /// \returns The ID, if known.
+ std::optional<ContextID>
+ lookupNamespaceID(llvm::StringRef Name,
+ std::optional<ContextID> ParentNamespaceID = std::nullopt);
+};
+
+} // end namespace api_notes
+} // end namespace clang
+
+#endif // LLVM_CLANG_APINOTES_READER_H
diff --git a/contrib/llvm-project/clang/include/clang/APINotes/APINotesWriter.h b/contrib/llvm-project/clang/include/clang/APINotes/APINotesWriter.h
new file mode 100644
index 000000000000..dad44623e16a
--- /dev/null
+++ b/contrib/llvm-project/clang/include/clang/APINotes/APINotesWriter.h
@@ -0,0 +1,110 @@
+//===-- APINotesWriter.h - API Notes Writer ---------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_APINOTES_WRITER_H
+#define LLVM_CLANG_APINOTES_WRITER_H
+
+#include "clang/APINotes/Types.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/VersionTuple.h"
+#include "llvm/Support/raw_ostream.h"
+
+#include <memory>
+
+namespace clang {
+class FileEntry;
+
+namespace api_notes {
+class APINotesWriter {
+ class Implementation;
+ std::unique_ptr<Implementation> Implementation;
+
+public:
+ APINotesWriter(llvm::StringRef ModuleName, const FileEntry *SF);
+ ~APINotesWriter();
+
+ APINotesWriter(const APINotesWriter &) = delete;
+ APINotesWriter &operator=(const APINotesWriter &) = delete;
+
+ void writeToStream(llvm::raw_ostream &OS);
+
+ /// Add information about a specific Objective-C class or protocol or a C++
+ /// namespace.
+ ///
+ /// \param Name The name of this class/protocol/namespace.
+ /// \param Kind Whether this is a class, a protocol, or a namespace.
+ /// \param Info Information about this class/protocol/namespace.
+ ///
+ /// \returns the ID of the class, protocol, or namespace, which can be used to
+ /// add properties and methods to the class/protocol/namespace.
+ ContextID addObjCContext(std::optional<ContextID> ParentCtxID,
+ llvm::StringRef Name, ContextKind Kind,
+ const ObjCContextInfo &Info,
+ llvm::VersionTuple SwiftVersion);
+
+ /// Add information about a specific Objective-C property.
+ ///
+ /// \param CtxID The context in which this property resides.
+ /// \param Name The name of this property.
+ /// \param Info Information about this property.
+ void addObjCProperty(ContextID CtxID, llvm::StringRef Name,
+ bool IsInstanceProperty, const ObjCPropertyInfo &Info,
+ llvm::VersionTuple SwiftVersion);
+
+ /// Add information about a specific Objective-C method.
+ ///
+ /// \param CtxID The context in which this method resides.
+ /// \param Selector The selector that names this method.
+ /// \param IsInstanceMethod Whether this method is an instance method
+ /// (vs. a class method).
+ /// \param Info Information about this method.
+ void addObjCMethod(ContextID CtxID, ObjCSelectorRef Selector,
+ bool IsInstanceMethod, const ObjCMethodInfo &Info,
+ llvm::VersionTuple SwiftVersion);
+
+ /// Add information about a global variable.
+ ///
+ /// \param Name The name of this global variable.
+ /// \param Info Information about this global variable.
+ void addGlobalVariable(std::optional<Context> Ctx, llvm::StringRef Name,
+ const GlobalVariableInfo &Info,
+ llvm::VersionTuple SwiftVersion);
+
+ /// Add information about a global function.
+ ///
+ /// \param Name The name of this global function.
+ /// \param Info Information about this global function.
+ void addGlobalFunction(std::optional<Context> Ctx, llvm::StringRef Name,
+ const GlobalFunctionInfo &Info,
+ llvm::VersionTuple SwiftVersion);
+
+ /// Add information about an enumerator.
+ ///
+ /// \param Name The name of this enumerator.
+ /// \param Info Information about this enumerator.
+ void addEnumConstant(llvm::StringRef Name, const EnumConstantInfo &Info,
+ llvm::VersionTuple SwiftVersion);
+
+ /// Add information about a tag (struct/union/enum/C++ class).
+ ///
+ /// \param Name The name of this tag.
+ /// \param Info Information about this tag.
+ void addTag(std::optional<Context> Ctx, llvm::StringRef Name,
+ const TagInfo &Info, llvm::VersionTuple SwiftVersion);
+
+ /// Add information about a typedef.
+ ///
+ /// \param Name The name of this typedef.
+ /// \param Info Information about this typedef.
+ void addTypedef(std::optional<Context> Ctx, llvm::StringRef Name,
+ const TypedefInfo &Info, llvm::VersionTuple SwiftVersion);
+};
+} // namespace api_notes
+} // namespace clang
+
+#endif // LLVM_CLANG_APINOTES_WRITER_H
diff --git a/contrib/llvm-project/clang/include/clang/APINotes/APINotesYAMLCompiler.h b/contrib/llvm-project/clang/include/clang/APINotes/APINotesYAMLCompiler.h
index 6098d0ee36fc..9c24ed85b6a1 100644
--- a/contrib/llvm-project/clang/include/clang/APINotes/APINotesYAMLCompiler.h
+++ b/contrib/llvm-project/clang/include/clang/APINotes/APINotesYAMLCompiler.h
@@ -10,14 +10,25 @@
#define LLVM_CLANG_APINOTES_APINOTESYAMLCOMPILER_H
#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/SourceMgr.h"
#include "llvm/Support/raw_ostream.h"
namespace clang {
+class FileEntry;
+} // namespace clang
+
+namespace clang {
namespace api_notes {
/// Parses the APINotes YAML content and writes the representation back to the
/// specified stream. This provides a means of testing the YAML processing of
/// the APINotes format.
bool parseAndDumpAPINotes(llvm::StringRef YI, llvm::raw_ostream &OS);
+
+/// Converts API notes from YAML format to binary format.
+bool compileAPINotes(llvm::StringRef YAMLInput, const FileEntry *SourceFile,
+ llvm::raw_ostream &OS,
+ llvm::SourceMgr::DiagHandlerTy DiagHandler = nullptr,
+ void *DiagHandlerCtxt = nullptr);
} // namespace api_notes
} // namespace clang
diff --git a/contrib/llvm-project/clang/include/clang/APINotes/Types.h b/contrib/llvm-project/clang/include/clang/APINotes/Types.h
index d9bf2f07291f..1d116becf06c 100644
--- a/contrib/llvm-project/clang/include/clang/APINotes/Types.h
+++ b/contrib/llvm-project/clang/include/clang/APINotes/Types.h
@@ -10,11 +10,16 @@
#define LLVM_CLANG_APINOTES_TYPES_H
#include "clang/Basic/Specifiers.h"
-#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/StringRef.h"
#include <climits>
+#include <optional>
#include <vector>
+namespace llvm {
+class raw_ostream;
+} // namespace llvm
+
namespace clang {
namespace api_notes {
enum class RetainCountConventionKind {
@@ -70,14 +75,14 @@ public:
: Unavailable(0), UnavailableInSwift(0), SwiftPrivateSpecified(0),
SwiftPrivate(0) {}
- llvm::Optional<bool> isSwiftPrivate() const {
- return SwiftPrivateSpecified ? llvm::Optional<bool>(SwiftPrivate)
- : llvm::None;
+ std::optional<bool> isSwiftPrivate() const {
+ return SwiftPrivateSpecified ? std::optional<bool>(SwiftPrivate)
+ : std::nullopt;
}
- void setSwiftPrivate(llvm::Optional<bool> Private) {
- SwiftPrivateSpecified = Private.hasValue();
- SwiftPrivate = Private.hasValue() ? *Private : 0;
+ void setSwiftPrivate(std::optional<bool> Private) {
+ SwiftPrivateSpecified = Private.has_value();
+ SwiftPrivate = Private.value_or(0);
}
friend bool operator==(const CommonEntityInfo &, const CommonEntityInfo &);
@@ -127,39 +132,33 @@ class CommonTypeInfo : public CommonEntityInfo {
/// The Swift type to which a given type is bridged.
///
/// Reflects the swift_bridge attribute.
- llvm::Optional<std::string> SwiftBridge;
+ std::optional<std::string> SwiftBridge;
/// The NS error domain for this type.
- llvm::Optional<std::string> NSErrorDomain;
+ std::optional<std::string> NSErrorDomain;
public:
- CommonTypeInfo() : CommonEntityInfo() {}
+ CommonTypeInfo() {}
- const llvm::Optional<std::string> &getSwiftBridge() const {
+ const std::optional<std::string> &getSwiftBridge() const {
return SwiftBridge;
}
- void setSwiftBridge(const llvm::Optional<std::string> &SwiftType) {
+ void setSwiftBridge(std::optional<std::string> SwiftType) {
SwiftBridge = SwiftType;
}
- void setSwiftBridge(const llvm::Optional<llvm::StringRef> &SwiftType) {
- SwiftBridge = SwiftType
- ? llvm::Optional<std::string>(std::string(*SwiftType))
- : llvm::None;
- }
-
- const llvm::Optional<std::string> &getNSErrorDomain() const {
+ const std::optional<std::string> &getNSErrorDomain() const {
return NSErrorDomain;
}
- void setNSErrorDomain(const llvm::Optional<std::string> &Domain) {
+ void setNSErrorDomain(const std::optional<std::string> &Domain) {
NSErrorDomain = Domain;
}
- void setNSErrorDomain(const llvm::Optional<llvm::StringRef> &Domain) {
- NSErrorDomain =
- Domain ? llvm::Optional<std::string>(std::string(*Domain)) : llvm::None;
+ void setNSErrorDomain(const std::optional<llvm::StringRef> &Domain) {
+ NSErrorDomain = Domain ? std::optional<std::string>(std::string(*Domain))
+ : std::nullopt;
}
friend bool operator==(const CommonTypeInfo &, const CommonTypeInfo &);
@@ -208,20 +207,20 @@ 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.
///
- /// eturns the default nullability, if implied, or None if there is no
- llvm::Optional<NullabilityKind> getDefaultNullability() const {
+ /// Returns the default nullability, if implied, or std::nullopt if there is
+ /// none.
+ std::optional<NullabilityKind> getDefaultNullability() const {
return HasDefaultNullability
- ? llvm::Optional<NullabilityKind>(
+ ? std::optional<NullabilityKind>(
static_cast<NullabilityKind>(DefaultNullability))
- : llvm::None;
+ : std::nullopt;
}
/// Set the default nullability for properties and methods of this class.
@@ -233,23 +232,23 @@ public:
bool hasDesignatedInits() const { return HasDesignatedInits; }
void setHasDesignatedInits(bool Value) { HasDesignatedInits = Value; }
- llvm::Optional<bool> getSwiftImportAsNonGeneric() const {
+ std::optional<bool> getSwiftImportAsNonGeneric() const {
return SwiftImportAsNonGenericSpecified
- ? llvm::Optional<bool>(SwiftImportAsNonGeneric)
- : llvm::None;
+ ? std::optional<bool>(SwiftImportAsNonGeneric)
+ : std::nullopt;
}
- void setSwiftImportAsNonGeneric(llvm::Optional<bool> Value) {
- SwiftImportAsNonGenericSpecified = Value.hasValue();
- SwiftImportAsNonGeneric = Value.hasValue() ? *Value : false;
+ void setSwiftImportAsNonGeneric(std::optional<bool> Value) {
+ SwiftImportAsNonGenericSpecified = Value.has_value();
+ SwiftImportAsNonGeneric = Value.value_or(false);
}
- llvm::Optional<bool> getSwiftObjCMembers() const {
- return SwiftObjCMembersSpecified ? llvm::Optional<bool>(SwiftObjCMembers)
- : llvm::None;
+ std::optional<bool> getSwiftObjCMembers() const {
+ return SwiftObjCMembersSpecified ? std::optional<bool>(SwiftObjCMembers)
+ : std::nullopt;
}
- void setSwiftObjCMembers(llvm::Optional<bool> Value) {
- SwiftObjCMembersSpecified = Value.hasValue();
- SwiftObjCMembers = Value.hasValue() ? *Value : false;
+ void setSwiftObjCMembers(std::optional<bool> Value) {
+ SwiftObjCMembersSpecified = Value.has_value();
+ SwiftObjCMembers = Value.value_or(false);
}
/// Strip off any information within the class information structure that is
@@ -309,12 +308,12 @@ 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>(
+ std::optional<NullabilityKind> getNullability() const {
+ return NullabilityAudited ? std::optional<NullabilityKind>(
static_cast<NullabilityKind>(Nullable))
- : llvm::None;
+ : std::nullopt;
}
void setNullabilityAudited(NullabilityKind kind) {
@@ -358,17 +357,16 @@ class ObjCPropertyInfo : public VariableInfo {
public:
ObjCPropertyInfo()
- : VariableInfo(), SwiftImportAsAccessorsSpecified(false),
- SwiftImportAsAccessors(false) {}
+ : SwiftImportAsAccessorsSpecified(false), SwiftImportAsAccessors(false) {}
- llvm::Optional<bool> getSwiftImportAsAccessors() const {
+ std::optional<bool> getSwiftImportAsAccessors() const {
return SwiftImportAsAccessorsSpecified
- ? llvm::Optional<bool>(SwiftImportAsAccessors)
- : llvm::None;
+ ? std::optional<bool>(SwiftImportAsAccessors)
+ : std::nullopt;
}
- void setSwiftImportAsAccessors(llvm::Optional<bool> Value) {
- SwiftImportAsAccessorsSpecified = Value.hasValue();
- SwiftImportAsAccessors = Value.hasValue() ? *Value : false;
+ void setSwiftImportAsAccessors(std::optional<bool> Value) {
+ SwiftImportAsAccessorsSpecified = Value.has_value();
+ SwiftImportAsAccessors = Value.value_or(false);
}
friend bool operator==(const ObjCPropertyInfo &, const ObjCPropertyInfo &);
@@ -423,28 +421,26 @@ class ParamInfo : public VariableInfo {
public:
ParamInfo()
- : VariableInfo(), NoEscapeSpecified(false), NoEscape(false),
- RawRetainCountConvention() {}
+ : NoEscapeSpecified(false), NoEscape(false), RawRetainCountConvention() {}
- llvm::Optional<bool> isNoEscape() const {
+ std::optional<bool> isNoEscape() const {
if (!NoEscapeSpecified)
- return llvm::None;
+ return std::nullopt;
return NoEscape;
}
- void setNoEscape(llvm::Optional<bool> Value) {
- NoEscapeSpecified = Value.hasValue();
- NoEscape = Value.hasValue() ? *Value : false;
+ void setNoEscape(std::optional<bool> Value) {
+ NoEscapeSpecified = Value.has_value();
+ NoEscape = Value.value_or(false);
}
- llvm::Optional<RetainCountConventionKind> getRetainCountConvention() const {
+ std::optional<RetainCountConventionKind> getRetainCountConvention() const {
if (!RawRetainCountConvention)
- return llvm::None;
+ return std::nullopt;
return static_cast<RetainCountConventionKind>(RawRetainCountConvention - 1);
}
void
- setRetainCountConvention(llvm::Optional<RetainCountConventionKind> Value) {
- RawRetainCountConvention =
- Value.hasValue() ? static_cast<unsigned>(Value.getValue()) + 1 : 0;
+ setRetainCountConvention(std::optional<RetainCountConventionKind> Value) {
+ RawRetainCountConvention = Value ? static_cast<unsigned>(*Value) + 1 : 0;
assert(getRetainCountConvention() == Value && "bitfield too small");
}
@@ -481,7 +477,7 @@ inline bool operator!=(const ParamInfo &LHS, const ParamInfo &RHS) {
/// API notes for a function or method.
class FunctionInfo : public CommonEntityInfo {
private:
- static constexpr const unsigned NullabilityKindMask = 0x3;
+ static constexpr const uint64_t NullabilityKindMask = 0x3;
static constexpr const unsigned NullabilityKindSize = 2;
static constexpr const unsigned ReturnInfoIndex = 0;
@@ -514,7 +510,7 @@ public:
std::vector<ParamInfo> Params;
FunctionInfo()
- : CommonEntityInfo(), NullabilityAudited(false), NumAdjustedNullable(0),
+ : NullabilityAudited(false), NumAdjustedNullable(0),
RawRetainCountConvention() {}
static unsigned getMaxNullabilityIndex() {
@@ -555,15 +551,14 @@ public:
NullabilityKind getReturnTypeInfo() const { return getTypeInfo(0); }
- llvm::Optional<RetainCountConventionKind> getRetainCountConvention() const {
+ std::optional<RetainCountConventionKind> getRetainCountConvention() const {
if (!RawRetainCountConvention)
- return llvm::None;
+ return std::nullopt;
return static_cast<RetainCountConventionKind>(RawRetainCountConvention - 1);
}
void
- setRetainCountConvention(llvm::Optional<RetainCountConventionKind> Value) {
- RawRetainCountConvention =
- Value.hasValue() ? static_cast<unsigned>(Value.getValue()) + 1 : 0;
+ setRetainCountConvention(std::optional<RetainCountConventionKind> Value) {
+ RawRetainCountConvention = Value ? static_cast<unsigned>(*Value) + 1 : 0;
assert(getRetainCountConvention() == Value && "bitfield too small");
}
@@ -607,8 +602,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 +633,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.
@@ -660,27 +654,38 @@ class TagInfo : public CommonTypeInfo {
unsigned IsFlagEnum : 1;
public:
- llvm::Optional<EnumExtensibilityKind> EnumExtensibility;
+ std::optional<std::string> SwiftImportAs;
+ std::optional<std::string> SwiftRetainOp;
+ std::optional<std::string> SwiftReleaseOp;
+
+ std::optional<EnumExtensibilityKind> EnumExtensibility;
- TagInfo() : CommonTypeInfo(), HasFlagEnum(0), IsFlagEnum(0) {}
+ TagInfo() : HasFlagEnum(0), IsFlagEnum(0) {}
- llvm::Optional<bool> isFlagEnum() const {
+ std::optional<bool> isFlagEnum() const {
if (HasFlagEnum)
return IsFlagEnum;
- return llvm::None;
+ return std::nullopt;
}
- void setFlagEnum(llvm::Optional<bool> Value) {
- HasFlagEnum = Value.hasValue();
- IsFlagEnum = Value.hasValue() ? *Value : false;
+ void setFlagEnum(std::optional<bool> Value) {
+ HasFlagEnum = Value.has_value();
+ IsFlagEnum = Value.value_or(false);
}
TagInfo &operator|=(const TagInfo &RHS) {
static_cast<CommonTypeInfo &>(*this) |= RHS;
- if (!HasFlagEnum && HasFlagEnum)
+ if (!SwiftImportAs)
+ SwiftImportAs = RHS.SwiftImportAs;
+ if (!SwiftRetainOp)
+ SwiftRetainOp = RHS.SwiftRetainOp;
+ if (!SwiftReleaseOp)
+ SwiftReleaseOp = RHS.SwiftReleaseOp;
+
+ if (!HasFlagEnum)
setFlagEnum(RHS.isFlagEnum());
- if (!EnumExtensibility.hasValue())
+ if (!EnumExtensibility)
EnumExtensibility = RHS.EnumExtensibility;
return *this;
@@ -693,6 +698,9 @@ public:
inline bool operator==(const TagInfo &LHS, const TagInfo &RHS) {
return static_cast<const CommonTypeInfo &>(LHS) == RHS &&
+ LHS.SwiftImportAs == RHS.SwiftImportAs &&
+ LHS.SwiftRetainOp == RHS.SwiftRetainOp &&
+ LHS.SwiftReleaseOp == RHS.SwiftReleaseOp &&
LHS.isFlagEnum() == RHS.isFlagEnum() &&
LHS.EnumExtensibility == RHS.EnumExtensibility;
}
@@ -704,13 +712,13 @@ inline bool operator!=(const TagInfo &LHS, const TagInfo &RHS) {
/// Describes API notes data for a typedef.
class TypedefInfo : public CommonTypeInfo {
public:
- llvm::Optional<SwiftNewTypeKind> SwiftWrapper;
+ std::optional<SwiftNewTypeKind> SwiftWrapper;
- TypedefInfo() : CommonTypeInfo() {}
+ TypedefInfo() {}
TypedefInfo &operator|=(const TypedefInfo &RHS) {
static_cast<CommonTypeInfo &>(*this) |= RHS;
- if (!SwiftWrapper.hasValue())
+ if (!SwiftWrapper)
SwiftWrapper = RHS.SwiftWrapper;
return *this;
}
@@ -728,6 +736,42 @@ inline bool operator==(const TypedefInfo &LHS, const TypedefInfo &RHS) {
inline bool operator!=(const TypedefInfo &LHS, const TypedefInfo &RHS) {
return !(LHS == RHS);
}
+
+/// The file extension used for the source representation of API notes.
+static const constexpr char SOURCE_APINOTES_EXTENSION[] = "apinotes";
+
+/// Opaque context ID used to refer to an Objective-C class or protocol or a C++
+/// namespace.
+class ContextID {
+public:
+ unsigned Value;
+
+ explicit ContextID(unsigned value) : Value(value) {}
+};
+
+enum class ContextKind : uint8_t {
+ ObjCClass = 0,
+ ObjCProtocol = 1,
+ Namespace = 2,
+};
+
+struct Context {
+ ContextID id;
+ ContextKind kind;
+
+ Context(ContextID id, ContextKind kind) : id(id), kind(kind) {}
+};
+
+/// A temporary reference to an Objective-C selector, suitable for
+/// referencing selector data on the stack.
+///
+/// Instances of this struct do not store references to any of the
+/// data they contain; it is up to the user to ensure that the data
+/// referenced by the identifier list persists.
+struct ObjCSelectorRef {
+ unsigned NumArgs;
+ llvm::ArrayRef<llvm::StringRef> Identifiers;
+};
} // namespace api_notes
} // namespace clang
diff --git a/contrib/llvm-project/clang/include/clang/ARCMigrate/ARCMT.h b/contrib/llvm-project/clang/include/clang/ARCMigrate/ARCMT.h
index 49e94a92cd0b..2b950e3d2cc2 100644
--- a/contrib/llvm-project/clang/include/clang/ARCMigrate/ARCMT.h
+++ b/contrib/llvm-project/clang/include/clang/ARCMigrate/ARCMT.h
@@ -102,7 +102,7 @@ class MigrationProcess {
public:
bool HadARCErrors;
- MigrationProcess(const CompilerInvocation &CI,
+ MigrationProcess(CompilerInvocation &CI,
std::shared_ptr<PCHContainerOperations> PCHContainerOps,
DiagnosticConsumer *diagClient,
StringRef outputDir = StringRef());
diff --git a/contrib/llvm-project/clang/include/clang/ARCMigrate/ARCMTActions.h b/contrib/llvm-project/clang/include/clang/ARCMigrate/ARCMTActions.h
index 641c259b3867..714f4b33db44 100644
--- a/contrib/llvm-project/clang/include/clang/ARCMigrate/ARCMTActions.h
+++ b/contrib/llvm-project/clang/include/clang/ARCMigrate/ARCMTActions.h
@@ -43,7 +43,7 @@ protected:
class MigrateAction : public WrapperFrontendAction {
std::string MigrateDir;
std::string PlistOut;
- bool EmitPremigrationARCErros;
+ bool EmitPremigrationARCErrors;
protected:
bool BeginInvocation(CompilerInstance &CI) override;
diff --git a/contrib/llvm-project/clang/include/clang/ARCMigrate/FileRemapper.h b/contrib/llvm-project/clang/include/clang/ARCMigrate/FileRemapper.h
index 4da68a678be2..afcee363516a 100644
--- a/contrib/llvm-project/clang/include/clang/ARCMigrate/FileRemapper.h
+++ b/contrib/llvm-project/clang/include/clang/ARCMigrate/FileRemapper.h
@@ -9,12 +9,13 @@
#ifndef LLVM_CLANG_ARCMIGRATE_FILEREMAPPER_H
#define LLVM_CLANG_ARCMIGRATE_FILEREMAPPER_H
+#include "clang/Basic/FileEntry.h"
#include "clang/Basic/LLVM.h"
#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/PointerUnion.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringRef.h"
#include <memory>
+#include <variant>
namespace llvm {
class MemoryBuffer;
@@ -23,7 +24,6 @@ namespace llvm {
namespace clang {
class FileManager;
- class FileEntry;
class DiagnosticsEngine;
class PreprocessorOptions;
@@ -33,11 +33,11 @@ class FileRemapper {
// FIXME: Reuse the same FileManager for multiple ASTContexts.
std::unique_ptr<FileManager> FileMgr;
- typedef llvm::PointerUnion<const FileEntry *, llvm::MemoryBuffer *> Target;
- typedef llvm::DenseMap<const FileEntry *, Target> MappingsTy;
+ using Target = std::variant<FileEntryRef, llvm::MemoryBuffer *>;
+ using MappingsTy = llvm::DenseMap<FileEntryRef, Target>;
MappingsTy FromToMappings;
- llvm::DenseMap<const FileEntry *, const FileEntry *> ToFromMappings;
+ llvm::DenseMap<const FileEntry *, FileEntryRef> ToFromMappings;
public:
FileRemapper();
@@ -66,10 +66,10 @@ public:
void clear(StringRef outputDir = StringRef());
private:
- void remap(const FileEntry *file, std::unique_ptr<llvm::MemoryBuffer> memBuf);
- void remap(const FileEntry *file, const FileEntry *newfile);
+ void remap(FileEntryRef file, std::unique_ptr<llvm::MemoryBuffer> memBuf);
+ void remap(FileEntryRef file, FileEntryRef newfile);
- const FileEntry *getOriginalFile(StringRef filePath);
+ OptionalFileEntryRef getOriginalFile(StringRef filePath);
void resetTarget(Target &targ);
bool report(const Twine &err, DiagnosticsEngine &Diag);
diff --git a/contrib/llvm-project/clang/include/clang/AST/APNumericStorage.h b/contrib/llvm-project/clang/include/clang/AST/APNumericStorage.h
new file mode 100644
index 000000000000..95eddbcd86e8
--- /dev/null
+++ b/contrib/llvm-project/clang/include/clang/AST/APNumericStorage.h
@@ -0,0 +1,71 @@
+//===--- APNumericStorage.h - Store APInt/APFloat in ASTContext -*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_APNUMERICSTORAGE_H
+#define LLVM_CLANG_AST_APNUMERICSTORAGE_H
+
+#include "llvm/ADT/APFloat.h"
+#include "llvm/ADT/APInt.h"
+
+namespace clang {
+class ASTContext;
+
+/// Used by IntegerLiteral/FloatingLiteral/EnumConstantDecl to store the
+/// numeric without leaking memory.
+///
+/// For large floats/integers, APFloat/APInt will allocate memory from the heap
+/// to represent these numbers. Unfortunately, when we use a BumpPtrAllocator
+/// to allocate IntegerLiteral/FloatingLiteral nodes the memory associated with
+/// the APFloat/APInt values will never get freed. APNumericStorage uses
+/// ASTContext's allocator for memory allocation.
+class APNumericStorage {
+ union {
+ uint64_t VAL; ///< Used to store the <= 64 bits integer value.
+ uint64_t *pVal; ///< Used to store the >64 bits integer value.
+ };
+ unsigned BitWidth;
+
+ bool hasAllocation() const { return llvm::APInt::getNumWords(BitWidth) > 1; }
+
+ APNumericStorage(const APNumericStorage &) = delete;
+ void operator=(const APNumericStorage &) = delete;
+
+protected:
+ APNumericStorage() : VAL(0), BitWidth(0) {}
+
+ llvm::APInt getIntValue() const {
+ unsigned NumWords = llvm::APInt::getNumWords(BitWidth);
+ if (NumWords > 1)
+ return llvm::APInt(BitWidth, NumWords, pVal);
+ else
+ return llvm::APInt(BitWidth, VAL);
+ }
+ void setIntValue(const ASTContext &C, const llvm::APInt &Val);
+};
+
+class APIntStorage : private APNumericStorage {
+public:
+ llvm::APInt getValue() const { return getIntValue(); }
+ void setValue(const ASTContext &C, const llvm::APInt &Val) {
+ setIntValue(C, Val);
+ }
+};
+
+class APFloatStorage : private APNumericStorage {
+public:
+ llvm::APFloat getValue(const llvm::fltSemantics &Semantics) const {
+ return llvm::APFloat(Semantics, getIntValue());
+ }
+ void setValue(const ASTContext &C, const llvm::APFloat &Val) {
+ setIntValue(C, Val.bitcastToAPInt());
+ }
+};
+
+} // end namespace clang
+
+#endif // LLVM_CLANG_AST_APNUMERICSTORAGE_H
diff --git a/contrib/llvm-project/clang/include/clang/AST/APValue.h b/contrib/llvm-project/clang/include/clang/AST/APValue.h
index 5f4ac02f53c9..c4206b73b115 100644
--- a/contrib/llvm-project/clang/include/clang/AST/APValue.h
+++ b/contrib/llvm-project/clang/include/clang/AST/APValue.h
@@ -238,7 +238,7 @@ public:
}
};
class LValuePathSerializationHelper {
- const void *ElemTy;
+ const void *Ty;
public:
ArrayRef<LValuePathEntry> Path;
@@ -267,15 +267,19 @@ private:
};
struct LV;
struct Vec {
- APValue *Elts;
- unsigned NumElts;
- Vec() : Elts(nullptr), NumElts(0) {}
+ APValue *Elts = nullptr;
+ unsigned NumElts = 0;
+ Vec() = default;
+ Vec(const Vec &) = delete;
+ Vec &operator=(const Vec &) = delete;
~Vec() { delete[] Elts; }
};
struct Arr {
APValue *Elts;
unsigned NumElts, ArrSize;
Arr(unsigned NumElts, unsigned ArrSize);
+ Arr(const Arr &) = delete;
+ Arr &operator=(const Arr &) = delete;
~Arr();
};
struct StructData {
@@ -283,12 +287,16 @@ private:
unsigned NumBases;
unsigned NumFields;
StructData(unsigned NumBases, unsigned NumFields);
+ StructData(const StructData &) = delete;
+ StructData &operator=(const StructData &) = delete;
~StructData();
};
struct UnionData {
const FieldDecl *Field;
APValue *Value;
UnionData();
+ UnionData(const UnionData &) = delete;
+ UnionData &operator=(const UnionData &) = delete;
~UnionData();
};
struct AddrLabelDiffData {
diff --git a/contrib/llvm-project/clang/include/clang/AST/ASTConcept.h b/contrib/llvm-project/clang/include/clang/AST/ASTConcept.h
index d0526f4fa5c5..5f9aa41d3e6c 100644
--- a/contrib/llvm-project/clang/include/clang/AST/ASTConcept.h
+++ b/contrib/llvm-project/clang/include/clang/AST/ASTConcept.h
@@ -1,9 +1,8 @@
//===--- ASTConcept.h - Concepts Related AST Data Structures ----*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// 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
//
//===----------------------------------------------------------------------===//
///
@@ -15,15 +14,21 @@
#ifndef LLVM_CLANG_AST_ASTCONCEPT_H
#define LLVM_CLANG_AST_ASTCONCEPT_H
-#include "clang/AST/Expr.h"
+#include "clang/AST/DeclarationName.h"
+#include "clang/AST/NestedNameSpecifier.h"
+#include "clang/AST/TemplateBase.h"
#include "clang/Basic/SourceLocation.h"
+#include "llvm/ADT/FoldingSet.h"
#include "llvm/ADT/PointerUnion.h"
#include "llvm/ADT/SmallVector.h"
#include <utility>
namespace clang {
+
class ConceptDecl;
-class ConceptSpecializationExpr;
+class Expr;
+class NamedDecl;
+struct PrintingPolicy;
/// The result of a constraint satisfaction check, containing the necessary
/// information to diagnose an unsatisfied constraint.
@@ -46,6 +51,7 @@ public:
using Detail = llvm::PointerUnion<Expr *, SubstitutionDiagnostic *>;
bool IsSatisfied = false;
+ bool ContainsErrors = false;
/// \brief Pairs of unsatisfied atomic constraint expressions along with the
/// substituted constraint expr, if the template arguments could be
@@ -60,6 +66,13 @@ public:
static void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &C,
const NamedDecl *ConstraintOwner,
ArrayRef<TemplateArgument> TemplateArgs);
+
+ bool HasSubstitutionFailure() {
+ for (const auto &Detail : Details)
+ if (Detail.second.dyn_cast<SubstitutionDiagnostic *>())
+ return true;
+ return false;
+ }
};
/// Pairs of unsatisfied atomic constraint expressions along with the
@@ -80,6 +93,7 @@ struct ASTConstraintSatisfaction final :
UnsatisfiedConstraintRecord> {
std::size_t NumRecords;
bool IsSatisfied : 1;
+ bool ContainsErrors : 1;
const UnsatisfiedConstraintRecord *begin() const {
return getTrailingObjects<UnsatisfiedConstraintRecord>();
@@ -91,15 +105,27 @@ struct ASTConstraintSatisfaction final :
ASTConstraintSatisfaction(const ASTContext &C,
const ConstraintSatisfaction &Satisfaction);
+ ASTConstraintSatisfaction(const ASTContext &C,
+ const ASTConstraintSatisfaction &Satisfaction);
static ASTConstraintSatisfaction *
Create(const ASTContext &C, const ConstraintSatisfaction &Satisfaction);
+ static ASTConstraintSatisfaction *
+ Rebuild(const ASTContext &C, const ASTConstraintSatisfaction &Satisfaction);
};
-/// \brief Common data class for constructs that reference concepts with
-/// template arguments.
+/// A reference to a concept and its template args, as it appears in the code.
+///
+/// Examples:
+/// template <int X> requires is_even<X> int half = X/2;
+/// ~~~~~~~~~~ (in ConceptSpecializationExpr)
+///
+/// std::input_iterator auto I = Container.begin();
+/// ~~~~~~~~~~~~~~~~~~~ (in AutoTypeLoc)
+///
+/// template <std::derives_from<Expr> T> void dump();
+/// ~~~~~~~~~~~~~~~~~~~~~~~ (in TemplateTypeParmDecl)
class ConceptReference {
-protected:
// \brief The optional nested name specifier used when naming the concept.
NestedNameSpecifierLoc NestedNameSpec;
@@ -123,18 +149,20 @@ protected:
/// concept.
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) {}
+public:
+ static ConceptReference *
+ Create(const ASTContext &C, NestedNameSpecifierLoc NNS,
+ SourceLocation TemplateKWLoc, DeclarationNameInfo ConceptNameInfo,
+ NamedDecl *FoundDecl, ConceptDecl *NamedConcept,
+ const ASTTemplateArgumentListInfo *ArgsAsWritten);
const NestedNameSpecifierLoc &getNestedNameSpecifierLoc() const {
return NestedNameSpec;
@@ -148,6 +176,26 @@ public:
SourceLocation getTemplateKWLoc() const { return TemplateKWLoc; }
+ SourceLocation getLocation() const { return getConceptNameLoc(); }
+
+ SourceLocation getBeginLoc() const LLVM_READONLY {
+ // Note that if the qualifier is null the template KW must also be null.
+ if (auto QualifierLoc = getNestedNameSpecifierLoc())
+ return QualifierLoc.getBeginLoc();
+ return getConceptNameInfo().getBeginLoc();
+ }
+
+ SourceLocation getEndLoc() const LLVM_READONLY {
+ return getTemplateArgsAsWritten() &&
+ getTemplateArgsAsWritten()->getRAngleLoc().isValid()
+ ? getTemplateArgsAsWritten()->getRAngleLoc()
+ : getConceptNameInfo().getEndLoc();
+ }
+
+ SourceRange getSourceRange() const LLVM_READONLY {
+ return SourceRange(getBeginLoc(), getEndLoc());
+ }
+
NamedDecl *getFoundDecl() const {
return FoundDecl;
}
@@ -165,22 +213,32 @@ public:
bool hasExplicitTemplateArgs() const {
return ArgsAsWritten != nullptr;
}
+
+ void print(llvm::raw_ostream &OS, const PrintingPolicy &Policy) const;
+ void dump() const;
+ void dump(llvm::raw_ostream &) const;
};
-class TypeConstraint : public ConceptReference {
+/// Models the abbreviated syntax to constrain a template type parameter:
+/// template <convertible_to<string> T> void print(T object);
+/// ~~~~~~~~~~~~~~~~~~~~~~
+/// Semantically, this adds an "immediately-declared constraint" with extra arg:
+/// requires convertible_to<T, string>
+///
+/// In the C++ grammar, a type-constraint is also used for auto types:
+/// convertible_to<string> auto X = ...;
+/// We do *not* model these as TypeConstraints, but AutoType(Loc) directly.
+class TypeConstraint {
/// \brief The immediately-declared constraint expression introduced by this
/// type-constraint.
Expr *ImmediatelyDeclaredConstraint = nullptr;
+ ConceptReference *ConceptRef;
public:
- TypeConstraint(NestedNameSpecifierLoc NNS,
- DeclarationNameInfo ConceptNameInfo, NamedDecl *FoundDecl,
- ConceptDecl *NamedConcept,
- const ASTTemplateArgumentListInfo *ArgsAsWritten,
- Expr *ImmediatelyDeclaredConstraint) :
- ConceptReference(NNS, /*TemplateKWLoc=*/SourceLocation(), ConceptNameInfo,
- FoundDecl, NamedConcept, ArgsAsWritten),
- ImmediatelyDeclaredConstraint(ImmediatelyDeclaredConstraint) {}
+ TypeConstraint(ConceptReference *ConceptRef,
+ Expr *ImmediatelyDeclaredConstraint)
+ : ImmediatelyDeclaredConstraint(ImmediatelyDeclaredConstraint),
+ ConceptRef(ConceptRef) {}
/// \brief Get the immediately-declared constraint expression introduced by
/// this type-constraint, that is - the constraint expression that is added to
@@ -189,7 +247,41 @@ public:
return ImmediatelyDeclaredConstraint;
}
- void print(llvm::raw_ostream &OS, PrintingPolicy Policy) const;
+ ConceptReference *getConceptReference() const { return ConceptRef; }
+
+ // FIXME: Instead of using these concept related functions the callers should
+ // directly work with the corresponding ConceptReference.
+ ConceptDecl *getNamedConcept() const { return ConceptRef->getNamedConcept(); }
+
+ SourceLocation getConceptNameLoc() const {
+ return ConceptRef->getConceptNameLoc();
+ }
+
+ bool hasExplicitTemplateArgs() const {
+ return ConceptRef->hasExplicitTemplateArgs();
+ }
+
+ const ASTTemplateArgumentListInfo *getTemplateArgsAsWritten() const {
+ return ConceptRef->getTemplateArgsAsWritten();
+ }
+
+ SourceLocation getTemplateKWLoc() const {
+ return ConceptRef->getTemplateKWLoc();
+ }
+
+ NamedDecl *getFoundDecl() const { return ConceptRef->getFoundDecl(); }
+
+ const NestedNameSpecifierLoc &getNestedNameSpecifierLoc() const {
+ return ConceptRef->getNestedNameSpecifierLoc();
+ }
+
+ const DeclarationNameInfo &getConceptNameInfo() const {
+ return ConceptRef->getConceptNameInfo();
+ }
+
+ void print(llvm::raw_ostream &OS, const PrintingPolicy &Policy) const {
+ ConceptRef->print(OS, Policy);
+ }
};
} // clang
diff --git a/contrib/llvm-project/clang/include/clang/AST/ASTConsumer.h b/contrib/llvm-project/clang/include/clang/AST/ASTConsumer.h
index ecdd8e873e1e..ebcd8059284d 100644
--- a/contrib/llvm-project/clang/include/clang/AST/ASTConsumer.h
+++ b/contrib/llvm-project/clang/include/clang/AST/ASTConsumer.h
@@ -33,12 +33,12 @@ namespace clang {
class ASTConsumer {
/// Whether this AST consumer also requires information about
/// semantic analysis.
- bool SemaConsumer;
+ bool SemaConsumer = false;
friend class SemaConsumer;
public:
- ASTConsumer() : SemaConsumer(false) { }
+ ASTConsumer() = default;
virtual ~ASTConsumer() {}
@@ -76,7 +76,7 @@ public:
virtual void HandleTagDeclRequiredDefinition(const TagDecl *D) {}
/// Invoked when a function is implicitly instantiated.
- /// Note that at this point point it does not have a body, its body is
+ /// Note that at this point it does not have a body, its body is
/// instantiated at the end of the translation unit and passed to
/// HandleTopLevelDecl.
virtual void HandleCXXImplicitFunctionInstantiation(FunctionDecl *D) {}
diff --git a/contrib/llvm-project/clang/include/clang/AST/ASTContext.h b/contrib/llvm-project/clang/include/clang/AST/ASTContext.h
index 34299581d89d..3e46a5da3fc0 100644
--- a/contrib/llvm-project/clang/include/clang/AST/ASTContext.h
+++ b/contrib/llvm-project/clang/include/clang/AST/ASTContext.h
@@ -14,65 +14,32 @@
#ifndef LLVM_CLANG_AST_ASTCONTEXT_H
#define LLVM_CLANG_AST_ASTCONTEXT_H
-#include "clang/AST/ASTContextAllocate.h"
#include "clang/AST/ASTFwd.h"
#include "clang/AST/CanonicalType.h"
#include "clang/AST/CommentCommandTraits.h"
#include "clang/AST/ComparisonCategories.h"
#include "clang/AST/Decl.h"
-#include "clang/AST/DeclBase.h"
#include "clang/AST/DeclarationName.h"
#include "clang/AST/ExternalASTSource.h"
-#include "clang/AST/NestedNameSpecifier.h"
#include "clang/AST/PrettyPrinter.h"
#include "clang/AST/RawCommentList.h"
#include "clang/AST/TemplateName.h"
-#include "clang/AST/Type.h"
-#include "clang/Basic/AddressSpaces.h"
-#include "clang/Basic/AttrKinds.h"
-#include "clang/Basic/IdentifierTable.h"
#include "clang/Basic/LLVM.h"
-#include "clang/Basic/LangOptions.h"
-#include "clang/Basic/Linkage.h"
-#include "clang/Basic/NoSanitizeList.h"
-#include "clang/Basic/OperatorKinds.h"
#include "clang/Basic/PartialDiagnostic.h"
-#include "clang/Basic/ProfileList.h"
#include "clang/Basic/SourceLocation.h"
-#include "clang/Basic/Specifiers.h"
-#include "clang/Basic/TargetCXXABI.h"
-#include "clang/Basic/XRayLists.h"
-#include "llvm/ADT/APSInt.h"
-#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/FoldingSet.h"
#include "llvm/ADT/IntrusiveRefCntPtr.h"
#include "llvm/ADT/MapVector.h"
-#include "llvm/ADT/None.h"
-#include "llvm/ADT/Optional.h"
#include "llvm/ADT/PointerIntPair.h"
#include "llvm/ADT/PointerUnion.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/TinyPtrVector.h"
-#include "llvm/ADT/Triple.h"
-#include "llvm/ADT/iterator_range.h"
-#include "llvm/Support/AlignOf.h"
-#include "llvm/Support/Allocator.h"
-#include "llvm/Support/Casting.h"
-#include "llvm/Support/Compiler.h"
#include "llvm/Support/TypeSize.h"
-#include <cassert>
-#include <cstddef>
-#include <cstdint>
-#include <iterator>
-#include <memory>
-#include <string>
-#include <type_traits>
-#include <utility>
-#include <vector>
+#include <optional>
namespace llvm {
@@ -90,6 +57,7 @@ class ASTMutationListener;
class ASTRecordLayout;
class AtomicExpr;
class BlockExpr;
+struct BlockVarCopyInit;
class BuiltinTemplateDecl;
class CharUnits;
class ConceptDecl;
@@ -98,18 +66,19 @@ class CXXConstructorDecl;
class CXXMethodDecl;
class CXXRecordDecl;
class DiagnosticsEngine;
-class ParentMapContext;
-class DynTypedNode;
class DynTypedNodeList;
class Expr;
+enum class FloatModeKind;
class GlobalDecl;
-class ItaniumMangleContext;
+class IdentifierTable;
+class LangOptions;
class MangleContext;
class MangleNumberingContext;
-class MaterializeTemporaryExpr;
class MemberSpecializationInfo;
class Module;
struct MSGuidDeclParts;
+class NestedNameSpecifier;
+class NoSanitizeList;
class ObjCCategoryDecl;
class ObjCCategoryImplDecl;
class ObjCContainerDecl;
@@ -123,9 +92,10 @@ class ObjCPropertyImplDecl;
class ObjCProtocolDecl;
class ObjCTypeParamDecl;
class OMPTraitInfo;
+class ParentMapContext;
struct ParsedTargetAttr;
class Preprocessor;
-class Stmt;
+class ProfileList;
class StoredDeclsMap;
class TargetAttr;
class TargetInfo;
@@ -133,11 +103,12 @@ class TemplateDecl;
class TemplateParameterList;
class TemplateTemplateParmDecl;
class TemplateTypeParmDecl;
+class TypeConstraint;
class UnresolvedSetIterator;
class UsingShadowDecl;
class VarTemplateDecl;
class VTableContextBase;
-struct BlockVarCopyInit;
+class XRayFunctionFilter;
namespace Builtin {
@@ -164,24 +135,46 @@ namespace serialization {
template <class> class AbstractTypeReader;
} // namespace serialization
+enum class AlignRequirementKind {
+ /// The alignment was not explicit in code.
+ None,
+
+ /// The alignment comes from an alignment attribute on a typedef.
+ RequiredByTypedef,
+
+ /// The alignment comes from an alignment attribute on a record type.
+ RequiredByRecord,
+
+ /// The alignment comes from an alignment attribute on a enum type.
+ RequiredByEnum,
+};
+
struct TypeInfo {
uint64_t Width = 0;
unsigned Align = 0;
- bool AlignIsRequired : 1;
+ AlignRequirementKind AlignRequirement;
- TypeInfo() : AlignIsRequired(false) {}
- TypeInfo(uint64_t Width, unsigned Align, bool AlignIsRequired)
- : Width(Width), Align(Align), AlignIsRequired(AlignIsRequired) {}
+ TypeInfo() : AlignRequirement(AlignRequirementKind::None) {}
+ TypeInfo(uint64_t Width, unsigned Align,
+ AlignRequirementKind AlignRequirement)
+ : Width(Width), Align(Align), AlignRequirement(AlignRequirement) {}
+ bool isAlignRequired() {
+ return AlignRequirement != AlignRequirementKind::None;
+ }
};
struct TypeInfoChars {
CharUnits Width;
CharUnits Align;
- bool AlignIsRequired : 1;
+ AlignRequirementKind AlignRequirement;
- TypeInfoChars() : AlignIsRequired(false) {}
- TypeInfoChars(CharUnits Width, CharUnits Align, bool AlignIsRequired)
- : Width(Width), Align(Align), AlignIsRequired(AlignIsRequired) {}
+ TypeInfoChars() : AlignRequirement(AlignRequirementKind::None) {}
+ TypeInfoChars(CharUnits Width, CharUnits Align,
+ AlignRequirementKind AlignRequirement)
+ : Width(Width), Align(Align), AlignRequirement(AlignRequirement) {}
+ bool isAlignRequired() {
+ return AlignRequirement != AlignRequirementKind::None;
+ }
};
/// Holds long-lived AST nodes (such as types and decls) that can be
@@ -192,7 +185,7 @@ class ASTContext : public RefCountedBase<ASTContext> {
mutable SmallVector<Type *, 0> Types;
mutable llvm::FoldingSet<ExtQuals> ExtQualNodes;
mutable llvm::FoldingSet<ComplexType> ComplexTypes;
- mutable llvm::FoldingSet<PointerType> PointerTypes;
+ mutable llvm::FoldingSet<PointerType> PointerTypes{GeneralTypesLog2InitSize};
mutable llvm::FoldingSet<AdjustedType> AdjustedTypes;
mutable llvm::FoldingSet<BlockPointerType> BlockPointerTypes;
mutable llvm::FoldingSet<LValueReferenceType> LValueReferenceTypes;
@@ -202,20 +195,25 @@ class ASTContext : public RefCountedBase<ASTContext> {
ConstantArrayTypes;
mutable llvm::FoldingSet<IncompleteArrayType> IncompleteArrayTypes;
mutable std::vector<VariableArrayType*> VariableArrayTypes;
- mutable llvm::FoldingSet<DependentSizedArrayType> DependentSizedArrayTypes;
- mutable llvm::FoldingSet<DependentSizedExtVectorType>
- DependentSizedExtVectorTypes;
- mutable llvm::FoldingSet<DependentAddressSpaceType>
+ mutable llvm::ContextualFoldingSet<DependentSizedArrayType, ASTContext &>
+ DependentSizedArrayTypes;
+ mutable llvm::ContextualFoldingSet<DependentSizedExtVectorType, ASTContext &>
+ DependentSizedExtVectorTypes;
+ mutable llvm::ContextualFoldingSet<DependentAddressSpaceType, ASTContext &>
DependentAddressSpaceTypes;
mutable llvm::FoldingSet<VectorType> VectorTypes;
- mutable llvm::FoldingSet<DependentVectorType> DependentVectorTypes;
+ mutable llvm::ContextualFoldingSet<DependentVectorType, ASTContext &>
+ DependentVectorTypes;
mutable llvm::FoldingSet<ConstantMatrixType> MatrixTypes;
- mutable llvm::FoldingSet<DependentSizedMatrixType> DependentSizedMatrixTypes;
+ mutable llvm::ContextualFoldingSet<DependentSizedMatrixType, ASTContext &>
+ DependentSizedMatrixTypes;
mutable llvm::FoldingSet<FunctionNoProtoType> FunctionNoProtoTypes;
mutable llvm::ContextualFoldingSet<FunctionProtoType, ASTContext&>
FunctionProtoTypes;
- mutable llvm::FoldingSet<DependentTypeOfExprType> DependentTypeOfExprTypes;
- mutable llvm::FoldingSet<DependentDecltypeType> DependentDecltypeTypes;
+ mutable llvm::ContextualFoldingSet<DependentTypeOfExprType, ASTContext &>
+ DependentTypeOfExprTypes;
+ mutable llvm::ContextualFoldingSet<DependentDecltypeType, ASTContext &>
+ DependentDecltypeTypes;
mutable llvm::FoldingSet<TemplateTypeParmType> TemplateTypeParmTypes;
mutable llvm::FoldingSet<ObjCTypeParamType> ObjCTypeParamTypes;
mutable llvm::FoldingSet<SubstTemplateTypeParmType>
@@ -224,8 +222,11 @@ class ASTContext : public RefCountedBase<ASTContext> {
SubstTemplateTypeParmPackTypes;
mutable llvm::ContextualFoldingSet<TemplateSpecializationType, ASTContext&>
TemplateSpecializationTypes;
- mutable llvm::FoldingSet<ParenType> ParenTypes;
- mutable llvm::FoldingSet<ElaboratedType> ElaboratedTypes;
+ mutable llvm::FoldingSet<ParenType> ParenTypes{GeneralTypesLog2InitSize};
+ mutable llvm::FoldingSet<UsingType> UsingTypes;
+ mutable llvm::FoldingSet<TypedefType> TypedefTypes;
+ mutable llvm::FoldingSet<ElaboratedType> ElaboratedTypes{
+ GeneralTypesLog2InitSize};
mutable llvm::FoldingSet<DependentNameType> DependentNameTypes;
mutable llvm::ContextualFoldingSet<DependentTemplateSpecializationType,
ASTContext&>
@@ -239,10 +240,12 @@ class ASTContext : public RefCountedBase<ASTContext> {
mutable llvm::FoldingSet<DeducedTemplateSpecializationType>
DeducedTemplateSpecializationTypes;
mutable llvm::FoldingSet<AtomicType> AtomicTypes;
- llvm::FoldingSet<AttributedType> AttributedTypes;
+ mutable llvm::FoldingSet<AttributedType> AttributedTypes;
mutable llvm::FoldingSet<PipeType> PipeTypes;
- mutable llvm::FoldingSet<ExtIntType> ExtIntTypes;
- mutable llvm::FoldingSet<DependentExtIntType> DependentExtIntTypes;
+ mutable llvm::FoldingSet<BitIntType> BitIntTypes;
+ mutable llvm::ContextualFoldingSet<DependentBitIntType, ASTContext &>
+ DependentBitIntTypes;
+ llvm::FoldingSet<BTFTagAttributedType> BTFTagAttributedTypes;
mutable llvm::FoldingSet<QualifiedTemplateName> QualifiedTemplateNames;
mutable llvm::FoldingSet<DependentTemplateName> DependentTemplateNames;
@@ -292,6 +295,10 @@ class ASTContext : public RefCountedBase<ASTContext> {
/// Mapping from GUIDs to the corresponding MSGuidDecl.
mutable llvm::FoldingSet<MSGuidDecl> MSGuidDecls;
+ /// Mapping from APValues to the corresponding UnnamedGlobalConstantDecl.
+ mutable llvm::FoldingSet<UnnamedGlobalConstantDecl>
+ UnnamedGlobalConstantDecls;
+
/// Mapping from APValues to the corresponding TemplateParamObjects.
mutable llvm::FoldingSet<TemplateParamObjectDecl> TemplateParamObjectDecls;
@@ -446,6 +453,13 @@ class ASTContext : public RefCountedBase<ASTContext> {
};
llvm::DenseMap<Module*, PerModuleInitializers*> ModuleInitializers;
+ /// This is the top-level (C++20) Named module we are building.
+ Module *CurrentCXXNamedModule = nullptr;
+
+ static constexpr unsigned ConstantArrayTypesLog2InitSize = 8;
+ static constexpr unsigned GeneralTypesLog2InitSize = 9;
+ static constexpr unsigned FunctionProtoTypesLog2InitSize = 12;
+
ASTContext &this_() { return *this; }
public:
@@ -605,9 +619,6 @@ private:
std::unique_ptr<CXXABI> ABI;
CXXABI *createCXXABI(const TargetInfo &T);
- /// The logical -> physical address space map.
- const LangASMap *AddrSpaceMap = nullptr;
-
/// Address space map mangling must be used with language specific
/// address spaces (e.g. OpenCL/CUDA)
bool AddrSpaceMapMangling;
@@ -633,6 +644,20 @@ public:
/// Returns the clang bytecode interpreter context.
interp::Context &getInterpContext();
+ struct CUDAConstantEvalContext {
+ /// Do not allow wrong-sided variables in constant expressions.
+ bool NoWrongSidedVars = false;
+ } CUDAConstantEvalCtx;
+ struct CUDAConstantEvalContextRAII {
+ ASTContext &Ctx;
+ CUDAConstantEvalContext SavedCtx;
+ CUDAConstantEvalContextRAII(ASTContext &Ctx_, bool NoWrongSidedVars)
+ : Ctx(Ctx_), SavedCtx(Ctx_.CUDAConstantEvalCtx) {
+ Ctx_.CUDAConstantEvalCtx.NoWrongSidedVars = NoWrongSidedVars;
+ }
+ ~CUDAConstantEvalContextRAII() { Ctx.CUDAConstantEvalCtx = SavedCtx; }
+ };
+
/// Returns the dynamic AST node parent map context.
ParentMapContext &getParentMapContext();
@@ -672,6 +697,12 @@ public:
SourceManager& getSourceManager() { return SourceMgr; }
const SourceManager& getSourceManager() const { return SourceMgr; }
+ // Cleans up some of the data structures. This allows us to do cleanup
+ // normally done in the destructor earlier. Renders much of the ASTContext
+ // unusable, mostly the actual AST nodes, so should be called when we no
+ // longer need access to the AST.
+ void cleanup();
+
llvm::BumpPtrAllocator &getAllocator() const {
return BumpAlloc;
}
@@ -728,7 +759,8 @@ public:
/// getRealTypeForBitwidth -
/// sets floating point QualTy according to specified bitwidth.
/// Returns empty type if there is no appropriate target types.
- QualType getRealTypeForBitwidth(unsigned DestWidth, bool ExplicitIEEE) const;
+ QualType getRealTypeForBitwidth(unsigned DestWidth,
+ FloatModeKind ExplicitType) const;
bool AtomicUsesUnsupportedLibcall(const AtomicExpr *E) const;
@@ -1024,6 +1056,12 @@ public:
/// Get the initializations to perform when importing a module, if any.
ArrayRef<Decl*> getModuleInitializers(Module *M);
+ /// Set the (C++20) module we are building.
+ void setCurrentNamedModule(Module *M);
+
+ /// Get module under construction, nullptr if this is not a C++20 module.
+ Module *getCurrentNamedModule() const { return CurrentCXXNamedModule; }
+
TranslationUnitDecl *getTranslationUnitDecl() const {
return TUDecl->getMostRecentDecl();
}
@@ -1054,7 +1092,7 @@ public:
CanQualType SignedCharTy, ShortTy, IntTy, LongTy, LongLongTy, Int128Ty;
CanQualType UnsignedCharTy, UnsignedShortTy, UnsignedIntTy, UnsignedLongTy;
CanQualType UnsignedLongLongTy, UnsignedInt128Ty;
- CanQualType FloatTy, DoubleTy, LongDoubleTy, Float128Ty;
+ CanQualType FloatTy, DoubleTy, LongDoubleTy, Float128Ty, Ibm128Ty;
CanQualType ShortAccumTy, AccumTy,
LongAccumTy; // ISO/IEC JTC1 SC22 WG14 N1169 Extension
CanQualType UnsignedShortAccumTy, UnsignedAccumTy, UnsignedLongAccumTy;
@@ -1069,8 +1107,6 @@ public:
CanQualType HalfTy; // [OpenCL 6.1.1.1], ARM NEON
CanQualType BFloat16Ty;
CanQualType Float16Ty; // C11 extension ISO/IEC TS 18661-3
- CanQualType FloatComplexTy, DoubleComplexTy, LongDoubleComplexTy;
- CanQualType Float128ComplexTy;
CanQualType VoidPtrTy, NullPtrTy;
CanQualType DependentTy, OverloadTy, BoundMemberTy, UnknownAnyTy;
CanQualType BuiltinFnTy;
@@ -1096,6 +1132,8 @@ public:
#define RVV_TYPE(Name, Id, SingletonId) \
CanQualType SingletonId;
#include "clang/Basic/RISCVVTypes.def"
+#define WASM_TYPE(Name, Id, SingletonId) CanQualType SingletonId;
+#include "clang/Basic/WebAssemblyReferenceTypes.def"
// Types for deductions in C++0x [stmt.ranged]'s desugaring. Built on demand.
mutable QualType AutoDeductTy; // Deduction against 'auto'.
@@ -1109,8 +1147,19 @@ public:
mutable TagDecl *MSGuidTagDecl = nullptr;
/// Keep track of CUDA/HIP device-side variables ODR-used by host code.
+ /// This does not include extern shared variables used by device host
+ /// functions as addresses of shared variables are per warp, therefore
+ /// cannot be accessed by host code.
llvm::DenseSet<const VarDecl *> CUDADeviceVarODRUsedByHost;
+ /// Keep track of CUDA/HIP external kernels or device variables ODR-used by
+ /// host code.
+ llvm::DenseSet<const ValueDecl *> CUDAExternalDeviceDeclODRUsedByHost;
+
+ /// Keep track of CUDA/HIP implicit host device functions used on device side
+ /// in device compilation.
+ llvm::DenseSet<const FunctionDecl *> CUDAImplicitHostDeviceFunUsedByDevice;
+
ASTContext(LangOptions &LOpts, SourceManager &SM, IdentifierTable &idents,
SelectorTable &sels, Builtin::Context &builtins,
TranslationUnitKind TUKind);
@@ -1152,8 +1201,9 @@ public:
/// Create a new implicit TU-level CXXRecordDecl or RecordDecl
/// declaration.
- RecordDecl *buildImplicitRecord(StringRef Name,
- RecordDecl::TagKind TK = TTK_Struct) const;
+ RecordDecl *buildImplicitRecord(
+ StringRef Name,
+ RecordDecl::TagKind TK = RecordDecl::TagKind::Struct) const;
/// Create a new implicit TU-level typedef declaration.
TypedefDecl *buildImplicitTypedef(QualType T, StringRef Name) const;
@@ -1253,11 +1303,11 @@ public:
/// declaration of a function with an exception specification is permitted
/// and preserved. Other type sugar (for instance, typedefs) is not.
QualType getFunctionTypeWithExceptionSpec(
- QualType Orig, const FunctionProtoType::ExceptionSpecInfo &ESI);
+ QualType Orig, const FunctionProtoType::ExceptionSpecInfo &ESI) const;
/// Determine whether two function types are the same, ignoring
/// exception specifications in cases where they're part of the type.
- bool hasSameFunctionTypeIgnoringExceptionSpec(QualType T, QualType U);
+ bool hasSameFunctionTypeIgnoringExceptionSpec(QualType T, QualType U) const;
/// Change the exception specification on a function once it is
/// delay-parsed, instantiated, or computed.
@@ -1303,6 +1353,9 @@ public:
CanQualType getDecayedType(CanQualType T) const {
return CanQualType::CreateUnsafe(getDecayedType((QualType) T));
}
+ /// Return the uniqued reference to a specified decay from the original
+ /// type to the decayed type.
+ QualType getDecayedType(QualType Orig, QualType Decayed) const;
/// Return the uniqued reference to the atomic type for the specified
/// type.
@@ -1322,13 +1375,13 @@ public:
/// Return a write_only pipe type for the specified type.
QualType getWritePipeType(QualType T) const;
- /// Return an extended integer type with the specified signedness and bit
+ /// Return a bit-precise integer type with the specified signedness and bit
/// count.
- QualType getExtIntType(bool Unsigned, unsigned NumBits) const;
+ QualType getBitIntType(bool Unsigned, unsigned NumBits) const;
- /// Return a dependent extended integer type with the specified signedness and
- /// bit count.
- QualType getDependentExtIntType(bool Unsigned, Expr *BitsExpr) const;
+ /// Return a dependent bit-precise integer type with the specified signedness
+ /// and bit count.
+ QualType getDependentBitIntType(bool Unsigned, Expr *BitsExpr) const;
/// Gets the struct used to keep track of the extended descriptor for
/// pointer to blocks.
@@ -1340,6 +1393,12 @@ public:
/// Get address space for OpenCL type.
LangAS getOpenCLTypeAddrSpace(const Type *T) const;
+ /// Returns default address space based on OpenCL version and enabled features
+ inline LangAS getDefaultOpenCLPointeeAddrSpace() {
+ return LangOpts.OpenCLGenericAddressSpace ? LangAS::opencl_generic
+ : LangAS::opencl_private;
+ }
+
void setcudaConfigureCallDecl(FunctionDecl *FD) {
cudaConfigureCallDecl = FD;
}
@@ -1376,8 +1435,7 @@ public:
/// Return a non-unique reference to the type for a variable array of
/// the specified element type.
QualType getVariableArrayType(QualType EltTy, Expr *NumElts,
- ArrayType::ArraySizeModifier ASM,
- unsigned IndexTypeQuals,
+ ArraySizeModifier ASM, unsigned IndexTypeQuals,
SourceRange Brackets) const;
/// Return a non-unique reference to the type for a dependently-sized
@@ -1386,21 +1444,19 @@ public:
/// FIXME: We will need these to be uniqued, or at least comparable, at some
/// point.
QualType getDependentSizedArrayType(QualType EltTy, Expr *NumElts,
- ArrayType::ArraySizeModifier ASM,
+ ArraySizeModifier ASM,
unsigned IndexTypeQuals,
SourceRange Brackets) const;
/// Return a unique reference to the type for an incomplete array of
/// the specified element type.
- QualType getIncompleteArrayType(QualType EltTy,
- ArrayType::ArraySizeModifier ASM,
+ QualType getIncompleteArrayType(QualType EltTy, ArraySizeModifier ASM,
unsigned IndexTypeQuals) const;
/// Return the unique reference to the type for a constant array of
/// the specified element type.
QualType getConstantArrayType(QualType EltTy, const llvm::APInt &ArySize,
- const Expr *SizeExpr,
- ArrayType::ArraySizeModifier ASM,
+ const Expr *SizeExpr, ArraySizeModifier ASM,
unsigned IndexTypeQuals) const;
/// Return a type for a constant array for a string literal of the
@@ -1427,21 +1483,27 @@ public:
/// Return the unique reference to a scalable vector type of the specified
/// element type and scalable number of elements.
+ /// For RISC-V, number of fields is also provided when it fetching for
+ /// tuple type.
///
/// \pre \p EltTy must be a built-in type.
- QualType getScalableVectorType(QualType EltTy, unsigned NumElts) const;
+ QualType getScalableVectorType(QualType EltTy, unsigned NumElts,
+ unsigned NumFields = 1) const;
+
+ /// Return a WebAssembly externref type.
+ QualType getWebAssemblyExternrefType() const;
/// Return the unique reference to a vector type of the specified
/// element type and size.
///
/// \pre \p VectorType must be a built-in type.
QualType getVectorType(QualType VectorType, unsigned NumElts,
- VectorType::VectorKind VecKind) const;
+ VectorKind VecKind) const;
/// Return the unique reference to the type for a dependently sized vector of
/// the specified element type.
QualType getDependentVectorType(QualType VectorType, Expr *SizeExpr,
SourceLocation AttrLoc,
- VectorType::VectorKind VecKind) const;
+ VectorKind VecKind) const;
/// Return the unique reference to an extended vector type
/// of the specified element type and size.
@@ -1497,6 +1559,12 @@ private:
QualType getFunctionTypeInternal(QualType ResultTy, ArrayRef<QualType> Args,
const FunctionProtoType::ExtProtoInfo &EPI,
bool OnlyWantCanonical) const;
+ QualType
+ getAutoTypeInternal(QualType DeducedType, AutoTypeKeyword Keyword,
+ bool IsDependent, bool IsPack = false,
+ ConceptDecl *TypeConstraintConcept = nullptr,
+ ArrayRef<TemplateArgument> TypeConstraintArgs = {},
+ bool IsCanon = false) const;
public:
/// Return the unique reference to the type for the specified type
@@ -1515,6 +1583,9 @@ public:
return getTypeDeclTypeSlow(Decl);
}
+ QualType getUsingType(const UsingShadowDecl *Found,
+ QualType Underlying) const;
+
/// Return the unique reference to the type for the specified
/// typedef-name decl.
QualType getTypedefType(const TypedefNameDecl *Decl,
@@ -1524,16 +1595,23 @@ public:
QualType getEnumType(const EnumDecl *Decl) const;
+ QualType
+ getUnresolvedUsingType(const UnresolvedUsingTypenameDecl *Decl) const;
+
QualType getInjectedClassNameType(CXXRecordDecl *Decl, QualType TST) const;
- QualType getAttributedType(attr::Kind attrKind,
- QualType modifiedType,
- QualType equivalentType);
+ QualType getAttributedType(attr::Kind attrKind, QualType modifiedType,
+ QualType equivalentType) const;
- QualType getSubstTemplateTypeParmType(const TemplateTypeParmType *Replaced,
- QualType Replacement) const;
- QualType getSubstTemplateTypeParmPackType(
- const TemplateTypeParmType *Replaced,
+ QualType getBTFTagAttributedType(const BTFTypeTagAttr *BTFAttr,
+ QualType Wrapped);
+
+ QualType
+ getSubstTemplateTypeParmType(QualType Replacement, Decl *AssociatedDecl,
+ unsigned Index,
+ std::optional<unsigned> PackIndex) const;
+ QualType getSubstTemplateTypeParmPackType(Decl *AssociatedDecl,
+ unsigned Index, bool Final,
const TemplateArgument &ArgPack);
QualType
@@ -1550,7 +1628,7 @@ public:
ArrayRef<TemplateArgument> Args) const;
QualType getTemplateSpecializationType(TemplateName T,
- const TemplateArgumentListInfo &Args,
+ ArrayRef<TemplateArgumentLoc> Args,
QualType Canon = QualType()) const;
TypeSourceInfo *
@@ -1571,10 +1649,9 @@ public:
const IdentifierInfo *Name,
QualType Canon = QualType()) const;
- QualType getDependentTemplateSpecializationType(ElaboratedTypeKeyword Keyword,
- NestedNameSpecifier *NNS,
- const IdentifierInfo *Name,
- const TemplateArgumentListInfo &Args) const;
+ QualType getDependentTemplateSpecializationType(
+ ElaboratedTypeKeyword Keyword, NestedNameSpecifier *NNS,
+ const IdentifierInfo *Name, ArrayRef<TemplateArgumentLoc> Args) const;
QualType getDependentTemplateSpecializationType(
ElaboratedTypeKeyword Keyword, NestedNameSpecifier *NNS,
const IdentifierInfo *Name, ArrayRef<TemplateArgument> Args) const;
@@ -1595,7 +1672,7 @@ public:
/// elsewhere, such as if the pattern contains a placeholder type or
/// if this is the canonical type of another pack expansion type.
QualType getPackExpansionType(QualType Pattern,
- Optional<unsigned> NumExpansions,
+ std::optional<unsigned> NumExpansions,
bool ExpectPackInType = true);
QualType getObjCInterfaceType(const ObjCInterfaceDecl *Decl,
@@ -1627,9 +1704,11 @@ public:
/// Return a ObjCObjectPointerType type for the given ObjCObjectType.
QualType getObjCObjectPointerType(QualType OIT) const;
- /// GCC extension.
- QualType getTypeOfExprType(Expr *e) const;
- QualType getTypeOfType(QualType t) const;
+ /// C23 feature and GCC extension.
+ QualType getTypeOfExprType(Expr *E, TypeOfKind Kind) const;
+ QualType getTypeOfType(QualType QT, TypeOfKind Kind) const;
+
+ QualType getReferenceQualifiedType(const Expr *e) const;
/// C++11 decltype.
QualType getDecltypeType(Expr *e, QualType UnderlyingType) const;
@@ -1650,6 +1729,10 @@ public:
/// C++11 deduction pattern for 'auto &&' type.
QualType getAutoRRefDeductType() const;
+ /// Remove any type constraints from a template parameter type, for
+ /// equivalence comparison of template parameters.
+ QualType getUnconstrainedType(QualType T) const;
+
/// C++17 deduced class template specialization type.
QualType getDeducedTemplateSpecializationType(TemplateName Template,
QualType DeducedType,
@@ -2106,16 +2189,20 @@ public:
TemplateName getQualifiedTemplateName(NestedNameSpecifier *NNS,
bool TemplateKeyword,
- TemplateDecl *Template) const;
+ TemplateName Template) const;
TemplateName getDependentTemplateName(NestedNameSpecifier *NNS,
const IdentifierInfo *Name) const;
TemplateName getDependentTemplateName(NestedNameSpecifier *NNS,
OverloadedOperatorKind Operator) const;
- TemplateName getSubstTemplateTemplateParm(TemplateTemplateParmDecl *param,
- TemplateName replacement) const;
- TemplateName getSubstTemplateTemplateParmPack(TemplateTemplateParmDecl *Param,
- const TemplateArgument &ArgPack) const;
+ TemplateName
+ getSubstTemplateTemplateParm(TemplateName replacement, Decl *AssociatedDecl,
+ unsigned Index,
+ std::optional<unsigned> PackIndex) const;
+ TemplateName getSubstTemplateTemplateParmPack(const TemplateArgument &ArgPack,
+ Decl *AssociatedDecl,
+ unsigned Index,
+ bool Final) const;
enum GetBuiltinTypeError {
/// No error
@@ -2179,6 +2266,17 @@ public:
/// false otherwise.
bool areLaxCompatibleSveTypes(QualType FirstType, QualType SecondType);
+ /// Return true if the given types are an RISC-V vector builtin type and a
+ /// VectorType that is a fixed-length representation of the RISC-V vector
+ /// builtin type for a specific vector-length.
+ bool areCompatibleRVVTypes(QualType FirstType, QualType SecondType);
+
+ /// Return true if the given vector types are lax-compatible RISC-V vector
+ /// types as defined by -flax-vector-conversions=, which permits implicit
+ /// conversions between vectors with different number of elements and/or
+ /// incompatible element types, false otherwise.
+ bool areLaxCompatibleRVVTypes(QualType FirstType, QualType SecondType);
+
/// Return true if the type has been explicitly qualified with ObjC ownership.
/// A type may be implicitly qualified with ownership under ObjC ARC, and in
/// some cases the compiler treats these differently.
@@ -2225,13 +2323,13 @@ public:
CharUnits getTypeSizeInChars(QualType T) const;
CharUnits getTypeSizeInChars(const Type *T) const;
- Optional<CharUnits> getTypeSizeInCharsIfKnown(QualType Ty) const {
+ std::optional<CharUnits> getTypeSizeInCharsIfKnown(QualType Ty) const {
if (Ty->isIncompleteType() || Ty->isDependentType())
- return None;
+ return std::nullopt;
return getTypeSizeInChars(Ty);
}
- Optional<CharUnits> getTypeSizeInCharsIfKnown(const Type *Ty) const {
+ std::optional<CharUnits> getTypeSizeInCharsIfKnown(const Type *Ty) const {
return getTypeSizeInCharsIfKnown(QualType(Ty, 0));
}
@@ -2287,6 +2385,9 @@ public:
bool isAlignmentRequired(const Type *T) const;
bool isAlignmentRequired(QualType T) const;
+ /// More type predicates useful for type checking/promotion
+ bool isPromotableIntegerType(QualType T) const; // C99 6.3.1.1p2
+
/// Return the "preferred" alignment of the specified type \p T for
/// the current target, in bits.
///
@@ -2415,7 +2516,9 @@ public:
/// Return true if the specified type has unique object representations
/// according to (C++17 [meta.unary.prop]p9)
- bool hasUniqueObjectRepresentations(QualType Ty) const;
+ bool
+ hasUniqueObjectRepresentations(QualType Ty,
+ bool CheckIfTriviallyCopyable = true) const;
//===--------------------------------------------------------------------===//
// Type Operators
@@ -2452,6 +2555,9 @@ public:
return getCanonicalType(T1) == getCanonicalType(T2);
}
+ /// Determine whether the given expressions \p X and \p Y are equivalent.
+ bool hasSameExpr(const Expr *X, const Expr *Y) const;
+
/// Return this type as a completely-unqualified array type,
/// capturing the qualifiers in \p Quals.
///
@@ -2476,9 +2582,9 @@ public:
bool hasSameNullabilityTypeQualifier(QualType SubT, QualType SuperT,
bool IsParam) const {
- auto SubTnullability = SubT->getNullability(*this);
- auto SuperTnullability = SuperT->getNullability(*this);
- if (SubTnullability.hasValue() == SuperTnullability.hasValue()) {
+ auto SubTnullability = SubT->getNullability();
+ auto SuperTnullability = SuperT->getNullability();
+ if (SubTnullability.has_value() == SuperTnullability.has_value()) {
// Neither has nullability; return true
if (!SubTnullability)
return true;
@@ -2505,8 +2611,10 @@ public:
bool ObjCMethodsAreEqual(const ObjCMethodDecl *MethodDecl,
const ObjCMethodDecl *MethodImp);
- bool UnwrapSimilarTypes(QualType &T1, QualType &T2);
- void UnwrapSimilarArrayTypes(QualType &T1, QualType &T2);
+ bool UnwrapSimilarTypes(QualType &T1, QualType &T2,
+ bool AllowPiMismatch = true);
+ void UnwrapSimilarArrayTypes(QualType &T1, QualType &T2,
+ bool AllowPiMismatch = true);
/// Determine if two types are similar, according to the C++ rules. That is,
/// determine if they are the same other than qualifiers on the initial
@@ -2569,11 +2677,40 @@ public:
/// template name uses the shortest form of the dependent
/// nested-name-specifier, which itself contains all canonical
/// types, values, and templates.
- TemplateName getCanonicalTemplateName(TemplateName Name) const;
+ TemplateName getCanonicalTemplateName(const TemplateName &Name) const;
/// Determine whether the given template names refer to the same
/// template.
- bool hasSameTemplateName(TemplateName X, TemplateName Y);
+ bool hasSameTemplateName(const TemplateName &X, const TemplateName &Y) const;
+
+ /// Determine whether the two declarations refer to the same entity.
+ bool isSameEntity(const NamedDecl *X, const NamedDecl *Y) const;
+
+ /// Determine whether two template parameter lists are similar enough
+ /// that they may be used in declarations of the same template.
+ bool isSameTemplateParameterList(const TemplateParameterList *X,
+ const TemplateParameterList *Y) const;
+
+ /// Determine whether two template parameters are similar enough
+ /// that they may be used in declarations of the same template.
+ bool isSameTemplateParameter(const NamedDecl *X, const NamedDecl *Y) const;
+
+ /// Determine whether two 'requires' expressions are similar enough that they
+ /// may be used in re-declarations.
+ ///
+ /// Use of 'requires' isn't mandatory, works with constraints expressed in
+ /// other ways too.
+ bool isSameConstraintExpr(const Expr *XCE, const Expr *YCE) const;
+
+ /// Determine whether two type contraint are similar enough that they could
+ /// used in declarations of the same template.
+ bool isSameTypeConstraint(const TypeConstraint *XTC,
+ const TypeConstraint *YTC) const;
+
+ /// Determine whether two default template arguments are similar enough
+ /// that they may be used in declarations of the same template.
+ bool isSameDefaultTemplateArgument(const NamedDecl *X,
+ const NamedDecl *Y) const;
/// Retrieve the "canonical" template argument.
///
@@ -2614,6 +2751,10 @@ public:
/// Return number of constant array elements.
uint64_t getConstantArrayElementCount(const ConstantArrayType *CA) const;
+ /// Return number of elements initialized in an ArrayInitLoopExpr.
+ uint64_t
+ getArrayInitLoopExprElementCount(const ArrayInitLoopExpr *AILE) const;
+
/// Perform adjustment on the parameter type of a function.
///
/// This routine adjusts the given parameter type @p T to the actual
@@ -2671,22 +2812,6 @@ public:
/// long double and double on AArch64 will return 0).
int getFloatingTypeSemanticOrder(QualType LHS, QualType RHS) const;
- /// Return a real floating point or a complex type (based on
- /// \p typeDomain/\p typeSize).
- ///
- /// \param typeDomain a real floating point or complex type.
- /// \param typeSize a real floating point or complex type.
- QualType getFloatingTypeOfSizeWithinDomain(QualType typeSize,
- QualType typeDomain) const;
-
- unsigned getTargetAddressSpace(QualType T) const {
- return getTargetAddressSpace(T.getQualifiers());
- }
-
- unsigned getTargetAddressSpace(Qualifiers Q) const {
- return getTargetAddressSpace(Q.getAddressSpace());
- }
-
unsigned getTargetAddressSpace(LangAS AS) const;
LangAS getLangASForBuiltinAddressSpace(unsigned AS) const;
@@ -2699,6 +2824,23 @@ public:
return AddrSpaceMapMangling || isTargetAddressSpace(AS);
}
+ // Merges two exception specifications, such that the resulting
+ // exception spec is the union of both. For example, if either
+ // of them can throw something, the result can throw it as well.
+ FunctionProtoType::ExceptionSpecInfo
+ mergeExceptionSpecs(FunctionProtoType::ExceptionSpecInfo ESI1,
+ FunctionProtoType::ExceptionSpecInfo ESI2,
+ SmallVectorImpl<QualType> &ExceptionTypeStorage,
+ bool AcceptDependent);
+
+ // For two "same" types, return a type which has
+ // the common sugar between them. If Unqualified is true,
+ // both types need only be the same unqualified type.
+ // The result will drop the qualifiers which do not occur
+ // in both types.
+ QualType getCommonSugaredType(QualType X, QualType Y,
+ bool Unqualified = false);
+
private:
// Helper for integer ordering
unsigned getIntegerRank(const Type *T) const;
@@ -2716,14 +2858,20 @@ public:
bool typesAreBlockPointerCompatible(QualType, QualType);
bool isObjCIdType(QualType T) const {
+ if (const auto *ET = dyn_cast<ElaboratedType>(T))
+ T = ET->getNamedType();
return T == getObjCIdType();
}
bool isObjCClassType(QualType T) const {
+ if (const auto *ET = dyn_cast<ElaboratedType>(T))
+ T = ET->getNamedType();
return T == getObjCClassType();
}
bool isObjCSelType(QualType T) const {
+ if (const auto *ET = dyn_cast<ElaboratedType>(T))
+ T = ET->getNamedType();
return T == getObjCSelType();
}
@@ -2749,10 +2897,12 @@ public:
bool canBindObjCObjectType(QualType To, QualType From);
// Functions for calculating composite types
- QualType mergeTypes(QualType, QualType, bool OfBlockPointer=false,
- bool Unqualified = false, bool BlockReturnType = false);
- QualType mergeFunctionTypes(QualType, QualType, bool OfBlockPointer=false,
- bool Unqualified = false, bool AllowCXX = false);
+ QualType mergeTypes(QualType, QualType, bool OfBlockPointer = false,
+ bool Unqualified = false, bool BlockReturnType = false,
+ bool IsConditionalOperator = false);
+ QualType mergeFunctionTypes(QualType, QualType, bool OfBlockPointer = false,
+ bool Unqualified = false, bool AllowCXX = false,
+ bool IsConditionalOperator = false);
QualType mergeFunctionParameterTypes(QualType, QualType,
bool OfBlockPointer = false,
bool Unqualified = false);
@@ -2923,7 +3073,7 @@ public:
}
GVALinkage GetGVALinkageForFunction(const FunctionDecl *FD) const;
- GVALinkage GetGVALinkageForVariable(const VarDecl *VD);
+ GVALinkage GetGVALinkageForVariable(const VarDecl *VD) const;
/// Determines if the decl can be CodeGen'ed or deserialized from PCH
/// lazily, only when used; this is only relevant for function or file scoped
@@ -2954,7 +3104,8 @@ public:
DeclaratorDecl *getDeclaratorForUnnamedTagDecl(const TagDecl *TD);
void setManglingNumber(const NamedDecl *ND, unsigned Number);
- unsigned getManglingNumber(const NamedDecl *ND) const;
+ unsigned getManglingNumber(const NamedDecl *ND,
+ bool ForAuxTarget = false) const;
void setStaticLocalNumber(const VarDecl *VD, unsigned Number);
unsigned getStaticLocalNumber(const VarDecl *VD) const;
@@ -2985,6 +3136,11 @@ public:
/// GUID value.
MSGuidDecl *getMSGuidDecl(MSGuidDeclParts Parts) const;
+ /// Return a declaration for a uniquified anonymous global constant
+ /// corresponding to a given APValue.
+ UnnamedGlobalConstantDecl *
+ getUnnamedGlobalConstantDecl(QualType Ty, const APValue &Value) const;
+
/// Return the template parameter object of the given type with the given
/// value.
TemplateParamObjectDecl *getTemplateParamObjectDecl(QualType T,
@@ -2994,6 +3150,9 @@ public:
/// valid feature names.
ParsedTargetAttr filterFunctionTargetAttrs(const TargetAttr *TD) const;
+ std::vector<std::string>
+ filterFunctionTargetVersionAttrs(const TargetVersionAttr *TV) const;
+
void getFunctionFeatureMap(llvm::StringMap<bool> &FeatureMap,
const FunctionDecl *) const;
void getFunctionFeatureMap(llvm::StringMap<bool> &FeatureMap,
@@ -3065,7 +3224,6 @@ private:
public:
ObjCEncOptions() : Bits(0) {}
- ObjCEncOptions(const ObjCEncOptions &RHS) : Bits(RHS.Bits) {}
#define OPT_LIST(V) \
V(ExpandPointedToStructures, 0) \
@@ -3086,11 +3244,11 @@ OPT_LIST(V)
#undef OPT_LIST
- LLVM_NODISCARD ObjCEncOptions keepingOnly(ObjCEncOptions Mask) const {
+ [[nodiscard]] ObjCEncOptions keepingOnly(ObjCEncOptions Mask) const {
return Bits & Mask.Bits;
}
- LLVM_NODISCARD ObjCEncOptions forComponentType() const {
+ [[nodiscard]] ObjCEncOptions forComponentType() const {
ObjCEncOptions Mask = ObjCEncOptions()
.setIsOutermostType()
.setIsStructField();
@@ -3201,39 +3359,18 @@ public:
/// Return a new OMPTraitInfo object owned by this context.
OMPTraitInfo &getNewOMPTraitInfo();
- /// Whether a C++ static variable may be externalized.
- bool mayExternalizeStaticVar(const Decl *D) const;
+ /// Whether a C++ static variable or CUDA/HIP kernel may be externalized.
+ bool mayExternalize(const Decl *D) const;
- /// Whether a C++ static variable should be externalized.
- bool shouldExternalizeStaticVar(const Decl *D) const;
+ /// Whether a C++ static variable or CUDA/HIP kernel should be externalized.
+ bool shouldExternalize(const Decl *D) const;
StringRef getCUIDHash() const;
- void AddSYCLKernelNamingDecl(const CXXRecordDecl *RD);
- bool IsSYCLKernelNamingDecl(const NamedDecl *RD) const;
- unsigned GetSYCLKernelNamingIndex(const NamedDecl *RD);
- /// A SourceLocation to store whether we have evaluated a kernel name already,
- /// and where it happened. If so, we need to diagnose an illegal use of the
- /// builtin.
- llvm::MapVector<const SYCLUniqueStableNameExpr *, std::string>
- SYCLUniqueStableNameEvaluatedValues;
-
private:
/// All OMPTraitInfo objects live in this collection, one per
/// `pragma omp [begin] declare variant` directive.
SmallVector<std::unique_ptr<OMPTraitInfo>, 4> OMPTraitInfoVector;
-
- /// A list of the (right now just lambda decls) declarations required to
- /// name all the SYCL kernels in the translation unit, so that we can get the
- /// correct kernel name, as well as implement
- /// __builtin_sycl_unique_stable_name.
- llvm::DenseMap<const DeclContext *,
- llvm::SmallPtrSet<const CXXRecordDecl *, 4>>
- SYCLKernelNamingTypes;
- std::unique_ptr<ItaniumMangleContext> SYCLKernelFilterContext;
- void FilterSYCLKernelNamingDecls(
- const CXXRecordDecl *RD,
- llvm::SmallVectorImpl<const CXXRecordDecl *> &Decls);
};
/// Insertion operator for diagnostics.
diff --git a/contrib/llvm-project/clang/include/clang/AST/ASTDiagnostic.h b/contrib/llvm-project/clang/include/clang/AST/ASTDiagnostic.h
index d6549e12d92a..ef2224982862 100644
--- a/contrib/llvm-project/clang/include/clang/AST/ASTDiagnostic.h
+++ b/contrib/llvm-project/clang/include/clang/AST/ASTDiagnostic.h
@@ -9,6 +9,7 @@
#ifndef LLVM_CLANG_AST_ASTDIAGNOSTIC_H
#define LLVM_CLANG_AST_ASTDIAGNOSTIC_H
+#include "clang/AST/Type.h"
#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/DiagnosticAST.h"
@@ -31,6 +32,12 @@ namespace clang {
SmallVectorImpl<char> &Output,
void *Cookie,
ArrayRef<intptr_t> QualTypeVals);
+
+ /// Returns a desugared version of the QualType, and marks ShouldAKA as true
+ /// whenever we remove significant sugar from the type. Make sure ShouldAKA
+ /// is initialized before passing it in.
+ QualType desugarForDiagnostic(ASTContext &Context, QualType QT,
+ bool &ShouldAKA);
} // end namespace clang
#endif
diff --git a/contrib/llvm-project/clang/include/clang/AST/ASTDumper.h b/contrib/llvm-project/clang/include/clang/AST/ASTDumper.h
index a154bc2db3a7..71ac467e5104 100644
--- a/contrib/llvm-project/clang/include/clang/AST/ASTDumper.h
+++ b/contrib/llvm-project/clang/include/clang/AST/ASTDumper.h
@@ -32,6 +32,7 @@ public:
TextNodeDumper &doGetNodeDelegate() { return NodeDumper; }
+ void dumpInvalidDeclContext(const DeclContext *DC);
void dumpLookups(const DeclContext *DC, bool DumpDecls);
template <typename SpecializationDecl>
diff --git a/contrib/llvm-project/clang/include/clang/AST/ASTFwd.h b/contrib/llvm-project/clang/include/clang/AST/ASTFwd.h
index 649b57113424..8823663386ea 100644
--- a/contrib/llvm-project/clang/include/clang/AST/ASTFwd.h
+++ b/contrib/llvm-project/clang/include/clang/AST/ASTFwd.h
@@ -30,6 +30,11 @@ class OMPClause;
#define GEN_CLANG_CLAUSE_CLASS
#define CLAUSE_CLASS(Enum, Str, Class) class Class;
#include "llvm/Frontend/OpenMP/OMP.inc"
+class Attr;
+#define ATTR(A) class A##Attr;
+#include "clang/Basic/AttrList.inc"
+class ObjCProtocolLoc;
+class ConceptReference;
} // end namespace clang
diff --git a/contrib/llvm-project/clang/include/clang/AST/ASTImportError.h b/contrib/llvm-project/clang/include/clang/AST/ASTImportError.h
new file mode 100644
index 000000000000..728314ca0936
--- /dev/null
+++ b/contrib/llvm-project/clang/include/clang/AST/ASTImportError.h
@@ -0,0 +1,50 @@
+//===- ASTImportError.h - Define errors while importing AST -----*- 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 the ASTImportError class which basically defines the kind
+// of error while importing AST .
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_ASTIMPORTERROR_H
+#define LLVM_CLANG_AST_ASTIMPORTERROR_H
+
+#include "llvm/Support/Error.h"
+
+namespace clang {
+
+class ASTImportError : public llvm::ErrorInfo<ASTImportError> {
+public:
+ /// \brief Kind of error when importing an AST component.
+ enum ErrorKind {
+ NameConflict, /// Naming ambiguity (likely ODR violation).
+ UnsupportedConstruct, /// Not supported node or case.
+ Unknown /// Other error.
+ };
+
+ ErrorKind Error;
+
+ static char ID;
+
+ ASTImportError() : Error(Unknown) {}
+ ASTImportError(const ASTImportError &Other) : Error(Other.Error) {}
+ ASTImportError &operator=(const ASTImportError &Other) {
+ Error = Other.Error;
+ return *this;
+ }
+ ASTImportError(ErrorKind Error) : Error(Error) {}
+
+ std::string toString() const;
+
+ void log(llvm::raw_ostream &OS) const override;
+ std::error_code convertToErrorCode() const override;
+};
+
+} // namespace clang
+
+#endif // LLVM_CLANG_AST_ASTIMPORTERROR_H
diff --git a/contrib/llvm-project/clang/include/clang/AST/ASTImporter.h b/contrib/llvm-project/clang/include/clang/AST/ASTImporter.h
index 17e673a8471a..4ffd91384657 100644
--- a/contrib/llvm-project/clang/include/clang/AST/ASTImporter.h
+++ b/contrib/llvm-project/clang/include/clang/AST/ASTImporter.h
@@ -14,7 +14,7 @@
#ifndef LLVM_CLANG_AST_ASTIMPORTER_H
#define LLVM_CLANG_AST_ASTIMPORTER_H
-#include "clang/AST/APValue.h"
+#include "clang/AST/ASTImportError.h"
#include "clang/AST/DeclBase.h"
#include "clang/AST/DeclarationName.h"
#include "clang/AST/ExprCXX.h"
@@ -27,9 +27,8 @@
#include "clang/Basic/SourceLocation.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/DenseSet.h"
-#include "llvm/ADT/Optional.h"
#include "llvm/ADT/SmallVector.h"
-#include "llvm/Support/Error.h"
+#include <optional>
#include <utility>
namespace clang {
@@ -49,33 +48,6 @@ class TagDecl;
class TranslationUnitDecl;
class TypeSourceInfo;
- class ImportError : public llvm::ErrorInfo<ImportError> {
- public:
- /// \brief Kind of error when importing an AST component.
- enum ErrorKind {
- NameConflict, /// Naming ambiguity (likely ODR violation).
- UnsupportedConstruct, /// Not supported node or case.
- Unknown /// Other error.
- };
-
- ErrorKind Error;
-
- static char ID;
-
- ImportError() : Error(Unknown) {}
- ImportError(const ImportError &Other) : Error(Other.Error) {}
- ImportError &operator=(const ImportError &Other) {
- Error = Other.Error;
- return *this;
- }
- ImportError(ErrorKind Error) : Error(Error) { }
-
- std::string toString() const;
-
- void log(raw_ostream &OS) const override;
- std::error_code convertToErrorCode() const override;
- };
-
// \brief Returns with a list of declarations started from the canonical decl
// then followed by subsequent decls in the translation unit.
// This gives a canonical list for each entry in the redecl chain.
@@ -259,7 +231,7 @@ class TypeSourceInfo;
/// imported. The same declaration may or may not be included in
/// ImportedDecls. This map is updated continuously during imports and never
/// cleared (like ImportedDecls).
- llvm::DenseMap<Decl *, ImportError> ImportDeclErrors;
+ llvm::DenseMap<Decl *, ASTImportError> ImportDeclErrors;
/// Mapping from the already-imported declarations in the "to"
/// context to the corresponding declarations in the "from" context.
@@ -286,6 +258,7 @@ class TypeSourceInfo;
FoundDeclsTy findDeclsInToCtx(DeclContext *DC, DeclarationName Name);
void AddToLookupTable(Decl *ToD);
+ llvm::Error ImportAttrs(Decl *ToD, Decl *FromD);
protected:
/// Can be overwritten by subclasses to implement their own import logic.
@@ -332,7 +305,7 @@ class TypeSourceInfo;
/// \param From Object to import.
/// \return Error information (success or error).
template <typename ImportT>
- LLVM_NODISCARD llvm::Error importInto(ImportT &To, const ImportT &From) {
+ [[nodiscard]] llvm::Error importInto(ImportT &To, const ImportT &From) {
auto ToOrErr = Import(From);
if (ToOrErr)
To = *ToOrErr;
@@ -379,6 +352,9 @@ class TypeSourceInfo;
return Import(const_cast<Decl *>(FromD));
}
+ llvm::Expected<InheritedConstructor>
+ Import(const InheritedConstructor &From);
+
/// Return the copy of the given declaration in the "to" context if
/// it has already been imported from the "from" context. Otherwise return
/// nullptr.
@@ -392,7 +368,7 @@ class TypeSourceInfo;
/// in the "to" context was imported. If it was not imported or of the wrong
/// type a null value is returned.
template <typename DeclT>
- llvm::Optional<DeclT *> getImportedFromDecl(const DeclT *ToD) const {
+ std::optional<DeclT *> getImportedFromDecl(const DeclT *ToD) const {
auto FromI = ImportedFromDecls.find(ToD);
if (FromI == ImportedFromDecls.end())
return {};
@@ -507,7 +483,7 @@ class TypeSourceInfo;
/// Import the definition of the given declaration, including all of
/// the declarations it contains.
- LLVM_NODISCARD llvm::Error ImportDefinition(Decl *From);
+ [[nodiscard]] llvm::Error ImportDefinition(Decl *From);
/// Cope with a name conflict when importing a declaration into the
/// given context.
@@ -589,10 +565,10 @@ class TypeSourceInfo;
/// Return if import of the given declaration has failed and if yes
/// the kind of the problem. This gives the first error encountered with
/// the node.
- llvm::Optional<ImportError> getImportDeclErrorIfAny(Decl *FromD) const;
+ std::optional<ASTImportError> getImportDeclErrorIfAny(Decl *FromD) const;
/// Mark (newly) imported declaration with error.
- void setImportDeclError(Decl *From, ImportError Error);
+ void setImportDeclError(Decl *From, ASTImportError Error);
/// Determine whether the given types are structurally
/// equivalent.
@@ -602,8 +578,8 @@ class TypeSourceInfo;
/// Determine the index of a field in its parent record.
/// F should be a field (or indirect field) declaration.
/// \returns The index of the field in its parent context (starting from 0).
- /// On error `None` is returned (parent context is non-record).
- static llvm::Optional<unsigned> getFieldIndex(Decl *F);
+ /// On error `std::nullopt` is returned (parent context is non-record).
+ static std::optional<unsigned> getFieldIndex(Decl *F);
};
} // namespace clang
diff --git a/contrib/llvm-project/clang/include/clang/AST/ASTImporterLookupTable.h b/contrib/llvm-project/clang/include/clang/AST/ASTImporterLookupTable.h
index 47dca2033839..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;
@@ -75,6 +74,10 @@ public:
// The function should be called when the old context is definitely different
// from the new.
void update(NamedDecl *ND, DeclContext *OldDC);
+ // Same as 'update' but allow if 'ND' is not in the table or the old context
+ // is the same as the new.
+ // FIXME: The old redeclaration context is not handled.
+ void updateForced(NamedDecl *ND, DeclContext *OldDC);
using LookupResult = DeclList;
LookupResult lookup(DeclContext *DC, DeclarationName Name) const;
// Check if the `ND` is within the lookup table (with its current name) in
diff --git a/contrib/llvm-project/clang/include/clang/AST/ASTImporterSharedState.h b/contrib/llvm-project/clang/include/clang/AST/ASTImporterSharedState.h
index 829eb1c611c3..446d7ee61ea5 100644
--- a/contrib/llvm-project/clang/include/clang/AST/ASTImporterSharedState.h
+++ b/contrib/llvm-project/clang/include/clang/AST/ASTImporterSharedState.h
@@ -1,9 +1,8 @@
//===- ASTImporterSharedState.h - ASTImporter specific state --*- C++ -*---===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// 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
//
//===----------------------------------------------------------------------===//
//
@@ -15,11 +14,11 @@
#ifndef LLVM_CLANG_AST_ASTIMPORTERSHAREDSTATE_H
#define LLVM_CLANG_AST_ASTIMPORTERSHAREDSTATE_H
+#include "clang/AST/ASTImportError.h"
#include "clang/AST/ASTImporterLookupTable.h"
#include "clang/AST/Decl.h"
#include "llvm/ADT/DenseMap.h"
-// FIXME We need this because of ImportError.
-#include "clang/AST/ASTImporter.h"
+#include <optional>
namespace clang {
@@ -38,7 +37,10 @@ class ASTImporterSharedState {
/// imported. The same declaration may or may not be included in
/// ImportedFromDecls. This map is updated continuously during imports and
/// never cleared (like ImportedFromDecls).
- llvm::DenseMap<Decl *, ImportError> ImportErrors;
+ llvm::DenseMap<Decl *, ASTImportError> ImportErrors;
+
+ /// Set of the newly created declarations.
+ llvm::DenseSet<Decl *> NewDecls;
// FIXME put ImportedFromDecls here!
// And from that point we can better encapsulate the lookup table.
@@ -64,17 +66,21 @@ public:
LookupTable->remove(ND);
}
- llvm::Optional<ImportError> getImportDeclErrorIfAny(Decl *ToD) const {
+ std::optional<ASTImportError> getImportDeclErrorIfAny(Decl *ToD) const {
auto Pos = ImportErrors.find(ToD);
if (Pos != ImportErrors.end())
return Pos->second;
else
- return Optional<ImportError>();
+ return std::nullopt;
}
- void setImportDeclError(Decl *To, ImportError Error) {
+ void setImportDeclError(Decl *To, ASTImportError Error) {
ImportErrors[To] = Error;
}
+
+ bool isNewDecl(const Decl *ToD) const { return NewDecls.count(ToD); }
+
+ void markAsNewDecl(Decl *ToD) { NewDecls.insert(ToD); }
};
} // namespace clang
diff --git a/contrib/llvm-project/clang/include/clang/AST/ASTLambda.h b/contrib/llvm-project/clang/include/clang/AST/ASTLambda.h
index 6fd82d6af490..646cb574847f 100644
--- a/contrib/llvm-project/clang/include/clang/AST/ASTLambda.h
+++ b/contrib/llvm-project/clang/include/clang/AST/ASTLambda.h
@@ -35,6 +35,21 @@ inline bool isLambdaCallOperator(const DeclContext *DC) {
return isLambdaCallOperator(cast<CXXMethodDecl>(DC));
}
+inline bool isLambdaCallWithExplicitObjectParameter(const DeclContext *DC) {
+ return isLambdaCallOperator(DC) &&
+ cast<CXXMethodDecl>(DC)->isExplicitObjectMemberFunction();
+}
+
+inline bool isLambdaCallWithImplicitObjectParameter(const DeclContext *DC) {
+ return isLambdaCallOperator(DC) &&
+ // FIXME: Checking for a null type is not great
+ // but lambdas with invalid captures or whose closure parameter list
+ // have not fully been parsed may have a call operator whose type is
+ // null.
+ !cast<CXXMethodDecl>(DC)->getType().isNull() &&
+ !cast<CXXMethodDecl>(DC)->isExplicitObjectMemberFunction();
+}
+
inline bool isGenericLambdaCallOperatorSpecialization(const CXXMethodDecl *MD) {
if (!MD) return false;
const CXXRecordDecl *LambdaClass = MD->getParent();
@@ -65,8 +80,8 @@ inline bool isGenericLambdaCallOperatorSpecialization(DeclContext *DC) {
}
inline bool isGenericLambdaCallOperatorOrStaticInvokerSpecialization(
- DeclContext *DC) {
- CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(DC);
+ const DeclContext *DC) {
+ const auto *MD = dyn_cast<CXXMethodDecl>(DC);
if (!MD) return false;
const CXXRecordDecl *LambdaClass = MD->getParent();
if (LambdaClass && LambdaClass->isGenericLambda())
@@ -75,7 +90,6 @@ inline bool isGenericLambdaCallOperatorOrStaticInvokerSpecialization(
return false;
}
-
// This returns the parent DeclContext ensuring that the correct
// parent DeclContext is returned for Lambdas
inline DeclContext *getLambdaAwareParentOfDeclContext(DeclContext *DC) {
diff --git a/contrib/llvm-project/clang/include/clang/AST/ASTNodeTraverser.h b/contrib/llvm-project/clang/include/clang/AST/ASTNodeTraverser.h
index 18e7f491f222..cc8dab97f8b0 100644
--- a/contrib/llvm-project/clang/include/clang/AST/ASTNodeTraverser.h
+++ b/contrib/llvm-project/clang/include/clang/AST/ASTNodeTraverser.h
@@ -104,7 +104,7 @@ public:
Visit(Comment, Comment);
// Decls within functions are visited by the body.
- if (!isa<FunctionDecl>(*D) && !isa<ObjCMethodDecl>(*D)) {
+ if (!isa<FunctionDecl, ObjCMethodDecl, BlockDecl>(*D)) {
if (Traversal != TK_AsIs) {
if (const auto *CTSD = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
auto SK = CTSD->getSpecializationKind();
@@ -246,12 +246,16 @@ public:
.getTypeConstraint()
->getImmediatelyDeclaredConstraint());
} else if (auto *NR = dyn_cast<concepts::NestedRequirement>(R)) {
- if (!NR->isSubstitutionFailure())
+ if (!NR->hasInvalidConstraint())
Visit(NR->getConstraintExpr());
}
});
}
+ void Visit(const ConceptReference *R) {
+ getNodeDelegate().AddChild([=] { getNodeDelegate().Visit(R); });
+ }
+
void Visit(const APValue &Value, QualType Ty) {
getNodeDelegate().AddChild([=] { getNodeDelegate().Visit(Value, Ty); });
}
@@ -288,6 +292,8 @@ public:
Visit(C);
else if (const auto *T = N.get<TemplateArgument>())
Visit(*T);
+ else if (const auto *CR = N.get<ConceptReference>())
+ Visit(CR);
}
void dumpDeclContext(const DeclContext *DC) {
@@ -384,18 +390,19 @@ public:
}
void VisitAttributedType(const AttributedType *T) {
// FIXME: AttrKind
- Visit(T->getModifiedType());
+ if (T->getModifiedType() != T->getEquivalentType())
+ Visit(T->getModifiedType());
}
- void VisitSubstTemplateTypeParmType(const SubstTemplateTypeParmType *T) {
- Visit(T->getReplacedParameter());
+ void VisitBTFTagAttributedType(const BTFTagAttributedType *T) {
+ Visit(T->getWrappedType());
}
+ void VisitSubstTemplateTypeParmType(const SubstTemplateTypeParmType *) {}
void
VisitSubstTemplateTypeParmPackType(const SubstTemplateTypeParmPackType *T) {
- Visit(T->getReplacedParameter());
Visit(T->getArgumentPack());
}
void VisitTemplateSpecializationType(const TemplateSpecializationType *T) {
- for (const auto &Arg : *T)
+ for (const auto &Arg : T->template_arguments())
Visit(Arg);
}
void VisitObjCObjectPointerType(const ObjCObjectPointerType *T) {
@@ -419,8 +426,12 @@ public:
}
void VisitFunctionDecl(const FunctionDecl *D) {
- if (const auto *FTSI = D->getTemplateSpecializationInfo())
+ if (FunctionTemplateSpecializationInfo *FTSI =
+ D->getTemplateSpecializationInfo())
dumpTemplateArgumentList(*FTSI->TemplateArguments);
+ else if (DependentFunctionTemplateSpecializationInfo *DFTSI =
+ D->getDependentSpecializationInfo())
+ dumpASTTemplateArgumentListInfo(DFTSI->TemplateArgumentsAsWritten);
if (D->param_begin())
for (const auto *Parameter : D->parameters())
@@ -464,6 +475,10 @@ public:
void VisitBindingDecl(const BindingDecl *D) {
if (Traversal == TK_IgnoreUnlessSpelledInSource)
return;
+
+ if (const auto *V = D->getHoldingVar())
+ Visit(V);
+
if (const auto *E = D->getBinding())
Visit(E);
}
@@ -472,6 +487,8 @@ public:
Visit(D->getAsmString());
}
+ void VisitTopLevelStmtDecl(const TopLevelStmtDecl *D) { Visit(D->getStmt()); }
+
void VisitCapturedDecl(const CapturedDecl *D) { Visit(D->getBody()); }
void VisitOMPThreadPrivateDecl(const OMPThreadPrivateDecl *D) {
@@ -565,11 +582,6 @@ public:
dumpTemplateParameters(D->getTemplateParameters());
}
- void VisitClassScopeFunctionSpecializationDecl(
- const ClassScopeFunctionSpecializationDecl *D) {
- Visit(D->getSpecialization());
- dumpASTTemplateArgumentListInfo(D->getTemplateArgsAsWritten());
- }
void VisitVarTemplateDecl(const VarTemplateDecl *D) { dumpTemplateDecl(D); }
void VisitBuiltinTemplateDecl(const BuiltinTemplateDecl *D) {
@@ -619,7 +631,14 @@ public:
Visit(D->getConstraintExpr());
}
+ void VisitImplicitConceptSpecializationDecl(
+ const ImplicitConceptSpecializationDecl *CSD) {
+ for (const TemplateArgument &Arg : CSD->getTemplateArguments())
+ Visit(Arg);
+ }
+
void VisitConceptSpecializationExpr(const ConceptSpecializationExpr *CSE) {
+ Visit(CSE->getSpecializationDecl());
if (CSE->hasExplicitTemplateArgs())
for (const auto &ArgLoc : CSE->getTemplateArgsAsWritten()->arguments())
dumpTemplateArgumentLoc(ArgLoc);
@@ -631,8 +650,15 @@ public:
}
void VisitFriendDecl(const FriendDecl *D) {
- if (!D->getFriendType())
+ if (D->getFriendType()) {
+ // Traverse any CXXRecordDecl owned by this type, since
+ // it will not be in the parent context:
+ if (auto *ET = D->getFriendType()->getType()->getAs<ElaboratedType>())
+ if (auto *TD = ET->getOwnedTagDecl())
+ Visit(TD);
+ } else {
Visit(D->getFriendDecl());
+ }
}
void VisitObjCMethodDecl(const ObjCMethodDecl *D) {
@@ -697,6 +723,12 @@ public:
}
}
+ void VisitCXXParenListInitExpr(const CXXParenListInitExpr *PLIE) {
+ if (auto *Filler = PLIE->getArrayFiller()) {
+ Visit(Filler, "array_filler");
+ }
+ }
+
void VisitBlockExpr(const BlockExpr *Node) { Visit(Node->getBlockDecl()); }
void VisitOpaqueValueExpr(const OpaqueValueExpr *Node) {
@@ -705,8 +737,11 @@ public:
}
void VisitGenericSelectionExpr(const GenericSelectionExpr *E) {
- Visit(E->getControllingExpr());
- Visit(E->getControllingExpr()->getType()); // FIXME: remove
+ if (E->isExprPredicate()) {
+ Visit(E->getControllingExpr());
+ Visit(E->getControllingExpr()->getType()); // FIXME: remove
+ } else
+ Visit(E->getControllingType()->getType());
for (const auto Assoc : E->associations()) {
Visit(Assoc);
diff --git a/contrib/llvm-project/clang/include/clang/AST/ASTStructuralEquivalence.h b/contrib/llvm-project/clang/include/clang/AST/ASTStructuralEquivalence.h
index c958a16aba21..029439c8e9a3 100644
--- a/contrib/llvm-project/clang/include/clang/AST/ASTStructuralEquivalence.h
+++ b/contrib/llvm-project/clang/include/clang/AST/ASTStructuralEquivalence.h
@@ -17,7 +17,7 @@
#include "clang/AST/DeclBase.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/DenseSet.h"
-#include "llvm/ADT/Optional.h"
+#include <optional>
#include <queue>
#include <utility>
@@ -69,15 +69,19 @@ struct StructuralEquivalenceContext {
/// \c true if the last diagnostic came from ToCtx.
bool LastDiagFromC2 = false;
+ /// Whether to ignore comparing the depth of template param(TemplateTypeParm)
+ bool IgnoreTemplateParmDepth;
+
StructuralEquivalenceContext(
ASTContext &FromCtx, ASTContext &ToCtx,
llvm::DenseSet<std::pair<Decl *, Decl *>> &NonEquivalentDecls,
- StructuralEquivalenceKind EqKind,
- bool StrictTypeSpelling = false, bool Complain = true,
- bool ErrorOnTagTypeMismatch = false)
+ StructuralEquivalenceKind EqKind, bool StrictTypeSpelling = false,
+ bool Complain = true, bool ErrorOnTagTypeMismatch = false,
+ bool IgnoreTemplateParmDepth = false)
: FromCtx(FromCtx), ToCtx(ToCtx), NonEquivalentDecls(NonEquivalentDecls),
EqKind(EqKind), StrictTypeSpelling(StrictTypeSpelling),
- ErrorOnTagTypeMismatch(ErrorOnTagTypeMismatch), Complain(Complain) {}
+ ErrorOnTagTypeMismatch(ErrorOnTagTypeMismatch), Complain(Complain),
+ IgnoreTemplateParmDepth(IgnoreTemplateParmDepth) {}
DiagnosticBuilder Diag1(SourceLocation Loc, unsigned DiagID);
DiagnosticBuilder Diag2(SourceLocation Loc, unsigned DiagID);
@@ -114,10 +118,10 @@ struct StructuralEquivalenceContext {
///
/// FIXME: This is needed by ASTImporter and ASTStructureEquivalence. It
/// probably makes more sense in some other common place then here.
- static llvm::Optional<unsigned>
+ static std::optional<unsigned>
findUntaggedStructOrUnionIndex(RecordDecl *Anon);
- // If ErrorOnTagTypeMismatch is set, return the the error, otherwise get the
+ // If ErrorOnTagTypeMismatch is set, return the error, otherwise get the
// relevant warning for the input error diagnostic.
unsigned getApplicableDiagnostic(unsigned ErrorDiagnostic);
diff --git a/contrib/llvm-project/clang/include/clang/AST/ASTTypeTraits.h b/contrib/llvm-project/clang/include/clang/AST/ASTTypeTraits.h
index 57195a9d6066..3988a15971db 100644
--- a/contrib/llvm-project/clang/include/clang/AST/ASTTypeTraits.h
+++ b/contrib/llvm-project/clang/include/clang/AST/ASTTypeTraits.h
@@ -17,6 +17,7 @@
#include "clang/AST/ASTFwd.h"
#include "clang/AST/DeclCXX.h"
+#include "clang/AST/LambdaCapture.h"
#include "clang/AST/NestedNameSpecifier.h"
#include "clang/AST/TemplateBase.h"
#include "clang/AST/TypeLoc.h"
@@ -25,10 +26,8 @@
#include "llvm/Support/AlignOf.h"
namespace llvm {
-
class raw_ostream;
-
-}
+} // namespace llvm
namespace clang {
@@ -52,11 +51,10 @@ enum TraversalKind {
class ASTNodeKind {
public:
/// Empty identifier. It matches nothing.
- ASTNodeKind() : KindId(NKI_None) {}
+ constexpr ASTNodeKind() : KindId(NKI_None) {}
/// Construct an identifier for T.
- template <class T>
- static ASTNodeKind getFromNodeKind() {
+ template <class T> static constexpr ASTNodeKind getFromNodeKind() {
return ASTNodeKind(KindToKindId<T>::Id);
}
@@ -65,27 +63,33 @@ public:
static ASTNodeKind getFromNode(const Decl &D);
static ASTNodeKind getFromNode(const Stmt &S);
static ASTNodeKind getFromNode(const Type &T);
+ static ASTNodeKind getFromNode(const TypeLoc &T);
+ static ASTNodeKind getFromNode(const LambdaCapture &L);
static ASTNodeKind getFromNode(const OMPClause &C);
+ static ASTNodeKind getFromNode(const Attr &A);
/// \}
/// Returns \c true if \c this and \c Other represent the same kind.
- bool isSame(ASTNodeKind Other) const {
+ constexpr bool isSame(ASTNodeKind Other) const {
return KindId != NKI_None && KindId == Other.KindId;
}
/// Returns \c true only for the default \c ASTNodeKind()
- bool isNone() const { return KindId == NKI_None; }
+ constexpr bool isNone() const { return KindId == NKI_None; }
+
+ /// Returns \c true if \c this is a base kind of (or same as) \c Other.
+ bool isBaseOf(ASTNodeKind Other) const;
/// Returns \c true if \c this is a base kind of (or same as) \c Other.
/// \param Distance If non-null, used to return the distance between \c this
/// and \c Other in the class hierarchy.
- bool isBaseOf(ASTNodeKind Other, unsigned *Distance = nullptr) const;
+ bool isBaseOf(ASTNodeKind Other, unsigned *Distance) const;
/// String representation of the kind.
StringRef asStringRef() const;
/// Strict weak ordering for ASTNodeKind.
- bool operator<(const ASTNodeKind &Other) const {
+ constexpr bool operator<(const ASTNodeKind &Other) const {
return KindId < Other.KindId;
}
@@ -119,7 +123,7 @@ public:
/// Check if the given ASTNodeKind identifies a type that offers pointer
/// identity. This is useful for the fast path in DynTypedNode.
- bool hasPointerIdentity() const {
+ constexpr bool hasPointerIdentity() const {
return KindId > NKI_LastKindWithoutPointerIdentity;
}
@@ -131,9 +135,12 @@ private:
NKI_None,
NKI_TemplateArgument,
NKI_TemplateArgumentLoc,
+ NKI_LambdaCapture,
NKI_TemplateName,
NKI_NestedNameSpecifierLoc,
NKI_QualType,
+#define TYPELOC(CLASS, PARENT) NKI_##CLASS##TypeLoc,
+#include "clang/AST/TypeLocNodes.def"
NKI_TypeLoc,
NKI_LastKindWithoutPointerIdentity = NKI_TypeLoc,
NKI_CXXBaseSpecifier,
@@ -152,11 +159,20 @@ private:
#define GEN_CLANG_CLAUSE_CLASS
#define CLAUSE_CLASS(Enum, Str, Class) NKI_##Class,
#include "llvm/Frontend/OpenMP/OMP.inc"
+ NKI_Attr,
+#define ATTR(A) NKI_##A##Attr,
+#include "clang/Basic/AttrList.inc"
+ NKI_ObjCProtocolLoc,
+ NKI_ConceptReference,
NKI_NumberOfKinds
};
/// Use getFromNodeKind<T>() to construct the kind.
- ASTNodeKind(NodeKindId KindId) : KindId(KindId) {}
+ constexpr ASTNodeKind(NodeKindId KindId) : KindId(KindId) {}
+
+ /// Returns \c true if \c Base is a base kind of (or same as) \c
+ /// Derived.
+ static bool isBaseOf(NodeKindId Base, NodeKindId Derived);
/// Returns \c true if \c Base is a base kind of (or same as) \c
/// Derived.
@@ -192,16 +208,22 @@ private:
KIND_TO_KIND_ID(CXXCtorInitializer)
KIND_TO_KIND_ID(TemplateArgument)
KIND_TO_KIND_ID(TemplateArgumentLoc)
+KIND_TO_KIND_ID(LambdaCapture)
KIND_TO_KIND_ID(TemplateName)
KIND_TO_KIND_ID(NestedNameSpecifier)
KIND_TO_KIND_ID(NestedNameSpecifierLoc)
KIND_TO_KIND_ID(QualType)
+#define TYPELOC(CLASS, PARENT) KIND_TO_KIND_ID(CLASS##TypeLoc)
+#include "clang/AST/TypeLocNodes.def"
KIND_TO_KIND_ID(TypeLoc)
KIND_TO_KIND_ID(Decl)
KIND_TO_KIND_ID(Stmt)
KIND_TO_KIND_ID(Type)
KIND_TO_KIND_ID(OMPClause)
+KIND_TO_KIND_ID(Attr)
+KIND_TO_KIND_ID(ObjCProtocolLoc)
KIND_TO_KIND_ID(CXXBaseSpecifier)
+KIND_TO_KIND_ID(ConceptReference)
#define DECL(DERIVED, BASE) KIND_TO_KIND_ID(DERIVED##Decl)
#include "clang/AST/DeclNodes.inc"
#define STMT(DERIVED, BASE) KIND_TO_KIND_ID(DERIVED)
@@ -211,6 +233,8 @@ KIND_TO_KIND_ID(CXXBaseSpecifier)
#define GEN_CLANG_CLAUSE_CLASS
#define CLAUSE_CLASS(Enum, Str, Class) KIND_TO_KIND_ID(Class)
#include "llvm/Frontend/OpenMP/OMP.inc"
+#define ATTR(A) KIND_TO_KIND_ID(A##Attr)
+#include "clang/Basic/AttrList.inc"
#undef KIND_TO_KIND_ID
inline raw_ostream &operator<<(raw_ostream &OS, ASTNodeKind K) {
@@ -299,7 +323,7 @@ public:
return getUnchecked<QualType>().getAsOpaquePtr() <
Other.getUnchecked<QualType>().getAsOpaquePtr();
- if (ASTNodeKind::getFromNodeKind<TypeLoc>().isSame(NodeKind)) {
+ if (ASTNodeKind::getFromNodeKind<TypeLoc>().isBaseOf(NodeKind)) {
auto TLA = getUnchecked<TypeLoc>();
auto TLB = Other.getUnchecked<TypeLoc>();
return std::make_pair(TLA.getType().getAsOpaquePtr(),
@@ -331,7 +355,7 @@ public:
if (ASTNodeKind::getFromNodeKind<QualType>().isSame(NodeKind))
return getUnchecked<QualType>() == Other.getUnchecked<QualType>();
- if (ASTNodeKind::getFromNodeKind<TypeLoc>().isSame(NodeKind))
+ if (ASTNodeKind::getFromNodeKind<TypeLoc>().isBaseOf(NodeKind))
return getUnchecked<TypeLoc>() == Other.getUnchecked<TypeLoc>();
if (ASTNodeKind::getFromNodeKind<NestedNameSpecifierLoc>().isSame(NodeKind))
@@ -360,7 +384,7 @@ public:
}
static unsigned getHashValue(const DynTypedNode &Val) {
// FIXME: Add hashing support for the remaining types.
- if (ASTNodeKind::getFromNodeKind<TypeLoc>().isSame(Val.NodeKind)) {
+ if (ASTNodeKind::getFromNodeKind<TypeLoc>().isBaseOf(Val.NodeKind)) {
auto TL = Val.getUnchecked<TypeLoc>();
return llvm::hash_combine(TL.getType().getAsOpaquePtr(),
TL.getOpaqueData());
@@ -450,6 +474,29 @@ private:
}
};
+ /// Converter that stores nodes by value. It must be possible to dynamically
+ /// cast the stored node within a type hierarchy without breaking (especially
+ /// through slicing).
+ template <typename T, typename BaseT,
+ typename = std::enable_if_t<(sizeof(T) == sizeof(BaseT))>>
+ struct DynCastValueConverter {
+ static const T *get(ASTNodeKind NodeKind, const void *Storage) {
+ if (ASTNodeKind::getFromNodeKind<T>().isBaseOf(NodeKind))
+ return &getUnchecked(NodeKind, Storage);
+ return nullptr;
+ }
+ static const T &getUnchecked(ASTNodeKind NodeKind, const void *Storage) {
+ assert(ASTNodeKind::getFromNodeKind<T>().isBaseOf(NodeKind));
+ return *static_cast<const T *>(reinterpret_cast<const BaseT *>(Storage));
+ }
+ static DynTypedNode create(const T &Node) {
+ DynTypedNode Result;
+ Result.NodeKind = ASTNodeKind::getFromNode(Node);
+ new (&Result.Storage) T(Node);
+ return Result;
+ }
+ };
+
ASTNodeKind NodeKind;
/// Stores the data of the node.
@@ -462,7 +509,7 @@ private:
/// have storage or unique pointers and thus need to be stored by value.
llvm::AlignedCharArrayUnion<const void *, TemplateArgument,
TemplateArgumentLoc, NestedNameSpecifierLoc,
- QualType, TypeLoc>
+ QualType, TypeLoc, ObjCProtocolLoc>
Storage;
};
@@ -486,6 +533,11 @@ struct DynTypedNode::BaseConverter<
T, std::enable_if_t<std::is_base_of<OMPClause, T>::value>>
: public DynCastPtrConverter<T, OMPClause> {};
+template <typename T>
+struct DynTypedNode::BaseConverter<
+ T, std::enable_if_t<std::is_base_of<Attr, T>::value>>
+ : public DynCastPtrConverter<T, Attr> {};
+
template <>
struct DynTypedNode::BaseConverter<
NestedNameSpecifier, void> : public PtrConverter<NestedNameSpecifier> {};
@@ -503,6 +555,10 @@ struct DynTypedNode::BaseConverter<TemplateArgumentLoc, void>
: public ValueConverter<TemplateArgumentLoc> {};
template <>
+struct DynTypedNode::BaseConverter<LambdaCapture, void>
+ : public ValueConverter<LambdaCapture> {};
+
+template <>
struct DynTypedNode::BaseConverter<
TemplateName, void> : public ValueConverter<TemplateName> {};
@@ -515,14 +571,23 @@ template <>
struct DynTypedNode::BaseConverter<QualType,
void> : public ValueConverter<QualType> {};
-template <>
+template <typename T>
struct DynTypedNode::BaseConverter<
- TypeLoc, void> : public ValueConverter<TypeLoc> {};
+ T, std::enable_if_t<std::is_base_of<TypeLoc, T>::value>>
+ : public DynCastValueConverter<T, TypeLoc> {};
template <>
struct DynTypedNode::BaseConverter<CXXBaseSpecifier, void>
: public PtrConverter<CXXBaseSpecifier> {};
+template <>
+struct DynTypedNode::BaseConverter<ObjCProtocolLoc, void>
+ : public ValueConverter<ObjCProtocolLoc> {};
+
+template <>
+struct DynTypedNode::BaseConverter<ConceptReference, void>
+ : public PtrConverter<ConceptReference> {};
+
// The only operation we allow on unsupported types is \c get.
// This allows to conveniently use \c DynTypedNode when having an arbitrary
// AST node that is not supported, but prevents misuse - a user cannot create
diff --git a/contrib/llvm-project/clang/include/clang/AST/ASTUnresolvedSet.h b/contrib/llvm-project/clang/include/clang/AST/ASTUnresolvedSet.h
index 8d2b23b3539a..398ffb188c95 100644
--- a/contrib/llvm-project/clang/include/clang/AST/ASTUnresolvedSet.h
+++ b/contrib/llvm-project/clang/include/clang/AST/ASTUnresolvedSet.h
@@ -69,7 +69,12 @@ public:
return false;
}
- void erase(unsigned I) { Decls[I] = Decls.pop_back_val(); }
+ void erase(unsigned I) {
+ if (I == Decls.size() - 1)
+ Decls.pop_back();
+ else
+ Decls[I] = Decls.pop_back_val();
+ }
void clear() { Decls.clear(); }
diff --git a/contrib/llvm-project/clang/include/clang/AST/AbstractBasicReader.h b/contrib/llvm-project/clang/include/clang/AST/AbstractBasicReader.h
index 5505d661b44e..1f2797cc7014 100644
--- a/contrib/llvm-project/clang/include/clang/AST/AbstractBasicReader.h
+++ b/contrib/llvm-project/clang/include/clang/AST/AbstractBasicReader.h
@@ -6,22 +6,22 @@
//
//===----------------------------------------------------------------------===//
-#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"
+#include <optional>
namespace clang {
namespace serialization {
template <class T>
-inline T makeNullableFromOptional(const Optional<T> &value) {
+inline T makeNullableFromOptional(const std::optional<T> &value) {
return (value ? *value : T());
}
-template <class T>
-inline T *makePointerFromOptional(Optional<T *> value) {
- return (value ? *value : nullptr);
+template <class T> inline T *makePointerFromOptional(std::optional<T *> value) {
+ return value.value_or(nullptr);
}
// PropertyReader is a class concept that requires the following method:
@@ -49,7 +49,7 @@ inline T *makePointerFromOptional(Optional<T *> value) {
// type-specific readers for all the enum types.
//
// template <class ValueType>
-// Optional<ValueType> writeOptional();
+// std::optional<ValueType> writeOptional();
//
// Reads an optional value from the current property.
//
@@ -157,7 +157,7 @@ public:
}
template <class T, class... Args>
- llvm::Optional<T> readOptional(Args &&...args) {
+ std::optional<T> readOptional(Args &&...args) {
return UnpackOptionalValue<T>::unpack(
ReadDispatcher<T>::read(asImpl(), std::forward<Args>(args)...));
}
@@ -190,7 +190,8 @@ public:
APValue::LValuePathSerializationHelper readLValuePathSerializationHelper(
SmallVectorImpl<APValue::LValuePathEntry> &path) {
- auto elemTy = asImpl().readQualType();
+ auto origTy = asImpl().readQualType();
+ auto elemTy = origTy;
unsigned pathLength = asImpl().readUInt32();
for (unsigned i = 0; i < pathLength; ++i) {
if (elemTy->template getAs<RecordType>()) {
@@ -208,7 +209,7 @@ public:
APValue::LValuePathEntry::ArrayIndex(asImpl().readUInt32()));
}
}
- return APValue::LValuePathSerializationHelper(path, elemTy);
+ return APValue::LValuePathSerializationHelper(path, origTy);
}
Qualifiers readQualifiers() {
diff --git a/contrib/llvm-project/clang/include/clang/AST/AbstractBasicWriter.h b/contrib/llvm-project/clang/include/clang/AST/AbstractBasicWriter.h
index 75aef734ba9b..07afa388de2c 100644
--- a/contrib/llvm-project/clang/include/clang/AST/AbstractBasicWriter.h
+++ b/contrib/llvm-project/clang/include/clang/AST/AbstractBasicWriter.h
@@ -6,25 +6,23 @@
//
//===----------------------------------------------------------------------===//
-#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"
+#include <optional>
namespace clang {
namespace serialization {
template <class T>
-inline llvm::Optional<T> makeOptionalFromNullable(const T &value) {
- return (value.isNull()
- ? llvm::Optional<T>()
- : llvm::Optional<T>(value));
+inline std::optional<T> makeOptionalFromNullable(const T &value) {
+ return (value.isNull() ? std::optional<T>() : std::optional<T>(value));
}
-template <class T>
-inline llvm::Optional<T*> makeOptionalFromPointer(T *value) {
- return (value ? llvm::Optional<T*>(value) : llvm::Optional<T*>());
+template <class T> inline std::optional<T *> makeOptionalFromPointer(T *value) {
+ return (value ? std::optional<T *>(value) : std::optional<T *>());
}
// PropertyWriter is a class concept that requires the following method:
@@ -51,7 +49,7 @@ inline llvm::Optional<T*> makeOptionalFromPointer(T *value) {
// type-specific writers for all the enum types.
//
// template <class ValueType>
-// void writeOptional(Optional<ValueType> value);
+// void writeOptional(std::optional<ValueType> value);
//
// Writes an optional value as the current property.
//
@@ -148,8 +146,7 @@ public:
}
}
- template <class T>
- void writeOptional(llvm::Optional<T> value) {
+ template <class T> void writeOptional(std::optional<T> value) {
WriteDispatcher<T>::write(asImpl(), PackOptionalValue<T>::pack(value));
}
diff --git a/contrib/llvm-project/clang/include/clang/AST/AbstractTypeReader.h b/contrib/llvm-project/clang/include/clang/AST/AbstractTypeReader.h
index 9fea7b26f678..e44bbf61c0ed 100644
--- a/contrib/llvm-project/clang/include/clang/AST/AbstractTypeReader.h
+++ b/contrib/llvm-project/clang/include/clang/AST/AbstractTypeReader.h
@@ -6,11 +6,12 @@
//
//===----------------------------------------------------------------------===//
-#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"
+#include "clang/AST/DeclObjC.h"
+#include "clang/AST/Type.h"
namespace clang {
namespace serialization {
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 dbfecc125049..8e9b7ad8b468 100644
--- a/contrib/llvm-project/clang/include/clang/AST/Attr.h
+++ b/contrib/llvm-project/clang/include/clang/AST/Attr.h
@@ -19,12 +19,13 @@
#include "clang/AST/Type.h"
#include "clang/Basic/AttrKinds.h"
#include "clang/Basic/AttributeCommonInfo.h"
-#include "clang/Basic/LangOptions.h"
#include "clang/Basic/LLVM.h"
+#include "clang/Basic/LangOptions.h"
#include "clang/Basic/OpenMPKinds.h"
#include "clang/Basic/Sanitizers.h"
#include "clang/Basic/SourceLocation.h"
-#include "llvm/ADT/StringSwitch.h"
+#include "llvm/Frontend/HLSL/HLSLResource.h"
+#include "llvm/Support/CodeGen.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/VersionTuple.h"
#include "llvm/Support/raw_ostream.h"
@@ -34,28 +35,29 @@
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.
class Attr : public AttributeCommonInfo {
private:
+ LLVM_PREFERRED_TYPE(attr::Kind)
unsigned AttrKind : 16;
protected:
/// An index into the spelling list of an
/// attribute defined in Attr.td file.
+ LLVM_PREFERRED_TYPE(bool)
unsigned Inherited : 1;
+ LLVM_PREFERRED_TYPE(bool)
unsigned IsPackExpansion : 1;
+ LLVM_PREFERRED_TYPE(bool)
unsigned Implicit : 1;
// FIXME: These are properties of the attribute kind, not state for this
// instance of the attribute.
+ LLVM_PREFERRED_TYPE(bool)
unsigned IsLateParsed : 1;
+ LLVM_PREFERRED_TYPE(bool)
unsigned InheritEvenIfAlreadyPresent : 1;
void *operator new(size_t bytes) noexcept {
@@ -109,6 +111,8 @@ public:
// Pretty print this attribute.
void printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const;
+
+ static StringRef getDocumentation(attr::Kind);
};
class TypeAttr : public Attr {
@@ -193,6 +197,22 @@ public:
}
};
+class HLSLAnnotationAttr : public InheritableAttr {
+protected:
+ HLSLAnnotationAttr(ASTContext &Context, const AttributeCommonInfo &CommonInfo,
+ attr::Kind AK, bool IsLateParsed,
+ bool InheritEvenIfAlreadyPresent)
+ : InheritableAttr(Context, CommonInfo, AK, IsLateParsed,
+ InheritEvenIfAlreadyPresent) {}
+
+public:
+ // Implement isa/cast/dyncast/etc.
+ static bool classof(const Attr *A) {
+ return A->getKind() >= attr::FirstHLSLAnnotationAttr &&
+ A->getKind() <= attr::LastHLSLAnnotationAttr;
+ }
+};
+
/// A parameter attribute which changes the argument-passing ABI rule
/// for the parameter.
class ParameterABIAttr : public InheritableParamAttr {
@@ -230,7 +250,9 @@ public:
class ParamIdx {
// Idx is exposed only via accessors that specify specific encodings.
unsigned Idx : 30;
+ LLVM_PREFERRED_TYPE(bool)
unsigned HasThis : 1;
+ LLVM_PREFERRED_TYPE(bool)
unsigned IsValid : 1;
void assertComparable(const ParamIdx &I) const {
@@ -350,30 +372,11 @@ public:
static_assert(sizeof(ParamIdx) == sizeof(ParamIdx::SerialType),
"ParamIdx does not fit its serialization type");
-/// Contains information gathered from parsing the contents of TargetAttr.
-struct ParsedTargetAttr {
- std::vector<std::string> Features;
- StringRef Architecture;
- StringRef Tune;
- StringRef BranchProtection;
- bool DuplicateArchitecture = false;
- bool DuplicateTune = false;
- bool operator ==(const ParsedTargetAttr &Other) const {
- return DuplicateArchitecture == Other.DuplicateArchitecture &&
- DuplicateTune == Other.DuplicateTune &&
- Architecture == Other.Architecture &&
- Tune == Other.Tune &&
- BranchProtection == Other.BranchProtection &&
- Features == Other.Features;
- }
-};
-
#include "clang/AST/Attrs.inc"
inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB,
const Attr *At) {
- DB.AddTaggedVal(reinterpret_cast<intptr_t>(At),
- DiagnosticsEngine::ak_attr);
+ DB.AddTaggedVal(reinterpret_cast<uint64_t>(At), DiagnosticsEngine::ak_attr);
return DB;
}
} // end namespace clang
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/BuiltinTypes.def b/contrib/llvm-project/clang/include/clang/AST/BuiltinTypes.def
index 039765dfdfea..c04f6f6f1271 100644
--- a/contrib/llvm-project/clang/include/clang/AST/BuiltinTypes.def
+++ b/contrib/llvm-project/clang/include/clang/AST/BuiltinTypes.def
@@ -218,6 +218,9 @@ FLOATING_TYPE(BFloat16, BFloat16Ty)
// '__float128'
FLOATING_TYPE(Float128, Float128Ty)
+// '__ibm128'
+FLOATING_TYPE(Ibm128, Ibm128Ty)
+
//===- Language-specific types --------------------------------------------===//
// This is the type of C++0x 'nullptr'.
diff --git a/contrib/llvm-project/clang/include/clang/AST/CXXInheritance.h b/contrib/llvm-project/clang/include/clang/AST/CXXInheritance.h
index 946b9e318baa..bbef01843e0b 100644
--- a/contrib/llvm-project/clang/include/clang/AST/CXXInheritance.h
+++ b/contrib/llvm-project/clang/include/clang/AST/CXXInheritance.h
@@ -20,7 +20,6 @@
#include "clang/AST/TypeOrdering.h"
#include "clang/Basic/Specifiers.h"
#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/MapVector.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/SmallVector.h"
@@ -131,6 +130,7 @@ class CXXBasePaths {
/// class subobjects for that class type. The key of the map is
/// the cv-unqualified canonical type of the base class subobject.
struct IsVirtBaseAndNumberNonVirtBases {
+ LLVM_PREFERRED_TYPE(bool)
unsigned IsVirtBase : 1;
unsigned NumberOfNonVirtBases : 31;
};
@@ -315,7 +315,7 @@ public:
/// virtual function; in abstract classes, the final overrider for at
/// least one virtual function is a pure virtual function. Due to
/// multiple, virtual inheritance, it is possible for a class to have
-/// more than one final overrider. Athough this is an error (per C++
+/// more than one final overrider. Although this is an error (per C++
/// [class.virtual]p2), it is not considered an error here: the final
/// overrider map can represent multiple final overriders for a
/// method, and it is up to the client to determine whether they are
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/CanonicalType.h b/contrib/llvm-project/clang/include/clang/AST/CanonicalType.h
index 15d7e9efc26a..dde08f0394c9 100644
--- a/contrib/llvm-project/clang/include/clang/AST/CanonicalType.h
+++ b/contrib/llvm-project/clang/include/clang/AST/CanonicalType.h
@@ -305,7 +305,6 @@ public:
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasSignedIntegerRepresentation)
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasUnsignedIntegerRepresentation)
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasFloatingRepresentation)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isPromotableIntegerType)
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isSignedIntegerType)
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isUnsignedIntegerType)
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isSignedIntegerOrEnumerationType)
@@ -529,7 +528,7 @@ struct CanProxyAdaptor<FunctionProtoType>
template<>
struct CanProxyAdaptor<TypeOfType> : public CanProxyBase<TypeOfType> {
- LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getUnderlyingType)
+ LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getUnmodifiedType)
};
template<>
diff --git a/contrib/llvm-project/clang/include/clang/AST/CharUnits.h b/contrib/llvm-project/clang/include/clang/AST/CharUnits.h
index f14d3abf71e5..c06354451dfb 100644
--- a/contrib/llvm-project/clang/include/clang/AST/CharUnits.h
+++ b/contrib/llvm-project/clang/include/clang/AST/CharUnits.h
@@ -64,6 +64,12 @@ namespace clang {
return CharUnits(Quantity);
}
+ /// fromQuantity - Construct a CharUnits quantity from an llvm::Align
+ /// quantity.
+ static CharUnits fromQuantity(llvm::Align Quantity) {
+ return CharUnits(Quantity.value());
+ }
+
// Compound assignment.
CharUnits& operator+= (const CharUnits &Other) {
Quantity += Other.Quantity;
@@ -182,6 +188,13 @@ namespace clang {
/// Beware llvm::Align assumes power of two 8-bit bytes.
llvm::Align getAsAlign() const { return llvm::Align(Quantity); }
+ /// getAsMaybeAlign - Returns Quantity as a valid llvm::Align or
+ /// std::nullopt, Beware llvm::MaybeAlign assumes power of two 8-bit
+ /// bytes.
+ llvm::MaybeAlign getAsMaybeAlign() const {
+ return llvm::MaybeAlign(Quantity);
+ }
+
/// alignTo - Returns the next integer (mod 2**64) that is
/// greater than or equal to this quantity and is a multiple of \p Align.
/// Align must be non-zero.
diff --git a/contrib/llvm-project/clang/include/clang/AST/Comment.h b/contrib/llvm-project/clang/include/clang/AST/Comment.h
index 54a4b0a9cfe6..dd9906727293 100644
--- a/contrib/llvm-project/clang/include/clang/AST/Comment.h
+++ b/contrib/llvm-project/clang/include/clang/AST/Comment.h
@@ -27,6 +27,8 @@ class TemplateParameterList;
namespace comments {
class FullComment;
+enum class InlineCommandRenderKind;
+enum class ParamCommandPassDirection;
/// Describes the syntax that was used in a documentation command.
///
@@ -47,6 +49,17 @@ enum CommandMarkerKind {
CMK_At = 1
};
+enum class CommentKind {
+ None = 0,
+#define COMMENT(CLASS, PARENT) CLASS,
+#define COMMENT_RANGE(BASE, FIRST, LAST) \
+ First##BASE##Constant = FIRST, Last##BASE##Constant = LAST,
+#define LAST_COMMENT_RANGE(BASE, FIRST, LAST) \
+ First##BASE##Constant = FIRST, Last##BASE##Constant = LAST
+#define ABSTRACT_COMMENT(COMMENT)
+#include "clang/AST/CommentNodes.inc"
+};
+
/// Any part of the comment.
/// Abstract class.
class Comment {
@@ -61,6 +74,7 @@ protected:
friend class Comment;
/// Type of this AST node.
+ LLVM_PREFERRED_TYPE(CommentKind)
unsigned Kind : 8;
};
enum { NumCommentBits = 8 };
@@ -68,10 +82,12 @@ protected:
class InlineContentCommentBitfields {
friend class InlineContentComment;
+ LLVM_PREFERRED_TYPE(CommentBitfields)
unsigned : NumCommentBits;
/// True if there is a newline after this inline content node.
/// (There is no separate AST node for a newline.)
+ LLVM_PREFERRED_TYPE(bool)
unsigned HasTrailingNewline : 1;
};
enum { NumInlineContentCommentBits = NumCommentBits + 1 };
@@ -79,12 +95,15 @@ protected:
class TextCommentBitfields {
friend class TextComment;
+ LLVM_PREFERRED_TYPE(InlineContentCommentBitfields)
unsigned : NumInlineContentCommentBits;
/// True if \c IsWhitespace field contains a valid value.
+ LLVM_PREFERRED_TYPE(bool)
mutable unsigned IsWhitespaceValid : 1;
/// True if this comment AST node contains only whitespace.
+ LLVM_PREFERRED_TYPE(bool)
mutable unsigned IsWhitespace : 1;
};
enum { NumTextCommentBits = NumInlineContentCommentBits + 2 };
@@ -92,10 +111,13 @@ protected:
class InlineCommandCommentBitfields {
friend class InlineCommandComment;
+ LLVM_PREFERRED_TYPE(InlineContentCommentBitfields)
unsigned : NumInlineContentCommentBits;
+ LLVM_PREFERRED_TYPE(InlineCommandRenderKind)
unsigned RenderKind : 3;
+ LLVM_PREFERRED_TYPE(CommandTraits::KnownCommandIDs)
unsigned CommandID : CommandInfo::NumCommandIDBits;
};
enum { NumInlineCommandCommentBits = NumInlineContentCommentBits + 3 +
@@ -104,9 +126,11 @@ protected:
class HTMLTagCommentBitfields {
friend class HTMLTagComment;
+ LLVM_PREFERRED_TYPE(InlineContentCommentBitfields)
unsigned : NumInlineContentCommentBits;
/// True if we found that this tag is malformed in some way.
+ LLVM_PREFERRED_TYPE(bool)
unsigned IsMalformed : 1;
};
enum { NumHTMLTagCommentBits = NumInlineContentCommentBits + 1 };
@@ -114,10 +138,12 @@ protected:
class HTMLStartTagCommentBitfields {
friend class HTMLStartTagComment;
+ LLVM_PREFERRED_TYPE(HTMLTagCommentBitfields)
unsigned : NumHTMLTagCommentBits;
/// True if this tag is self-closing (e. g., <br />). This is based on tag
/// spelling in comment (plain <br> would not set this flag).
+ LLVM_PREFERRED_TYPE(bool)
unsigned IsSelfClosing : 1;
};
enum { NumHTMLStartTagCommentBits = NumHTMLTagCommentBits + 1 };
@@ -125,12 +151,15 @@ protected:
class ParagraphCommentBitfields {
friend class ParagraphComment;
+ LLVM_PREFERRED_TYPE(CommentBitfields)
unsigned : NumCommentBits;
/// True if \c IsWhitespace field contains a valid value.
+ LLVM_PREFERRED_TYPE(bool)
mutable unsigned IsWhitespaceValid : 1;
/// True if this comment AST node contains only whitespace.
+ LLVM_PREFERRED_TYPE(bool)
mutable unsigned IsWhitespace : 1;
};
enum { NumParagraphCommentBits = NumCommentBits + 2 };
@@ -138,12 +167,15 @@ protected:
class BlockCommandCommentBitfields {
friend class BlockCommandComment;
+ LLVM_PREFERRED_TYPE(CommentBitfields)
unsigned : NumCommentBits;
+ LLVM_PREFERRED_TYPE(CommandTraits::KnownCommandIDs)
unsigned CommandID : CommandInfo::NumCommandIDBits;
/// Describes the syntax that was used in a documentation command.
/// Contains values from CommandMarkerKind enum.
+ LLVM_PREFERRED_TYPE(CommandMarkerKind)
unsigned CommandMarker : 1;
};
enum { NumBlockCommandCommentBits = NumCommentBits +
@@ -152,12 +184,15 @@ protected:
class ParamCommandCommentBitfields {
friend class ParamCommandComment;
+ LLVM_PREFERRED_TYPE(BlockCommandCommentBitfields)
unsigned : NumBlockCommandCommentBits;
- /// Parameter passing direction, see ParamCommandComment::PassDirection.
+ /// Parameter passing direction.
+ LLVM_PREFERRED_TYPE(ParamCommandPassDirection)
unsigned Direction : 2;
/// True if direction was specified explicitly in the comment.
+ LLVM_PREFERRED_TYPE(bool)
unsigned IsDirectionExplicit : 1;
};
enum { NumParamCommandCommentBits = NumBlockCommandCommentBits + 3 };
@@ -183,22 +218,16 @@ protected:
}
public:
- enum CommentKind {
- NoCommentKind = 0,
-#define COMMENT(CLASS, PARENT) CLASS##Kind,
-#define COMMENT_RANGE(BASE, FIRST, LAST) \
- First##BASE##Constant=FIRST##Kind, Last##BASE##Constant=LAST##Kind,
-#define LAST_COMMENT_RANGE(BASE, FIRST, LAST) \
- First##BASE##Constant=FIRST##Kind, Last##BASE##Constant=LAST##Kind
-#define ABSTRACT_COMMENT(COMMENT)
-#include "clang/AST/CommentNodes.inc"
+ struct Argument {
+ SourceRange Range;
+ StringRef Text;
};
Comment(CommentKind K,
SourceLocation LocBegin,
SourceLocation LocEnd) :
Loc(LocBegin), Range(SourceRange(LocBegin, LocEnd)) {
- CommentBits.Kind = K;
+ CommentBits.Kind = llvm::to_underlying(K);
}
CommentKind getCommentKind() const {
@@ -244,8 +273,9 @@ protected:
public:
static bool classof(const Comment *C) {
- return C->getCommentKind() >= FirstInlineContentCommentConstant &&
- C->getCommentKind() <= LastInlineContentCommentConstant;
+ return C->getCommentKind() >=
+ CommentKind::FirstInlineContentCommentConstant &&
+ C->getCommentKind() <= CommentKind::LastInlineContentCommentConstant;
}
void addTrailingNewline() {
@@ -262,16 +292,14 @@ class TextComment : public InlineContentComment {
StringRef Text;
public:
- TextComment(SourceLocation LocBegin,
- SourceLocation LocEnd,
- StringRef Text) :
- InlineContentComment(TextCommentKind, LocBegin, LocEnd),
- Text(Text) {
+ TextComment(SourceLocation LocBegin, SourceLocation LocEnd, StringRef Text)
+ : InlineContentComment(CommentKind::TextComment, LocBegin, LocEnd),
+ Text(Text) {
TextCommentBits.IsWhitespaceValid = false;
}
static bool classof(const Comment *C) {
- return C->getCommentKind() == TextCommentKind;
+ return C->getCommentKind() == CommentKind::TextComment;
}
child_iterator child_begin() const { return nullptr; }
@@ -293,44 +321,35 @@ private:
bool isWhitespaceNoCache() const;
};
+/// The most appropriate rendering mode for this command, chosen on command
+/// semantics in Doxygen.
+enum class InlineCommandRenderKind {
+ Normal,
+ Bold,
+ Monospaced,
+ Emphasized,
+ Anchor
+};
+
/// A command with word-like arguments that is considered inline content.
class InlineCommandComment : public InlineContentComment {
-public:
- struct Argument {
- SourceRange Range;
- StringRef Text;
-
- Argument(SourceRange Range, StringRef Text) : Range(Range), Text(Text) { }
- };
-
- /// The most appropriate rendering mode for this command, chosen on command
- /// semantics in Doxygen.
- enum RenderKind {
- RenderNormal,
- RenderBold,
- RenderMonospaced,
- RenderEmphasized,
- RenderAnchor
- };
-
protected:
/// Command arguments.
ArrayRef<Argument> Args;
public:
- InlineCommandComment(SourceLocation LocBegin,
- SourceLocation LocEnd,
- unsigned CommandID,
- RenderKind RK,
- ArrayRef<Argument> Args) :
- InlineContentComment(InlineCommandCommentKind, LocBegin, LocEnd),
- Args(Args) {
- InlineCommandCommentBits.RenderKind = RK;
+ InlineCommandComment(SourceLocation LocBegin, SourceLocation LocEnd,
+ unsigned CommandID, InlineCommandRenderKind RK,
+ ArrayRef<Argument> Args)
+ : InlineContentComment(CommentKind::InlineCommandComment, LocBegin,
+ LocEnd),
+ Args(Args) {
+ InlineCommandCommentBits.RenderKind = llvm::to_underlying(RK);
InlineCommandCommentBits.CommandID = CommandID;
}
static bool classof(const Comment *C) {
- return C->getCommentKind() == InlineCommandCommentKind;
+ return C->getCommentKind() == CommentKind::InlineCommandComment;
}
child_iterator child_begin() const { return nullptr; }
@@ -349,8 +368,9 @@ public:
return SourceRange(getBeginLoc().getLocWithOffset(-1), getEndLoc());
}
- RenderKind getRenderKind() const {
- return static_cast<RenderKind>(InlineCommandCommentBits.RenderKind);
+ InlineCommandRenderKind getRenderKind() const {
+ return static_cast<InlineCommandRenderKind>(
+ InlineCommandCommentBits.RenderKind);
}
unsigned getNumArgs() const {
@@ -388,8 +408,8 @@ protected:
public:
static bool classof(const Comment *C) {
- return C->getCommentKind() >= FirstHTMLTagCommentConstant &&
- C->getCommentKind() <= LastHTMLTagCommentConstant;
+ return C->getCommentKind() >= CommentKind::FirstHTMLTagCommentConstant &&
+ C->getCommentKind() <= CommentKind::LastHTMLTagCommentConstant;
}
StringRef getTagName() const LLVM_READONLY { return TagName; }
@@ -424,19 +444,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());
@@ -451,18 +465,16 @@ private:
ArrayRef<Attribute> Attributes;
public:
- HTMLStartTagComment(SourceLocation LocBegin,
- StringRef TagName) :
- HTMLTagComment(HTMLStartTagCommentKind,
- LocBegin, LocBegin.getLocWithOffset(1 + TagName.size()),
- TagName,
- LocBegin.getLocWithOffset(1),
- LocBegin.getLocWithOffset(1 + TagName.size())) {
+ HTMLStartTagComment(SourceLocation LocBegin, StringRef TagName)
+ : HTMLTagComment(CommentKind::HTMLStartTagComment, LocBegin,
+ LocBegin.getLocWithOffset(1 + TagName.size()), TagName,
+ LocBegin.getLocWithOffset(1),
+ LocBegin.getLocWithOffset(1 + TagName.size())) {
HTMLStartTagCommentBits.IsSelfClosing = false;
}
static bool classof(const Comment *C) {
- return C->getCommentKind() == HTMLStartTagCommentKind;
+ return C->getCommentKind() == CommentKind::HTMLStartTagComment;
}
child_iterator child_begin() const { return nullptr; }
@@ -506,18 +518,14 @@ public:
/// A closing HTML tag.
class HTMLEndTagComment : public HTMLTagComment {
public:
- HTMLEndTagComment(SourceLocation LocBegin,
- SourceLocation LocEnd,
- StringRef TagName) :
- HTMLTagComment(HTMLEndTagCommentKind,
- LocBegin, LocEnd,
- TagName,
- LocBegin.getLocWithOffset(2),
- LocBegin.getLocWithOffset(2 + TagName.size()))
- { }
+ HTMLEndTagComment(SourceLocation LocBegin, SourceLocation LocEnd,
+ StringRef TagName)
+ : HTMLTagComment(CommentKind::HTMLEndTagComment, LocBegin, LocEnd,
+ TagName, LocBegin.getLocWithOffset(2),
+ LocBegin.getLocWithOffset(2 + TagName.size())) {}
static bool classof(const Comment *C) {
- return C->getCommentKind() == HTMLEndTagCommentKind;
+ return C->getCommentKind() == CommentKind::HTMLEndTagComment;
}
child_iterator child_begin() const { return nullptr; }
@@ -537,8 +545,9 @@ protected:
public:
static bool classof(const Comment *C) {
- return C->getCommentKind() >= FirstBlockContentCommentConstant &&
- C->getCommentKind() <= LastBlockContentCommentConstant;
+ return C->getCommentKind() >=
+ CommentKind::FirstBlockContentCommentConstant &&
+ C->getCommentKind() <= CommentKind::LastBlockContentCommentConstant;
}
};
@@ -547,11 +556,10 @@ class ParagraphComment : public BlockContentComment {
ArrayRef<InlineContentComment *> Content;
public:
- ParagraphComment(ArrayRef<InlineContentComment *> Content) :
- BlockContentComment(ParagraphCommentKind,
- SourceLocation(),
- SourceLocation()),
- Content(Content) {
+ ParagraphComment(ArrayRef<InlineContentComment *> Content)
+ : BlockContentComment(CommentKind::ParagraphComment, SourceLocation(),
+ SourceLocation()),
+ Content(Content) {
if (Content.empty()) {
ParagraphCommentBits.IsWhitespace = true;
ParagraphCommentBits.IsWhitespaceValid = true;
@@ -566,7 +574,7 @@ public:
}
static bool classof(const Comment *C) {
- return C->getCommentKind() == ParagraphCommentKind;
+ return C->getCommentKind() == CommentKind::ParagraphComment;
}
child_iterator child_begin() const {
@@ -594,15 +602,6 @@ private:
/// arguments depends on command name) and a paragraph as an argument
/// (e. g., \\brief).
class BlockCommandComment : public BlockContentComment {
-public:
- struct Argument {
- SourceRange Range;
- StringRef Text;
-
- Argument() { }
- Argument(SourceRange Range, StringRef Text) : Range(Range), Text(Text) { }
- };
-
protected:
/// Word-like arguments.
ArrayRef<Argument> Args;
@@ -623,20 +622,19 @@ protected:
}
public:
- BlockCommandComment(SourceLocation LocBegin,
- SourceLocation LocEnd,
- unsigned CommandID,
- CommandMarkerKind CommandMarker) :
- BlockContentComment(BlockCommandCommentKind, LocBegin, LocEnd),
- Paragraph(nullptr) {
+ BlockCommandComment(SourceLocation LocBegin, SourceLocation LocEnd,
+ unsigned CommandID, CommandMarkerKind CommandMarker)
+ : BlockContentComment(CommentKind::BlockCommandComment, LocBegin, LocEnd),
+ Paragraph(nullptr) {
setLocation(getCommandNameBeginLoc());
BlockCommandCommentBits.CommandID = CommandID;
BlockCommandCommentBits.CommandMarker = CommandMarker;
}
static bool classof(const Comment *C) {
- return C->getCommentKind() >= FirstBlockCommandCommentConstant &&
- C->getCommentKind() <= LastBlockCommandCommentConstant;
+ return C->getCommentKind() >=
+ CommentKind::FirstBlockCommandCommentConstant &&
+ C->getCommentKind() <= CommentKind::LastBlockCommandCommentConstant;
}
child_iterator child_begin() const {
@@ -707,6 +705,8 @@ public:
}
};
+enum class ParamCommandPassDirection { In, Out, InOut };
+
/// Doxygen \\param command.
class ParamCommandComment : public BlockCommandComment {
private:
@@ -719,39 +719,33 @@ public:
VarArgParamIndex = ~0U/*InvalidParamIndex*/ - 1U
};
- ParamCommandComment(SourceLocation LocBegin,
- SourceLocation LocEnd,
- unsigned CommandID,
- CommandMarkerKind CommandMarker) :
- BlockCommandComment(ParamCommandCommentKind, LocBegin, LocEnd,
- CommandID, CommandMarker),
- ParamIndex(InvalidParamIndex) {
- ParamCommandCommentBits.Direction = In;
+ ParamCommandComment(SourceLocation LocBegin, SourceLocation LocEnd,
+ unsigned CommandID, CommandMarkerKind CommandMarker)
+ : BlockCommandComment(CommentKind::ParamCommandComment, LocBegin, LocEnd,
+ CommandID, CommandMarker),
+ ParamIndex(InvalidParamIndex) {
+ ParamCommandCommentBits.Direction =
+ llvm::to_underlying(ParamCommandPassDirection::In);
ParamCommandCommentBits.IsDirectionExplicit = false;
}
static bool classof(const Comment *C) {
- return C->getCommentKind() == ParamCommandCommentKind;
+ return C->getCommentKind() == CommentKind::ParamCommandComment;
}
- enum PassDirection {
- In,
- Out,
- InOut
- };
-
- static const char *getDirectionAsString(PassDirection D);
+ static const char *getDirectionAsString(ParamCommandPassDirection D);
- PassDirection getDirection() const LLVM_READONLY {
- return static_cast<PassDirection>(ParamCommandCommentBits.Direction);
+ ParamCommandPassDirection getDirection() const LLVM_READONLY {
+ return static_cast<ParamCommandPassDirection>(
+ ParamCommandCommentBits.Direction);
}
bool isDirectionExplicit() const LLVM_READONLY {
return ParamCommandCommentBits.IsDirectionExplicit;
}
- void setDirection(PassDirection Direction, bool Explicit) {
- ParamCommandCommentBits.Direction = Direction;
+ void setDirection(ParamCommandPassDirection Direction, bool Explicit) {
+ ParamCommandCommentBits.Direction = llvm::to_underlying(Direction);
ParamCommandCommentBits.IsDirectionExplicit = Explicit;
}
@@ -813,16 +807,13 @@ private:
ArrayRef<unsigned> Position;
public:
- TParamCommandComment(SourceLocation LocBegin,
- SourceLocation LocEnd,
- unsigned CommandID,
- CommandMarkerKind CommandMarker) :
- BlockCommandComment(TParamCommandCommentKind, LocBegin, LocEnd, CommandID,
- CommandMarker)
- { }
+ TParamCommandComment(SourceLocation LocBegin, SourceLocation LocEnd,
+ unsigned CommandID, CommandMarkerKind CommandMarker)
+ : BlockCommandComment(CommentKind::TParamCommandComment, LocBegin, LocEnd,
+ CommandID, CommandMarker) {}
static bool classof(const Comment *C) {
- return C->getCommentKind() == TParamCommandCommentKind;
+ return C->getCommentKind() == CommentKind::TParamCommandComment;
}
bool hasParamName() const {
@@ -864,16 +855,13 @@ class VerbatimBlockLineComment : public Comment {
StringRef Text;
public:
- VerbatimBlockLineComment(SourceLocation LocBegin,
- StringRef Text) :
- Comment(VerbatimBlockLineCommentKind,
- LocBegin,
- LocBegin.getLocWithOffset(Text.size())),
- Text(Text)
- { }
+ VerbatimBlockLineComment(SourceLocation LocBegin, StringRef Text)
+ : Comment(CommentKind::VerbatimBlockLineComment, LocBegin,
+ LocBegin.getLocWithOffset(Text.size())),
+ Text(Text) {}
static bool classof(const Comment *C) {
- return C->getCommentKind() == VerbatimBlockLineCommentKind;
+ return C->getCommentKind() == CommentKind::VerbatimBlockLineComment;
}
child_iterator child_begin() const { return nullptr; }
@@ -895,16 +883,15 @@ protected:
ArrayRef<VerbatimBlockLineComment *> Lines;
public:
- VerbatimBlockComment(SourceLocation LocBegin,
- SourceLocation LocEnd,
- unsigned CommandID) :
- BlockCommandComment(VerbatimBlockCommentKind,
- LocBegin, LocEnd, CommandID,
- CMK_At) // FIXME: improve source fidelity.
- { }
+ VerbatimBlockComment(SourceLocation LocBegin, SourceLocation LocEnd,
+ unsigned CommandID)
+ : BlockCommandComment(CommentKind::VerbatimBlockComment, LocBegin, LocEnd,
+ CommandID,
+ CMK_At) // FIXME: improve source fidelity.
+ {}
static bool classof(const Comment *C) {
- return C->getCommentKind() == VerbatimBlockCommentKind;
+ return C->getCommentKind() == CommentKind::VerbatimBlockComment;
}
child_iterator child_begin() const {
@@ -946,21 +933,16 @@ protected:
SourceLocation TextBegin;
public:
- VerbatimLineComment(SourceLocation LocBegin,
- SourceLocation LocEnd,
- unsigned CommandID,
- SourceLocation TextBegin,
- StringRef Text) :
- BlockCommandComment(VerbatimLineCommentKind,
- LocBegin, LocEnd,
- CommandID,
- CMK_At), // FIXME: improve source fidelity.
- Text(Text),
- TextBegin(TextBegin)
- { }
+ VerbatimLineComment(SourceLocation LocBegin, SourceLocation LocEnd,
+ unsigned CommandID, SourceLocation TextBegin,
+ StringRef Text)
+ : BlockCommandComment(CommentKind::VerbatimLineComment, LocBegin, LocEnd,
+ CommandID,
+ CMK_At), // FIXME: improve source fidelity.
+ Text(Text), TextBegin(TextBegin) {}
static bool classof(const Comment *C) {
- return C->getCommentKind() == VerbatimLineCommentKind;
+ return C->getCommentKind() == CommentKind::VerbatimLineComment;
}
child_iterator child_begin() const { return nullptr; }
@@ -1019,8 +1001,6 @@ struct DeclInfo {
/// \li member function template,
/// \li member function template specialization,
/// \li ObjC method,
- /// \li a typedef for a function pointer, member function pointer,
- /// ObjC block.
FunctionKind,
/// Something that we consider a "class":
@@ -1030,8 +1010,8 @@ struct DeclInfo {
ClassKind,
/// Something that we consider a "variable":
- /// \li namespace scope variables;
- /// \li static and non-static class data members;
+ /// \li namespace scope variables and variable templates;
+ /// \li static and non-static class data members and member templates;
/// \li enumerators.
VariableKind,
@@ -1055,27 +1035,37 @@ struct DeclInfo {
};
/// If false, only \c CommentDecl is valid.
+ LLVM_PREFERRED_TYPE(bool)
unsigned IsFilled : 1;
/// Simplified kind of \c CommentDecl, see \c DeclKind enum.
+ LLVM_PREFERRED_TYPE(DeclKind)
unsigned Kind : 3;
/// Is \c CommentDecl a template declaration.
+ LLVM_PREFERRED_TYPE(TemplateDeclKind)
unsigned TemplateKind : 2;
/// Is \c CommentDecl an ObjCMethodDecl.
+ LLVM_PREFERRED_TYPE(bool)
unsigned IsObjCMethod : 1;
/// Is \c CommentDecl a non-static member function of C++ class or
/// instance method of ObjC class.
/// Can be true only if \c IsFunctionDecl is true.
+ LLVM_PREFERRED_TYPE(bool)
unsigned IsInstanceMethod : 1;
/// Is \c CommentDecl a static member function of C++ class or
/// class method of ObjC class.
/// Can be true only if \c IsFunctionDecl is true.
+ LLVM_PREFERRED_TYPE(bool)
unsigned IsClassMethod : 1;
+ /// Is \c CommentDecl something we consider a "function" that's variadic.
+ LLVM_PREFERRED_TYPE(bool)
+ unsigned IsVariadic : 1;
+
void fill();
DeclKind getKind() const LLVM_READONLY {
@@ -1085,6 +1075,8 @@ struct DeclInfo {
TemplateDeclKind getTemplateKind() const LLVM_READONLY {
return static_cast<TemplateDeclKind>(TemplateKind);
}
+
+ bool involvesFunctionType() const { return !ReturnType.isNull(); }
};
/// A full comment attached to a declaration, contains block content.
@@ -1093,9 +1085,9 @@ class FullComment : public Comment {
DeclInfo *ThisDeclInfo;
public:
- FullComment(ArrayRef<BlockContentComment *> Blocks, DeclInfo *D) :
- Comment(FullCommentKind, SourceLocation(), SourceLocation()),
- Blocks(Blocks), ThisDeclInfo(D) {
+ FullComment(ArrayRef<BlockContentComment *> Blocks, DeclInfo *D)
+ : Comment(CommentKind::FullComment, SourceLocation(), SourceLocation()),
+ Blocks(Blocks), ThisDeclInfo(D) {
if (Blocks.empty())
return;
@@ -1105,7 +1097,7 @@ public:
}
static bool classof(const Comment *C) {
- return C->getCommentKind() == FullCommentKind;
+ return C->getCommentKind() == CommentKind::FullComment;
}
child_iterator child_begin() const {
diff --git a/contrib/llvm-project/clang/include/clang/AST/CommentCommands.td b/contrib/llvm-project/clang/include/clang/AST/CommentCommands.td
index fbbfc9f7e0b7..e839031752cd 100644
--- a/contrib/llvm-project/clang/include/clang/AST/CommentCommands.td
+++ b/contrib/llvm-project/clang/include/clang/AST/CommentCommands.td
@@ -31,6 +31,7 @@ class Command<string name> {
}
class InlineCommand<string name> : Command<name> {
+ let NumArgs = 1;
let IsInlineCommand = 1;
}
@@ -62,6 +63,11 @@ class VerbatimLineCommand<string name> : Command<name> {
let IsVerbatimLineCommand = 1;
}
+class PropertyCommand<string name> : Command<name> {
+ let NumArgs = 0;
+ let IsInlineCommand = 1;
+}
+
class DeclarationVerbatimLineCommand<string name> :
VerbatimLineCommand<name> {
let IsDeclarationCommand = 1;
@@ -86,9 +92,23 @@ def C : InlineCommand<"c">;
def P : InlineCommand<"p">;
def A : InlineCommand<"a">;
def E : InlineCommand<"e">;
+def N : InlineCommand<"n"> { let NumArgs = 0; }
def Em : InlineCommand<"em">;
-def Ref : InlineCommand<"ref">;
-def Anchor : InlineCommand<"anchor">;
+def Emoji : InlineCommand<"emoji">;
+
+def Anchor : InlineCommand<"anchor">;
+def Ref : InlineCommand<"ref">;
+def RefItem : InlineCommand<"refitem">;
+def Cite : InlineCommand<"cite">;
+
+def CopyBrief : InlineCommand<"copybrief">;
+def CopyDetails : InlineCommand<"copydetails">;
+def CopyDoc : InlineCommand<"copydoc">;
+
+// Typically not used inline, but they take a single word.
+def Extends : InlineCommand<"extends">;
+def Implements : InlineCommand<"implements">;
+def MemberOf : InlineCommand<"memberof">;
//===----------------------------------------------------------------------===//
// BlockCommand
@@ -141,13 +161,15 @@ def Post : BlockCommand<"post">;
def Pre : BlockCommand<"pre">;
def Remark : BlockCommand<"remark">;
def Remarks : BlockCommand<"remarks">;
-def Retval : BlockCommand<"retval">;
+def Retval : BlockCommand<"retval"> { let NumArgs = 1; }
def Sa : BlockCommand<"sa">;
def See : BlockCommand<"see">;
def Since : BlockCommand<"since">;
+def Test : BlockCommand<"test">;
def Todo : BlockCommand<"todo">;
def Version : BlockCommand<"version">;
def Warning : BlockCommand<"warning">;
+def XRefItem : BlockCommand<"xrefitem"> { let NumArgs = 3; }
// HeaderDoc commands
def Abstract : BlockCommand<"abstract"> { let IsBriefCommand = 1; }
def ClassDesign : RecordLikeDetailCommand<"classdesign">;
@@ -170,6 +192,8 @@ def SuperClass : RecordLikeDetailCommand<"superclass">;
defm Code : VerbatimBlockCommand<"code", "endcode">;
defm Verbatim : VerbatimBlockCommand<"verbatim", "endverbatim">;
+
+defm DocbookOnly : VerbatimBlockCommand<"docbookonly", "enddocbookonly">;
defm Htmlonly : VerbatimBlockCommand<"htmlonly", "endhtmlonly">;
defm Latexonly : VerbatimBlockCommand<"latexonly", "endlatexonly">;
defm Xmlonly : VerbatimBlockCommand<"xmlonly", "endxmlonly">;
@@ -178,10 +202,19 @@ defm Rtfonly : VerbatimBlockCommand<"rtfonly", "endrtfonly">;
defm Dot : VerbatimBlockCommand<"dot", "enddot">;
defm Msc : VerbatimBlockCommand<"msc", "endmsc">;
+defm Uml : VerbatimBlockCommand<"startuml", "enduml">;
+
+// Actually not verbatim blocks, we should also parse commands within them.
+defm Internal : VerbatimBlockCommand<"internal", "endinternal">;
+// TODO: conflicts with HeaderDoc link, /link.
+//defm Link : VerbatimBlockCommand<"link", "endlink">;
+defm ParBlock : VerbatimBlockCommand<"parblock", "endparblock">;
+defm SecRefList : VerbatimBlockCommand<"secreflist", "endsecreflist">;
// These three commands have special support in CommentLexer to recognize their
// names.
def FDollar : VerbatimBlockCommand<"f$">; // Inline LaTeX formula
+defm FParen : VerbatimBlockCommand<"f(", "f)">; // Inline LaTeX text
defm FBracket : VerbatimBlockCommand<"f[", "f]">; // Displayed LaTeX formula
defm FBrace : VerbatimBlockCommand<"f{", "f}">; // LaTeX environment
@@ -199,11 +232,18 @@ def Addtogroup : VerbatimLineCommand<"addtogroup">;
def Weakgroup : VerbatimLineCommand<"weakgroup">;
def Name : VerbatimLineCommand<"name">;
+// These actually take a single word, but it's optional.
+// And they're used on a separate line typically, not inline.
+def Dir : VerbatimLineCommand<"dir">;
+def File : VerbatimLineCommand<"file">;
+
def Section : VerbatimLineCommand<"section">;
def Subsection : VerbatimLineCommand<"subsection">;
def Subsubsection : VerbatimLineCommand<"subsubsection">;
def Paragraph : VerbatimLineCommand<"paragraph">;
+def TableOfContents : VerbatimLineCommand<"tableofcontents">;
+def Page : VerbatimLineCommand<"page">;
def Mainpage : VerbatimLineCommand<"mainpage">;
def Subpage : VerbatimLineCommand<"subpage">;
@@ -212,13 +252,80 @@ def Related : VerbatimLineCommand<"related">;
def RelatesAlso : VerbatimLineCommand<"relatesalso">;
def RelatedAlso : VerbatimLineCommand<"relatedalso">;
+def AddIndex : VerbatimLineCommand<"addindex">;
+
+// These take a single argument mostly, but since they include a file they'll
+// typically be on their own line.
+def DocbookInclude : VerbatimLineCommand<"docbookinclude">;
+def DontInclude : VerbatimLineCommand<"dontinclude">;
+def Example : VerbatimLineCommand<"example">;
+def HtmlInclude : VerbatimLineCommand<"htmlinclude">;
+def Include : VerbatimLineCommand<"include">;
+def ManInclude : VerbatimLineCommand<"maninclude">;
+def LatexInclude : VerbatimLineCommand<"latexinclude">;
+def RtfInclude : VerbatimLineCommand<"rtfinclude">;
+def Snippet : VerbatimLineCommand<"snippet">;
+def VerbInclude : VerbatimLineCommand<"verbinclude">;
+def XmlInclude : VerbatimLineCommand<"xmlinclude">;
+
+def Image : VerbatimLineCommand<"image">;
+def DotFile : VerbatimLineCommand<"dotfile">;
+def MscFile : VerbatimLineCommand<"mscfile">;
+def DiaFile : VerbatimLineCommand<"diafile">;
+
+def Line : VerbatimLineCommand<"line">;
+def Skip : VerbatimLineCommand<"skip">;
+def SkipLine : VerbatimLineCommand<"skipline">;
+def Until : VerbatimLineCommand<"until">;
+
+def NoOp : VerbatimLineCommand<"noop">;
+
+// We might also build proper support for if/ifnot/else/elseif/endif.
+def If : VerbatimLineCommand<"if">;
+def IfNot : VerbatimLineCommand<"ifnot">;
+def Else : VerbatimLineCommand<"else">;
+def ElseIf : VerbatimLineCommand<"elseif">;
+def Endif : VerbatimLineCommand<"endif">;
+
+// Not treated as VerbatimBlockCommand because it spans multiple comments.
+def Cond : VerbatimLineCommand<"cond">;
+def EndCond : VerbatimLineCommand<"endcond">;
+
+//===----------------------------------------------------------------------===//
+// PropertyCommand
+//===----------------------------------------------------------------------===//
+
+def CallGraph : PropertyCommand<"callgraph">;
+def HideCallGraph : PropertyCommand<"hidecallgraph">;
+def CallerGraph : PropertyCommand<"callergraph">;
+def HideCallerGraph : PropertyCommand<"hidecallergraph">;
+def ShowInitializer : PropertyCommand<"showinitializer">;
+def HideInitializer : PropertyCommand<"hideinitializer">;
+def ShowRefBy : PropertyCommand<"showrefby">;
+def HideRefBy : PropertyCommand<"hiderefby">;
+def ShowRefs : PropertyCommand<"showrefs">;
+def HideRefs : PropertyCommand<"hiderefs">;
+
+def Private : PropertyCommand<"private">;
+def Protected : PropertyCommand<"protected">;
+def Public : PropertyCommand<"public">;
+def Pure : PropertyCommand<"pure">;
+def Static : PropertyCommand<"static">;
+
+def NoSubgrouping : PropertyCommand<"nosubgrouping">;
+def PrivateSection : PropertyCommand<"privatesection">;
+def ProtectedSection : PropertyCommand<"protectedsection">;
+def PublicSection : PropertyCommand<"publicsection">;
+
//===----------------------------------------------------------------------===//
// DeclarationVerbatimLineCommand
//===----------------------------------------------------------------------===//
// Doxygen commands.
+def Concept : DeclarationVerbatimLineCommand<"concept">;
def Def : DeclarationVerbatimLineCommand<"def">;
def Fn : DeclarationVerbatimLineCommand<"fn">;
+def IDLExcept : DeclarationVerbatimLineCommand<"idlexcept">;
def Namespace : DeclarationVerbatimLineCommand<"namespace">;
def Overload : DeclarationVerbatimLineCommand<"overload">;
def Property : DeclarationVerbatimLineCommand<"property">;
diff --git a/contrib/llvm-project/clang/include/clang/AST/CommentHTMLTags.td b/contrib/llvm-project/clang/include/clang/AST/CommentHTMLTags.td
index 251490094940..a1ce8c6da96c 100644
--- a/contrib/llvm-project/clang/include/clang/AST/CommentHTMLTags.td
+++ b/contrib/llvm-project/clang/include/clang/AST/CommentHTMLTags.td
@@ -52,11 +52,11 @@ def Tr : Tag<"tr"> { let EndTagOptional = 1; }
def Th : Tag<"th"> { let EndTagOptional = 1; }
def Td : Tag<"td"> { let EndTagOptional = 1; }
-// Define a blacklist of attributes that are not safe to pass through to HTML
+// Define a list of attributes that are not safe to pass through to HTML
// output if the input is untrusted.
//
-// FIXME: this should be a whitelist. When changing this to a whitelist, don't
-// forget to change the default in the TableGen backend.
+// FIXME: This should be a list of attributes that _are_ safe. When changing
+// this change, don't forget to change the default in the TableGen backend.
class Attribute<string spelling> {
string Spelling = spelling;
bit IsSafeToPassThrough = 1;
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/CommentParser.h b/contrib/llvm-project/clang/include/clang/AST/CommentParser.h
index 1a0cfb06e52b..e11e818b1af0 100644
--- a/contrib/llvm-project/clang/include/clang/AST/CommentParser.h
+++ b/contrib/llvm-project/clang/include/clang/AST/CommentParser.h
@@ -97,9 +97,8 @@ public:
void parseTParamCommandArgs(TParamCommandComment *TPC,
TextTokenRetokenizer &Retokenizer);
- void parseBlockCommandArgs(BlockCommandComment *BC,
- TextTokenRetokenizer &Retokenizer,
- unsigned NumArgs);
+ ArrayRef<Comment::Argument>
+ parseCommandArgs(TextTokenRetokenizer &Retokenizer, unsigned NumArgs);
BlockCommandComment *parseBlockCommand();
InlineCommandComment *parseInlineCommand();
diff --git a/contrib/llvm-project/clang/include/clang/AST/CommentSema.h b/contrib/llvm-project/clang/include/clang/AST/CommentSema.h
index 6dfe0f4920d0..03f13283ac0d 100644
--- a/contrib/llvm-project/clang/include/clang/AST/CommentSema.h
+++ b/contrib/llvm-project/clang/include/clang/AST/CommentSema.h
@@ -80,7 +80,7 @@ public:
ArrayRef<T> copyArray(ArrayRef<T> Source) {
if (!Source.empty())
return Source.copy(Allocator);
- return None;
+ return std::nullopt;
}
ParagraphComment *actOnParagraphComment(
@@ -130,14 +130,8 @@ public:
InlineCommandComment *actOnInlineCommand(SourceLocation CommandLocBegin,
SourceLocation CommandLocEnd,
- unsigned CommandID);
-
- InlineCommandComment *actOnInlineCommand(SourceLocation CommandLocBegin,
- SourceLocation CommandLocEnd,
unsigned CommandID,
- SourceLocation ArgLocBegin,
- SourceLocation ArgLocEnd,
- StringRef Arg);
+ ArrayRef<Comment::Argument> Args);
InlineContentComment *actOnUnknownCommand(SourceLocation LocBegin,
SourceLocation LocEnd,
@@ -181,6 +175,7 @@ public:
FullComment *actOnFullComment(ArrayRef<BlockContentComment *> Blocks);
+private:
void checkBlockCommandEmptyParagraph(BlockCommandComment *Command);
void checkReturnsCommand(const BlockCommandComment *Command);
@@ -198,19 +193,19 @@ public:
void checkContainerDecl(const BlockCommandComment *Comment);
/// Resolve parameter names to parameter indexes in function declaration.
- /// Emit diagnostics about unknown parametrs.
+ /// Emit diagnostics about unknown parameters.
void resolveParamCommandIndexes(const FullComment *FC);
+ /// \returns \c true if the declaration that this comment is attached to
+ /// is a pointer to function/method/block type or has such a type.
+ bool involvesFunctionType();
+
bool isFunctionDecl();
bool isAnyFunctionDecl();
/// \returns \c true if declaration that this comment is attached to declares
/// a function pointer.
bool isFunctionPointerVarDecl();
- /// \returns \c true if the declaration that this comment is attached to
- /// declares a variable or a field whose type is a function or a block
- /// pointer.
- bool isFunctionOrBlockPointerVarLikeDecl();
bool isFunctionOrMethodVariadic();
bool isObjCMethodDecl();
bool isObjCPropertyDecl();
@@ -249,8 +244,7 @@ public:
StringRef Typo,
const TemplateParameterList *TemplateParameters);
- InlineCommandComment::RenderKind
- getInlineCommandRenderKind(StringRef Name) const;
+ InlineCommandRenderKind getInlineCommandRenderKind(StringRef Name) const;
};
} // end namespace comments
diff --git a/contrib/llvm-project/clang/include/clang/AST/CommentVisitor.h b/contrib/llvm-project/clang/include/clang/AST/CommentVisitor.h
index d9a7439f7cc0..bbb624a23e68 100644
--- a/contrib/llvm-project/clang/include/clang/AST/CommentVisitor.h
+++ b/contrib/llvm-project/clang/include/clang/AST/CommentVisitor.h
@@ -31,8 +31,9 @@ public:
switch (C->getCommentKind()) {
default: llvm_unreachable("Unknown comment kind!");
#define ABSTRACT_COMMENT(COMMENT)
-#define COMMENT(CLASS, PARENT) \
- case Comment::CLASS##Kind: DISPATCH(CLASS, CLASS);
+#define COMMENT(CLASS, PARENT) \
+ case CommentKind::CLASS: \
+ DISPATCH(CLASS, CLASS);
#include "clang/AST/CommentNodes.inc"
#undef ABSTRACT_COMMENT
#undef COMMENT
diff --git a/contrib/llvm-project/clang/include/clang/AST/ComparisonCategories.h b/contrib/llvm-project/clang/include/clang/AST/ComparisonCategories.h
index b41e934142ee..b4ad37e394ce 100644
--- a/contrib/llvm-project/clang/include/clang/AST/ComparisonCategories.h
+++ b/contrib/llvm-project/clang/include/clang/AST/ComparisonCategories.h
@@ -19,6 +19,7 @@
#include "llvm/ADT/DenseMap.h"
#include <array>
#include <cassert>
+#include <optional>
#include <vector>
namespace llvm {
@@ -38,9 +39,8 @@ class NamespaceDecl;
/// An enumeration representing the different comparison categories
/// types.
///
-/// C++2a [cmp.categories.pre] The types weak_equality, strong_equality,
-/// partial_ordering, weak_ordering, and strong_ordering are collectively
-/// termed the comparison category types.
+/// C++20 [cmp.categories.pre] The types partial_ordering, weak_ordering, and
+/// strong_ordering are collectively termed the comparison category types.
enum class ComparisonCategoryType : unsigned char {
PartialOrdering,
WeakOrdering,
@@ -58,7 +58,8 @@ inline ComparisonCategoryType commonComparisonType(ComparisonCategoryType A,
/// Get the comparison category that should be used when comparing values of
/// type \c T.
-Optional<ComparisonCategoryType> getComparisonCategoryForBuiltinCmp(QualType T);
+std::optional<ComparisonCategoryType>
+getComparisonCategoryForBuiltinCmp(QualType T);
/// An enumeration representing the possible results of a three-way
/// comparison. These values map onto instances of comparison category types
@@ -115,8 +116,7 @@ private:
public:
/// The declaration for the comparison category type from the
/// standard library.
- // FIXME: Make this const
- CXXRecordDecl *Record = nullptr;
+ const CXXRecordDecl *Record = nullptr;
/// The Kind of the comparison category type
ComparisonCategoryType Kind;
@@ -146,7 +146,7 @@ public:
return Kind == CCK::PartialOrdering;
}
- /// Converts the specified result kind into the the correct result kind
+ /// Converts the specified result kind into the correct result kind
/// for this category. Specifically it lowers strong equality results to
/// weak equivalence if needed.
ComparisonCategoryResult makeWeakResult(ComparisonCategoryResult Res) const {
diff --git a/contrib/llvm-project/clang/include/clang/AST/ComputeDependence.h b/contrib/llvm-project/clang/include/clang/AST/ComputeDependence.h
index 8db09e6b57d0..f62611cb4c3c 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"
@@ -30,7 +30,8 @@ class UnaryExprOrTypeTraitExpr;
class ArraySubscriptExpr;
class MatrixSubscriptExpr;
class CompoundLiteralExpr;
-class CastExpr;
+class ImplicitCastExpr;
+class ExplicitCastExpr;
class BinaryOperator;
class ConditionalOperator;
class BinaryConditionalOperator;
@@ -70,6 +71,7 @@ class CXXPseudoDestructorExpr;
class OverloadExpr;
class DependentScopeDeclRefExpr;
class CXXConstructExpr;
+class CXXTemporaryObjectExpr;
class CXXDefaultInitExpr;
class CXXDefaultArgExpr;
class LambdaExpr;
@@ -77,6 +79,7 @@ class CXXUnresolvedConstructExpr;
class CXXDependentScopeMemberExpr;
class MaterializeTemporaryExpr;
class CXXFoldExpr;
+class CXXParenListInitExpr;
class TypeTraitExpr;
class ConceptSpecializationExpr;
class SYCLUniqueStableNameExpr;
@@ -114,7 +117,8 @@ ExprDependence computeDependence(UnaryExprOrTypeTraitExpr *E);
ExprDependence computeDependence(ArraySubscriptExpr *E);
ExprDependence computeDependence(MatrixSubscriptExpr *E);
ExprDependence computeDependence(CompoundLiteralExpr *E);
-ExprDependence computeDependence(CastExpr *E);
+ExprDependence computeDependence(ImplicitCastExpr *E);
+ExprDependence computeDependence(ExplicitCastExpr *E);
ExprDependence computeDependence(BinaryOperator *E);
ExprDependence computeDependence(ConditionalOperator *E);
ExprDependence computeDependence(BinaryConditionalOperator *E);
@@ -156,6 +160,7 @@ ExprDependence computeDependence(OverloadExpr *E, bool KnownDependent,
bool KnownContainsUnexpandedParameterPack);
ExprDependence computeDependence(DependentScopeDeclRefExpr *E);
ExprDependence computeDependence(CXXConstructExpr *E);
+ExprDependence computeDependence(CXXTemporaryObjectExpr *E);
ExprDependence computeDependence(CXXDefaultInitExpr *E);
ExprDependence computeDependence(CXXDefaultArgExpr *E);
ExprDependence computeDependence(LambdaExpr *E,
@@ -164,6 +169,7 @@ ExprDependence computeDependence(CXXUnresolvedConstructExpr *E);
ExprDependence computeDependence(CXXDependentScopeMemberExpr *E);
ExprDependence computeDependence(MaterializeTemporaryExpr *E);
ExprDependence computeDependence(CXXFoldExpr *E);
+ExprDependence computeDependence(CXXParenListInitExpr *E);
ExprDependence computeDependence(TypeTraitExpr *E);
ExprDependence computeDependence(ConceptSpecializationExpr *E,
bool ValueDependent);
diff --git a/contrib/llvm-project/clang/include/clang/AST/CurrentSourceLocExprScope.h b/contrib/llvm-project/clang/include/clang/AST/CurrentSourceLocExprScope.h
index 4ebbdf63abb5..4f8343efad16 100644
--- a/contrib/llvm-project/clang/include/clang/AST/CurrentSourceLocExprScope.h
+++ b/contrib/llvm-project/clang/include/clang/AST/CurrentSourceLocExprScope.h
@@ -1,9 +1,8 @@
//===--- CurrentSourceLocExprScope.h ----------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// 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
//
//===----------------------------------------------------------------------===//
//
@@ -12,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>
@@ -72,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 30a9458bc2ee..f26fb5ad5f13 100644
--- a/contrib/llvm-project/clang/include/clang/AST/Decl.h
+++ b/contrib/llvm-project/clang/include/clang/AST/Decl.h
@@ -13,6 +13,7 @@
#ifndef LLVM_CLANG_AST_DECL_H
#define LLVM_CLANG_AST_DECL_H
+#include "clang/AST/APNumericStorage.h"
#include "clang/AST/APValue.h"
#include "clang/AST/ASTContextAllocate.h"
#include "clang/AST/DeclAccessPair.h"
@@ -35,7 +36,6 @@
#include "clang/Basic/Visibility.h"
#include "llvm/ADT/APSInt.h"
#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/Optional.h"
#include "llvm/ADT/PointerIntPair.h"
#include "llvm/ADT/PointerUnion.h"
#include "llvm/ADT/StringRef.h"
@@ -46,6 +46,7 @@
#include <cassert>
#include <cstddef>
#include <cstdint>
+#include <optional>
#include <string>
#include <utility>
@@ -53,7 +54,6 @@ namespace clang {
class ASTContext;
struct ASTTemplateArgumentListInfo;
-class Attr;
class CompoundStmt;
class DependentFunctionTemplateSpecializationInfo;
class EnumDecl;
@@ -74,9 +74,9 @@ class TemplateArgumentList;
class TemplateArgumentListInfo;
class TemplateParameterList;
class TypeAliasTemplateDecl;
-class TypeLoc;
class UnresolvedSetImpl;
class VarTemplateDecl;
+enum class ImplicitParamKind;
/// The top declaration context.
class TranslationUnitDecl : public Decl,
@@ -293,7 +293,9 @@ public:
/// Pretty-print the unqualified name of this declaration. Can be overloaded
/// by derived classes to provide a more user-friendly name when appropriate.
- virtual void printName(raw_ostream &os) const;
+ virtual void printName(raw_ostream &OS, const PrintingPolicy &Policy) const;
+ /// Calls printName() with the ASTContext printing policy from the decl.
+ void printName(raw_ostream &OS) const;
/// Get the actual, stored name of the declaration, which may be a special
/// name.
@@ -357,7 +359,8 @@ public:
///
/// \param IsKnownNewer \c true if this declaration is known to be newer
/// than \p OldD (for instance, if this declaration is newly-created).
- bool declarationReplaces(NamedDecl *OldD, bool IsKnownNewer = true) const;
+ bool declarationReplaces(const NamedDecl *OldD,
+ bool IsKnownNewer = true) const;
/// Determine whether this declaration has linkage.
bool hasLinkage() const;
@@ -395,9 +398,7 @@ public:
/// Get the linkage from a semantic point of view. Entities in
/// anonymous namespaces are external (in c++98).
- Linkage getFormalLinkage() const {
- return clang::getFormalLinkage(getLinkageInternal());
- }
+ Linkage getFormalLinkage() const;
/// True if this decl has external linkage.
bool hasExternalFormalLinkage() const {
@@ -437,7 +438,7 @@ public:
/// If visibility was explicitly specified for this
/// declaration, return that visibility.
- Optional<Visibility>
+ std::optional<Visibility>
getExplicitVisibility(ExplicitVisibilityKind kind) const;
/// True if the computed linkage is valid. Used for consistency
@@ -454,6 +455,8 @@ public:
return hasCachedLinkage();
}
+ bool isPlaceholderVar(const LangOptions &LangOpts) const;
+
/// Looks through UsingDecls and ObjCCompatibleAliasDecls for
/// the underlying named decl.
NamedDecl *getUnderlyingDecl() {
@@ -542,6 +545,9 @@ public:
class NamespaceDecl : public NamedDecl, public DeclContext,
public Redeclarable<NamespaceDecl>
{
+
+ enum Flags : unsigned { F_Inline = 1 << 0, F_Nested = 1 << 1 };
+
/// The starting location of the source range, pointing
/// to either the namespace or the inline keyword.
SourceLocation LocStart;
@@ -553,11 +559,12 @@ class NamespaceDecl : public NamedDecl, public DeclContext,
/// this namespace or to the first namespace in the chain (the latter case
/// only when this is not the first in the chain), along with a
/// boolean value indicating whether this is an inline namespace.
- llvm::PointerIntPair<NamespaceDecl *, 1, bool> AnonOrFirstNamespaceAndInline;
+ llvm::PointerIntPair<NamespaceDecl *, 2, unsigned>
+ AnonOrFirstNamespaceAndFlags;
NamespaceDecl(ASTContext &C, DeclContext *DC, bool Inline,
SourceLocation StartLoc, SourceLocation IdLoc,
- IdentifierInfo *Id, NamespaceDecl *PrevDecl);
+ IdentifierInfo *Id, NamespaceDecl *PrevDecl, bool Nested);
using redeclarable_base = Redeclarable<NamespaceDecl>;
@@ -569,10 +576,10 @@ public:
friend class ASTDeclReader;
friend class ASTDeclWriter;
- static NamespaceDecl *Create(ASTContext &C, DeclContext *DC,
- bool Inline, SourceLocation StartLoc,
- SourceLocation IdLoc, IdentifierInfo *Id,
- NamespaceDecl *PrevDecl);
+ static NamespaceDecl *Create(ASTContext &C, DeclContext *DC, bool Inline,
+ SourceLocation StartLoc, SourceLocation IdLoc,
+ IdentifierInfo *Id, NamespaceDecl *PrevDecl,
+ bool Nested);
static NamespaceDecl *CreateDeserialized(ASTContext &C, unsigned ID);
@@ -601,12 +608,33 @@ public:
/// Returns true if this is an inline namespace declaration.
bool isInline() const {
- return AnonOrFirstNamespaceAndInline.getInt();
+ return AnonOrFirstNamespaceAndFlags.getInt() & F_Inline;
}
/// Set whether this is an inline namespace declaration.
void setInline(bool Inline) {
- AnonOrFirstNamespaceAndInline.setInt(Inline);
+ unsigned F = AnonOrFirstNamespaceAndFlags.getInt();
+ if (Inline)
+ AnonOrFirstNamespaceAndFlags.setInt(F | F_Inline);
+ else
+ AnonOrFirstNamespaceAndFlags.setInt(F & ~F_Inline);
+ }
+
+ /// Returns true if this is a nested namespace declaration.
+ /// \code
+ /// namespace outer::nested { }
+ /// \endcode
+ bool isNested() const {
+ return AnonOrFirstNamespaceAndFlags.getInt() & F_Nested;
+ }
+
+ /// Set whether this is a nested namespace declaration.
+ void setNested(bool Nested) {
+ unsigned F = AnonOrFirstNamespaceAndFlags.getInt();
+ if (Nested)
+ AnonOrFirstNamespaceAndFlags.setInt(F | F_Nested);
+ else
+ AnonOrFirstNamespaceAndFlags.setInt(F & ~F_Nested);
}
/// Returns true if the inline qualifier for \c Name is redundant.
@@ -614,7 +642,9 @@ public:
if (!isInline())
return false;
auto X = lookup(Name);
- auto Y = getParent()->lookup(Name);
+ // We should not perform a lookup within a transparent context, so find a
+ // non-transparent parent context.
+ auto Y = getParent()->getNonTransparentContext()->lookup(Name);
return std::distance(X.begin(), X.end()) ==
std::distance(Y.begin(), Y.end());
}
@@ -633,11 +663,11 @@ public:
/// Retrieve the anonymous namespace nested inside this namespace,
/// if any.
NamespaceDecl *getAnonymousNamespace() const {
- return getOriginalNamespace()->AnonOrFirstNamespaceAndInline.getPointer();
+ return getOriginalNamespace()->AnonOrFirstNamespaceAndFlags.getPointer();
}
void setAnonymousNamespace(NamespaceDecl *D) {
- getOriginalNamespace()->AnonOrFirstNamespaceAndInline.setPointer(D);
+ getOriginalNamespace()->AnonOrFirstNamespaceAndFlags.setPointer(D);
}
/// Retrieves the canonical declaration of this namespace.
@@ -668,6 +698,8 @@ public:
}
};
+class VarDecl;
+
/// Represent the declaration of a variable (in which case it is
/// an lvalue) a function (in which case it is a function designator) or
/// an enum constant.
@@ -689,6 +721,18 @@ public:
/// or declared with the weak or weak-ref attr.
bool isWeak() const;
+ /// Whether this variable is the implicit variable for a lambda init-capture.
+ /// Only VarDecl can be init captures, but both VarDecl and BindingDecl
+ /// can be captured.
+ bool isInitCapture() const;
+
+ // If this is a VarDecl, or a BindindDecl with an
+ // associated decomposed VarDecl, return that VarDecl.
+ VarDecl *getPotentiallyDecomposedVarDecl();
+ const VarDecl *getPotentiallyDecomposedVarDecl() const {
+ return const_cast<ValueDecl *>(this)->getPotentiallyDecomposedVarDecl();
+ }
+
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classofKind(Kind K) { return K >= firstValue && K <= lastValue; }
@@ -861,7 +905,7 @@ struct EvaluatedStmt {
bool HasICEInit : 1;
bool CheckedForICEInit : 1;
- Stmt *Value;
+ LazyDeclStmtPtr Value;
APValue Evaluated;
EvaluatedStmt()
@@ -882,7 +926,10 @@ public:
CallInit,
/// Direct list-initialization (C++11)
- ListInit
+ ListInit,
+
+ /// Parenthesized list-initialization (C++20)
+ ParenListInit
};
/// Kinds of thread-local storage.
@@ -925,12 +972,16 @@ private:
friend class ASTDeclReader;
friend class VarDecl;
+ LLVM_PREFERRED_TYPE(StorageClass)
unsigned SClass : 3;
+ LLVM_PREFERRED_TYPE(ThreadStorageClassSpecifier)
unsigned TSCSpec : 2;
+ LLVM_PREFERRED_TYPE(InitializationStyle)
unsigned InitStyle : 2;
/// Whether this variable is an ARC pseudo-__strong variable; see
/// isARCPseudoStrong() for details.
+ LLVM_PREFERRED_TYPE(bool)
unsigned ARCPseudoStrong : 1;
};
enum { NumVarDeclBits = 8 };
@@ -951,22 +1002,27 @@ protected:
friend class ASTDeclReader;
friend class ParmVarDecl;
+ LLVM_PREFERRED_TYPE(VarDeclBitfields)
unsigned : NumVarDeclBits;
/// Whether this parameter inherits a default argument from a
/// prior declaration.
+ LLVM_PREFERRED_TYPE(bool)
unsigned HasInheritedDefaultArg : 1;
/// Describes the kind of default argument for this parameter. By default
/// this is none. If this is normal, then the default argument is stored in
/// the \c VarDecl initializer expression unless we were unable to parse
/// (even an invalid) expression for the default argument.
+ LLVM_PREFERRED_TYPE(DefaultArgKind)
unsigned DefaultArgKind : 2;
/// Whether this parameter undergoes K&R argument promotion.
+ LLVM_PREFERRED_TYPE(bool)
unsigned IsKNRPromoted : 1;
/// Whether this parameter is an ObjC method parameter or not.
+ LLVM_PREFERRED_TYPE(bool)
unsigned IsObjCMethodParam : 1;
/// If IsObjCMethodParam, a Decl::ObjCDeclQualifier.
@@ -985,51 +1041,64 @@ protected:
friend class ImplicitParamDecl;
friend class VarDecl;
+ LLVM_PREFERRED_TYPE(VarDeclBitfields)
unsigned : NumVarDeclBits;
// FIXME: We need something similar to CXXRecordDecl::DefinitionData.
/// Whether this variable is a definition which was demoted due to
/// module merge.
+ LLVM_PREFERRED_TYPE(bool)
unsigned IsThisDeclarationADemotedDefinition : 1;
/// Whether this variable is the exception variable in a C++ catch
/// or an Objective-C @catch statement.
+ LLVM_PREFERRED_TYPE(bool)
unsigned ExceptionVar : 1;
/// Whether this local variable could be allocated in the return
/// slot of its function, enabling the named return value optimization
/// (NRVO).
+ LLVM_PREFERRED_TYPE(bool)
unsigned NRVOVariable : 1;
/// Whether this variable is the for-range-declaration in a C++0x
/// for-range statement.
+ LLVM_PREFERRED_TYPE(bool)
unsigned CXXForRangeDecl : 1;
/// Whether this variable is the for-in loop declaration in Objective-C.
+ LLVM_PREFERRED_TYPE(bool)
unsigned ObjCForDecl : 1;
/// Whether this variable is (C++1z) inline.
+ LLVM_PREFERRED_TYPE(bool)
unsigned IsInline : 1;
/// Whether this variable has (C++1z) inline explicitly specified.
+ LLVM_PREFERRED_TYPE(bool)
unsigned IsInlineSpecified : 1;
/// Whether this variable is (C++0x) constexpr.
+ LLVM_PREFERRED_TYPE(bool)
unsigned IsConstexpr : 1;
/// Whether this variable is the implicit variable for a lambda
/// init-capture.
+ LLVM_PREFERRED_TYPE(bool)
unsigned IsInitCapture : 1;
/// Whether this local extern variable's previous declaration was
/// declared in the same block scope. This controls whether we should merge
/// the type of this declaration with its previous declaration.
+ LLVM_PREFERRED_TYPE(bool)
unsigned PreviousDeclInSameBlockScope : 1;
/// Defines kind of the ImplicitParamDecl: 'this', 'self', 'vtt', '_cmd' or
/// something else.
+ LLVM_PREFERRED_TYPE(ImplicitParamKind)
unsigned ImplicitParamKind : 3;
+ LLVM_PREFERRED_TYPE(bool)
unsigned EscapingByref : 1;
};
@@ -1041,7 +1110,7 @@ protected:
};
VarDecl(Kind DK, ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
- SourceLocation IdLoc, IdentifierInfo *Id, QualType T,
+ SourceLocation IdLoc, const IdentifierInfo *Id, QualType T,
TypeSourceInfo *TInfo, StorageClass SC);
using redeclarable_base = Redeclarable<VarDecl>;
@@ -1071,8 +1140,8 @@ public:
static VarDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation StartLoc, SourceLocation IdLoc,
- IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo,
- StorageClass S);
+ const IdentifierInfo *Id, QualType T,
+ TypeSourceInfo *TInfo, StorageClass S);
static VarDecl *CreateDeserialized(ASTContext &C, unsigned ID);
@@ -1316,12 +1385,15 @@ public:
EvaluatedStmt *getEvaluatedStmt() const;
/// Attempt to evaluate the value of the initializer attached to this
- /// declaration, and produce notes explaining why it cannot be evaluated or is
- /// not a constant expression. Returns a pointer to the value if evaluation
- /// succeeded, 0 otherwise.
+ /// declaration, and produce notes explaining why it cannot be evaluated.
+ /// Returns a pointer to the value if evaluation succeeded, 0 otherwise.
APValue *evaluateValue() const;
- APValue *evaluateValue(SmallVectorImpl<PartialDiagnosticAt> &Notes) const;
+private:
+ APValue *evaluateValueImpl(SmallVectorImpl<PartialDiagnosticAt> &Notes,
+ bool IsConstantInitialization) const;
+
+public:
/// Return the already-evaluated value of this variable's
/// initializer, or NULL if the value is not yet known. Returns pointer
/// to untyped APValue if the value could not be evaluated.
@@ -1588,38 +1660,55 @@ public:
/// kind?
QualType::DestructionKind needsDestruction(const ASTContext &Ctx) const;
+ /// Whether this variable has a flexible array member initialized with one
+ /// or more elements. This can only be called for declarations where
+ /// hasInit() is true.
+ ///
+ /// (The standard doesn't allow initializing flexible array members; this is
+ /// a gcc/msvc extension.)
+ bool hasFlexibleArrayInit(const ASTContext &Ctx) const;
+
+ /// If hasFlexibleArrayInit is true, compute the number of additional bytes
+ /// necessary to store those elements. Otherwise, returns zero.
+ ///
+ /// This can only be called for declarations where hasInit() is true.
+ CharUnits getFlexibleArrayInitChars(const ASTContext &Ctx) const;
+
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classofKind(Kind K) { return K >= firstVar && K <= lastVar; }
};
-class ImplicitParamDecl : public VarDecl {
- void anchor() override;
+/// Defines the kind of the implicit parameter: is this an implicit parameter
+/// with pointer to 'this', 'self', '_cmd', virtual table pointers, captured
+/// context or something else.
+enum class ImplicitParamKind {
+ /// Parameter for Objective-C 'self' argument
+ ObjCSelf,
-public:
- /// Defines the kind of the implicit parameter: is this an implicit parameter
- /// with pointer to 'this', 'self', '_cmd', virtual table pointers, captured
- /// context or something else.
- enum ImplicitParamKind : unsigned {
- /// Parameter for Objective-C 'self' argument
- ObjCSelf,
+ /// Parameter for Objective-C '_cmd' argument
+ ObjCCmd,
- /// Parameter for Objective-C '_cmd' argument
- ObjCCmd,
+ /// Parameter for C++ 'this' argument
+ CXXThis,
- /// Parameter for C++ 'this' argument
- CXXThis,
+ /// Parameter for C++ virtual table pointers
+ CXXVTT,
- /// Parameter for C++ virtual table pointers
- CXXVTT,
+ /// Parameter for captured context
+ CapturedContext,
- /// Parameter for captured context
- CapturedContext,
+ /// Parameter for Thread private variable
+ ThreadPrivateVar,
- /// Other implicit parameter
- Other,
- };
+ /// Other implicit parameter
+ Other,
+};
+class ImplicitParamDecl : public VarDecl {
+ void anchor() override;
+
+public:
/// Create implicit parameter.
static ImplicitParamDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation IdLoc, IdentifierInfo *Id,
@@ -1634,7 +1723,7 @@ public:
ImplicitParamKind ParamKind)
: VarDecl(ImplicitParam, C, DC, IdLoc, IdLoc, Id, Type,
/*TInfo=*/nullptr, SC_None) {
- NonParmVarDeclBits.ImplicitParamKind = ParamKind;
+ NonParmVarDeclBits.ImplicitParamKind = llvm::to_underlying(ParamKind);
setImplicit();
}
@@ -1642,7 +1731,7 @@ public:
: VarDecl(ImplicitParam, C, /*DC=*/nullptr, SourceLocation(),
SourceLocation(), /*Id=*/nullptr, Type,
/*TInfo=*/nullptr, SC_None) {
- NonParmVarDeclBits.ImplicitParamKind = ParamKind;
+ NonParmVarDeclBits.ImplicitParamKind = llvm::to_underlying(ParamKind);
setImplicit();
}
@@ -1745,6 +1834,18 @@ public:
ParmVarDeclBits.IsKNRPromoted = promoted;
}
+ bool isExplicitObjectParameter() const {
+ return ExplicitObjectParameterIntroducerLoc.isValid();
+ }
+
+ void setExplicitObjectParameterLoc(SourceLocation Loc) {
+ ExplicitObjectParameterIntroducerLoc = Loc;
+ }
+
+ SourceLocation getExplicitObjectParamThisLoc() const {
+ return ExplicitObjectParameterIntroducerLoc;
+ }
+
Expr *getDefaultArg();
const Expr *getDefaultArg() const {
return const_cast<ParmVarDecl *>(this)->getDefaultArg();
@@ -1811,7 +1912,10 @@ public:
static bool classofKind(Kind K) { return K == ParmVar; }
private:
+ friend class ASTDeclReader;
+
enum { ParameterIndexSentinel = (1 << NumParameterIndexBits) - 1 };
+ SourceLocation ExplicitObjectParameterIntroducerLoc;
void setParameterIndex(unsigned parameterIndex) {
if (parameterIndex >= ParameterIndexSentinel) {
@@ -1835,7 +1939,9 @@ enum class MultiVersionKind {
None,
Target,
CPUSpecific,
- CPUDispatch
+ CPUDispatch,
+ TargetClones,
+ TargetVersion
};
/// Represents a function declaration or definition.
@@ -1869,7 +1975,10 @@ public:
TK_FunctionTemplateSpecialization,
// A function template specialization that hasn't yet been resolved to a
// particular specialized function template.
- TK_DependentFunctionTemplateSpecialization
+ TK_DependentFunctionTemplateSpecialization,
+ // A non-template function which is in a dependent scope.
+ TK_DependentNonTemplate
+
};
/// Stashed information about a defaulted function definition whose body has
@@ -1915,23 +2024,26 @@ private:
/// EndRangeLoc.
SourceLocation EndRangeLoc;
+ SourceLocation DefaultKWLoc;
+
/// The template or declaration that this declaration
/// describes or was instantiated from, respectively.
///
- /// For non-templates, this value will be NULL. For function
- /// declarations that describe a function template, this will be a
- /// pointer to a FunctionTemplateDecl. For member functions
- /// of class template specializations, this will be a MemberSpecializationInfo
+ /// For non-templates this value will be NULL, unless this declaration was
+ /// declared directly inside of a function template, in which case it will
+ /// have a pointer to a FunctionDecl, stored in the NamedDecl. For function
+ /// declarations that describe a function template, this will be a pointer to
+ /// a FunctionTemplateDecl, stored in the NamedDecl. For member functions of
+ /// class template specializations, this will be a MemberSpecializationInfo
/// pointer containing information about the specialization.
/// For function template specializations, this will be a
/// FunctionTemplateSpecializationInfo, which contains information about
/// the template being specialized and the template arguments involved in
/// that specialization.
- llvm::PointerUnion<FunctionTemplateDecl *,
- MemberSpecializationInfo *,
+ llvm::PointerUnion<NamedDecl *, MemberSpecializationInfo *,
FunctionTemplateSpecializationInfo *,
DependentFunctionTemplateSpecializationInfo *>
- TemplateOrSpecialization;
+ TemplateOrSpecialization;
/// Provides source/type location info for the declaration name embedded in
/// the DeclaratorDecl base class.
@@ -1987,8 +2099,8 @@ private:
protected:
FunctionDecl(Kind DK, ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
const DeclarationNameInfo &NameInfo, QualType T,
- TypeSourceInfo *TInfo, StorageClass S, bool isInlineSpecified,
- ConstexprSpecKind ConstexprKind,
+ TypeSourceInfo *TInfo, StorageClass S, bool UsesFPIntrin,
+ bool isInlineSpecified, ConstexprSpecKind ConstexprKind,
Expr *TrailingRequiresClause = nullptr);
using redeclarable_base = Redeclarable<FunctionDecl>;
@@ -2022,23 +2134,23 @@ public:
static FunctionDecl *
Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
SourceLocation NLoc, DeclarationName N, QualType T,
- TypeSourceInfo *TInfo, StorageClass SC, bool isInlineSpecified = false,
- bool hasWrittenPrototype = true,
+ TypeSourceInfo *TInfo, StorageClass SC, bool UsesFPIntrin = false,
+ bool isInlineSpecified = false, bool hasWrittenPrototype = true,
ConstexprSpecKind ConstexprKind = ConstexprSpecKind::Unspecified,
Expr *TrailingRequiresClause = nullptr) {
DeclarationNameInfo NameInfo(N, NLoc);
return FunctionDecl::Create(C, DC, StartLoc, NameInfo, T, TInfo, SC,
- isInlineSpecified, hasWrittenPrototype,
- ConstexprKind, TrailingRequiresClause);
+ UsesFPIntrin, isInlineSpecified,
+ hasWrittenPrototype, ConstexprKind,
+ TrailingRequiresClause);
}
- static FunctionDecl *Create(ASTContext &C, DeclContext *DC,
- SourceLocation StartLoc,
- const DeclarationNameInfo &NameInfo, QualType T,
- TypeSourceInfo *TInfo, StorageClass SC,
- bool isInlineSpecified, bool hasWrittenPrototype,
- ConstexprSpecKind ConstexprKind,
- Expr *TrailingRequiresClause);
+ static FunctionDecl *
+ Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
+ const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo,
+ StorageClass SC, bool UsesFPIntrin, bool isInlineSpecified,
+ bool hasWrittenPrototype, ConstexprSpecKind ConstexprKind,
+ Expr *TrailingRequiresClause);
static FunctionDecl *CreateDeserialized(ASTContext &C, unsigned ID);
@@ -2098,7 +2210,7 @@ public:
/// declaration to the declaration that is a definition (if there is one).
///
/// \param CheckForPendingFriendDefinition If \c true, also check for friend
- /// declarations that were instantiataed from function definitions.
+ /// declarations that were instantiated from function definitions.
/// Such a declaration behaves as if it is a definition for the
/// purpose of redefinition checking, but isn't actually a "real"
/// definition until its body is instantiated.
@@ -2182,8 +2294,8 @@ public:
/// Whether this virtual function is pure, i.e. makes the containing class
/// abstract.
- bool isPure() const { return FunctionDeclBits.IsPure; }
- void setPure(bool P = true);
+ bool isPureVirtual() const { return FunctionDeclBits.IsPureVirtual; }
+ void setIsPureVirtual(bool P = true);
/// Whether this templated function will be late parsed.
bool isLateTemplateParsed() const {
@@ -2220,6 +2332,16 @@ public:
FunctionDeclBits.IsExplicitlyDefaulted = ED;
}
+ SourceLocation getDefaultLoc() const {
+ return isExplicitlyDefaulted() ? DefaultKWLoc : SourceLocation();
+ }
+
+ void setDefaultLoc(SourceLocation NewLoc) {
+ assert((NewLoc.isInvalid() || isExplicitlyDefaulted()) &&
+ "Can't set default loc is function isn't explicitly defaulted");
+ DefaultKWLoc = NewLoc;
+ }
+
/// True if this method is user-declared and was not
/// deleted or defaulted on its first declaration.
bool isUserProvided() const {
@@ -2230,6 +2352,13 @@ public:
DeclAsWritten->getCanonicalDecl()->isDefaulted());
}
+ bool isIneligibleOrNotSelected() const {
+ return FunctionDeclBits.IsIneligibleOrNotSelected;
+ }
+ void setIneligibleOrNotSelected(bool II) {
+ FunctionDeclBits.IsIneligibleOrNotSelected = II;
+ }
+
/// Whether falling off this function implicitly returns null/zero.
/// If a more specific implicit return value is required, front-ends
/// should synthesize the appropriate return statements.
@@ -2291,6 +2420,21 @@ public:
return getConstexprKind() == ConstexprSpecKind::Consteval;
}
+ void setBodyContainsImmediateEscalatingExpressions(bool Set) {
+ FunctionDeclBits.BodyContainsImmediateEscalatingExpression = Set;
+ }
+
+ bool BodyContainsImmediateEscalatingExpressions() const {
+ return FunctionDeclBits.BodyContainsImmediateEscalatingExpression;
+ }
+
+ bool isImmediateEscalating() const;
+
+ // The function is a C++ immediate function.
+ // This can be either a consteval function, or an immediate escalating
+ // function containing an immediate escalating expression.
+ bool isImmediateFunction() const;
+
/// Whether the instantiation of this function is pending.
/// This bit is set when the decision to instantiate this function is made
/// and unset if and when the function body is created. That leaves out
@@ -2385,7 +2529,7 @@ public:
/// If this function is an allocation/deallocation function that takes
/// the `std::nothrow_t` tag, return true through IsNothrow,
bool isReplaceableGlobalAllocationFunction(
- Optional<unsigned> *AlignmentParam = nullptr,
+ std::optional<unsigned> *AlignmentParam = nullptr,
bool *IsNothrow = nullptr) const;
/// Determine if this function provides an inline implementation of a builtin.
@@ -2437,6 +2581,23 @@ public:
getCanonicalDecl()->FunctionDeclBits.IsMultiVersion = V;
}
+ // Sets that this is a constrained friend where the constraint refers to an
+ // enclosing template.
+ void setFriendConstraintRefersToEnclosingTemplate(bool V = true) {
+ getCanonicalDecl()
+ ->FunctionDeclBits.FriendConstraintRefersToEnclosingTemplate = V;
+ }
+ // Indicates this function is a constrained friend, where the constraint
+ // refers to an enclosing template for hte purposes of [temp.friend]p9.
+ bool FriendConstraintRefersToEnclosingTemplate() const {
+ return getCanonicalDecl()
+ ->FunctionDeclBits.FriendConstraintRefersToEnclosingTemplate;
+ }
+
+ /// Determine whether a function is a friend function that cannot be
+ /// redeclared outside of its class, per C++ [temp.friend]p9.
+ bool isMemberLikeConstrainedFriend() const;
+
/// Gets the kind of multiversioning attribute this declaration has. Note that
/// this can return a value even if the function is not multiversion, such as
/// the case of 'target'.
@@ -2454,6 +2615,10 @@ public:
/// the target functionality.
bool isTargetMultiVersion() const;
+ /// True if this function is a multiversioned dispatch function as a part of
+ /// the target-clones functionality.
+ bool isTargetClonesMultiVersion() const;
+
/// \brief Get the associated-constraints of this function declaration.
/// Currently, this will either be a vector of size 1 containing the
/// trailing-requires-clause or an empty vector.
@@ -2515,6 +2680,23 @@ public:
/// parameters have default arguments (in C++).
unsigned getMinRequiredArguments() const;
+ /// Returns the minimum number of non-object arguments needed to call this
+ /// function. This produces the same value as getMinRequiredArguments except
+ /// it does not count the explicit object argument, if any.
+ unsigned getMinRequiredExplicitArguments() const;
+
+ bool hasCXXExplicitFunctionObjectParameter() const;
+
+ unsigned getNumNonObjectParams() const;
+
+ const ParmVarDecl *getNonObjectParameter(unsigned I) const {
+ return getParamDecl(hasCXXExplicitFunctionObjectParameter() ? I + 1 : I);
+ }
+
+ ParmVarDecl *getNonObjectParameter(unsigned I) {
+ return getParamDecl(hasCXXExplicitFunctionObjectParameter() ? I + 1 : I);
+ }
+
/// Determine whether this function has a single parameter, or multiple
/// parameters where all but the first have default arguments.
///
@@ -2591,6 +2773,14 @@ public:
FunctionDeclBits.IsInline = I;
}
+ /// Determine whether the function was declared in source context
+ /// that requires constrained FP intrinsics
+ bool UsesFPIntrin() const { return FunctionDeclBits.UsesFPIntrin; }
+
+ /// Set whether the function was declared in source context
+ /// that requires constrained FP intrinsics
+ void setUsesFPIntrin(bool I) { FunctionDeclBits.UsesFPIntrin = I; }
+
/// Flag that this function is implicitly inline.
void setImplicitlyInline(bool I = true) { FunctionDeclBits.IsInline = I; }
@@ -2655,6 +2845,13 @@ public:
setInstantiationOfMemberFunction(getASTContext(), FD, TSK);
}
+ /// Specify that this function declaration was instantiated from a
+ /// FunctionDecl FD. This is only used if this is a function declaration
+ /// declared locally inside of a function template.
+ void setInstantiatedFromDecl(FunctionDecl *FD);
+
+ FunctionDecl *getInstantiatedFromDecl() const;
+
/// Retrieves the function template that is described by this
/// function declaration.
///
@@ -2673,9 +2870,7 @@ public:
/// Determine whether this function is a function template
/// specialization.
- bool isFunctionTemplateSpecialization() const {
- return getPrimaryTemplate() != nullptr;
- }
+ bool isFunctionTemplateSpecialization() const;
/// If this function is actually a function template specialization,
/// retrieve information about this function template specialization.
@@ -2758,9 +2953,9 @@ public:
/// Specifies that this function declaration is actually a
/// dependent function template specialization.
- void setDependentTemplateSpecialization(ASTContext &Context,
- const UnresolvedSetImpl &Templates,
- const TemplateArgumentListInfo &TemplateArgs);
+ void setDependentTemplateSpecialization(
+ ASTContext &Context, const UnresolvedSetImpl &Templates,
+ const TemplateArgumentListInfo *TemplateArgs);
DependentFunctionTemplateSpecializationInfo *
getDependentSpecializationInfo() const;
@@ -2820,11 +3015,7 @@ public:
/// Represents a member of a struct/union/class.
class FieldDecl : public DeclaratorDecl, public Mergeable<FieldDecl> {
- unsigned BitField : 1;
- unsigned Mutable : 1;
- mutable unsigned CachedFieldIndex : 30;
-
- /// The kinds of value we can store in InitializerOrBitWidth.
+ /// The kinds of value we can store in StorageKind.
///
/// Note that this is compatible with InClassInitStyle except for
/// ISK_CapturedVLAType.
@@ -2847,10 +3038,18 @@ class FieldDecl : public DeclaratorDecl, public Mergeable<FieldDecl> {
ISK_CapturedVLAType,
};
+ LLVM_PREFERRED_TYPE(bool)
+ unsigned BitField : 1;
+ LLVM_PREFERRED_TYPE(bool)
+ unsigned Mutable : 1;
+ LLVM_PREFERRED_TYPE(InitStorageKind)
+ unsigned StorageKind : 2;
+ mutable unsigned CachedFieldIndex : 28;
+
/// If this is a bitfield with a default member initializer, this
/// structure is used to represent the two expressions.
- struct InitAndBitWidth {
- Expr *Init;
+ struct InitAndBitWidthStorage {
+ LazyDeclStmtPtr Init;
Expr *BitWidth;
};
@@ -2863,16 +3062,25 @@ class FieldDecl : public DeclaratorDecl, public Mergeable<FieldDecl> {
/// and attached.
// FIXME: Tail-allocate this to reduce the size of FieldDecl in the
// overwhelmingly common case that we have none of these things.
- llvm::PointerIntPair<void *, 2, InitStorageKind> InitStorage;
+ union {
+ // Active member if ISK is not ISK_CapturedVLAType and BitField is false.
+ LazyDeclStmtPtr Init;
+ // Active member if ISK is ISK_NoInit and BitField is true.
+ Expr *BitWidth;
+ // Active member if ISK is ISK_InClass*Init and BitField is true.
+ InitAndBitWidthStorage *InitAndBitWidth;
+ // Active member if ISK is ISK_CapturedVLAType.
+ const VariableArrayType *CapturedVLAType;
+ };
protected:
FieldDecl(Kind DK, DeclContext *DC, SourceLocation StartLoc,
- SourceLocation IdLoc, IdentifierInfo *Id,
- QualType T, TypeSourceInfo *TInfo, Expr *BW, bool Mutable,
+ SourceLocation IdLoc, IdentifierInfo *Id, QualType T,
+ TypeSourceInfo *TInfo, Expr *BW, bool Mutable,
InClassInitStyle InitStyle)
- : DeclaratorDecl(DK, DC, IdLoc, Id, T, TInfo, StartLoc),
- BitField(false), Mutable(Mutable), CachedFieldIndex(0),
- InitStorage(nullptr, (InitStorageKind) InitStyle) {
+ : DeclaratorDecl(DK, DC, IdLoc, Id, T, TInfo, StartLoc), BitField(false),
+ Mutable(Mutable), StorageKind((InitStorageKind)InitStyle),
+ CachedFieldIndex(0), Init() {
if (BW)
setBitWidth(BW);
}
@@ -2908,15 +3116,16 @@ public:
/// store the data for the anonymous union or struct.
bool isAnonymousStructOrUnion() const;
+ /// Returns the expression that represents the bit width, if this field
+ /// is a bit field. For non-bitfields, this returns \c nullptr.
Expr *getBitWidth() const {
if (!BitField)
return nullptr;
- void *Ptr = InitStorage.getPointer();
- if (getInClassInitStyle())
- return static_cast<InitAndBitWidth*>(Ptr)->BitWidth;
- return static_cast<Expr*>(Ptr);
+ return hasInClassInitializer() ? InitAndBitWidth->BitWidth : BitWidth;
}
+ /// Computes the bit width of this field, if this is a bit field.
+ /// May not be called on non-bitfields.
unsigned getBitWidthValue(const ASTContext &Ctx) const;
/// Set the bit-field width for this member.
@@ -2925,11 +3134,11 @@ public:
assert(!hasCapturedVLAType() && !BitField &&
"bit width or captured type already set");
assert(Width && "no bit width specified");
- InitStorage.setPointer(
- InitStorage.getInt()
- ? new (getASTContext())
- InitAndBitWidth{getInClassInitializer(), Width}
- : static_cast<void*>(Width));
+ if (hasInClassInitializer())
+ InitAndBitWidth =
+ new (getASTContext()) InitAndBitWidthStorage{Init, Width};
+ else
+ BitWidth = Width;
BitField = true;
}
@@ -2937,7 +3146,11 @@ public:
// Note: used by some clients (i.e., do not remove it).
void removeBitWidth() {
assert(isBitField() && "no bitfield width to remove");
- InitStorage.setPointer(getInClassInitializer());
+ if (hasInClassInitializer()) {
+ // Read the old initializer before we change the active union member.
+ auto ExistingInit = InitAndBitWidth->Init;
+ Init = ExistingInit;
+ }
BitField = false;
}
@@ -2951,11 +3164,14 @@ public:
/// [[no_unique_address]] attribute.
bool isZeroSize(const ASTContext &Ctx) const;
+ /// Determine if this field is of potentially-overlapping class type, that
+ /// is, subobject with the [[no_unique_address]] attribute
+ bool isPotentiallyOverlapping() const;
+
/// Get the kind of (C++11) default member initializer that this field has.
InClassInitStyle getInClassInitStyle() const {
- InitStorageKind storageKind = InitStorage.getInt();
- return (storageKind == ISK_CapturedVLAType
- ? ICIS_NoInit : (InClassInitStyle) storageKind);
+ return (StorageKind == ISK_CapturedVLAType ? ICIS_NoInit
+ : (InClassInitStyle)StorageKind);
}
/// Determine whether this member has a C++11 default member initializer.
@@ -2963,44 +3179,44 @@ public:
return getInClassInitStyle() != ICIS_NoInit;
}
+ /// Determine whether getInClassInitializer() would return a non-null pointer
+ /// without deserializing the initializer.
+ bool hasNonNullInClassInitializer() const {
+ return hasInClassInitializer() && (BitField ? InitAndBitWidth->Init : Init);
+ }
+
/// Get the C++11 default member initializer for this member, or null if one
/// has not been set. If a valid declaration has a default member initializer,
/// but this returns null, then we have not parsed and attached it yet.
- Expr *getInClassInitializer() const {
- if (!hasInClassInitializer())
- return nullptr;
- void *Ptr = InitStorage.getPointer();
- if (BitField)
- return static_cast<InitAndBitWidth*>(Ptr)->Init;
- return static_cast<Expr*>(Ptr);
- }
+ Expr *getInClassInitializer() const;
/// Set the C++11 in-class initializer for this member.
- void setInClassInitializer(Expr *Init) {
- assert(hasInClassInitializer() && !getInClassInitializer());
- if (BitField)
- static_cast<InitAndBitWidth*>(InitStorage.getPointer())->Init = Init;
- else
- InitStorage.setPointer(Init);
- }
+ void setInClassInitializer(Expr *NewInit);
+private:
+ void setLazyInClassInitializer(LazyDeclStmtPtr NewInit);
+
+public:
/// Remove the C++11 in-class initializer from this member.
void removeInClassInitializer() {
assert(hasInClassInitializer() && "no initializer to remove");
- InitStorage.setPointerAndInt(getBitWidth(), ISK_NoInit);
+ StorageKind = ISK_NoInit;
+ if (BitField) {
+ // Read the bit width before we change the active union member.
+ Expr *ExistingBitWidth = InitAndBitWidth->BitWidth;
+ BitWidth = ExistingBitWidth;
+ }
}
/// Determine whether this member captures the variable length array
/// type.
bool hasCapturedVLAType() const {
- return InitStorage.getInt() == ISK_CapturedVLAType;
+ return StorageKind == ISK_CapturedVLAType;
}
/// Get the captured variable length array type.
const VariableArrayType *getCapturedVLAType() const {
- return hasCapturedVLAType() ? static_cast<const VariableArrayType *>(
- InitStorage.getPointer())
- : nullptr;
+ return hasCapturedVLAType() ? CapturedVLAType : nullptr;
}
/// Set the captured variable length array type for this field.
@@ -3028,21 +3244,24 @@ public:
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classofKind(Kind K) { return K >= firstField && K <= lastField; }
+
+ void printName(raw_ostream &OS, const PrintingPolicy &Policy) const override;
};
/// An instance of this object exists for each enum constant
/// that is defined. For example, in "enum X {a,b}", each of a/b are
/// EnumConstantDecl's, X is an instance of EnumDecl, and the type of a/b is a
/// TagType for the X EnumDecl.
-class EnumConstantDecl : public ValueDecl, public Mergeable<EnumConstantDecl> {
+class EnumConstantDecl : public ValueDecl,
+ public Mergeable<EnumConstantDecl>,
+ public APIntStorage {
Stmt *Init; // an integer constant expression
- llvm::APSInt Val; // The value.
+ bool IsUnsigned;
protected:
- EnumConstantDecl(DeclContext *DC, SourceLocation L,
+ EnumConstantDecl(const ASTContext &C, DeclContext *DC, SourceLocation L,
IdentifierInfo *Id, QualType T, Expr *E,
- const llvm::APSInt &V)
- : ValueDecl(EnumConstant, DC, L, Id, T), Init((Stmt*)E), Val(V) {}
+ const llvm::APSInt &V);
public:
friend class StmtIteratorBase;
@@ -3055,10 +3274,15 @@ public:
const Expr *getInitExpr() const { return (const Expr*) Init; }
Expr *getInitExpr() { return (Expr*) Init; }
- const llvm::APSInt &getInitVal() const { return Val; }
+ llvm::APSInt getInitVal() const {
+ return llvm::APSInt(getValue(), IsUnsigned);
+ }
void setInitExpr(Expr *E) { Init = (Stmt*) E; }
- void setInitVal(const llvm::APSInt &V) { Val = V; }
+ void setInitVal(const ASTContext &C, const llvm::APSInt &V) {
+ setValue(C, V);
+ IsUnsigned = V.isUnsigned();
+ }
SourceRange getSourceRange() const override LLVM_READONLY;
@@ -3096,7 +3320,7 @@ public:
using chain_iterator = ArrayRef<NamedDecl *>::const_iterator;
ArrayRef<NamedDecl *> chain() const {
- return llvm::makeArrayRef(Chaining, ChainingSize);
+ return llvm::ArrayRef(Chaining, ChainingSize);
}
chain_iterator chain_begin() const { return chain().begin(); }
chain_iterator chain_end() const { return chain().end(); }
@@ -3470,6 +3694,24 @@ public:
/// parameters.
bool isDependentType() const { return isDependentContext(); }
+ /// Whether this declaration was a definition in some module but was forced
+ /// to be a declaration.
+ ///
+ /// Useful for clients checking if a module has a definition of a specific
+ /// symbol and not interested in the final AST with deduplicated definitions.
+ bool isThisDeclarationADemotedDefinition() const {
+ return TagDeclBits.IsThisDeclarationADemotedDefinition;
+ }
+
+ /// Mark a definition as a declaration and maintain information it _was_
+ /// a definition.
+ void demoteThisDefinitionToDeclaration() {
+ assert(isCompleteDefinition() &&
+ "Should demote definitions only, not forward declarations");
+ setCompleteDefinition(false);
+ TagDeclBits.IsThisDeclarationADemotedDefinition = true;
+ }
+
/// Starts the definition of this tag declaration.
///
/// This method should be invoked at the beginning of the definition
@@ -3495,13 +3737,15 @@ public:
return static_cast<TagKind>(TagDeclBits.TagDeclKind);
}
- void setTagKind(TagKind TK) { TagDeclBits.TagDeclKind = TK; }
+ void setTagKind(TagKind TK) {
+ TagDeclBits.TagDeclKind = llvm::to_underlying(TK);
+ }
- bool isStruct() const { return getTagKind() == TTK_Struct; }
- bool isInterface() const { return getTagKind() == TTK_Interface; }
- bool isClass() const { return getTagKind() == TTK_Class; }
- bool isUnion() const { return getTagKind() == TTK_Union; }
- bool isEnum() const { return getTagKind() == TTK_Enum; }
+ bool isStruct() const { return getTagKind() == TagTypeKind::Struct; }
+ bool isInterface() const { return getTagKind() == TagTypeKind::Interface; }
+ bool isClass() const { return getTagKind() == TagTypeKind::Class; }
+ bool isUnion() const { return getTagKind() == TagTypeKind::Union; }
+ bool isEnum() const { return getTagKind() == TagTypeKind::Enum; }
/// Is this tag type named, either directly or via being defined in
/// a typedef of this type?
@@ -3555,6 +3799,9 @@ public:
return getExtInfo()->TemplParamLists[i];
}
+ using TypeDecl::printName;
+ void printName(raw_ostream &OS, const PrintingPolicy &Policy) const override;
+
void setTemplateParameterListsInfo(ASTContext &Context,
ArrayRef<TemplateParameterList *> TPLists);
@@ -3688,6 +3935,10 @@ public:
bool IsFixed);
static EnumDecl *CreateDeserialized(ASTContext &C, unsigned ID);
+ /// Overrides to provide correct range when there's an enum-base specifier
+ /// with forward declarations.
+ SourceRange getSourceRange() const override LLVM_READONLY;
+
/// When created, the EnumDecl corresponds to a
/// forward-declared enum. This method is used to mark the
/// declaration as being defined; its enumerators have already been
@@ -3769,6 +4020,11 @@ public:
/// -101 1001011 8
unsigned getNumNegativeBits() const { return EnumDeclBits.NumNegativeBits; }
+ /// Calculates the [Min,Max) values the enum can store based on the
+ /// NumPositiveBits and NumNegativeBits. This matters for enums that do not
+ /// have a fixed underlying type.
+ void getValueRange(llvm::APInt &Max, llvm::APInt &Min) const;
+
/// Returns true if this is a C++11 scoped enumeration.
bool isScoped() const { return EnumDeclBits.IsScoped; }
@@ -3839,6 +4095,29 @@ public:
static bool classofKind(Kind K) { return K == Enum; }
};
+/// Enum that represents the different ways arguments are passed to and
+/// returned from function calls. This takes into account the target-specific
+/// and version-specific rules along with the rules determined by the
+/// language.
+enum class RecordArgPassingKind {
+ /// The argument of this type can be passed directly in registers.
+ CanPassInRegs,
+
+ /// The argument of this type cannot be passed directly in registers.
+ /// Records containing this type as a subobject are not forced to be passed
+ /// indirectly. This value is used only in C++. This value is required by
+ /// C++ because, in uncommon situations, it is possible for a class to have
+ /// only trivial copy/move constructors even when one of its subobjects has
+ /// a non-trivial copy/move constructor (if e.g. the corresponding copy/move
+ /// constructor in the derived class is deleted).
+ CannotPassInRegs,
+
+ /// The argument of this type cannot be passed directly in registers.
+ /// Records containing this type as a subobject are forced to be passed
+ /// indirectly.
+ CanNeverPassInRegs
+};
+
/// Represents a struct/union/class. For example:
/// struct X; // Forward declaration, no "body".
/// union Y { int A, B; }; // Has body with members A and B (FieldDecls).
@@ -3848,28 +4127,7 @@ class RecordDecl : public TagDecl {
// to save some space. Use the provided accessors to access it.
public:
friend class DeclContext;
- /// Enum that represents the different ways arguments are passed to and
- /// returned from function calls. This takes into account the target-specific
- /// and version-specific rules along with the rules determined by the
- /// language.
- enum ArgPassingKind : unsigned {
- /// The argument of this type can be passed directly in registers.
- APK_CanPassInRegs,
-
- /// The argument of this type cannot be passed directly in registers.
- /// Records containing this type as a subobject are not forced to be passed
- /// indirectly. This value is used only in C++. This value is required by
- /// C++ because, in uncommon situations, it is possible for a class to have
- /// only trivial copy/move constructors even when one of its subobjects has
- /// a non-trivial copy/move constructor (if e.g. the corresponding copy/move
- /// constructor in the derived class is deleted).
- APK_CannotPassInRegs,
-
- /// The argument of this type cannot be passed directly in registers.
- /// Records containing this type as a subobject are forced to be passed
- /// indirectly.
- APK_CanNeverPassInRegs
- };
+ friend class ASTDeclReader;
protected:
RecordDecl(Kind DK, TagKind TK, const ASTContext &C, DeclContext *DC,
@@ -3994,15 +4252,16 @@ public:
/// it must have at least one trivial, non-deleted copy or move constructor.
/// FIXME: This should be set as part of completeDefinition.
bool canPassInRegisters() const {
- return getArgPassingRestrictions() == APK_CanPassInRegs;
+ return getArgPassingRestrictions() == RecordArgPassingKind::CanPassInRegs;
}
- ArgPassingKind getArgPassingRestrictions() const {
- return static_cast<ArgPassingKind>(RecordDeclBits.ArgPassingRestrictions);
+ RecordArgPassingKind getArgPassingRestrictions() const {
+ return static_cast<RecordArgPassingKind>(
+ RecordDeclBits.ArgPassingRestrictions);
}
- void setArgPassingRestrictions(ArgPassingKind Kind) {
- RecordDeclBits.ArgPassingRestrictions = Kind;
+ void setArgPassingRestrictions(RecordArgPassingKind Kind) {
+ RecordDeclBits.ArgPassingRestrictions = llvm::to_underlying(Kind);
}
bool isParamDestroyedInCallee() const {
@@ -4013,6 +4272,12 @@ public:
RecordDeclBits.ParamDestroyedInCallee = V;
}
+ bool isRandomized() const { return RecordDeclBits.IsRandomized; }
+
+ void setIsRandomized(bool V) { RecordDeclBits.IsRandomized = V; }
+
+ void reorderDecls(const SmallVectorImpl<Decl *> &Decls);
+
/// Determines whether this declaration represents the
/// injected class name.
///
@@ -4097,9 +4362,16 @@ public:
/// nullptr is returned if no named data member exists.
const FieldDecl *findFirstNamedDataMember() const;
+ /// Get precomputed ODRHash or add a new one.
+ unsigned getODRHash();
+
private:
/// Deserialize just the fields.
void LoadFieldsFromExternalStorage() const;
+
+ /// True if a valid hash is stored in ODRHash.
+ bool hasODRHash() const { return RecordDeclBits.ODRHash; }
+ void setODRHash(unsigned Hash) { RecordDeclBits.ODRHash = Hash; }
};
class FileScopeAsmDecl : public Decl {
@@ -4134,6 +4406,41 @@ public:
static bool classofKind(Kind K) { return K == FileScopeAsm; }
};
+/// A declaration that models statements at global scope. This declaration
+/// supports incremental and interactive C/C++.
+///
+/// \note This is used in libInterpreter, clang -cc1 -fincremental-extensions
+/// and in tools such as clang-repl.
+class TopLevelStmtDecl : public Decl {
+ friend class ASTDeclReader;
+ friend class ASTDeclWriter;
+
+ Stmt *Statement = nullptr;
+ bool IsSemiMissing = false;
+
+ TopLevelStmtDecl(DeclContext *DC, SourceLocation L, Stmt *S)
+ : Decl(TopLevelStmt, DC, L), Statement(S) {}
+
+ virtual void anchor();
+
+public:
+ static TopLevelStmtDecl *Create(ASTContext &C, Stmt *Statement);
+ static TopLevelStmtDecl *CreateDeserialized(ASTContext &C, unsigned ID);
+
+ SourceRange getSourceRange() const override LLVM_READONLY;
+ Stmt *getStmt() { return Statement; }
+ const Stmt *getStmt() const { return Statement; }
+ void setStmt(Stmt *S) {
+ assert(IsSemiMissing && "Operation supported for printing values only!");
+ Statement = S;
+ }
+ bool isSemiMissing() const { return IsSemiMissing; }
+ void setSemiMissing(bool Missing = true) { IsSemiMissing = Missing; }
+
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+ static bool classofKind(Kind K) { return K == TopLevelStmt; }
+};
+
/// Represents a block literal declaration, which is like an
/// unnamed FunctionDecl. For example:
/// ^{ statement-body } or ^(int arg1, float arg2){ statement-body }
@@ -4429,6 +4736,16 @@ public:
/// @import std.vector;
/// \endcode
///
+/// A C++20 module import declaration imports the named module or partition.
+/// Periods are permitted in C++20 module names, but have no semantic meaning.
+/// For example:
+/// \code
+/// import NamedModule;
+/// import :SomePartition; // Must be a partition of the current module.
+/// import Names.Like.this; // Allowed.
+/// import :and.Also.Partition.names;
+/// \endcode
+///
/// Import declarations can also be implicitly generated from
/// \#include/\#import directives.
class ImportDecl final : public Decl,
@@ -4505,7 +4822,7 @@ public:
static bool classofKind(Kind K) { return K == Import; }
};
-/// Represents a C++ Modules TS module export declaration.
+/// Represents a standard C++ module export declaration.
///
/// For example:
/// \code
@@ -4572,11 +4889,56 @@ public:
static bool classofKind(Kind K) { return K == Empty; }
};
+/// HLSLBufferDecl - Represent a cbuffer or tbuffer declaration.
+class HLSLBufferDecl final : public NamedDecl, public DeclContext {
+ /// LBraceLoc - The ending location of the source range.
+ SourceLocation LBraceLoc;
+ /// RBraceLoc - The ending location of the source range.
+ SourceLocation RBraceLoc;
+ /// KwLoc - The location of the cbuffer or tbuffer keyword.
+ SourceLocation KwLoc;
+ /// IsCBuffer - Whether the buffer is a cbuffer (and not a tbuffer).
+ bool IsCBuffer;
+
+ HLSLBufferDecl(DeclContext *DC, bool CBuffer, SourceLocation KwLoc,
+ IdentifierInfo *ID, SourceLocation IDLoc,
+ SourceLocation LBrace);
+
+public:
+ static HLSLBufferDecl *Create(ASTContext &C, DeclContext *LexicalParent,
+ bool CBuffer, SourceLocation KwLoc,
+ IdentifierInfo *ID, SourceLocation IDLoc,
+ SourceLocation LBrace);
+ static HLSLBufferDecl *CreateDeserialized(ASTContext &C, unsigned ID);
+
+ SourceRange getSourceRange() const override LLVM_READONLY {
+ return SourceRange(getLocStart(), RBraceLoc);
+ }
+ SourceLocation getLocStart() const LLVM_READONLY { return KwLoc; }
+ SourceLocation getLBraceLoc() const { return LBraceLoc; }
+ SourceLocation getRBraceLoc() const { return RBraceLoc; }
+ void setRBraceLoc(SourceLocation L) { RBraceLoc = L; }
+ bool isCBuffer() const { return IsCBuffer; }
+
+ // Implement isa/cast/dyncast/etc.
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+ static bool classofKind(Kind K) { return K == HLSLBuffer; }
+ static DeclContext *castToDeclContext(const HLSLBufferDecl *D) {
+ return static_cast<DeclContext *>(const_cast<HLSLBufferDecl *>(D));
+ }
+ static HLSLBufferDecl *castFromDeclContext(const DeclContext *DC) {
+ return static_cast<HLSLBufferDecl *>(const_cast<DeclContext *>(DC));
+ }
+
+ friend class ASTDeclReader;
+ friend class ASTDeclWriter;
+};
+
/// Insertion operator for diagnostics. This allows sending NamedDecl's
/// into a diagnostic with <<.
inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &PD,
const NamedDecl *ND) {
- PD.AddTaggedVal(reinterpret_cast<intptr_t>(ND),
+ PD.AddTaggedVal(reinterpret_cast<uint64_t>(ND),
DiagnosticsEngine::ak_nameddecl);
return PD;
}
diff --git a/contrib/llvm-project/clang/include/clang/AST/DeclBase.h b/contrib/llvm-project/clang/include/clang/AST/DeclBase.h
index 482d2889a25a..eb7a1a320600 100644
--- a/contrib/llvm-project/clang/include/clang/AST/DeclBase.h
+++ b/contrib/llvm-project/clang/include/clang/AST/DeclBase.h
@@ -16,8 +16,10 @@
#include "clang/AST/ASTDumperUtils.h"
#include "clang/AST/AttrIterator.h"
#include "clang/AST/DeclarationName.h"
+#include "clang/AST/SelectorLocationsKind.h"
#include "clang/Basic/IdentifierTable.h"
#include "clang/Basic/LLVM.h"
+#include "clang/Basic/LangOptions.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Basic/Specifiers.h"
#include "llvm/ADT/ArrayRef.h"
@@ -48,18 +50,12 @@ class ExternalSourceSymbolAttr;
class FunctionDecl;
class FunctionType;
class IdentifierInfo;
-enum Linkage : unsigned char;
+enum class 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;
@@ -216,7 +212,7 @@ public:
/// The kind of ownership a declaration has, for visibility purposes.
/// This enumeration is designed such that higher values represent higher
/// levels of name hiding.
- enum class ModuleOwnershipKind : unsigned {
+ enum class ModuleOwnershipKind : unsigned char {
/// This declaration is not owned by a module.
Unowned,
@@ -231,8 +227,15 @@ public:
/// module is imported.
VisibleWhenImported,
+ /// This declaration has an owning module, and is visible to lookups
+ /// that occurs within that module. And it is reachable in other module
+ /// when the owning module is transitively imported.
+ ReachableWhenImported,
+
/// This declaration has an owning module, but is only visible to
/// lookups that occur within that module.
+ /// The discarded declarations in global module fragment belongs
+ /// to this group too.
ModulePrivate
};
@@ -241,8 +244,8 @@ protected:
/// DeclContext. These pointers form the linked list that is
/// traversed via DeclContext's decls_begin()/decls_end().
///
- /// The extra two bits are used for the ModuleOwnershipKind.
- llvm::PointerIntPair<Decl *, 2, ModuleOwnershipKind> NextInContextAndBits;
+ /// The extra three bits are used for the ModuleOwnershipKind.
+ llvm::PointerIntPair<Decl *, 3, ModuleOwnershipKind> NextInContextAndBits;
private:
friend class DeclContext;
@@ -282,31 +285,38 @@ private:
SourceLocation Loc;
/// DeclKind - This indicates which class this is.
+ LLVM_PREFERRED_TYPE(Kind)
unsigned DeclKind : 7;
/// InvalidDecl - This indicates a semantic error occurred.
+ LLVM_PREFERRED_TYPE(bool)
unsigned InvalidDecl : 1;
/// HasAttrs - This indicates whether the decl has attributes or not.
+ LLVM_PREFERRED_TYPE(bool)
unsigned HasAttrs : 1;
/// Implicit - Whether this declaration was implicitly generated by
/// the implementation rather than explicitly written by the user.
+ LLVM_PREFERRED_TYPE(bool)
unsigned Implicit : 1;
/// Whether this declaration was "used", meaning that a definition is
/// required.
+ LLVM_PREFERRED_TYPE(bool)
unsigned Used : 1;
/// Whether this declaration was "referenced".
/// The difference with 'Used' is whether the reference appears in a
/// evaluated context or not, e.g. functions used in uninstantiated templates
/// are regarded as "referenced" but not "used".
+ LLVM_PREFERRED_TYPE(bool)
unsigned Referenced : 1;
/// Whether this declaration is a top-level declaration (function,
/// global variable, etc.) that is lexically inside an objc container
/// definition.
+ LLVM_PREFERRED_TYPE(bool)
unsigned TopLevelDeclInObjCContainer : 1;
/// Whether statistic collection is enabled.
@@ -319,20 +329,24 @@ protected:
friend class ASTReader;
friend class CXXClassMemberWrapper;
friend class LinkageComputer;
+ friend class RecordDecl;
template<typename decl_type> friend class Redeclarable;
/// Access - Used by C++ decls for the access specifier.
// NOTE: VC++ treats enums as signed, avoid using the AccessSpecifier enum
+ LLVM_PREFERRED_TYPE(AccessSpecifier)
unsigned Access : 2;
/// Whether this declaration was loaded from an AST file.
+ LLVM_PREFERRED_TYPE(bool)
unsigned FromASTFile : 1;
/// IdentifierNamespace - This specifies what IDNS_* namespace this lives in.
+ LLVM_PREFERRED_TYPE(IdentifierNamespace)
unsigned IdentifierNamespace : 14;
/// If 0, we have not computed the linkage of this declaration.
- /// Otherwise, it is the linkage + 1.
+ LLVM_PREFERRED_TYPE(Linkage)
mutable unsigned CacheValidAndLinkage : 3;
/// Allocate memory for a deserialized declaration.
@@ -352,7 +366,7 @@ protected:
DeclContext *Parent, std::size_t Extra = 0);
private:
- bool AccessDeclContextSanity() const;
+ bool AccessDeclContextCheck() const;
/// Get the module ownership kind to use for a local lexical child of \p DC,
/// which may be either a local or (rarely) an imported declaration.
@@ -383,7 +397,7 @@ protected:
Implicit(false), Used(false), Referenced(false),
TopLevelDeclInObjCContainer(false), Access(AS_none), FromASTFile(0),
IdentifierNamespace(getIdentifierNamespaceForKind(DK)),
- CacheValidAndLinkage(0) {
+ CacheValidAndLinkage(llvm::to_underlying(Linkage::Invalid)) {
if (StatisticsEnabled) add(DK);
}
@@ -392,7 +406,7 @@ protected:
Used(false), Referenced(false), TopLevelDeclInObjCContainer(false),
Access(AS_none), FromASTFile(0),
IdentifierNamespace(getIdentifierNamespaceForKind(DK)),
- CacheValidAndLinkage(0) {
+ CacheValidAndLinkage(llvm::to_underlying(Linkage::Invalid)) {
if (StatisticsEnabled) add(DK);
}
@@ -402,11 +416,11 @@ protected:
void updateOutOfDate(IdentifierInfo &II) const;
Linkage getCachedLinkage() const {
- return Linkage(CacheValidAndLinkage - 1);
+ return static_cast<Linkage>(CacheValidAndLinkage);
}
void setCachedLinkage(Linkage L) const {
- CacheValidAndLinkage = L + 1;
+ CacheValidAndLinkage = llvm::to_underlying(L);
}
bool hasCachedLinkage() const {
@@ -445,6 +459,14 @@ public:
return const_cast<Decl*>(this)->getDeclContext();
}
+ /// Return the non transparent context.
+ /// See the comment of `DeclContext::isTransparentContext()` for the
+ /// definition of transparent context.
+ DeclContext *getNonTransparentDeclContext();
+ const DeclContext *getNonTransparentDeclContext() const {
+ return const_cast<Decl *>(this)->getNonTransparentDeclContext();
+ }
+
/// Find the innermost non-closure ancestor of this declaration,
/// walking up through blocks, lambdas, etc. If that ancestor is
/// not a code context (!isFunctionOrMethod()), returns null.
@@ -464,6 +486,18 @@ public:
bool isInStdNamespace() const;
+ // Return true if this is a FileContext Decl.
+ bool isFileContextDecl() const;
+
+ /// Whether it resembles a flexible array member. This is a static member
+ /// because we want to be able to call it with a nullptr. That allows us to
+ /// perform non-Decl specific checks based on the object's type and strict
+ /// flex array level.
+ static bool isFlexibleArrayMemberLike(
+ ASTContext &Context, const Decl *D, QualType Ty,
+ LangOptions::StrictFlexArraysLevelKind StrictFlexArraysLevel,
+ bool IgnoreTemplateOrMacroSubstitution);
+
ASTContext &getASTContext() const LLVM_READONLY;
/// Helper to get the language options from the ASTContext.
@@ -472,11 +506,11 @@ public:
void setAccess(AccessSpecifier AS) {
Access = AS;
- assert(AccessDeclContextSanity());
+ assert(AccessDeclContextCheck());
}
AccessSpecifier getAccess() const {
- assert(AccessDeclContextSanity());
+ assert(AccessDeclContextCheck());
return AccessSpecifier(Access);
}
@@ -514,17 +548,18 @@ public:
return hasAttrs() ? getAttrs().end() : nullptr;
}
- template <typename T>
- void dropAttr() {
+ template <typename... Ts> void dropAttrs() {
if (!HasAttrs) return;
AttrVec &Vec = getAttrs();
- llvm::erase_if(Vec, [](Attr *A) { return isa<T>(A); });
+ llvm::erase_if(Vec, [](Attr *A) { return isa<Ts...>(A); });
if (Vec.empty())
HasAttrs = false;
}
+ template <typename T> void dropAttr() { dropAttrs<T>(); }
+
template <typename T>
llvm::iterator_range<specific_attr_iterator<T>> specific_attrs() const {
return llvm::make_range(specific_attr_begin<T>(), specific_attr_end<T>());
@@ -613,6 +648,41 @@ 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;
+
+ bool isInvisibleOutsideTheOwningModule() const {
+ return getModuleOwnershipKind() > ModuleOwnershipKind::VisibleWhenImported;
+ }
+
+ /// Whether this declaration comes from another module unit.
+ bool isInAnotherModuleUnit() const;
+
+ /// FIXME: Implement discarding declarations actually in global module
+ /// fragment. See [module.global.frag]p3,4 for details.
+ bool isDiscardedInGlobalModuleFragment() const { return false; }
+
+ /// Check if we should skip checking ODRHash for declaration \param D.
+ ///
+ /// The existing ODRHash mechanism seems to be not stable enough and
+ /// the false positive ODR violation reports are annoying and we rarely see
+ /// true ODR violation reports. Also we learned that MSVC disabled ODR checks
+ /// for declarations in GMF. So we try to disable ODR checks in the GMF to
+ /// get better user experiences before we make the ODR violation checks stable
+ /// enough.
+ bool shouldSkipCheckingODR() const;
+
/// Return true if this declaration has an attribute which acts as
/// definition of the entity, such as 'alias' or 'ifunc'.
bool hasDefiningAttr() const;
@@ -775,7 +845,7 @@ public:
}
/// Get the module that owns this declaration for linkage purposes.
- /// There only ever is such a module under the C++ Modules TS.
+ /// There only ever is such a standard C++ module.
///
/// \param IgnoreLinkage Ignore the linkage of the entity; assume that
/// all declarations in a global module fragment are unowned.
@@ -790,6 +860,11 @@ public:
return (int)getModuleOwnershipKind() <= (int)ModuleOwnershipKind::Visible;
}
+ bool isReachable() const {
+ return (int)getModuleOwnershipKind() <=
+ (int)ModuleOwnershipKind::ReachableWhenImported;
+ }
+
/// Set that this declaration is globally visible, even if it came from a
/// module that is not visible.
void setVisibleDespiteOwningModule() {
@@ -891,10 +966,12 @@ public:
/// If this decl is defined inside a function/method/block it returns
/// the corresponding DeclContext, otherwise it returns null.
- const DeclContext *getParentFunctionOrMethod() const;
- DeclContext *getParentFunctionOrMethod() {
- return const_cast<DeclContext*>(
- const_cast<const Decl*>(this)->getParentFunctionOrMethod());
+ const DeclContext *
+ getParentFunctionOrMethod(bool LexicalParent = false) const;
+ DeclContext *getParentFunctionOrMethod(bool LexicalParent = false) {
+ return const_cast<DeclContext *>(
+ const_cast<const Decl *>(this)->getParentFunctionOrMethod(
+ LexicalParent));
}
/// Retrieves the "canonical" declaration of the given declaration.
@@ -1089,7 +1166,7 @@ public:
/// Determine whether this is a block-scope declaration with linkage.
/// This will either be a local variable declaration declared 'extern', or a
/// local function declaration.
- bool isLocalExternDecl() {
+ bool isLocalExternDecl() const {
return IdentifierNamespace & IDNS_LocalExtern;
}
@@ -1130,6 +1207,12 @@ public:
}
}
+ /// Clears the namespace of this declaration.
+ ///
+ /// This is useful if we want this declaration to be available for
+ /// redeclaration lookup but otherwise hidden for ordinary name lookups.
+ void clearIdentifierNamespace() { IdentifierNamespace = 0; }
+
enum FriendObjectKind {
FOK_None, ///< Not a friend object.
FOK_Declared, ///< A friend of a previously-declared entity.
@@ -1185,6 +1268,10 @@ public:
/// have a FunctionType.
const FunctionType *getFunctionType(bool BlocksToo = true) const;
+ // Looks through the Decl's underlying type to determine if it's a
+ // function pointer type.
+ bool isFunctionPointerType() const;
+
private:
void setAttrsImpl(const AttrVec& Attrs, ASTContext &Ctx);
void setDeclContextsImpl(DeclContext *SemaDC, DeclContext *LexicalDC,
@@ -1327,6 +1414,18 @@ public:
}
};
+/// Only used by CXXDeductionGuideDecl.
+enum class DeductionCandidate : unsigned char {
+ Normal,
+ Copy,
+ Aggregate,
+};
+
+enum class RecordArgPassingKind;
+enum class OMPDeclareReductionInitKind;
+enum class ObjCImplementationControl;
+enum class LinkageSpecLanguageIDs;
+
/// DeclContext - This is used only as base class of specific decl types that
/// can act as declaration contexts. These decls are (only the top classes
/// that directly derive from DeclContext are mentioned, not their subclasses):
@@ -1347,6 +1446,8 @@ public:
class DeclContext {
/// For makeDeclVisibleInContextImpl
friend class ASTDeclReader;
+ /// For checking the new bits in the Serialization part.
+ friend class ASTDeclWriter;
/// For reconcileExternalVisibleStorage, CreateStoredDeclsMap,
/// hasNeedToReconcileExternalVisibleStorage
friend class ExternalASTSource;
@@ -1365,35 +1466,42 @@ class DeclContext {
class DeclContextBitfields {
friend class DeclContext;
/// DeclKind - This indicates which class this is.
+ LLVM_PREFERRED_TYPE(Decl::Kind)
uint64_t DeclKind : 7;
/// Whether this declaration context also has some external
/// storage that contains additional declarations that are lexically
/// part of this context.
+ LLVM_PREFERRED_TYPE(bool)
mutable uint64_t ExternalLexicalStorage : 1;
/// Whether this declaration context also has some external
/// storage that contains additional declarations that are visible
/// in this context.
+ LLVM_PREFERRED_TYPE(bool)
mutable uint64_t ExternalVisibleStorage : 1;
/// Whether this declaration context has had externally visible
/// storage added since the last lookup. In this case, \c LookupPtr's
/// invariant may not hold and needs to be fixed before we perform
/// another lookup.
+ LLVM_PREFERRED_TYPE(bool)
mutable uint64_t NeedToReconcileExternalVisibleStorage : 1;
/// If \c true, this context may have local lexical declarations
/// that are missing from the lookup table.
+ LLVM_PREFERRED_TYPE(bool)
mutable uint64_t HasLazyLocalLexicalLookups : 1;
/// If \c true, the external source may have lexical declarations
/// that are missing from the lookup table.
+ LLVM_PREFERRED_TYPE(bool)
mutable uint64_t HasLazyExternalLexicalLookups : 1;
/// If \c true, lookups should only return identifier from
/// DeclContext scope (for example TranslationUnit). Used in
/// LookupQualifiedName()
+ LLVM_PREFERRED_TYPE(bool)
mutable uint64_t UseQualifiedLookup : 1;
};
@@ -1406,48 +1514,60 @@ class DeclContext {
class TagDeclBitfields {
friend class TagDecl;
/// For the bits in DeclContextBitfields
+ LLVM_PREFERRED_TYPE(DeclContextBitfields)
uint64_t : NumDeclContextBits;
/// The TagKind enum.
+ LLVM_PREFERRED_TYPE(TagTypeKind)
uint64_t TagDeclKind : 3;
/// True if this is a definition ("struct foo {};"), false if it is a
/// declaration ("struct foo;"). It is not considered a definition
/// until the definition has been fully processed.
+ LLVM_PREFERRED_TYPE(bool)
uint64_t IsCompleteDefinition : 1;
/// True if this is currently being defined.
+ LLVM_PREFERRED_TYPE(bool)
uint64_t IsBeingDefined : 1;
/// True if this tag declaration is "embedded" (i.e., defined or declared
/// for the very first time) in the syntax of a declarator.
+ LLVM_PREFERRED_TYPE(bool)
uint64_t IsEmbeddedInDeclarator : 1;
/// True if this tag is free standing, e.g. "struct foo;".
+ LLVM_PREFERRED_TYPE(bool)
uint64_t IsFreeStanding : 1;
/// Indicates whether it is possible for declarations of this kind
/// to have an out-of-date definition.
///
/// This option is only enabled when modules are enabled.
+ LLVM_PREFERRED_TYPE(bool)
uint64_t MayHaveOutOfDateDef : 1;
/// Has the full definition of this type been required by a use somewhere in
/// the TU.
+ LLVM_PREFERRED_TYPE(bool)
uint64_t IsCompleteDefinitionRequired : 1;
+
+ /// Whether this tag is a definition which was demoted due to
+ /// a module merge.
+ LLVM_PREFERRED_TYPE(bool)
+ uint64_t IsThisDeclarationADemotedDefinition : 1;
};
- /// Number of non-inherited bits in TagDeclBitfields.
- enum { NumTagDeclBits = 9 };
+ /// Number of inherited and non-inherited bits in TagDeclBitfields.
+ enum { NumTagDeclBits = NumDeclContextBits + 10 };
/// Stores the bits used by EnumDecl.
/// If modified NumEnumDeclBit and the accessor
/// methods in EnumDecl should be updated appropriately.
class EnumDeclBitfields {
friend class EnumDecl;
- /// For the bits in DeclContextBitfields.
- uint64_t : NumDeclContextBits;
/// For the bits in TagDeclBitfields.
+ LLVM_PREFERRED_TYPE(TagDeclBitfields)
uint64_t : NumTagDeclBits;
/// Width in bits required to store all the non-negative
@@ -1460,78 +1580,102 @@ class DeclContext {
/// True if this tag declaration is a scoped enumeration. Only
/// possible in C++11 mode.
+ LLVM_PREFERRED_TYPE(bool)
uint64_t IsScoped : 1;
/// If this tag declaration is a scoped enum,
/// then this is true if the scoped enum was declared using the class
/// tag, false if it was declared with the struct tag. No meaning is
/// associated if this tag declaration is not a scoped enum.
+ LLVM_PREFERRED_TYPE(bool)
uint64_t IsScopedUsingClassTag : 1;
/// True if this is an enumeration with fixed underlying type. Only
/// possible in C++11, Microsoft extensions, or Objective C mode.
+ LLVM_PREFERRED_TYPE(bool)
uint64_t IsFixed : 1;
/// True if a valid hash is stored in ODRHash.
+ LLVM_PREFERRED_TYPE(bool)
uint64_t HasODRHash : 1;
};
- /// Number of non-inherited bits in EnumDeclBitfields.
- enum { NumEnumDeclBits = 20 };
+ /// Number of inherited and non-inherited bits in EnumDeclBitfields.
+ enum { NumEnumDeclBits = NumTagDeclBits + 20 };
/// Stores the bits used by RecordDecl.
/// If modified NumRecordDeclBits and the accessor
/// methods in RecordDecl should be updated appropriately.
class RecordDeclBitfields {
friend class RecordDecl;
- /// For the bits in DeclContextBitfields.
- uint64_t : NumDeclContextBits;
/// For the bits in TagDeclBitfields.
+ LLVM_PREFERRED_TYPE(TagDeclBitfields)
uint64_t : NumTagDeclBits;
/// This is true if this struct ends with a flexible
/// array member (e.g. int X[]) or if this union contains a struct that does.
/// If so, this cannot be contained in arrays or other structs as a member.
+ LLVM_PREFERRED_TYPE(bool)
uint64_t HasFlexibleArrayMember : 1;
/// Whether this is the type of an anonymous struct or union.
+ LLVM_PREFERRED_TYPE(bool)
uint64_t AnonymousStructOrUnion : 1;
/// This is true if this struct has at least one member
/// containing an Objective-C object pointer type.
+ LLVM_PREFERRED_TYPE(bool)
uint64_t HasObjectMember : 1;
/// This is true if struct has at least one member of
/// 'volatile' type.
+ LLVM_PREFERRED_TYPE(bool)
uint64_t HasVolatileMember : 1;
/// Whether the field declarations of this record have been loaded
/// from external storage. To avoid unnecessary deserialization of
/// methods/nested types we allow deserialization of just the fields
/// when needed.
+ LLVM_PREFERRED_TYPE(bool)
mutable uint64_t LoadedFieldsFromExternalStorage : 1;
/// Basic properties of non-trivial C structs.
+ LLVM_PREFERRED_TYPE(bool)
uint64_t NonTrivialToPrimitiveDefaultInitialize : 1;
+ LLVM_PREFERRED_TYPE(bool)
uint64_t NonTrivialToPrimitiveCopy : 1;
+ LLVM_PREFERRED_TYPE(bool)
uint64_t NonTrivialToPrimitiveDestroy : 1;
/// The following bits indicate whether this is or contains a C union that
/// is non-trivial to default-initialize, destruct, or copy. These bits
/// imply the associated basic non-triviality predicates declared above.
+ LLVM_PREFERRED_TYPE(bool)
uint64_t HasNonTrivialToPrimitiveDefaultInitializeCUnion : 1;
+ LLVM_PREFERRED_TYPE(bool)
uint64_t HasNonTrivialToPrimitiveDestructCUnion : 1;
+ LLVM_PREFERRED_TYPE(bool)
uint64_t HasNonTrivialToPrimitiveCopyCUnion : 1;
/// Indicates whether this struct is destroyed in the callee.
+ LLVM_PREFERRED_TYPE(bool)
uint64_t ParamDestroyedInCallee : 1;
/// Represents the way this type is passed to a function.
+ LLVM_PREFERRED_TYPE(RecordArgPassingKind)
uint64_t ArgPassingRestrictions : 2;
+
+ /// Indicates whether this struct has had its field layout randomized.
+ LLVM_PREFERRED_TYPE(bool)
+ uint64_t IsRandomized : 1;
+
+ /// True if a valid hash is stored in ODRHash. This should shave off some
+ /// extra storage and prevent CXXRecordDecl to store unused bits.
+ uint64_t ODRHash : 26;
};
- /// Number of non-inherited bits in RecordDeclBitfields.
- enum { NumRecordDeclBits = 14 };
+ /// Number of inherited and non-inherited bits in RecordDeclBitfields.
+ enum { NumRecordDeclBits = NumTagDeclBits + 41 };
/// Stores the bits used by OMPDeclareReductionDecl.
/// If modified NumOMPDeclareReductionDeclBits and the accessor
@@ -1539,113 +1683,156 @@ class DeclContext {
class OMPDeclareReductionDeclBitfields {
friend class OMPDeclareReductionDecl;
/// For the bits in DeclContextBitfields
+ LLVM_PREFERRED_TYPE(DeclContextBitfields)
uint64_t : NumDeclContextBits;
/// Kind of initializer,
- /// function call or omp_priv<init_expr> initializtion.
+ /// function call or omp_priv<init_expr> initialization.
+ LLVM_PREFERRED_TYPE(OMPDeclareReductionInitKind)
uint64_t InitializerKind : 2;
};
- /// Number of non-inherited bits in OMPDeclareReductionDeclBitfields.
- enum { NumOMPDeclareReductionDeclBits = 2 };
+ /// Number of inherited and non-inherited bits in
+ /// OMPDeclareReductionDeclBitfields.
+ enum { NumOMPDeclareReductionDeclBits = NumDeclContextBits + 2 };
/// Stores the bits used by FunctionDecl.
/// If modified NumFunctionDeclBits and the accessor
/// methods in FunctionDecl and CXXDeductionGuideDecl
- /// (for IsCopyDeductionCandidate) should be updated appropriately.
+ /// (for DeductionCandidateKind) should be updated appropriately.
class FunctionDeclBitfields {
friend class FunctionDecl;
- /// For IsCopyDeductionCandidate
+ /// For DeductionCandidateKind
friend class CXXDeductionGuideDecl;
/// For the bits in DeclContextBitfields.
+ LLVM_PREFERRED_TYPE(DeclContextBitfields)
uint64_t : NumDeclContextBits;
+ LLVM_PREFERRED_TYPE(StorageClass)
uint64_t SClass : 3;
+ LLVM_PREFERRED_TYPE(bool)
uint64_t IsInline : 1;
+ LLVM_PREFERRED_TYPE(bool)
uint64_t IsInlineSpecified : 1;
+ LLVM_PREFERRED_TYPE(bool)
uint64_t IsVirtualAsWritten : 1;
- uint64_t IsPure : 1;
+ LLVM_PREFERRED_TYPE(bool)
+ uint64_t IsPureVirtual : 1;
+ LLVM_PREFERRED_TYPE(bool)
uint64_t HasInheritedPrototype : 1;
+ LLVM_PREFERRED_TYPE(bool)
uint64_t HasWrittenPrototype : 1;
+ LLVM_PREFERRED_TYPE(bool)
uint64_t IsDeleted : 1;
/// Used by CXXMethodDecl
+ LLVM_PREFERRED_TYPE(bool)
uint64_t IsTrivial : 1;
/// This flag indicates whether this function is trivial for the purpose of
/// calls. This is meaningful only when this function is a copy/move
/// constructor or a destructor.
+ LLVM_PREFERRED_TYPE(bool)
uint64_t IsTrivialForCall : 1;
+ LLVM_PREFERRED_TYPE(bool)
uint64_t IsDefaulted : 1;
+ LLVM_PREFERRED_TYPE(bool)
uint64_t IsExplicitlyDefaulted : 1;
+ LLVM_PREFERRED_TYPE(bool)
uint64_t HasDefaultedFunctionInfo : 1;
+
+ /// For member functions of complete types, whether this is an ineligible
+ /// special member function or an unselected destructor. See
+ /// [class.mem.special].
+ LLVM_PREFERRED_TYPE(bool)
+ uint64_t IsIneligibleOrNotSelected : 1;
+
+ LLVM_PREFERRED_TYPE(bool)
uint64_t HasImplicitReturnZero : 1;
+ LLVM_PREFERRED_TYPE(bool)
uint64_t IsLateTemplateParsed : 1;
/// Kind of contexpr specifier as defined by ConstexprSpecKind.
+ LLVM_PREFERRED_TYPE(ConstexprSpecKind)
uint64_t ConstexprKind : 2;
+ LLVM_PREFERRED_TYPE(bool)
+ uint64_t BodyContainsImmediateEscalatingExpression : 1;
+
+ LLVM_PREFERRED_TYPE(bool)
uint64_t InstantiationIsPending : 1;
/// Indicates if the function uses __try.
+ LLVM_PREFERRED_TYPE(bool)
uint64_t UsesSEHTry : 1;
/// Indicates if the function was a definition
/// but its body was skipped.
+ LLVM_PREFERRED_TYPE(bool)
uint64_t HasSkippedBody : 1;
/// Indicates if the function declaration will
/// have a body, once we're done parsing it.
+ LLVM_PREFERRED_TYPE(bool)
uint64_t WillHaveBody : 1;
/// Indicates that this function is a multiversioned
/// function using attribute 'target'.
+ LLVM_PREFERRED_TYPE(bool)
uint64_t IsMultiVersion : 1;
- /// [C++17] Only used by CXXDeductionGuideDecl. Indicates that
- /// the Deduction Guide is the implicitly generated 'copy
- /// deduction candidate' (is used during overload resolution).
- uint64_t IsCopyDeductionCandidate : 1;
+ /// Only used by CXXDeductionGuideDecl. Indicates the kind
+ /// of the Deduction Guide that is implicitly generated
+ /// (used during overload resolution).
+ LLVM_PREFERRED_TYPE(DeductionCandidate)
+ uint64_t DeductionCandidateKind : 2;
/// Store the ODRHash after first calculation.
+ LLVM_PREFERRED_TYPE(bool)
uint64_t HasODRHash : 1;
/// Indicates if the function uses Floating Point Constrained Intrinsics
+ LLVM_PREFERRED_TYPE(bool)
uint64_t UsesFPIntrin : 1;
+
+ // Indicates this function is a constrained friend, where the constraint
+ // refers to an enclosing template for hte purposes of [temp.friend]p9.
+ LLVM_PREFERRED_TYPE(bool)
+ uint64_t FriendConstraintRefersToEnclosingTemplate : 1;
};
- /// Number of non-inherited bits in FunctionDeclBitfields.
- enum { NumFunctionDeclBits = 27 };
+ /// Number of inherited and non-inherited bits in FunctionDeclBitfields.
+ enum { NumFunctionDeclBits = NumDeclContextBits + 31 };
/// Stores the bits used by CXXConstructorDecl. If modified
/// NumCXXConstructorDeclBits and the accessor
/// methods in CXXConstructorDecl should be updated appropriately.
class CXXConstructorDeclBitfields {
friend class CXXConstructorDecl;
- /// For the bits in DeclContextBitfields.
- uint64_t : NumDeclContextBits;
/// For the bits in FunctionDeclBitfields.
+ LLVM_PREFERRED_TYPE(FunctionDeclBitfields)
uint64_t : NumFunctionDeclBits;
- /// 24 bits to fit in the remaining available space.
+ /// 20 bits to fit in the remaining available space.
/// Note that this makes CXXConstructorDeclBitfields take
/// exactly 64 bits and thus the width of NumCtorInitializers
/// will need to be shrunk if some bit is added to NumDeclContextBitfields,
/// NumFunctionDeclBitfields or CXXConstructorDeclBitfields.
- uint64_t NumCtorInitializers : 21;
+ uint64_t NumCtorInitializers : 17;
+ LLVM_PREFERRED_TYPE(bool)
uint64_t IsInheritingConstructor : 1;
/// Whether this constructor has a trail-allocated explicit specifier.
+ LLVM_PREFERRED_TYPE(bool)
uint64_t HasTrailingExplicitSpecifier : 1;
/// If this constructor does't have a trail-allocated explicit specifier.
/// Whether this constructor is explicit specified.
+ LLVM_PREFERRED_TYPE(bool)
uint64_t IsSimpleExplicit : 1;
};
- /// Number of non-inherited bits in CXXConstructorDeclBitfields.
- enum {
- NumCXXConstructorDeclBits = 64 - NumDeclContextBits - NumFunctionDeclBits
- };
+ /// Number of inherited and non-inherited bits in CXXConstructorDeclBitfields.
+ enum { NumCXXConstructorDeclBits = NumFunctionDeclBits + 20 };
/// Stores the bits used by ObjCMethodDecl.
/// If modified NumObjCMethodDeclBits and the accessor
@@ -1654,43 +1841,56 @@ class DeclContext {
friend class ObjCMethodDecl;
/// For the bits in DeclContextBitfields.
+ LLVM_PREFERRED_TYPE(DeclContextBitfields)
uint64_t : NumDeclContextBits;
/// The conventional meaning of this method; an ObjCMethodFamily.
/// This is not serialized; instead, it is computed on demand and
/// cached.
+ LLVM_PREFERRED_TYPE(ObjCMethodFamily)
mutable uint64_t Family : ObjCMethodFamilyBitWidth;
/// instance (true) or class (false) method.
+ LLVM_PREFERRED_TYPE(bool)
uint64_t IsInstance : 1;
+ LLVM_PREFERRED_TYPE(bool)
uint64_t IsVariadic : 1;
/// True if this method is the getter or setter for an explicit property.
+ LLVM_PREFERRED_TYPE(bool)
uint64_t IsPropertyAccessor : 1;
/// True if this method is a synthesized property accessor stub.
+ LLVM_PREFERRED_TYPE(bool)
uint64_t IsSynthesizedAccessorStub : 1;
/// Method has a definition.
+ LLVM_PREFERRED_TYPE(bool)
uint64_t IsDefined : 1;
/// Method redeclaration in the same interface.
+ LLVM_PREFERRED_TYPE(bool)
uint64_t IsRedeclaration : 1;
/// Is redeclared in the same interface.
+ LLVM_PREFERRED_TYPE(bool)
mutable uint64_t HasRedeclaration : 1;
/// \@required/\@optional
+ LLVM_PREFERRED_TYPE(ObjCImplementationControl)
uint64_t DeclImplementation : 2;
/// in, inout, etc.
+ LLVM_PREFERRED_TYPE(Decl::ObjCDeclQualifier)
uint64_t objcDeclQualifier : 7;
/// Indicates whether this method has a related result type.
+ LLVM_PREFERRED_TYPE(bool)
uint64_t RelatedResultType : 1;
/// Whether the locations of the selector identifiers are in a
/// "standard" position, a enum SelectorLocationsKind.
+ LLVM_PREFERRED_TYPE(SelectorLocationsKind)
uint64_t SelLocsKind : 2;
/// Whether this method overrides any other in the class hierarchy.
@@ -1700,14 +1900,16 @@ class DeclContext {
/// the same selector and is of the same kind (class or instance).
/// A method in an implementation is not considered as overriding the same
/// method in the interface or its categories.
+ LLVM_PREFERRED_TYPE(bool)
uint64_t IsOverriding : 1;
/// Indicates if the method was a definition but its body was skipped.
+ LLVM_PREFERRED_TYPE(bool)
uint64_t HasSkippedBody : 1;
};
- /// Number of non-inherited bits in ObjCMethodDeclBitfields.
- enum { NumObjCMethodDeclBits = 24 };
+ /// Number of inherited and non-inherited bits in ObjCMethodDeclBitfields.
+ enum { NumObjCMethodDeclBits = NumDeclContextBits + 24 };
/// Stores the bits used by ObjCContainerDecl.
/// If modified NumObjCContainerDeclBits and the accessor
@@ -1715,6 +1917,7 @@ class DeclContext {
class ObjCContainerDeclBitfields {
friend class ObjCContainerDecl;
/// For the bits in DeclContextBitfields
+ LLVM_PREFERRED_TYPE(DeclContextBitfields)
uint32_t : NumDeclContextBits;
// Not a bitfield but this saves space.
@@ -1722,10 +1925,10 @@ class DeclContext {
SourceLocation AtStart;
};
- /// Number of non-inherited bits in ObjCContainerDeclBitfields.
+ /// Number of inherited and non-inherited bits in ObjCContainerDeclBitfields.
/// Note that here we rely on the fact that SourceLocation is 32 bits
/// wide. We check this with the static_assert in the ctor of DeclContext.
- enum { NumObjCContainerDeclBits = 64 - NumDeclContextBits };
+ enum { NumObjCContainerDeclBits = 64 };
/// Stores the bits used by LinkageSpecDecl.
/// If modified NumLinkageSpecDeclBits and the accessor
@@ -1733,21 +1936,23 @@ class DeclContext {
class LinkageSpecDeclBitfields {
friend class LinkageSpecDecl;
/// For the bits in DeclContextBitfields.
+ LLVM_PREFERRED_TYPE(DeclContextBitfields)
uint64_t : NumDeclContextBits;
- /// The language for this linkage specification with values
- /// in the enum LinkageSpecDecl::LanguageIDs.
+ /// The language for this linkage specification.
+ LLVM_PREFERRED_TYPE(LinkageSpecLanguageIDs)
uint64_t Language : 3;
/// True if this linkage spec has braces.
/// This is needed so that hasBraces() returns the correct result while the
/// linkage spec body is being parsed. Once RBraceLoc has been set this is
/// not used, so it doesn't need to be serialized.
+ LLVM_PREFERRED_TYPE(bool)
uint64_t HasBraces : 1;
};
- /// Number of non-inherited bits in LinkageSpecDeclBitfields.
- enum { NumLinkageSpecDeclBits = 4 };
+ /// Number of inherited and non-inherited bits in LinkageSpecDeclBitfields.
+ enum { NumLinkageSpecDeclBits = NumDeclContextBits + 4 };
/// Stores the bits used by BlockDecl.
/// If modified NumBlockDeclBits and the accessor
@@ -1755,25 +1960,32 @@ class DeclContext {
class BlockDeclBitfields {
friend class BlockDecl;
/// For the bits in DeclContextBitfields.
+ LLVM_PREFERRED_TYPE(DeclContextBitfields)
uint64_t : NumDeclContextBits;
+ LLVM_PREFERRED_TYPE(bool)
uint64_t IsVariadic : 1;
+ LLVM_PREFERRED_TYPE(bool)
uint64_t CapturesCXXThis : 1;
+ LLVM_PREFERRED_TYPE(bool)
uint64_t BlockMissingReturnType : 1;
+ LLVM_PREFERRED_TYPE(bool)
uint64_t IsConversionFromLambda : 1;
/// A bit that indicates this block is passed directly to a function as a
/// non-escaping parameter.
+ LLVM_PREFERRED_TYPE(bool)
uint64_t DoesNotEscape : 1;
/// A bit that indicates whether it's possible to avoid coying this block to
/// the heap when it initializes or is assigned to a local variable with
/// automatic storage.
+ LLVM_PREFERRED_TYPE(bool)
uint64_t CanAvoidCopyToHeap : 1;
};
- /// Number of non-inherited bits in BlockDeclBitfields.
- enum { NumBlockDeclBits = 5 };
+ /// Number of inherited and non-inherited bits in BlockDeclBitfields.
+ enum { NumBlockDeclBits = NumDeclContextBits + 5 };
/// Pointer to the data structure used to lookup declarations
/// within this context (or a DependentStoredDeclsMap if this is a
@@ -1850,6 +2062,10 @@ protected:
public:
~DeclContext();
+ // For use when debugging; hasValidDeclKind() will always return true for
+ // a correctly constructed object within its lifetime.
+ bool hasValidDeclKind() const;
+
Decl::Kind getDeclKind() const {
return static_cast<Decl::Kind>(DeclContextBits.DeclKind);
}
@@ -1965,7 +2181,7 @@ public:
/// Here, E is a transparent context, so its enumerator (Val1) will
/// appear (semantically) that it is in the same context of E.
/// Examples of transparent contexts include: enumerations (except for
- /// C++0x scoped enums), and C++ linkage specifications.
+ /// C++0x scoped enums), C++ linkage specifications and export declaration.
bool isTransparentContext() const;
/// Determines whether this context or some of its ancestors is a
@@ -1997,6 +2213,12 @@ public:
return const_cast<DeclContext*>(this)->getNonClosureAncestor();
}
+ // Retrieve the nearest context that is not a transparent context.
+ DeclContext *getNonTransparentContext();
+ const DeclContext *getNonTransparentContext() const {
+ return const_cast<DeclContext *>(this)->getNonTransparentContext();
+ }
+
/// getPrimaryContext - There may be many different
/// declarations of the same entity (including forward declarations
/// of classes, multiple definitions of namespaces, etc.), each with
@@ -2452,10 +2674,8 @@ public:
D == LastDecl);
}
- bool setUseQualifiedLookup(bool use = true) const {
- bool old_value = DeclContextBits.UseQualifiedLookup;
+ void setUseQualifiedLookup(bool use = true) const {
DeclContextBits.UseQualifiedLookup = use;
- return old_value;
}
bool shouldUseQualifiedLookup() const {
@@ -2465,6 +2685,8 @@ public:
static bool classof(const Decl *D);
static bool classof(const DeclContext *D) { return true; }
+ void dumpAsDecl() const;
+ void dumpAsDecl(const ASTContext *Ctx) const;
void dumpDeclContext() const;
void dumpLookups() const;
void dumpLookups(llvm::raw_ostream &OS, bool DumpDecls = false,
@@ -2514,14 +2736,6 @@ private:
void reconcileExternalVisibleStorage() const;
bool LoadLexicalDeclsFromExternalStorage() const;
- /// Makes a declaration visible within this context, but
- /// suppresses searches for external declarations with the same
- /// name.
- ///
- /// Analogous to makeDeclVisibleInContext, but for the exclusive
- /// use of addDeclInternal().
- void makeDeclVisibleInContextInternal(NamedDecl *D);
-
StoredDeclsMap *CreateStoredDeclsMap(ASTContext &C) const;
void loadLazyLocalLexicalLookups();
diff --git a/contrib/llvm-project/clang/include/clang/AST/DeclCXX.h b/contrib/llvm-project/clang/include/clang/AST/DeclCXX.h
index 0d5ad40fc19e..9cebaff63bb0 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;
@@ -155,22 +154,26 @@ class CXXBaseSpecifier {
SourceLocation EllipsisLoc;
/// Whether this is a virtual base class or not.
+ LLVM_PREFERRED_TYPE(bool)
unsigned Virtual : 1;
/// Whether this is the base of a class (true) or of a struct (false).
///
/// This determines the mapping from the access specifier as written in the
/// source code to the access specifier used for semantic analysis.
+ LLVM_PREFERRED_TYPE(bool)
unsigned BaseOfClass : 1;
/// Access specifier as written in the source code (may be AS_none).
///
/// The actual type of data stored here is an AccessSpecifier, but we use
- /// "unsigned" here to work around a VC++ bug.
+ /// "unsigned" here to work around Microsoft ABI.
+ LLVM_PREFERRED_TYPE(AccessSpecifier)
unsigned Access : 2;
/// Whether the class contains a using declaration
/// to inherit the named class's constructors.
+ LLVM_PREFERRED_TYPE(bool)
unsigned InheritConstructors : 1;
/// The type of the base class.
@@ -261,8 +264,9 @@ class CXXRecordDecl : public RecordDecl {
friend class ASTWriter;
friend class DeclContext;
friend class LambdaExpr;
+ friend class ODRDiagsEmitter;
- friend void FunctionDecl::setPure(bool);
+ friend void FunctionDecl::setIsPureVirtual(bool);
friend void TagDecl::startDefinition();
/// Values used in DefinitionData fields to represent special members.
@@ -276,21 +280,33 @@ class CXXRecordDecl : public RecordDecl {
SMF_All = 0x3f
};
+public:
+ enum LambdaDependencyKind {
+ LDK_Unknown = 0,
+ LDK_AlwaysDependent,
+ LDK_NeverDependent,
+ };
+
+private:
struct DefinitionData {
#define FIELD(Name, Width, Merge) \
unsigned Name : Width;
#include "CXXRecordDeclDefinitionBits.def"
/// Whether this class describes a C++ lambda.
+ LLVM_PREFERRED_TYPE(bool)
unsigned IsLambda : 1;
/// Whether we are currently parsing base specifiers.
+ LLVM_PREFERRED_TYPE(bool)
unsigned IsParsingBaseSpecifiers : 1;
/// True when visible conversion functions are already computed
/// and are available.
+ LLVM_PREFERRED_TYPE(bool)
unsigned ComputedVisibleConversions : 1;
+ LLVM_PREFERRED_TYPE(bool)
unsigned HasODRHash : 1;
/// A hash of parts of the class to help in ODR checking.
@@ -349,11 +365,11 @@ class CXXRecordDecl : public RecordDecl {
}
ArrayRef<CXXBaseSpecifier> bases() const {
- return llvm::makeArrayRef(getBases(), NumBases);
+ return llvm::ArrayRef(getBases(), NumBases);
}
ArrayRef<CXXBaseSpecifier> vbases() const {
- return llvm::makeArrayRef(getVBases(), NumVBases);
+ return llvm::ArrayRef(getVBases(), NumVBases);
}
private:
@@ -375,46 +391,56 @@ class CXXRecordDecl : public RecordDecl {
/// lambda will have been created with the enclosing context as its
/// declaration context, rather than function. This is an unfortunate
/// artifact of having to parse the default arguments before.
- unsigned Dependent : 1;
+ LLVM_PREFERRED_TYPE(LambdaDependencyKind)
+ unsigned DependencyKind : 2;
/// Whether this lambda is a generic lambda.
+ LLVM_PREFERRED_TYPE(bool)
unsigned IsGenericLambda : 1;
/// The Default Capture.
+ LLVM_PREFERRED_TYPE(LambdaCaptureDefault)
unsigned CaptureDefault : 2;
/// The number of captures in this lambda is limited 2^NumCaptures.
unsigned NumCaptures : 15;
/// The number of explicit captures in this lambda.
- unsigned NumExplicitCaptures : 13;
+ unsigned NumExplicitCaptures : 12;
/// Has known `internal` linkage.
+ LLVM_PREFERRED_TYPE(bool)
unsigned HasKnownInternalLinkage : 1;
/// The number used to indicate this lambda expression for name
/// mangling in the Itanium C++ ABI.
unsigned ManglingNumber : 31;
+ /// The index of this lambda within its context declaration. This is not in
+ /// general the same as the mangling number.
+ unsigned IndexInContext;
+
/// The declaration that provides context for this lambda, if the
/// actual DeclContext does not suffice. This is used for lambdas that
/// occur within default arguments of function parameters within the class
/// or within a data member initializer.
LazyDeclPtr ContextDecl;
- /// The list of captures, both explicit and implicit, for this
- /// lambda.
- Capture *Captures = nullptr;
+ /// The lists of captures, both explicit and implicit, for this
+ /// lambda. One list is provided for each merged copy of the lambda.
+ /// The first list corresponds to the canonical definition.
+ /// The destructor is registered by AddCaptureList when necessary.
+ llvm::TinyPtrVector<Capture*> Captures;
/// The type of the call method.
TypeSourceInfo *MethodTyInfo;
- LambdaDefinitionData(CXXRecordDecl *D, TypeSourceInfo *Info, bool Dependent,
+ LambdaDefinitionData(CXXRecordDecl *D, TypeSourceInfo *Info, unsigned DK,
bool IsGeneric, LambdaCaptureDefault CaptureDefault)
- : DefinitionData(D), Dependent(Dependent), IsGenericLambda(IsGeneric),
+ : DefinitionData(D), DependencyKind(DK), IsGenericLambda(IsGeneric),
CaptureDefault(CaptureDefault), NumCaptures(0),
NumExplicitCaptures(0), HasKnownInternalLinkage(0), ManglingNumber(0),
- MethodTyInfo(Info) {
+ IndexInContext(0), MethodTyInfo(Info) {
IsLambda = true;
// C++1z [expr.prim.lambda]p4:
@@ -422,6 +448,9 @@ class CXXRecordDecl : public RecordDecl {
Aggregate = false;
PlainOldData = false;
}
+
+ // Add a list of captures.
+ void AddCaptureList(ASTContext &Ctx, Capture *CaptureList);
};
struct DefinitionData *dataPtr() const {
@@ -548,7 +577,7 @@ public:
bool DelayTypeCreation = false);
static CXXRecordDecl *CreateLambda(const ASTContext &C, DeclContext *DC,
TypeSourceInfo *Info, SourceLocation Loc,
- bool DependentLambda, bool IsGeneric,
+ unsigned DependencyKind, bool IsGeneric,
LambdaCaptureDefault CaptureDefault);
static CXXRecordDecl *CreateDeserialized(const ASTContext &C, unsigned ID);
@@ -1035,6 +1064,12 @@ public:
return static_cast<LambdaCaptureDefault>(getLambdaData().CaptureDefault);
}
+ bool isCapturelessLambda() const {
+ if (!isLambda())
+ return false;
+ return getLambdaCaptureDefault() == LCD_None && capture_size() == 0;
+ }
+
/// Set the captures for this lambda closure type.
void setCaptures(ASTContext &Context, ArrayRef<LambdaCapture> Captures);
@@ -1050,8 +1085,14 @@ public:
///
/// \note No entries will be added for init-captures, as they do not capture
/// variables.
- void getCaptureFields(llvm::DenseMap<const VarDecl *, FieldDecl *> &Captures,
- FieldDecl *&ThisCapture) const;
+ ///
+ /// \note If multiple versions of the lambda are merged together, they may
+ /// have different variable declarations corresponding to the same capture.
+ /// In that case, all of those variable declarations will be added to the
+ /// Captures list, so it may have more than one variable listed per field.
+ void
+ getCaptureFields(llvm::DenseMap<const ValueDecl *, FieldDecl *> &Captures,
+ FieldDecl *&ThisCapture) const;
using capture_const_iterator = const LambdaCapture *;
using capture_const_range = llvm::iterator_range<capture_const_iterator>;
@@ -1061,7 +1102,9 @@ public:
}
capture_const_iterator captures_begin() const {
- return isLambda() ? getLambdaData().Captures : nullptr;
+ if (!isLambda()) return nullptr;
+ LambdaDefinitionData &LambdaData = getLambdaData();
+ return LambdaData.Captures.empty() ? nullptr : LambdaData.Captures.front();
}
capture_const_iterator captures_end() const {
@@ -1071,6 +1114,11 @@ public:
unsigned capture_size() const { return getLambdaData().NumCaptures; }
+ const LambdaCapture *getCapture(unsigned I) const {
+ assert(isLambda() && I < capture_size() && "invalid index for capture");
+ return captures_begin() + I;
+ }
+
using conversion_iterator = UnresolvedSetIterator;
conversion_iterator conversion_begin() const {
@@ -1139,6 +1187,13 @@ public:
///
/// \note This does NOT include a check for union-ness.
bool isEmpty() const { return data().Empty; }
+ /// Marks this record as empty. This is used by DWARFASTParserClang
+ /// when parsing records with empty fields having [[no_unique_address]]
+ /// attribute
+ void markEmpty() { data().Empty = true; }
+
+ void setInitMethod(bool Val) { data().HasInitMethod = Val; }
+ bool hasInitMethod() const { return data().HasInitMethod; }
bool hasPrivateFields() const {
return data().HasPrivateFields;
@@ -1160,7 +1215,7 @@ public:
/// Determine whether this class has a pure virtual function.
///
- /// The class is is abstract per (C++ [class.abstract]p2) if it declares
+ /// The class is abstract per (C++ [class.abstract]p2) if it declares
/// a pure virtual function or inherits a pure virtual function that is
/// not overridden.
bool isAbstract() const { return data().Abstract; }
@@ -1370,6 +1425,9 @@ public:
/// (C++11 [class]p6).
bool isTriviallyCopyable() const;
+ /// Determine whether this class is considered trivially copyable per
+ bool isTriviallyCopyConstructible() const;
+
/// Determine whether this class is considered trivial.
///
/// C++11 [class]p6:
@@ -1381,37 +1439,39 @@ public:
/// Determine whether this class is a literal type.
///
- /// C++11 [basic.types]p10:
+ /// C++20 [basic.types]p10:
/// A class type that has all the following properties:
- /// - it has a trivial destructor
- /// - every constructor call and full-expression in the
- /// brace-or-equal-intializers for non-static data members (if any) is
- /// a constant expression.
- /// - it is an aggregate type or has at least one constexpr constructor
- /// or constructor template that is not a copy or move constructor, and
- /// - all of its non-static data members and base classes are of literal
- /// types
- ///
- /// We resolve DR1361 by ignoring the second bullet. We resolve DR1452 by
- /// treating types with trivial default constructors as literal types.
- ///
- /// Only in C++17 and beyond, are lambdas literal types.
- bool isLiteral() const {
- const LangOptions &LangOpts = getLangOpts();
- return (LangOpts.CPlusPlus20 ? hasConstexprDestructor()
- : hasTrivialDestructor()) &&
- (!isLambda() || LangOpts.CPlusPlus17) &&
- !hasNonLiteralTypeFieldsOrBases() &&
- (isAggregate() || isLambda() ||
- hasConstexprNonCopyMoveConstructor() ||
- hasTrivialDefaultConstructor());
- }
+ /// - it has a constexpr destructor
+ /// - all of its non-static non-variant data members and base classes
+ /// are of non-volatile literal types, and it:
+ /// - is a closure type
+ /// - is an aggregate union type that has either no variant members
+ /// or at least one variant member of non-volatile literal type
+ /// - is a non-union aggregate type for which each of its anonymous
+ /// union members satisfies the above requirements for an aggregate
+ /// union type, or
+ /// - has at least one constexpr constructor or constructor template
+ /// that is not a copy or move constructor.
+ bool isLiteral() const;
/// Determine whether this is a structural type.
bool isStructural() const {
return isLiteral() && data().StructuralIfLiteral;
}
+ /// Notify the class that this destructor is now selected.
+ ///
+ /// Important properties of the class depend on destructor properties. Since
+ /// C++20, it is possible to have multiple destructor declarations in a class
+ /// out of which one will be selected at the end.
+ /// This is called separately from addedMember because it has to be deferred
+ /// to the completion of the class.
+ void addedSelectedDestructor(CXXDestructorDecl *DD);
+
+ /// Notify the class that an eligible SMF has been added.
+ /// This updates triviality and destructor based properties of the class accordingly.
+ void addedEligibleSpecialMemberFunction(const CXXMethodDecl *MD, unsigned SMKind);
+
/// If this record is an instantiation of a member class,
/// retrieves the member class from which it was instantiated.
///
@@ -1726,18 +1786,31 @@ public:
/// the declaration context suffices.
Decl *getLambdaContextDecl() const;
- /// Set the mangling number and context declaration for a lambda
- /// class.
- void setLambdaMangling(unsigned ManglingNumber, Decl *ContextDecl,
- bool HasKnownInternalLinkage = false) {
+ /// Retrieve the index of this lambda within the context declaration returned
+ /// by getLambdaContextDecl().
+ unsigned getLambdaIndexInContext() const {
assert(isLambda() && "Not a lambda closure type!");
- getLambdaData().ManglingNumber = ManglingNumber;
- getLambdaData().ContextDecl = ContextDecl;
- getLambdaData().HasKnownInternalLinkage = HasKnownInternalLinkage;
+ return getLambdaData().IndexInContext;
}
- /// Set the device side mangling number.
- void setDeviceLambdaManglingNumber(unsigned Num) const;
+ /// Information about how a lambda is numbered within its context.
+ struct LambdaNumbering {
+ Decl *ContextDecl = nullptr;
+ unsigned IndexInContext = 0;
+ unsigned ManglingNumber = 0;
+ unsigned DeviceManglingNumber = 0;
+ bool HasKnownInternalLinkage = false;
+ };
+
+ /// Set the mangling numbers and context declaration for a lambda class.
+ void setLambdaNumbering(LambdaNumbering Numbering);
+
+ // Get the mangling numbers and context declaration for a lambda class.
+ LambdaNumbering getLambdaNumbering() const {
+ return {getLambdaContextDecl(), getLambdaIndexInContext(),
+ getLambdaManglingNumber(), getDeviceLambdaManglingNumber(),
+ hasKnownLambdaInternalLinkage()};
+ }
/// Retrieve the device side mangling number.
unsigned getDeviceLambdaManglingNumber() const;
@@ -1772,13 +1845,37 @@ public:
/// function declaration itself is dependent. This flag indicates when we
/// know that the lambda is dependent despite that.
bool isDependentLambda() const {
- return isLambda() && getLambdaData().Dependent;
+ return isLambda() && getLambdaData().DependencyKind == LDK_AlwaysDependent;
+ }
+
+ bool isNeverDependentLambda() const {
+ return isLambda() && getLambdaData().DependencyKind == LDK_NeverDependent;
+ }
+
+ unsigned getLambdaDependencyKind() const {
+ if (!isLambda())
+ return LDK_Unknown;
+ return getLambdaData().DependencyKind;
}
TypeSourceInfo *getLambdaTypeInfo() const {
return getLambdaData().MethodTyInfo;
}
+ void setLambdaTypeInfo(TypeSourceInfo *TS) {
+ assert(DefinitionData && DefinitionData->IsLambda &&
+ "setting lambda property of non-lambda class");
+ auto &DL = static_cast<LambdaDefinitionData &>(*DefinitionData);
+ DL.MethodTyInfo = TS;
+ }
+
+ void setLambdaIsGeneric(bool IsGeneric) {
+ assert(DefinitionData && DefinitionData->IsLambda &&
+ "setting lambda property of non-lambda class");
+ auto &DL = static_cast<LambdaDefinitionData &>(*DefinitionData);
+ DL.IsGenericLambda = IsGeneric;
+ }
+
// Determine whether this type is an Interface Like type for
// __interface inheritance purposes.
bool isInterfaceLike() const;
@@ -1855,13 +1952,13 @@ private:
ExplicitSpecifier ES,
const DeclarationNameInfo &NameInfo, QualType T,
TypeSourceInfo *TInfo, SourceLocation EndLocation,
- CXXConstructorDecl *Ctor)
+ CXXConstructorDecl *Ctor, DeductionCandidate Kind)
: FunctionDecl(CXXDeductionGuide, C, DC, StartLoc, NameInfo, T, TInfo,
- SC_None, false, ConstexprSpecKind::Unspecified),
+ SC_None, false, false, ConstexprSpecKind::Unspecified),
Ctor(Ctor), ExplicitSpec(ES) {
if (EndLocation.isValid())
setRangeEnd(EndLocation);
- setIsCopyDeductionCandidate(false);
+ setDeductionCandidateKind(Kind);
}
CXXConstructorDecl *Ctor;
@@ -1876,14 +1973,15 @@ public:
Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
ExplicitSpecifier ES, const DeclarationNameInfo &NameInfo, QualType T,
TypeSourceInfo *TInfo, SourceLocation EndLocation,
- CXXConstructorDecl *Ctor = nullptr);
+ CXXConstructorDecl *Ctor = nullptr,
+ DeductionCandidate Kind = DeductionCandidate::Normal);
static CXXDeductionGuideDecl *CreateDeserialized(ASTContext &C, unsigned ID);
ExplicitSpecifier getExplicitSpecifier() { return ExplicitSpec; }
const ExplicitSpecifier getExplicitSpecifier() const { return ExplicitSpec; }
- /// Return true if the declartion is already resolved to be explicit.
+ /// Return true if the declaration is already resolved to be explicit.
bool isExplicit() const { return ExplicitSpec.isExplicit(); }
/// Get the template for which this guide performs deduction.
@@ -1893,16 +1991,15 @@ public:
/// Get the constructor from which this deduction guide was generated, if
/// this is an implicit deduction guide.
- CXXConstructorDecl *getCorrespondingConstructor() const {
- return Ctor;
- }
+ CXXConstructorDecl *getCorrespondingConstructor() const { return Ctor; }
- void setIsCopyDeductionCandidate(bool isCDC = true) {
- FunctionDeclBits.IsCopyDeductionCandidate = isCDC;
+ void setDeductionCandidateKind(DeductionCandidate K) {
+ FunctionDeclBits.DeductionCandidateKind = static_cast<unsigned char>(K);
}
- bool isCopyDeductionCandidate() const {
- return FunctionDeclBits.IsCopyDeductionCandidate;
+ DeductionCandidate getDeductionCandidateKind() const {
+ return static_cast<DeductionCandidate>(
+ FunctionDeclBits.DeductionCandidateKind);
}
// Implement isa/cast/dyncast/etc.
@@ -1939,6 +2036,14 @@ public:
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classofKind(Kind K) { return K == RequiresExprBody; }
+
+ static DeclContext *castToDeclContext(const RequiresExprBodyDecl *D) {
+ return static_cast<DeclContext *>(const_cast<RequiresExprBodyDecl *>(D));
+ }
+
+ static RequiresExprBodyDecl *castFromDeclContext(const DeclContext *DC) {
+ return static_cast<RequiresExprBodyDecl *>(const_cast<DeclContext *>(DC));
+ }
};
/// Represents a static or instance method of a struct/union/class.
@@ -1952,29 +2057,39 @@ protected:
CXXMethodDecl(Kind DK, ASTContext &C, CXXRecordDecl *RD,
SourceLocation StartLoc, const DeclarationNameInfo &NameInfo,
QualType T, TypeSourceInfo *TInfo, StorageClass SC,
- bool isInline, ConstexprSpecKind ConstexprKind,
- SourceLocation EndLocation,
+ bool UsesFPIntrin, bool isInline,
+ ConstexprSpecKind ConstexprKind, SourceLocation EndLocation,
Expr *TrailingRequiresClause = nullptr)
- : FunctionDecl(DK, C, RD, StartLoc, NameInfo, T, TInfo, SC, isInline,
- ConstexprKind, TrailingRequiresClause) {
+ : FunctionDecl(DK, C, RD, StartLoc, NameInfo, T, TInfo, SC, UsesFPIntrin,
+ isInline, ConstexprKind, TrailingRequiresClause) {
if (EndLocation.isValid())
setRangeEnd(EndLocation);
}
public:
- static CXXMethodDecl *Create(ASTContext &C, CXXRecordDecl *RD,
- SourceLocation StartLoc,
- const DeclarationNameInfo &NameInfo, QualType T,
- TypeSourceInfo *TInfo, StorageClass SC,
- bool isInline, ConstexprSpecKind ConstexprKind,
- SourceLocation EndLocation,
- Expr *TrailingRequiresClause = nullptr);
+ static CXXMethodDecl *
+ Create(ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc,
+ const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo,
+ StorageClass SC, bool UsesFPIntrin, bool isInline,
+ ConstexprSpecKind ConstexprKind, SourceLocation EndLocation,
+ Expr *TrailingRequiresClause = nullptr);
static CXXMethodDecl *CreateDeserialized(ASTContext &C, unsigned ID);
bool isStatic() const;
bool isInstance() const { return !isStatic(); }
+ /// [C++2b][dcl.fct]/p7
+ /// An explicit object member function is a non-static
+ /// member function with an explicit object parameter. e.g.,
+ /// void func(this SomeType);
+ bool isExplicitObjectMemberFunction() const;
+
+ /// [C++2b][dcl.fct]/p7
+ /// An implicit object member function is a non-static
+ /// member function without an explicit object parameter.
+ bool isImplicitObjectMemberFunction() const;
+
/// Returns true if the given operator is implicitly static in a record
/// context.
static bool isStaticOverloadedOperator(OverloadedOperatorKind OOK) {
@@ -1995,7 +2110,7 @@ public:
// Member function is virtual if it is marked explicitly so, or if it is
// declared in __interface -- then it is automatically pure virtual.
- if (CD->isVirtualAsWritten() || CD->isPure())
+ if (CD->isVirtualAsWritten() || CD->isPureVirtual())
return true;
return CD->size_overridden_methods() != 0;
@@ -2083,14 +2198,19 @@ public:
/// Return the type of the object pointed by \c this.
///
/// See getThisType() for usage restriction.
- QualType getThisObjectType() const;
+
+ QualType getFunctionObjectParameterReferenceType() const;
+ QualType getFunctionObjectParameterType() const {
+ return getFunctionObjectParameterReferenceType().getNonReferenceType();
+ }
+
+ unsigned getNumExplicitParams() const {
+ return getNumParams() - (isExplicitObjectMemberFunction() ? 1 : 0);
+ }
static QualType getThisType(const FunctionProtoType *FPT,
const CXXRecordDecl *Decl);
- static QualType getThisObjectType(const FunctionProtoType *FPT,
- const CXXRecordDecl *Decl);
-
Qualifiers getMethodQualifiers() const {
return getType()->castAs<FunctionProtoType>()->getMethodQuals();
}
@@ -2197,14 +2317,17 @@ class CXXCtorInitializer final {
/// If the initializee is a type, whether that type makes this
/// a delegating initialization.
+ LLVM_PREFERRED_TYPE(bool)
unsigned IsDelegating : 1;
/// If the initializer is a base initializer, this keeps track
/// of whether the base is virtual or not.
+ LLVM_PREFERRED_TYPE(bool)
unsigned IsVirtual : 1;
/// Whether or not the initializer is explicitly written
/// in the sources.
+ LLVM_PREFERRED_TYPE(bool)
unsigned IsWritten : 1;
/// If IsWritten is true, then this number keeps track of the textual order
@@ -2413,7 +2536,8 @@ class CXXConstructorDecl final
CXXConstructorDecl(ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc,
const DeclarationNameInfo &NameInfo, QualType T,
- TypeSourceInfo *TInfo, ExplicitSpecifier ES, bool isInline,
+ TypeSourceInfo *TInfo, ExplicitSpecifier ES,
+ bool UsesFPIntrin, bool isInline,
bool isImplicitlyDeclared, ConstexprSpecKind ConstexprKind,
InheritedConstructor Inherited,
Expr *TrailingRequiresClause);
@@ -2456,8 +2580,8 @@ public:
static CXXConstructorDecl *
Create(ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc,
const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo,
- ExplicitSpecifier ES, bool isInline, bool isImplicitlyDeclared,
- ConstexprSpecKind ConstexprKind,
+ ExplicitSpecifier ES, bool UsesFPIntrin, bool isInline,
+ bool isImplicitlyDeclared, ConstexprSpecKind ConstexprKind,
InheritedConstructor Inherited = InheritedConstructor(),
Expr *TrailingRequiresClause = nullptr);
@@ -2479,7 +2603,7 @@ public:
return getCanonicalDecl()->getExplicitSpecifierInternal();
}
- /// Return true if the declartion is already resolved to be explicit.
+ /// Return true if the declaration is already resolved to be explicit.
bool isExplicit() const { return getExplicitSpecifier().isExplicit(); }
/// Iterates through the member/base initializer list.
@@ -2676,25 +2800,24 @@ class CXXDestructorDecl : public CXXMethodDecl {
CXXDestructorDecl(ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc,
const DeclarationNameInfo &NameInfo, QualType T,
- TypeSourceInfo *TInfo, bool isInline,
+ TypeSourceInfo *TInfo, bool UsesFPIntrin, bool isInline,
bool isImplicitlyDeclared, ConstexprSpecKind ConstexprKind,
Expr *TrailingRequiresClause = nullptr)
: CXXMethodDecl(CXXDestructor, C, RD, StartLoc, NameInfo, T, TInfo,
- SC_None, isInline, ConstexprKind, SourceLocation(),
- TrailingRequiresClause) {
+ SC_None, UsesFPIntrin, isInline, ConstexprKind,
+ SourceLocation(), TrailingRequiresClause) {
setImplicit(isImplicitlyDeclared);
}
void anchor() override;
public:
- static CXXDestructorDecl *Create(ASTContext &C, CXXRecordDecl *RD,
- SourceLocation StartLoc,
- const DeclarationNameInfo &NameInfo,
- QualType T, TypeSourceInfo *TInfo,
- bool isInline, bool isImplicitlyDeclared,
- ConstexprSpecKind ConstexprKind,
- Expr *TrailingRequiresClause = nullptr);
+ static CXXDestructorDecl *
+ Create(ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc,
+ const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo,
+ bool UsesFPIntrin, bool isInline, bool isImplicitlyDeclared,
+ ConstexprSpecKind ConstexprKind,
+ Expr *TrailingRequiresClause = nullptr);
static CXXDestructorDecl *CreateDeserialized(ASTContext & C, unsigned ID);
void setOperatorDelete(FunctionDecl *OD, Expr *ThisArg);
@@ -2732,12 +2855,13 @@ public:
class CXXConversionDecl : public CXXMethodDecl {
CXXConversionDecl(ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc,
const DeclarationNameInfo &NameInfo, QualType T,
- TypeSourceInfo *TInfo, bool isInline, ExplicitSpecifier ES,
- ConstexprSpecKind ConstexprKind, SourceLocation EndLocation,
+ TypeSourceInfo *TInfo, bool UsesFPIntrin, bool isInline,
+ ExplicitSpecifier ES, ConstexprSpecKind ConstexprKind,
+ SourceLocation EndLocation,
Expr *TrailingRequiresClause = nullptr)
: CXXMethodDecl(CXXConversion, C, RD, StartLoc, NameInfo, T, TInfo,
- SC_None, isInline, ConstexprKind, EndLocation,
- TrailingRequiresClause),
+ SC_None, UsesFPIntrin, isInline, ConstexprKind,
+ EndLocation, TrailingRequiresClause),
ExplicitSpec(ES) {}
void anchor() override;
@@ -2750,8 +2874,9 @@ public:
static CXXConversionDecl *
Create(ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc,
const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo,
- bool isInline, ExplicitSpecifier ES, ConstexprSpecKind ConstexprKind,
- SourceLocation EndLocation, Expr *TrailingRequiresClause = nullptr);
+ bool UsesFPIntrin, bool isInline, ExplicitSpecifier ES,
+ ConstexprSpecKind ConstexprKind, SourceLocation EndLocation,
+ Expr *TrailingRequiresClause = nullptr);
static CXXConversionDecl *CreateDeserialized(ASTContext &C, unsigned ID);
ExplicitSpecifier getExplicitSpecifier() {
@@ -2762,7 +2887,7 @@ public:
return getCanonicalDecl()->ExplicitSpec;
}
- /// Return true if the declartion is already resolved to be explicit.
+ /// Return true if the declaration is already resolved to be explicit.
bool isExplicit() const { return getExplicitSpecifier().isExplicit(); }
void setExplicitSpecifier(ExplicitSpecifier ES) { ExplicitSpec = ES; }
@@ -2787,6 +2912,12 @@ public:
static bool classofKind(Kind K) { return K == CXXConversion; }
};
+/// Represents the language in a linkage specification.
+///
+/// The values are part of the serialization ABI for
+/// ASTs and cannot be changed without altering that ABI.
+enum class LinkageSpecLanguageIDs { C = 1, CXX = 2 };
+
/// Represents a linkage specification.
///
/// For example:
@@ -2797,14 +2928,7 @@ class LinkageSpecDecl : public Decl, public DeclContext {
virtual void anchor();
// This class stores some data in DeclContext::LinkageSpecDeclBits to save
// some space. Use the provided accessors to access it.
-public:
- /// Represents the language in a linkage specification.
- ///
- /// The values are part of the serialization ABI for
- /// ASTs and cannot be changed without altering that ABI.
- enum LanguageIDs { lang_c = 1, lang_cxx = 2 };
-private:
/// The source location for the extern keyword.
SourceLocation ExternLoc;
@@ -2812,22 +2936,25 @@ private:
SourceLocation RBraceLoc;
LinkageSpecDecl(DeclContext *DC, SourceLocation ExternLoc,
- SourceLocation LangLoc, LanguageIDs lang, bool HasBraces);
+ SourceLocation LangLoc, LinkageSpecLanguageIDs lang,
+ bool HasBraces);
public:
static LinkageSpecDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation ExternLoc,
- SourceLocation LangLoc, LanguageIDs Lang,
- bool HasBraces);
+ SourceLocation LangLoc,
+ LinkageSpecLanguageIDs Lang, bool HasBraces);
static LinkageSpecDecl *CreateDeserialized(ASTContext &C, unsigned ID);
/// Return the language specified by this linkage specification.
- LanguageIDs getLanguage() const {
- return static_cast<LanguageIDs>(LinkageSpecDeclBits.Language);
+ LinkageSpecLanguageIDs getLanguage() const {
+ return static_cast<LinkageSpecLanguageIDs>(LinkageSpecDeclBits.Language);
}
/// Set the language specified by this linkage specification.
- void setLanguage(LanguageIDs L) { LinkageSpecDeclBits.Language = L; }
+ void setLanguage(LinkageSpecLanguageIDs L) {
+ LinkageSpecDeclBits.Language = llvm::to_underlying(L);
+ }
/// Determines whether this linkage specification had braces in
/// its syntactic form.
@@ -3290,7 +3417,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;
@@ -3476,6 +3603,7 @@ class ConstructorUsingShadowDecl final : public UsingShadowDecl {
/// \c true if the constructor ultimately named by this using shadow
/// declaration is within a virtual base class subobject of the class that
/// contains this declaration.
+ LLVM_PREFERRED_TYPE(bool)
unsigned IsVirtual : 1;
ConstructorUsingShadowDecl(ASTContext &C, DeclContext *DC, SourceLocation Loc,
@@ -3578,17 +3706,15 @@ public:
class UsingEnumDecl : public BaseUsingDecl, public Mergeable<UsingEnumDecl> {
/// The source location of the 'using' keyword itself.
SourceLocation UsingLocation;
-
- /// Location of the 'enum' keyword.
+ /// The source location of the 'enum' keyword.
SourceLocation EnumLocation;
-
- /// The enum
- EnumDecl *Enum;
+ /// 'qual::SomeEnum' as an EnumType, possibly with Elaborated/Typedef sugar.
+ TypeSourceInfo *EnumType;
UsingEnumDecl(DeclContext *DC, DeclarationName DN, SourceLocation UL,
- SourceLocation EL, SourceLocation NL, EnumDecl *ED)
- : BaseUsingDecl(UsingEnum, DC, NL, DN), UsingLocation(UL),
- EnumLocation(EL), Enum(ED) {}
+ SourceLocation EL, SourceLocation NL, TypeSourceInfo *EnumType)
+ : BaseUsingDecl(UsingEnum, DC, NL, DN), UsingLocation(UL), EnumLocation(EL),
+ EnumType(EnumType){}
void anchor() override;
@@ -3603,13 +3729,29 @@ public:
/// The source location of the 'enum' keyword.
SourceLocation getEnumLoc() const { return EnumLocation; }
void setEnumLoc(SourceLocation L) { EnumLocation = L; }
+ NestedNameSpecifier *getQualifier() const {
+ return getQualifierLoc().getNestedNameSpecifier();
+ }
+ NestedNameSpecifierLoc getQualifierLoc() const {
+ if (auto ETL = EnumType->getTypeLoc().getAs<ElaboratedTypeLoc>())
+ return ETL.getQualifierLoc();
+ return NestedNameSpecifierLoc();
+ }
+ // Returns the "qualifier::Name" part as a TypeLoc.
+ TypeLoc getEnumTypeLoc() const {
+ return EnumType->getTypeLoc();
+ }
+ TypeSourceInfo *getEnumType() const {
+ return EnumType;
+ }
+ void setEnumType(TypeSourceInfo *TSI) { EnumType = TSI; }
public:
- EnumDecl *getEnumDecl() const { return Enum; }
+ EnumDecl *getEnumDecl() const { return cast<EnumDecl>(EnumType->getType()->getAsTagDecl()); }
static UsingEnumDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation UsingL, SourceLocation EnumL,
- SourceLocation NameL, EnumDecl *ED);
+ SourceLocation NameL, TypeSourceInfo *EnumType);
static UsingEnumDecl *CreateDeserialized(ASTContext &C, unsigned ID);
@@ -3677,7 +3819,7 @@ public:
/// Get the set of using declarations that this pack expanded into. Note that
/// some of these may still be unresolved.
ArrayRef<NamedDecl *> expansions() const {
- return llvm::makeArrayRef(getTrailingObjects<NamedDecl *>(), NumExpansions);
+ return llvm::ArrayRef(getTrailingObjects<NamedDecl *>(), NumExpansions);
}
static UsingPackDecl *Create(ASTContext &C, DeclContext *DC,
@@ -3908,12 +4050,12 @@ public:
/// Represents a C++11 static_assert declaration.
class StaticAssertDecl : public Decl {
llvm::PointerIntPair<Expr *, 1, bool> AssertExprAndFailed;
- StringLiteral *Message;
+ Expr *Message;
SourceLocation RParenLoc;
StaticAssertDecl(DeclContext *DC, SourceLocation StaticAssertLoc,
- Expr *AssertExpr, StringLiteral *Message,
- SourceLocation RParenLoc, bool Failed)
+ Expr *AssertExpr, Expr *Message, SourceLocation RParenLoc,
+ bool Failed)
: Decl(StaticAssert, DC, StaticAssertLoc),
AssertExprAndFailed(AssertExpr, Failed), Message(Message),
RParenLoc(RParenLoc) {}
@@ -3925,15 +4067,15 @@ public:
static StaticAssertDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation StaticAssertLoc,
- Expr *AssertExpr, StringLiteral *Message,
+ Expr *AssertExpr, Expr *Message,
SourceLocation RParenLoc, bool Failed);
static StaticAssertDecl *CreateDeserialized(ASTContext &C, unsigned ID);
Expr *getAssertExpr() { return AssertExprAndFailed.getPointer(); }
const Expr *getAssertExpr() const { return AssertExprAndFailed.getPointer(); }
- StringLiteral *getMessage() { return Message; }
- const StringLiteral *getMessage() const { return Message; }
+ Expr *getMessage() { return Message; }
+ const Expr *getMessage() const { return Message; }
bool isFailed() const { return AssertExprAndFailed.getInt(); }
@@ -4047,10 +4189,10 @@ public:
unsigned NumBindings);
ArrayRef<BindingDecl *> bindings() const {
- return llvm::makeArrayRef(getTrailingObjects<BindingDecl *>(), NumBindings);
+ return llvm::ArrayRef(getTrailingObjects<BindingDecl *>(), NumBindings);
}
- void printName(raw_ostream &os) const override;
+ void printName(raw_ostream &OS, const PrintingPolicy &Policy) const override;
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classofKind(Kind K) { return K == Decomposition; }
@@ -4163,7 +4305,8 @@ private:
public:
/// Print this UUID in a human-readable format.
- void printName(llvm::raw_ostream &OS) const override;
+ void printName(llvm::raw_ostream &OS,
+ const PrintingPolicy &Policy) const override;
/// Get the decomposed parts of this declaration.
Parts getParts() const { return PartVal; }
@@ -4185,6 +4328,55 @@ public:
static bool classofKind(Kind K) { return K == Decl::MSGuid; }
};
+/// An artificial decl, representing a global anonymous constant value which is
+/// uniquified by value within a translation unit.
+///
+/// These is currently only used to back the LValue returned by
+/// __builtin_source_location, but could potentially be used for other similar
+/// situations in the future.
+class UnnamedGlobalConstantDecl : public ValueDecl,
+ public Mergeable<UnnamedGlobalConstantDecl>,
+ public llvm::FoldingSetNode {
+
+ // The constant value of this global.
+ APValue Value;
+
+ void anchor() override;
+
+ UnnamedGlobalConstantDecl(const ASTContext &C, DeclContext *DC, QualType T,
+ const APValue &Val);
+
+ static UnnamedGlobalConstantDecl *Create(const ASTContext &C, QualType T,
+ const APValue &APVal);
+ static UnnamedGlobalConstantDecl *CreateDeserialized(ASTContext &C,
+ unsigned ID);
+
+ // Only ASTContext::getUnnamedGlobalConstantDecl and deserialization create
+ // these.
+ friend class ASTContext;
+ friend class ASTReader;
+ friend class ASTDeclReader;
+
+public:
+ /// Print this in a human-readable format.
+ void printName(llvm::raw_ostream &OS,
+ const PrintingPolicy &Policy) const override;
+
+ const APValue &getValue() const { return Value; }
+
+ static void Profile(llvm::FoldingSetNodeID &ID, QualType Ty,
+ const APValue &APVal) {
+ Ty.Profile(ID);
+ APVal.Profile(ID);
+ }
+ void Profile(llvm::FoldingSetNodeID &ID) {
+ Profile(ID, getType(), getValue());
+ }
+
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+ static bool classofKind(Kind K) { return K == Decl::UnnamedGlobalConstant; }
+};
+
/// Insertion operator for diagnostics. This allows sending an AccessSpecifier
/// into a diagnostic with <<.
const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB,
diff --git a/contrib/llvm-project/clang/include/clang/AST/DeclContextInternals.h b/contrib/llvm-project/clang/include/clang/AST/DeclContextInternals.h
index 2eef2343b750..903cdb7bfcc8 100644
--- a/contrib/llvm-project/clang/include/clang/AST/DeclContextInternals.h
+++ b/contrib/llvm-project/clang/include/clang/AST/DeclContextInternals.h
@@ -78,8 +78,7 @@ class StoredDeclsList {
}
Data.setPointer(NewHead);
- assert(llvm::find_if(getLookupResult(), ShouldErase) ==
- getLookupResult().end() && "Still exists!");
+ assert(llvm::none_of(getLookupResult(), ShouldErase) && "Still exists!");
}
void erase(NamedDecl *ND) {
@@ -91,7 +90,7 @@ public:
StoredDeclsList(StoredDeclsList &&RHS) : Data(RHS.Data) {
RHS.Data.setPointer(nullptr);
- RHS.Data.setInt(0);
+ RHS.Data.setInt(false);
}
void MaybeDeallocList() {
@@ -115,7 +114,7 @@ public:
Data = RHS.Data;
RHS.Data.setPointer(nullptr);
- RHS.Data.setInt(0);
+ RHS.Data.setInt(false);
return *this;
}
@@ -143,7 +142,7 @@ public:
}
void setHasExternalDecls() {
- Data.setInt(1);
+ Data.setInt(true);
}
void remove(NamedDecl *D) {
@@ -156,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) {
@@ -172,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/DeclFriend.h b/contrib/llvm-project/clang/include/clang/AST/DeclFriend.h
index 6f8306c6025e..3e6ca5b32192 100644
--- a/contrib/llvm-project/clang/include/clang/AST/DeclFriend.h
+++ b/contrib/llvm-project/clang/include/clang/AST/DeclFriend.h
@@ -23,7 +23,6 @@
#include "clang/Basic/LLVM.h"
#include "clang/Basic/SourceLocation.h"
#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/None.h"
#include "llvm/ADT/PointerUnion.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/Compiler.h"
@@ -74,6 +73,7 @@ private:
/// True if this 'friend' declaration is unsupported. Eventually we
/// will support every possible friend declaration, but for now we
/// silently ignore some and set this flag to authorize all access.
+ LLVM_PREFERRED_TYPE(bool)
unsigned UnsupportedFriend : 1;
// The number of "outer" template parameter lists in non-templatic
@@ -108,11 +108,10 @@ public:
friend class ASTNodeImporter;
friend TrailingObjects;
- static FriendDecl *Create(ASTContext &C, DeclContext *DC,
- SourceLocation L, FriendUnion Friend_,
- SourceLocation FriendL,
- ArrayRef<TemplateParameterList*> FriendTypeTPLists
- = None);
+ static FriendDecl *
+ Create(ASTContext &C, DeclContext *DC, SourceLocation L, FriendUnion Friend_,
+ SourceLocation FriendL,
+ ArrayRef<TemplateParameterList *> FriendTypeTPLists = std::nullopt);
static FriendDecl *CreateDeserialized(ASTContext &C, unsigned ID,
unsigned FriendTypeNumTPLists);
diff --git a/contrib/llvm-project/clang/include/clang/AST/DeclObjC.h b/contrib/llvm-project/clang/include/clang/AST/DeclObjC.h
index 6bb9cdf67034..f8f894b4b10d 100644
--- a/contrib/llvm-project/clang/include/clang/AST/DeclObjC.h
+++ b/contrib/llvm-project/clang/include/clang/AST/DeclObjC.h
@@ -25,9 +25,8 @@
#include "clang/Basic/SourceLocation.h"
#include "clang/Basic/Specifiers.h"
#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/DenseSet.h"
-#include "llvm/ADT/None.h"
+#include "llvm/ADT/MapVector.h"
#include "llvm/ADT/PointerIntPair.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringRef.h"
@@ -116,6 +115,8 @@ public:
const SourceLocation *Locs, ASTContext &Ctx);
};
+enum class ObjCImplementationControl { None, Required, Optional };
+
/// ObjCMethodDecl - Represents an instance or class method declaration.
/// ObjC methods can be declared within 4 contexts: class interfaces,
/// categories, protocols, and class implementations. While C++ member
@@ -140,10 +141,6 @@ class ObjCMethodDecl : public NamedDecl, public DeclContext {
// This class stores some data in DeclContext::ObjCMethodDeclBits
// to save some space. Use the provided accessors to access it.
-public:
- enum ImplementationControl { None, Required, Optional };
-
-private:
/// Return type of this method.
QualType MethodDeclType;
@@ -169,14 +166,14 @@ private:
/// constructed by createImplicitParams.
ImplicitParamDecl *CmdDecl = nullptr;
- ObjCMethodDecl(SourceLocation beginLoc, SourceLocation endLoc,
- Selector SelInfo, QualType T, TypeSourceInfo *ReturnTInfo,
- DeclContext *contextDecl, bool isInstance = true,
- bool isVariadic = false, bool isPropertyAccessor = false,
- bool isSynthesizedAccessorStub = false,
- bool isImplicitlyDeclared = false, bool isDefined = false,
- ImplementationControl impControl = None,
- bool HasRelatedResultType = false);
+ ObjCMethodDecl(
+ SourceLocation beginLoc, SourceLocation endLoc, Selector SelInfo,
+ QualType T, TypeSourceInfo *ReturnTInfo, DeclContext *contextDecl,
+ bool isInstance = true, bool isVariadic = false,
+ bool isPropertyAccessor = false, bool isSynthesizedAccessorStub = false,
+ bool isImplicitlyDeclared = false, bool isDefined = false,
+ ObjCImplementationControl impControl = ObjCImplementationControl::None,
+ bool HasRelatedResultType = false);
SelectorLocationsKind getSelLocsKind() const {
return static_cast<SelectorLocationsKind>(ObjCMethodDeclBits.SelLocsKind);
@@ -236,7 +233,7 @@ public:
bool isVariadic = false, bool isPropertyAccessor = false,
bool isSynthesizedAccessorStub = false,
bool isImplicitlyDeclared = false, bool isDefined = false,
- ImplementationControl impControl = None,
+ ObjCImplementationControl impControl = ObjCImplementationControl::None,
bool HasRelatedResultType = false);
static ObjCMethodDecl *CreateDeserialized(ASTContext &C, unsigned ID);
@@ -374,8 +371,7 @@ public:
// ArrayRef access to formal parameters. This should eventually
// replace the iterator interface above.
ArrayRef<ParmVarDecl*> parameters() const {
- return llvm::makeArrayRef(const_cast<ParmVarDecl**>(getParams()),
- NumParams);
+ return llvm::ArrayRef(const_cast<ParmVarDecl **>(getParams()), NumParams);
}
ParmVarDecl *getParamDecl(unsigned Idx) {
@@ -389,9 +385,8 @@ public:
/// Sets the method's parameters and selector source locations.
/// If the method is implicit (not coming from source) \p SelLocs is
/// ignored.
- void setMethodParams(ASTContext &C,
- ArrayRef<ParmVarDecl*> Params,
- ArrayRef<SourceLocation> SelLocs = llvm::None);
+ void setMethodParams(ASTContext &C, ArrayRef<ParmVarDecl *> Params,
+ ArrayRef<SourceLocation> SelLocs = std::nullopt);
// Iterator access to parameter types.
struct GetTypeFn {
@@ -487,6 +482,9 @@ public:
/// True if the method is tagged as objc_direct
bool isDirectMethod() const;
+ /// True if the method has a parameter that's destroyed in the callee.
+ bool hasParamDestroyedInCallee() const;
+
/// Returns the property associated with this method's selector.
///
/// Note that even if this particular method is not marked as a property
@@ -495,16 +493,17 @@ public:
const ObjCPropertyDecl *findPropertyDecl(bool CheckOverrides = true) const;
// Related to protocols declared in \@protocol
- void setDeclImplementation(ImplementationControl ic) {
- ObjCMethodDeclBits.DeclImplementation = ic;
+ void setDeclImplementation(ObjCImplementationControl ic) {
+ ObjCMethodDeclBits.DeclImplementation = llvm::to_underlying(ic);
}
- ImplementationControl getImplementationControl() const {
- return ImplementationControl(ObjCMethodDeclBits.DeclImplementation);
+ ObjCImplementationControl getImplementationControl() const {
+ return static_cast<ObjCImplementationControl>(
+ ObjCMethodDeclBits.DeclImplementation);
}
bool isOptional() const {
- return getImplementationControl() == Optional;
+ return getImplementationControl() == ObjCImplementationControl::Optional;
}
/// Returns true if this specific method declaration is marked with the
@@ -581,6 +580,7 @@ class ObjCTypeParamDecl : public TypedefNameDecl {
unsigned Index : 14;
/// The variance of the type parameter.
+ LLVM_PREFERRED_TYPE(ObjCTypeParamVariance)
unsigned Variance : 2;
/// The location of the variance, if any.
@@ -742,10 +742,13 @@ private:
QualType DeclType;
TypeSourceInfo *DeclTypeSourceInfo;
+ LLVM_PREFERRED_TYPE(ObjCPropertyAttribute::Kind)
unsigned PropertyAttributes : NumObjCPropertyAttrsBits;
+ LLVM_PREFERRED_TYPE(ObjCPropertyAttribute::Kind)
unsigned PropertyAttributesAsWritten : NumObjCPropertyAttrsBits;
// \@required/\@optional
+ LLVM_PREFERRED_TYPE(PropertyControl)
unsigned PropertyImplementation : 2;
// getter name of NULL if no getter
@@ -776,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);
@@ -1072,21 +1071,23 @@ 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;
using PropertyMap =
- llvm::DenseMap<std::pair<IdentifierInfo *, unsigned/*isClassProperty*/>,
- ObjCPropertyDecl *>;
+ llvm::MapVector<std::pair<IdentifierInfo *, unsigned /*isClassProperty*/>,
+ ObjCPropertyDecl *>;
using ProtocolPropertySet = llvm::SmallDenseSet<const ObjCProtocolDecl *, 8>;
using PropertyDeclOrder = llvm::SmallVector<ObjCPropertyDecl *, 8>;
/// This routine collects list of properties to be implemented in the class.
/// This includes, class's and its conforming protocols' properties.
/// Note, the superclass's properties are not included in the list.
- virtual void collectPropertiesToImplement(PropertyMap &PM,
- PropertyDeclOrder &PO) const {}
+ virtual void collectPropertiesToImplement(PropertyMap &PM) const {}
SourceLocation getAtStartLoc() const { return ObjCContainerDeclBits.AtStart; }
@@ -1148,6 +1149,7 @@ public:
class ObjCInterfaceDecl : public ObjCContainerDecl
, public Redeclarable<ObjCInterfaceDecl> {
friend class ASTContext;
+ friend class ODRDiagsEmitter;
/// TypeForDecl - This indicates the Type object that represents this
/// TypeDecl. It is a cache maintained by ASTContext::getObjCInterfaceType
@@ -1180,14 +1182,17 @@ class ObjCInterfaceDecl : public ObjCContainerDecl
/// Indicates that the contents of this Objective-C class will be
/// completed by the external AST source when required.
+ LLVM_PREFERRED_TYPE(bool)
mutable unsigned ExternallyCompleted : 1;
/// Indicates that the ivar cache does not yet include ivars
/// declared in the implementation.
+ LLVM_PREFERRED_TYPE(bool)
mutable unsigned IvarListMissingImplementation : 1;
/// Indicates that this interface decl contains at least one initializer
/// marked with the 'objc_designated_initializer' attribute.
+ LLVM_PREFERRED_TYPE(bool)
unsigned HasDesignatedInitializers : 1;
enum InheritedDesignatedInitializersState {
@@ -1203,8 +1208,16 @@ class ObjCInterfaceDecl : public ObjCContainerDecl
};
/// One of the \c InheritedDesignatedInitializersState enumeratos.
+ LLVM_PREFERRED_TYPE(InheritedDesignatedInitializersState)
mutable unsigned InheritedDesignatedInitializers : 2;
+ /// Tracks whether a ODR hash has been computed for this interface.
+ LLVM_PREFERRED_TYPE(bool)
+ unsigned HasODRHash : 1;
+
+ /// A hash of parts of the class to help in ODR checking.
+ unsigned ODRHash = 0;
+
/// The location of the last location in this declaration, before
/// the properties/methods. For example, this will be the '>', '}', or
/// identifier,
@@ -1213,7 +1226,7 @@ class ObjCInterfaceDecl : public ObjCContainerDecl
DefinitionData()
: ExternallyCompleted(false), IvarListMissingImplementation(true),
HasDesignatedInitializers(false),
- InheritedDesignatedInitializers(IDI_Unknown) {}
+ InheritedDesignatedInitializers(IDI_Unknown), HasODRHash(false) {}
};
/// The type parameters associated with this class, if any.
@@ -1537,6 +1550,13 @@ public:
/// a forward declaration (\@class) to a definition (\@interface).
void startDefinition();
+ /// Starts the definition without sharing it with other redeclarations.
+ /// Such definition shouldn't be used for anything but only to compare if
+ /// a duplicate is compatible with previous definition or if it is
+ /// a distinct duplicate.
+ void startDuplicateDefinitionForComparison();
+ void mergeDuplicateDefinitionWithCommon(const ObjCInterfaceDecl *Definition);
+
/// Retrieve the superclass type.
const ObjCObjectType *getSuperClassType() const {
if (TypeSourceInfo *TInfo = getSuperClassTInfo())
@@ -1778,8 +1798,7 @@ public:
*FindPropertyVisibleInPrimaryClass(IdentifierInfo *PropertyId,
ObjCPropertyQueryKind QueryKind) const;
- void collectPropertiesToImplement(PropertyMap &PM,
- PropertyDeclOrder &PO) const override;
+ void collectPropertiesToImplement(PropertyMap &PM) const override;
/// isSuperClassOf - Return true if this class is the specified class or is a
/// super class of the specified interface class.
@@ -1895,10 +1914,17 @@ public:
const Type *getTypeForDecl() const { return TypeForDecl; }
void setTypeForDecl(const Type *TD) const { TypeForDecl = TD; }
+ /// Get precomputed ODRHash or add a new one.
+ unsigned getODRHash();
+
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classofKind(Kind K) { return K == ObjCInterface; }
private:
+ /// True if a valid hash is stored in ODRHash.
+ bool hasODRHash() const;
+ void setHasODRHash(bool HasHash);
+
const ObjCInterfaceDecl *findInterfaceWithDesignatedInitializers() const;
bool inheritsDesignatedInitializers() const;
};
@@ -1949,12 +1975,22 @@ public:
/// in; this is either the interface where the ivar was declared, or the
/// interface the ivar is conceptually a part of in the case of synthesized
/// ivars.
- const ObjCInterfaceDecl *getContainingInterface() const;
+ ObjCInterfaceDecl *getContainingInterface();
+ const ObjCInterfaceDecl *getContainingInterface() const {
+ return const_cast<ObjCIvarDecl *>(this)->getContainingInterface();
+ }
ObjCIvarDecl *getNextIvar() { return NextIvar; }
const ObjCIvarDecl *getNextIvar() const { return NextIvar; }
void setNextIvar(ObjCIvarDecl *ivar) { NextIvar = ivar; }
+ ObjCIvarDecl *getCanonicalDecl() override {
+ return cast<ObjCIvarDecl>(FieldDecl::getCanonicalDecl());
+ }
+ const ObjCIvarDecl *getCanonicalDecl() const {
+ return const_cast<ObjCIvarDecl *>(this)->getCanonicalDecl();
+ }
+
void setAccessControl(AccessControl ac) { DeclAccess = ac; }
AccessControl getAccessControl() const { return AccessControl(DeclAccess); }
@@ -1980,7 +2016,9 @@ private:
ObjCIvarDecl *NextIvar = nullptr;
// NOTE: VC++ treats enums as signed, avoid using the AccessControl enum
+ LLVM_PREFERRED_TYPE(AccessControl)
unsigned DeclAccess : 3;
+ LLVM_PREFERRED_TYPE(bool)
unsigned Synthesized : 1;
};
@@ -2045,6 +2083,13 @@ class ObjCProtocolDecl : public ObjCContainerDecl,
/// Referenced protocols
ObjCProtocolList ReferencedProtocols;
+
+ /// Tracks whether a ODR hash has been computed for this protocol.
+ LLVM_PREFERRED_TYPE(bool)
+ unsigned HasODRHash : 1;
+
+ /// A hash of parts of the class to help in ODR checking.
+ unsigned ODRHash = 0;
};
/// Contains a pointer to the data associated with this class,
@@ -2081,10 +2126,15 @@ class ObjCProtocolDecl : public ObjCContainerDecl,
return getMostRecentDecl();
}
+ /// True if a valid hash is stored in ODRHash.
+ bool hasODRHash() const;
+ void setHasODRHash(bool HasHash);
+
public:
friend class ASTDeclReader;
friend class ASTDeclWriter;
friend class ASTReader;
+ friend class ODRDiagsEmitter;
static ObjCProtocolDecl *Create(ASTContext &C, DeclContext *DC,
IdentifierInfo *Id,
@@ -2209,6 +2259,13 @@ public:
/// Starts the definition of this Objective-C protocol.
void startDefinition();
+ /// Starts the definition without sharing it with other redeclarations.
+ /// Such definition shouldn't be used for anything but only to compare if
+ /// a duplicate is compatible with previous definition or if it is
+ /// a distinct duplicate.
+ void startDuplicateDefinitionForComparison();
+ void mergeDuplicateDefinitionWithCommon(const ObjCProtocolDecl *Definition);
+
/// Produce a name to be used for protocol's metadata. It comes either via
/// objc_runtime_name attribute or protocol name.
StringRef getObjCRuntimeNameAsString() const;
@@ -2234,13 +2291,15 @@ public:
ObjCProtocolDecl *getCanonicalDecl() override { return getFirstDecl(); }
const ObjCProtocolDecl *getCanonicalDecl() const { return getFirstDecl(); }
- void collectPropertiesToImplement(PropertyMap &PM,
- PropertyDeclOrder &PO) const override;
+ void collectPropertiesToImplement(PropertyMap &PM) const override;
void collectInheritedProtocolProperties(const ObjCPropertyDecl *Property,
ProtocolPropertySet &PS,
PropertyDeclOrder &PO) const;
+ /// Get precomputed ODRHash or add a new one.
+ unsigned getODRHash();
+
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classofKind(Kind K) { return K == ObjCProtocol; }
};
@@ -2549,9 +2608,11 @@ class ObjCImplementationDecl : public ObjCImplDecl {
/// Do the ivars of this class require initialization other than
/// zero-initialization?
+ LLVM_PREFERRED_TYPE(bool)
bool HasNonZeroConstructors : 1;
/// Do the ivars of this class require non-trivial destruction?
+ LLVM_PREFERRED_TYPE(bool)
bool HasDestructors : 1;
ObjCImplementationDecl(DeclContext *DC,
@@ -2876,15 +2937,16 @@ ObjCInterfaceDecl::filtered_category_iterator<Filter>::operator++() {
}
inline bool ObjCInterfaceDecl::isVisibleCategory(ObjCCategoryDecl *Cat) {
- return Cat->isUnconditionallyVisible();
+ return !Cat->isInvalidDecl() && Cat->isUnconditionallyVisible();
}
inline bool ObjCInterfaceDecl::isVisibleExtension(ObjCCategoryDecl *Cat) {
- return Cat->IsClassExtension() && Cat->isUnconditionallyVisible();
+ return !Cat->isInvalidDecl() && Cat->IsClassExtension() &&
+ Cat->isUnconditionallyVisible();
}
inline bool ObjCInterfaceDecl::isKnownExtension(ObjCCategoryDecl *Cat) {
- return Cat->IsClassExtension();
+ return !Cat->isInvalidDecl() && Cat->IsClassExtension();
}
} // namespace clang
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/DeclOpenMP.h b/contrib/llvm-project/clang/include/clang/AST/DeclOpenMP.h
index 4aa5bde92e12..73725e6e8566 100644
--- a/contrib/llvm-project/clang/include/clang/AST/DeclOpenMP.h
+++ b/contrib/llvm-project/clang/include/clang/AST/DeclOpenMP.h
@@ -34,7 +34,7 @@ template <typename U> class OMPDeclarativeDirective : public U {
/// Get the clauses storage.
MutableArrayRef<OMPClause *> getClauses() {
if (!Data)
- return llvm::None;
+ return std::nullopt;
return Data->getClauses();
}
@@ -90,7 +90,7 @@ public:
ArrayRef<OMPClause *> clauses() const {
if (!Data)
- return llvm::None;
+ return std::nullopt;
return Data->getClauses();
}
};
@@ -118,12 +118,12 @@ class OMPThreadPrivateDecl final : public OMPDeclarativeDirective<Decl> {
ArrayRef<const Expr *> getVars() const {
auto **Storage = reinterpret_cast<Expr **>(Data->getChildren().data());
- return llvm::makeArrayRef(Storage, Data->getNumChildren());
+ return llvm::ArrayRef(Storage, Data->getNumChildren());
}
MutableArrayRef<Expr *> getVars() {
auto **Storage = reinterpret_cast<Expr **>(Data->getChildren().data());
- return llvm::makeMutableArrayRef(Storage, Data->getNumChildren());
+ return llvm::MutableArrayRef(Storage, Data->getNumChildren());
}
void setVars(ArrayRef<Expr *> VL);
@@ -158,6 +158,12 @@ public:
static bool classofKind(Kind K) { return K == OMPThreadPrivate; }
};
+enum class OMPDeclareReductionInitKind {
+ Call, // Initialized by function call.
+ Direct, // omp_priv(<expr>)
+ Copy // omp_priv = <expr>
+};
+
/// This represents '#pragma omp declare reduction ...' directive.
/// For example, in the following, declared reduction 'foo' for types 'int' and
/// 'float':
@@ -171,14 +177,7 @@ public:
class OMPDeclareReductionDecl final : public ValueDecl, public DeclContext {
// This class stores some data in DeclContext::OMPDeclareReductionDeclBits
// to save some space. Use the provided accessors to access it.
-public:
- enum InitKind {
- CallInit, // Initialized by function call.
- DirectInit, // omp_priv(<expr>)
- CopyInit // omp_priv = <expr>
- };
-private:
friend class ASTDeclReader;
/// Combiner for declare reduction construct.
Expr *Combiner = nullptr;
@@ -239,8 +238,9 @@ public:
Expr *getInitializer() { return Initializer; }
const Expr *getInitializer() const { return Initializer; }
/// Get initializer kind.
- InitKind getInitializerKind() const {
- return static_cast<InitKind>(OMPDeclareReductionDeclBits.InitializerKind);
+ OMPDeclareReductionInitKind getInitializerKind() const {
+ return static_cast<OMPDeclareReductionInitKind>(
+ OMPDeclareReductionDeclBits.InitializerKind);
}
/// Get Orig variable of the initializer.
Expr *getInitOrig() { return Orig; }
@@ -249,9 +249,9 @@ public:
Expr *getInitPriv() { return Priv; }
const Expr *getInitPriv() const { return Priv; }
/// Set initializer expression for the declare reduction construct.
- void setInitializer(Expr *E, InitKind IK) {
+ void setInitializer(Expr *E, OMPDeclareReductionInitKind IK) {
Initializer = E;
- OMPDeclareReductionDeclBits.InitializerKind = IK;
+ OMPDeclareReductionDeclBits.InitializerKind = llvm::to_underlying(IK);
}
/// Set initializer Orig and Priv vars.
void setInitializerData(Expr *OrigE, Expr *PrivE) {
@@ -481,12 +481,12 @@ class OMPAllocateDecl final : public OMPDeclarativeDirective<Decl> {
ArrayRef<const Expr *> getVars() const {
auto **Storage = reinterpret_cast<Expr **>(Data->getChildren().data());
- return llvm::makeArrayRef(Storage, Data->getNumChildren());
+ return llvm::ArrayRef(Storage, Data->getNumChildren());
}
MutableArrayRef<Expr *> getVars() {
auto **Storage = reinterpret_cast<Expr **>(Data->getChildren().data());
- return llvm::makeMutableArrayRef(Storage, Data->getNumChildren());
+ return llvm::MutableArrayRef(Storage, Data->getNumChildren());
}
void setVars(ArrayRef<Expr *> VL);
diff --git a/contrib/llvm-project/clang/include/clang/AST/DeclTemplate.h b/contrib/llvm-project/clang/include/clang/AST/DeclTemplate.h
index cbaa287f225a..832ad2de6b08 100755
--- a/contrib/llvm-project/clang/include/clang/AST/DeclTemplate.h
+++ b/contrib/llvm-project/clang/include/clang/AST/DeclTemplate.h
@@ -15,6 +15,7 @@
#define LLVM_CLANG_AST_DECLTEMPLATE_H
#include "clang/AST/ASTConcept.h"
+#include "clang/AST/ASTContext.h"
#include "clang/AST/Decl.h"
#include "clang/AST/DeclBase.h"
#include "clang/AST/DeclCXX.h"
@@ -38,6 +39,7 @@
#include <cstddef>
#include <cstdint>
#include <iterator>
+#include <optional>
#include <utility>
namespace clang {
@@ -81,13 +83,16 @@ class TemplateParameterList final
/// Whether this template parameter list contains an unexpanded parameter
/// pack.
+ LLVM_PREFERRED_TYPE(bool)
unsigned ContainsUnexpandedParameterPack : 1;
/// Whether this template parameter list has a requires clause.
+ LLVM_PREFERRED_TYPE(bool)
unsigned HasRequiresClause : 1;
/// Whether any of the template parameters has constrained-parameter
/// constraint-expression.
+ LLVM_PREFERRED_TYPE(bool)
unsigned HasConstrainedParameters : 1;
protected:
@@ -115,6 +120,8 @@ public:
SourceLocation RAngleLoc,
Expr *RequiresClause);
+ void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &C) const;
+
/// Iterates through the template parameters in this list.
using iterator = NamedDecl **;
@@ -128,11 +135,9 @@ public:
unsigned size() const { return NumParams; }
- ArrayRef<NamedDecl*> asArray() {
- return llvm::makeArrayRef(begin(), end());
- }
+ ArrayRef<NamedDecl *> asArray() { return llvm::ArrayRef(begin(), end()); }
ArrayRef<const NamedDecl*> asArray() const {
- return llvm::makeArrayRef(begin(), size());
+ return llvm::ArrayRef(begin(), size());
}
NamedDecl* getParam(unsigned Idx) {
@@ -203,7 +208,8 @@ public:
void print(raw_ostream &Out, const ASTContext &Context,
const PrintingPolicy &Policy, bool OmitTemplateKW = false) const;
- static bool shouldIncludeTypeForArgument(const TemplateParameterList *TPL,
+ static bool shouldIncludeTypeForArgument(const PrintingPolicy &Policy,
+ const TemplateParameterList *TPL,
unsigned Idx);
};
@@ -272,8 +278,7 @@ public:
///
/// This operation assumes that the input argument list outlives it.
/// This takes the list as a pointer to avoid looking like a copy
- /// constructor, since this really really isn't safe to use that
- /// way.
+ /// constructor, since this really isn't safe to use that way.
explicit TemplateArgumentList(const TemplateArgumentList *Other)
: Arguments(Other->data()), NumArguments(Other->size()) {}
@@ -288,7 +293,7 @@ public:
/// Produce this as an array ref.
ArrayRef<TemplateArgument> asArray() const {
- return llvm::makeArrayRef(data(), size());
+ return llvm::ArrayRef(data(), size());
}
/// Retrieve the number of template arguments in this
@@ -372,11 +377,20 @@ public:
/// Set that the default argument was inherited from another parameter.
void setInherited(const ASTContext &C, ParmDecl *InheritedFrom) {
- assert(!isInherited() && "default argument already inherited");
InheritedFrom = getParmOwningDefaultArg(InheritedFrom);
if (!isSet())
ValueOrInherited = InheritedFrom;
- else
+ else if ([[maybe_unused]] auto *D =
+ ValueOrInherited.template dyn_cast<ParmDecl *>()) {
+ assert(C.isSameDefaultTemplateArgument(D, InheritedFrom));
+ ValueOrInherited =
+ new (allocateDefaultArgStorageChain(C)) Chain{InheritedFrom, get()};
+ } else if (auto *Inherited =
+ ValueOrInherited.template dyn_cast<Chain *>()) {
+ assert(C.isSameDefaultTemplateArgument(Inherited->PrevDeclWithDefaultArg,
+ InheritedFrom));
+ Inherited->PrevDeclWithDefaultArg = InheritedFrom;
+ } else
ValueOrInherited = new (allocateDefaultArgStorageChain(C))
Chain{InheritedFrom, ValueOrInherited.template get<ArgType>()};
}
@@ -430,6 +444,9 @@ public:
/// Get the underlying, templated declaration.
NamedDecl *getTemplatedDecl() const { return TemplatedDecl; }
+ // Should a specialization behave like an alias for another type.
+ bool isTypeAlias() const;
+
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
@@ -446,18 +463,17 @@ protected:
NamedDecl *TemplatedDecl;
TemplateParameterList *TemplateParams;
+public:
void setTemplateParameters(TemplateParameterList *TParams) {
TemplateParams = TParams;
}
-public:
- /// Initialize the underlying templated declaration and
- /// template parameters.
- void init(NamedDecl *templatedDecl, TemplateParameterList* templateParams) {
- assert(!TemplatedDecl && "TemplatedDecl already set!");
- assert(!TemplateParams && "TemplateParams already set!");
- TemplatedDecl = templatedDecl;
- TemplateParams = templateParams;
+ /// Initialize the underlying templated declaration.
+ void init(NamedDecl *NewTemplatedDecl) {
+ if (TemplatedDecl)
+ assert(TemplatedDecl == NewTemplatedDecl && "Inconsistent TemplatedDecl");
+ else
+ TemplatedDecl = NewTemplatedDecl;
}
};
@@ -497,7 +513,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) {
@@ -570,7 +586,7 @@ public:
/// \code
/// template<typename> struct A {
/// template<typename> void f();
- /// template<> void f<int>(); // ClassScopeFunctionSpecializationDecl
+ /// template<> void f<int>();
/// };
/// \endcode
///
@@ -606,7 +622,7 @@ public:
static void
Profile(llvm::FoldingSetNodeID &ID, ArrayRef<TemplateArgument> TemplateArgs,
- ASTContext &Context) {
+ const ASTContext &Context) {
ID.AddInteger(TemplateArgs.size());
for (const TemplateArgument &TemplateArg : TemplateArgs)
TemplateArg.Profile(ID, Context);
@@ -669,78 +685,48 @@ public:
/// Provides information about a dependent function-template
/// specialization declaration.
///
-/// Since explicit function template specialization and instantiation
-/// declarations can only appear in namespace scope, and you can only
-/// specialize a member of a fully-specialized class, the only way to
-/// get one of these is in a friend declaration like the following:
+/// This is used for function templates explicit specializations declared
+/// within class templates:
+///
+/// \code
+/// template<typename> struct A {
+/// template<typename> void f();
+/// template<> void f<int>(); // DependentFunctionTemplateSpecializationInfo
+/// };
+/// \endcode
+///
+/// As well as dependent friend declarations naming function template
+/// specializations declared within class templates:
///
/// \code
/// template \<class T> void foo(T);
/// template \<class T> class A {
-/// friend void foo<>(T);
+/// friend void foo<>(T); // DependentFunctionTemplateSpecializationInfo
/// };
/// \endcode
class DependentFunctionTemplateSpecializationInfo final
: private llvm::TrailingObjects<DependentFunctionTemplateSpecializationInfo,
- TemplateArgumentLoc,
FunctionTemplateDecl *> {
- /// The number of potential template candidates.
- unsigned NumTemplates;
-
- /// The number of template arguments.
- unsigned NumArgs;
-
- /// The locations of the left and right angle brackets.
- SourceRange AngleLocs;
+ friend TrailingObjects;
- size_t numTrailingObjects(OverloadToken<TemplateArgumentLoc>) const {
- return NumArgs;
- }
- size_t numTrailingObjects(OverloadToken<FunctionTemplateDecl *>) const {
- return NumTemplates;
- }
+ /// The number of candidates for the primary template.
+ unsigned NumCandidates;
DependentFunctionTemplateSpecializationInfo(
- const UnresolvedSetImpl &Templates,
- const TemplateArgumentListInfo &TemplateArgs);
+ const UnresolvedSetImpl &Candidates,
+ const ASTTemplateArgumentListInfo *TemplateArgsWritten);
public:
- friend TrailingObjects;
+ /// The template arguments as written in the sources, if provided.
+ const ASTTemplateArgumentListInfo *TemplateArgumentsAsWritten;
static DependentFunctionTemplateSpecializationInfo *
- Create(ASTContext &Context, const UnresolvedSetImpl &Templates,
- const TemplateArgumentListInfo &TemplateArgs);
+ Create(ASTContext &Context, const UnresolvedSetImpl &Candidates,
+ const TemplateArgumentListInfo *TemplateArgs);
- /// Returns the number of function templates that this might
- /// be a specialization of.
- unsigned getNumTemplates() const { return NumTemplates; }
-
- /// Returns the i'th template candidate.
- FunctionTemplateDecl *getTemplate(unsigned I) const {
- assert(I < getNumTemplates() && "template index out of range");
- return getTrailingObjects<FunctionTemplateDecl *>()[I];
- }
-
- /// Returns the explicit template arguments that were given.
- const TemplateArgumentLoc *getTemplateArgs() const {
- return getTrailingObjects<TemplateArgumentLoc>();
- }
-
- /// Returns the number of explicit template arguments that were given.
- unsigned getNumTemplateArgs() const { return NumArgs; }
-
- /// Returns the nth template argument.
- const TemplateArgumentLoc &getTemplateArg(unsigned I) const {
- assert(I < getNumTemplateArgs() && "template arg index out of range");
- return getTemplateArgs()[I];
- }
-
- SourceLocation getLAngleLoc() const {
- return AngleLocs.getBegin();
- }
-
- SourceLocation getRAngleLoc() const {
- return AngleLocs.getEnd();
+ /// Returns the candidates for the primary function template.
+ ArrayRef<FunctionTemplateDecl *> getCandidates() const {
+ return {getTrailingObjects<FunctionTemplateDecl *>(), NumCandidates};
}
};
@@ -831,6 +817,15 @@ protected:
/// The first value in the array is the number of specializations/partial
/// specializations that follow.
uint32_t *LazySpecializations = nullptr;
+
+ /// The set of "injected" template arguments used within this
+ /// template.
+ ///
+ /// This pointer refers to the template arguments (there are as
+ /// many template arguments as template parameters) for the
+ /// template, and is allocated lazily, since most templates do not
+ /// require the use of this information.
+ TemplateArgument *InjectedArgs = nullptr;
};
/// Pointer to the common data shared by all declarations of this
@@ -938,6 +933,14 @@ public:
getCommonPtr()->InstantiatedFromMember.setPointer(TD);
}
+ /// Retrieve the "injected" template arguments that correspond to the
+ /// template parameters of this template.
+ ///
+ /// Although the C++ standard has no notion of the "injected" template
+ /// arguments for a template, the notion is convenient when
+ /// we need to perform substitutions inside the definition of a template.
+ ArrayRef<TemplateArgument> getInjectedTemplateArgs();
+
using redecl_range = redeclarable_base::redecl_range;
using redecl_iterator = redeclarable_base::redecl_iterator;
@@ -982,15 +985,6 @@ protected:
/// template, including explicit specializations and instantiations.
llvm::FoldingSetVector<FunctionTemplateSpecializationInfo> Specializations;
- /// The set of "injected" template arguments used within this
- /// function template.
- ///
- /// This pointer refers to the template arguments (there are as
- /// many template arguments as template parameaters) for the function
- /// template, and is allocated lazily, since most function templates do not
- /// require the use of this information.
- TemplateArgument *InjectedArgs = nullptr;
-
Common() = default;
};
@@ -1090,21 +1084,12 @@ public:
return makeSpecIterator(getSpecializations(), true);
}
- /// Retrieve the "injected" template arguments that correspond to the
- /// template parameters of this function template.
- ///
- /// Although the C++ standard has no notion of the "injected" template
- /// arguments for a function template, the notion is convenient when
- /// we need to perform substitutions inside the definition of a function
- /// template.
- ArrayRef<TemplateArgument> getInjectedTemplateArgs();
-
/// Return whether this function template is an abbreviated function template,
/// e.g. `void foo(auto x)` or `template<typename T> void foo(auto x)`
bool isAbbreviated() const {
// Since the invented template parameters generated from 'auto' parameters
// are either appended to the end of the explicit template parameter list or
- // form a new template paramter list, we can simply observe the last
+ // form a new template parameter list, we can simply observe the last
// parameter to determine if such a thing happened.
const TemplateParameterList *TPL = getTemplateParameters();
return TPL->getParam(TPL->size() - 1)->isImplicit();
@@ -1143,23 +1128,40 @@ public:
/// parameters and is not part of the Decl hierarchy. Just a facility.
class TemplateParmPosition {
protected:
- // FIXME: These probably don't need to be ints. int:5 for depth, int:8 for
- // position? Maybe?
- unsigned Depth;
- unsigned Position;
+ enum { DepthWidth = 20, PositionWidth = 12 };
+ unsigned Depth : DepthWidth;
+ unsigned Position : PositionWidth;
- TemplateParmPosition(unsigned D, unsigned P) : Depth(D), Position(P) {}
+ static constexpr unsigned MaxDepth = (1U << DepthWidth) - 1;
+ static constexpr unsigned MaxPosition = (1U << PositionWidth) - 1;
+
+ TemplateParmPosition(unsigned D, unsigned P) : Depth(D), Position(P) {
+ // The input may fill maximum values to show that it is invalid.
+ // Add one here to convert it to zero.
+ assert((D + 1) <= MaxDepth &&
+ "The depth of template parmeter position is more than 2^20!");
+ assert((P + 1) <= MaxPosition &&
+ "The position of template parmeter position is more than 2^12!");
+ }
public:
TemplateParmPosition() = delete;
/// Get the nesting depth of the template parameter.
unsigned getDepth() const { return Depth; }
- void setDepth(unsigned D) { Depth = D; }
+ void setDepth(unsigned D) {
+ assert((D + 1) <= MaxDepth &&
+ "The depth of template parmeter position is more than 2^20!");
+ Depth = D;
+ }
/// Get the position of the template parameter within its parameter list.
unsigned getPosition() const { return Position; }
- void setPosition(unsigned P) { Position = P; }
+ void setPosition(unsigned P) {
+ assert((P + 1) <= MaxPosition &&
+ "The position of template parmeter position is more than 2^12!");
+ Position = P;
+ }
/// Get the index of the template parameter within its parameter list.
unsigned getIndex() const { return Position; }
@@ -1189,10 +1191,10 @@ class TemplateTypeParmDecl final : public TypeDecl,
/// Whether the type constraint has been initialized. This can be false if the
/// constraint was not initialized yet or if there was an error forming the
- /// type constriant.
+ /// type constraint.
bool TypeConstraintInitialized : 1;
- /// Whether this non-type template parameter is an "expanded"
+ /// Whether this type template parameter is an "expanded"
/// parameter pack, meaning that its type is a pack expansion and we
/// already know the set of types that expansion expands to.
bool ExpandedParameterPack : 1;
@@ -1206,23 +1208,20 @@ class TemplateTypeParmDecl final : public TypeDecl,
DefArgStorage DefaultArgument;
TemplateTypeParmDecl(DeclContext *DC, SourceLocation KeyLoc,
- SourceLocation IdLoc, IdentifierInfo *Id,
- bool Typename, bool HasTypeConstraint,
- Optional<unsigned> NumExpanded)
+ SourceLocation IdLoc, IdentifierInfo *Id, bool Typename,
+ bool HasTypeConstraint,
+ std::optional<unsigned> NumExpanded)
: TypeDecl(TemplateTypeParm, DC, IdLoc, Id, KeyLoc), Typename(Typename),
- HasTypeConstraint(HasTypeConstraint), TypeConstraintInitialized(false),
- ExpandedParameterPack(NumExpanded),
- NumExpanded(NumExpanded ? *NumExpanded : 0) {}
+ HasTypeConstraint(HasTypeConstraint), TypeConstraintInitialized(false),
+ ExpandedParameterPack(NumExpanded),
+ NumExpanded(NumExpanded.value_or(0)) {}
public:
- static TemplateTypeParmDecl *Create(const ASTContext &C, DeclContext *DC,
- SourceLocation KeyLoc,
- SourceLocation NameLoc,
- unsigned D, unsigned P,
- IdentifierInfo *Id, bool Typename,
- bool ParameterPack,
- bool HasTypeConstraint = false,
- Optional<unsigned> NumExpanded = None);
+ static TemplateTypeParmDecl *
+ Create(const ASTContext &C, DeclContext *DC, SourceLocation KeyLoc,
+ SourceLocation NameLoc, unsigned D, unsigned P, IdentifierInfo *Id,
+ bool Typename, bool ParameterPack, bool HasTypeConstraint = false,
+ std::optional<unsigned> NumExpanded = std::nullopt);
static TemplateTypeParmDecl *CreateDeserialized(const ASTContext &C,
unsigned ID);
static TemplateTypeParmDecl *CreateDeserialized(const ASTContext &C,
@@ -1344,10 +1343,7 @@ public:
nullptr;
}
- void setTypeConstraint(NestedNameSpecifierLoc NNS,
- DeclarationNameInfo NameInfo, NamedDecl *FoundDecl,
- ConceptDecl *CD,
- const ASTTemplateArgumentListInfo *ArgsAsWritten,
+ void setTypeConstraint(ConceptReference *CR,
Expr *ImmediatelyDeclaredConstraint);
/// Determine whether this template parameter has a type-constraint.
@@ -1358,7 +1354,7 @@ public:
/// \brief Get the associated-constraints of this template parameter.
/// This will either be the immediately-introduced constraint or empty.
///
- /// Use this instead of getConstraintExpression for concepts APIs that
+ /// Use this instead of getTypeConstraint for concepts APIs that
/// accept an ArrayRef of constraint expressions.
void getAssociatedConstraints(llvm::SmallVectorImpl<const Expr *> &AC) const {
if (HasTypeConstraint)
@@ -1840,7 +1836,7 @@ class ClassTemplateSpecializationDecl
SourceLocation PointOfInstantiation;
/// The kind of specialization this declaration refers to.
- /// Really a value of type TemplateSpecializationKind.
+ LLVM_PREFERRED_TYPE(TemplateSpecializationKind)
unsigned SpecializationKind : 3;
protected:
@@ -2054,7 +2050,7 @@ public:
static void
Profile(llvm::FoldingSetNodeID &ID, ArrayRef<TemplateArgument> TemplateArgs,
- ASTContext &Context) {
+ const ASTContext &Context) {
ID.AddInteger(TemplateArgs.size());
for (const TemplateArgument &TemplateArg : TemplateArgs)
TemplateArg.Profile(ID, Context);
@@ -2230,7 +2226,7 @@ public:
static void
Profile(llvm::FoldingSetNodeID &ID, ArrayRef<TemplateArgument> TemplateArgs,
- TemplateParameterList *TPL, ASTContext &Context);
+ TemplateParameterList *TPL, const ASTContext &Context);
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
@@ -2280,9 +2276,15 @@ protected:
return static_cast<Common *>(RedeclarableTemplateDecl::getCommonPtr());
}
+ void setCommonPtr(Common *C) {
+ RedeclarableTemplateDecl::Common = C;
+ }
+
public:
+
friend class ASTDeclReader;
friend class ASTDeclWriter;
+ friend class TemplateDeclInstantiator;
/// Load any lazily-loaded specializations from the external source.
void LoadLazySpecializations() const;
@@ -2457,10 +2459,10 @@ private:
SourceLocation FriendLoc;
FriendTemplateDecl(DeclContext *DC, SourceLocation Loc,
- MutableArrayRef<TemplateParameterList *> Params,
+ TemplateParameterList **Params, unsigned NumParams,
FriendUnion Friend, SourceLocation FriendLoc)
- : Decl(Decl::FriendTemplate, DC, Loc), NumParams(Params.size()),
- Params(Params.data()), Friend(Friend), FriendLoc(FriendLoc) {}
+ : Decl(Decl::FriendTemplate, DC, Loc), NumParams(NumParams),
+ Params(Params), Friend(Friend), FriendLoc(FriendLoc) {}
FriendTemplateDecl(EmptyShell Empty) : Decl(Decl::FriendTemplate, Empty) {}
@@ -2580,70 +2582,6 @@ public:
static bool classofKind(Kind K) { return K == TypeAliasTemplate; }
};
-/// Declaration of a function specialization at template class scope.
-///
-/// For example:
-/// \code
-/// template <class T>
-/// class A {
-/// template <class U> void foo(U a) { }
-/// template<> void foo(int a) { }
-/// }
-/// \endcode
-///
-/// "template<> foo(int a)" will be saved in Specialization as a normal
-/// CXXMethodDecl. Then during an instantiation of class A, it will be
-/// transformed into an actual function specialization.
-///
-/// FIXME: This is redundant; we could store the same information directly on
-/// the CXXMethodDecl as a DependentFunctionTemplateSpecializationInfo.
-class ClassScopeFunctionSpecializationDecl : public Decl {
- CXXMethodDecl *Specialization;
- const ASTTemplateArgumentListInfo *TemplateArgs;
-
- ClassScopeFunctionSpecializationDecl(
- DeclContext *DC, SourceLocation Loc, CXXMethodDecl *FD,
- const ASTTemplateArgumentListInfo *TemplArgs)
- : Decl(Decl::ClassScopeFunctionSpecialization, DC, Loc),
- Specialization(FD), TemplateArgs(TemplArgs) {}
-
- ClassScopeFunctionSpecializationDecl(EmptyShell Empty)
- : Decl(Decl::ClassScopeFunctionSpecialization, Empty) {}
-
- virtual void anchor();
-
-public:
- friend class ASTDeclReader;
- friend class ASTDeclWriter;
-
- CXXMethodDecl *getSpecialization() const { return Specialization; }
- bool hasExplicitTemplateArgs() const { return TemplateArgs; }
- const ASTTemplateArgumentListInfo *getTemplateArgsAsWritten() const {
- return TemplateArgs;
- }
-
- static ClassScopeFunctionSpecializationDecl *
- Create(ASTContext &C, DeclContext *DC, SourceLocation Loc, CXXMethodDecl *FD,
- bool HasExplicitTemplateArgs,
- const TemplateArgumentListInfo &TemplateArgs) {
- return new (C, DC) ClassScopeFunctionSpecializationDecl(
- DC, Loc, FD,
- HasExplicitTemplateArgs
- ? ASTTemplateArgumentListInfo::Create(C, TemplateArgs)
- : nullptr);
- }
-
- static ClassScopeFunctionSpecializationDecl *
- CreateDeserialized(ASTContext &Context, unsigned ID);
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
-
- static bool classofKind(Kind K) {
- return K == Decl::ClassScopeFunctionSpecialization;
- }
-};
-
/// Represents a variable template specialization, which refers to
/// a variable template with a given set of template arguments.
///
@@ -2697,19 +2635,20 @@ class VarTemplateSpecializationDecl : public VarDecl,
/// The template arguments used to describe this specialization.
const TemplateArgumentList *TemplateArgs;
- TemplateArgumentListInfo TemplateArgsInfo;
+ const ASTTemplateArgumentListInfo *TemplateArgsInfo = nullptr;
/// The point where this template was instantiated (if any).
SourceLocation PointOfInstantiation;
/// The kind of specialization this declaration refers to.
- /// Really a value of type TemplateSpecializationKind.
+ LLVM_PREFERRED_TYPE(TemplateSpecializationKind)
unsigned SpecializationKind : 3;
/// Whether this declaration is a complete definition of the
/// variable template specialization. We can't otherwise tell apart
/// an instantiated declaration from an instantiated definition with
/// no initializer.
+ LLVM_PREFERRED_TYPE(bool)
unsigned IsCompleteDefinition : 1;
protected:
@@ -2752,8 +2691,9 @@ public:
// TODO: Always set this when creating the new specialization?
void setTemplateArgsInfo(const TemplateArgumentListInfo &ArgsInfo);
+ void setTemplateArgsInfo(const ASTTemplateArgumentListInfo *ArgsInfo);
- const TemplateArgumentListInfo &getTemplateArgsInfo() const {
+ const ASTTemplateArgumentListInfo *getTemplateArgsInfo() const {
return TemplateArgsInfo;
}
@@ -2898,13 +2838,15 @@ public:
return ExplicitInfo ? ExplicitInfo->TemplateKeywordLoc : SourceLocation();
}
+ SourceRange getSourceRange() const override LLVM_READONLY;
+
void Profile(llvm::FoldingSetNodeID &ID) const {
Profile(ID, TemplateArgs->asArray(), getASTContext());
}
static void Profile(llvm::FoldingSetNodeID &ID,
ArrayRef<TemplateArgument> TemplateArgs,
- ASTContext &Context) {
+ const ASTContext &Context) {
ID.AddInteger(TemplateArgs.size());
for (const TemplateArgument &TemplateArg : TemplateArgs)
TemplateArg.Profile(ID, Context);
@@ -3055,6 +2997,8 @@ public:
return First->InstantiatedFromMember.setInt(true);
}
+ SourceRange getSourceRange() const override LLVM_READONLY;
+
void Profile(llvm::FoldingSetNodeID &ID) const {
Profile(ID, getTemplateArgs().asArray(), getTemplateParameters(),
getASTContext());
@@ -3062,7 +3006,7 @@ public:
static void
Profile(llvm::FoldingSetNodeID &ID, ArrayRef<TemplateArgument> TemplateArgs,
- TemplateParameterList *TPL, ASTContext &Context);
+ TemplateParameterList *TPL, const ASTContext &Context);
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
@@ -3227,7 +3171,7 @@ public:
static bool classofKind(Kind K) { return K == VarTemplate; }
};
-/// Declaration of a C++2a concept.
+/// Declaration of a C++20 concept.
class ConceptDecl : public TemplateDecl, public Mergeable<ConceptDecl> {
protected:
Expr *ConstraintExpr;
@@ -3256,8 +3200,12 @@ public:
return isa<TemplateTypeParmDecl>(getTemplateParameters()->getParam(0));
}
- ConceptDecl *getCanonicalDecl() override { return getFirstDecl(); }
- const ConceptDecl *getCanonicalDecl() const { return getFirstDecl(); }
+ ConceptDecl *getCanonicalDecl() override {
+ return cast<ConceptDecl>(getPrimaryMergedDecl(this));
+ }
+ const ConceptDecl *getCanonicalDecl() const {
+ return const_cast<ConceptDecl *>(this)->getCanonicalDecl();
+ }
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
@@ -3268,6 +3216,40 @@ public:
friend class ASTDeclWriter;
};
+// An implementation detail of ConceptSpecialicationExpr that holds the template
+// arguments, so we can later use this to reconstitute the template arguments
+// during constraint checking.
+class ImplicitConceptSpecializationDecl final
+ : public Decl,
+ private llvm::TrailingObjects<ImplicitConceptSpecializationDecl,
+ TemplateArgument> {
+ unsigned NumTemplateArgs;
+
+ ImplicitConceptSpecializationDecl(DeclContext *DC, SourceLocation SL,
+ ArrayRef<TemplateArgument> ConvertedArgs);
+ ImplicitConceptSpecializationDecl(EmptyShell Empty, unsigned NumTemplateArgs);
+
+public:
+ static ImplicitConceptSpecializationDecl *
+ Create(const ASTContext &C, DeclContext *DC, SourceLocation SL,
+ ArrayRef<TemplateArgument> ConvertedArgs);
+ static ImplicitConceptSpecializationDecl *
+ CreateDeserialized(const ASTContext &C, unsigned ID,
+ unsigned NumTemplateArgs);
+
+ ArrayRef<TemplateArgument> getTemplateArguments() const {
+ return ArrayRef<TemplateArgument>(getTrailingObjects<TemplateArgument>(),
+ NumTemplateArgs);
+ }
+ void setTemplateArguments(ArrayRef<TemplateArgument> Converted);
+
+ static bool classofKind(Kind K) { return K == ImplicitConceptSpecialization; }
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+
+ friend TrailingObjects;
+ friend class ASTDeclReader;
+};
+
/// A template parameter object.
///
/// Template parameter objects represent values of class type used as template
@@ -3305,14 +3287,17 @@ private:
public:
/// Print this template parameter object in a human-readable format.
- void printName(llvm::raw_ostream &OS) const override;
+ void printName(llvm::raw_ostream &OS,
+ const PrintingPolicy &Policy) const override;
/// Print this object as an equivalent expression.
void printAsExpr(llvm::raw_ostream &OS) const;
+ void printAsExpr(llvm::raw_ostream &OS, const PrintingPolicy &Policy) const;
/// Print this object as an initializer suitable for a variable of the
/// object's type.
void printAsInit(llvm::raw_ostream &OS) const;
+ void printAsInit(llvm::raw_ostream &OS, const PrintingPolicy &Policy) const;
const APValue &getValue() const { return Value; }
@@ -3365,7 +3350,7 @@ inline TemplateDecl *getAsTypeTemplateDecl(Decl *D) {
///
/// In \c A<int,int>::B, \c NTs and \c TTs have expanded pack size 2, and \c Us
/// is not a pack expansion, so returns an empty Optional.
-inline Optional<unsigned> getExpandedPackSize(const NamedDecl *Param) {
+inline std::optional<unsigned> getExpandedPackSize(const NamedDecl *Param) {
if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(Param)) {
if (TTP->isExpandedParameterPack())
return TTP->getNumExpansionParameters();
@@ -3381,9 +3366,13 @@ inline Optional<unsigned> getExpandedPackSize(const NamedDecl *Param) {
return TTP->getNumExpansionTemplateParameters();
}
- return None;
+ return std::nullopt;
}
+/// Internal helper used by Subst* nodes to retrieve the parameter list
+/// for their AssociatedDecl.
+TemplateParameterList *getReplacedTemplateParameterList(Decl *D);
+
} // namespace clang
#endif // LLVM_CLANG_AST_DECLTEMPLATE_H
diff --git a/contrib/llvm-project/clang/include/clang/AST/DeclarationName.h b/contrib/llvm-project/clang/include/clang/AST/DeclarationName.h
index 38da6fc727fb..c9b01dc53964 100644
--- a/contrib/llvm-project/clang/include/clang/AST/DeclarationName.h
+++ b/contrib/llvm-project/clang/include/clang/AST/DeclarationName.h
@@ -21,6 +21,7 @@
#include "clang/Basic/SourceLocation.h"
#include "llvm/ADT/DenseMapInfo.h"
#include "llvm/ADT/FoldingSet.h"
+#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/type_traits.h"
#include <cassert>
@@ -34,11 +35,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>;
@@ -119,14 +118,14 @@ class alignas(IdentifierInfoAlignment) CXXLiteralOperatorIdName
friend class clang::DeclarationName;
friend class clang::DeclarationNameTable;
- IdentifierInfo *ID;
+ const IdentifierInfo *ID;
/// Extra information associated with this operator name that
/// can be used by the front end. All bits are really needed
/// so it is not possible to stash something in the low order bits.
void *FETokenInfo;
- CXXLiteralOperatorIdName(IdentifierInfo *II)
+ CXXLiteralOperatorIdName(const IdentifierInfo *II)
: DeclarationNameExtra(CXXLiteralOperatorName), ID(II),
FETokenInfo(nullptr) {}
@@ -194,6 +193,13 @@ class DeclarationName {
"The various classes that DeclarationName::Ptr can point to"
" must be at least aligned to 8 bytes!");
+ static_assert(
+ std::is_same<std::underlying_type_t<StoredNameKind>,
+ std::underlying_type_t<
+ detail::DeclarationNameExtra::ExtraKind>>::value,
+ "The various enums used to compute values for NameKind should "
+ "all have the same underlying type");
+
public:
/// The kind of the name stored in this DeclarationName.
/// The first 7 enumeration values are stored inline and correspond
@@ -207,15 +213,18 @@ public:
CXXDestructorName = StoredCXXDestructorName,
CXXConversionFunctionName = StoredCXXConversionFunctionName,
CXXOperatorName = StoredCXXOperatorName,
- CXXDeductionGuideName = UncommonNameKindOffset +
- detail::DeclarationNameExtra::CXXDeductionGuideName,
- CXXLiteralOperatorName =
- UncommonNameKindOffset +
- detail::DeclarationNameExtra::CXXLiteralOperatorName,
- CXXUsingDirective = UncommonNameKindOffset +
- detail::DeclarationNameExtra::CXXUsingDirective,
- ObjCMultiArgSelector = UncommonNameKindOffset +
- detail::DeclarationNameExtra::ObjCMultiArgSelector
+ CXXDeductionGuideName = llvm::addEnumValues(
+ UncommonNameKindOffset,
+ detail::DeclarationNameExtra::CXXDeductionGuideName),
+ CXXLiteralOperatorName = llvm::addEnumValues(
+ UncommonNameKindOffset,
+ detail::DeclarationNameExtra::CXXLiteralOperatorName),
+ CXXUsingDirective =
+ llvm::addEnumValues(UncommonNameKindOffset,
+ detail::DeclarationNameExtra::CXXUsingDirective),
+ ObjCMultiArgSelector =
+ llvm::addEnumValues(UncommonNameKindOffset,
+ detail::DeclarationNameExtra::ObjCMultiArgSelector),
};
private:
@@ -353,7 +362,8 @@ public:
}
/// Construct a declaration name from an Objective-C selector.
- DeclarationName(Selector Sel) : Ptr(Sel.InfoPtr) {}
+ DeclarationName(Selector Sel)
+ : Ptr(reinterpret_cast<uintptr_t>(Sel.InfoPtr.getOpaqueValue())) {}
/// Returns the name for all C++ using-directives.
static DeclarationName getUsingDirectiveName() {
@@ -469,7 +479,7 @@ public:
/// If this name is the name of a literal operator,
/// retrieve the identifier associated with it.
- IdentifierInfo *getCXXLiteralIdentifier() const {
+ const IdentifierInfo *getCXXLiteralIdentifier() const {
if (getNameKind() == CXXLiteralOperatorName) {
assert(getPtr() && "getCXXLiteralIdentifier on a null DeclarationName!");
return castAsCXXLiteralOperatorIdName()->ID;
@@ -641,7 +651,7 @@ public:
}
/// Get the name of the literal operator function with II as the identifier.
- DeclarationName getCXXLiteralOperatorName(IdentifierInfo *II);
+ DeclarationName getCXXLiteralOperatorName(const IdentifierInfo *II);
};
/// DeclarationNameLoc - Additional source/type location info
@@ -754,7 +764,7 @@ public:
};
/// DeclarationNameInfo - A collector data type for bundling together
-/// a DeclarationName and the correspnding source/type location info.
+/// a DeclarationName and the corresponding source/type location info.
struct DeclarationNameInfo {
private:
/// Name - The declaration name, also encoding name kind.
@@ -932,7 +942,7 @@ class AssumedTemplateStorage : public UncommonTemplateNameStorage {
friend class ASTContext;
AssumedTemplateStorage(DeclarationName Name)
- : UncommonTemplateNameStorage(Assumed, 0), Name(Name) {}
+ : UncommonTemplateNameStorage(Assumed, 0, 0), Name(Name) {}
DeclarationName Name;
public:
diff --git a/contrib/llvm-project/clang/include/clang/AST/DependenceFlags.h b/contrib/llvm-project/clang/include/clang/AST/DependenceFlags.h
index 62efdb4ce6e4..3b3c1afb096a 100644
--- a/contrib/llvm-project/clang/include/clang/AST/DependenceFlags.h
+++ b/contrib/llvm-project/clang/include/clang/AST/DependenceFlags.h
@@ -130,6 +130,14 @@ public:
// Dependence that is propagated syntactically, regardless of semantics.
Syntactic = UnexpandedPack | Instantiation | Error,
+ // Dependence that is propagated semantically, even in cases where the
+ // type doesn't syntactically appear. This currently excludes only
+ // UnexpandedPack. Even though Instantiation dependence is also notionally
+ // syntactic, we also want to propagate it semantically because anything
+ // that semantically depends on an instantiation-dependent entity should
+ // always be instantiated when that instantiation-dependent entity is.
+ Semantic =
+ Instantiation | Type | Value | Dependent | Error | VariablyModified,
LLVM_MARK_AS_BITMASK_ENUM(/*LargestValue=*/VariablyModified)
};
@@ -175,6 +183,14 @@ public:
return Result;
}
+ /// Extract the semantic portions of this type's dependence that apply even
+ /// to uses where the type does not appear syntactically.
+ Dependence semantic() {
+ Dependence Result = *this;
+ Result.V &= Semantic;
+ return Result;
+ }
+
TypeDependence type() const {
return translate(V, UnexpandedPack, TypeDependence::UnexpandedPack) |
translate(V, Instantiation, TypeDependence::Instantiation) |
@@ -231,7 +247,10 @@ private:
inline ExprDependence toExprDependence(TemplateArgumentDependence TA) {
return Dependence(TA).expr();
}
-inline ExprDependence toExprDependence(TypeDependence D) {
+inline ExprDependence toExprDependenceForImpliedType(TypeDependence D) {
+ return Dependence(D).semantic().expr();
+}
+inline ExprDependence toExprDependenceAsWritten(TypeDependence D) {
return Dependence(D).expr();
}
// Note: it's often necessary to strip `Dependent` from qualifiers.
@@ -269,6 +288,9 @@ inline TypeDependence toTypeDependence(TemplateArgumentDependence D) {
inline TypeDependence toSyntacticDependence(TypeDependence D) {
return Dependence(D).syntactic().type();
}
+inline TypeDependence toSemanticDependence(TypeDependence D) {
+ return Dependence(D).semantic().type();
+}
inline NestedNameSpecifierDependence
toNestedNameSpecifierDependendence(TypeDependence D) {
diff --git a/contrib/llvm-project/clang/include/clang/AST/DependentDiagnostic.h b/contrib/llvm-project/clang/include/clang/AST/DependentDiagnostic.h
index 18276d54d540..cadf97062004 100644
--- a/contrib/llvm-project/clang/include/clang/AST/DependentDiagnostic.h
+++ b/contrib/llvm-project/clang/include/clang/AST/DependentDiagnostic.h
@@ -113,7 +113,9 @@ private:
struct {
SourceLocation Loc;
+ LLVM_PREFERRED_TYPE(AccessSpecifier)
unsigned Access : 2;
+ LLVM_PREFERRED_TYPE(bool)
unsigned IsMember : 1;
NamedDecl *TargetDecl;
CXXRecordDecl *NamingClass;
diff --git a/contrib/llvm-project/clang/include/clang/AST/Expr.h b/contrib/llvm-project/clang/include/clang/AST/Expr.h
index 8efa8fdbe2bb..9820bd11da86 100644
--- a/contrib/llvm-project/clang/include/clang/AST/Expr.h
+++ b/contrib/llvm-project/clang/include/clang/AST/Expr.h
@@ -13,6 +13,7 @@
#ifndef LLVM_CLANG_AST_EXPR_H
#define LLVM_CLANG_AST_EXPR_H
+#include "clang/AST/APNumericStorage.h"
#include "clang/AST/APValue.h"
#include "clang/AST/ASTVector.h"
#include "clang/AST/ComputeDependence.h"
@@ -36,6 +37,7 @@
#include "llvm/Support/AtomicOrdering.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/TrailingObjects.h"
+#include <optional>
namespace clang {
class APValue;
@@ -134,8 +136,8 @@ protected:
void setDependence(ExprDependence Deps) {
ExprBits.Dependent = static_cast<unsigned>(Deps);
}
- friend class ASTImporter; // Sets dependence dircetly.
- friend class ASTStmtReader; // Sets dependence dircetly.
+ friend class ASTImporter; // Sets dependence directly.
+ friend class ASTStmtReader; // Sets dependence directly.
public:
QualType getType() const { return TR; }
@@ -170,7 +172,7 @@ public:
}
/// Determines whether the type of this expression depends on
- /// - a template paramter (C++ [temp.dep.expr], which means that its type
+ /// - a template parameter (C++ [temp.dep.expr], which means that its type
/// could change from one template instantiation to the next)
/// - or an error
///
@@ -523,15 +525,25 @@ public:
/// semantically correspond to a bool.
bool isKnownToHaveBooleanValue(bool Semantic = true) const;
+ /// Check whether this array fits the idiom of a flexible array member,
+ /// depending on the value of -fstrict-flex-array.
+ /// When IgnoreTemplateOrMacroSubstitution is set, it doesn't consider sizes
+ /// resulting from the substitution of a macro or a template as special sizes.
+ bool isFlexibleArrayMemberLike(
+ ASTContext &Context,
+ LangOptions::StrictFlexArraysLevelKind StrictFlexArraysLevel,
+ bool IgnoreTemplateOrMacroSubstitution = false) const;
+
/// isIntegerConstantExpr - Return the value if this expression is a valid
- /// integer constant expression. If not a valid i-c-e, return None and fill
- /// in Loc (if specified) with the location of the invalid expression.
+ /// integer constant expression. If not a valid i-c-e, return std::nullopt
+ /// and fill in Loc (if specified) with the location of the invalid
+ /// expression.
///
/// Note: This does not perform the implicit conversions required by C++11
/// [expr.const]p5.
- Optional<llvm::APSInt> getIntegerConstantExpr(const ASTContext &Ctx,
- SourceLocation *Loc = nullptr,
- bool isEvaluated = true) const;
+ std::optional<llvm::APSInt>
+ getIntegerConstantExpr(const ASTContext &Ctx,
+ SourceLocation *Loc = nullptr) const;
bool isIntegerConstantExpr(const ASTContext &Ctx,
SourceLocation *Loc = nullptr) const;
@@ -555,7 +567,7 @@ public:
SmallVectorImpl<
PartialDiagnosticAt> &Diags);
- /// isPotentialConstantExprUnevaluted - Return true if this expression might
+ /// isPotentialConstantExprUnevaluated - Return true if this expression might
/// be usable in a constant expression in C++11 in an unevaluated context, if
/// it were in function FD marked constexpr. Return false if the function can
/// never produce a constant expression, along with diagnostics describing
@@ -572,16 +584,22 @@ public:
bool isConstantInitializer(ASTContext &Ctx, bool ForRef,
const Expr **Culprit = nullptr) const;
+ /// If this expression is an unambiguous reference to a single declaration,
+ /// in the style of __builtin_function_start, return that declaration. Note
+ /// that this may return a non-static member function or field in C++ if this
+ /// expression is a member pointer constant.
+ const ValueDecl *getAsBuiltinConstantDeclRef(const ASTContext &Context) const;
+
/// EvalStatus is a struct with detailed info about an evaluation in progress.
struct EvalStatus {
/// Whether the evaluated expression has side effects.
/// For example, (f() && 0) can be folded, but it still has side effects.
- bool HasSideEffects;
+ bool HasSideEffects = false;
/// Whether the evaluation hit undefined behavior.
/// For example, 1.0 / 0.0 can be folded to Inf, but has undefined behavior.
/// Likewise, INT_MAX + 1 can be folded to INT_MIN, but has UB.
- bool HasUndefinedBehavior;
+ bool HasUndefinedBehavior = false;
/// Diag - If this is non-null, it will be filled in with a stack of notes
/// indicating why evaluation failed (or why it failed to produce a constant
@@ -590,10 +608,16 @@ public:
/// foldable. If the expression is foldable, but not a constant expression,
/// the notes will describes why it isn't a constant expression. If the
/// expression *is* a constant expression, no notes will be produced.
- SmallVectorImpl<PartialDiagnosticAt> *Diag;
+ ///
+ /// FIXME: this causes significant performance concerns and should be
+ /// refactored at some point. Not all evaluations of the constant
+ /// expression interpreter will display the given diagnostics, this means
+ /// those kinds of uses are paying the expense of generating a diagnostic
+ /// (which may include expensive operations like converting APValue objects
+ /// to a string representation).
+ SmallVectorImpl<PartialDiagnosticAt> *Diag = nullptr;
- EvalStatus()
- : HasSideEffects(false), HasUndefinedBehavior(false), Diag(nullptr) {}
+ EvalStatus() = default;
// hasSideEffects - Return true if the evaluated expression has
// side effects.
@@ -648,8 +672,8 @@ public:
SideEffectsKind AllowSideEffects = SE_NoSideEffects,
bool InConstantContext = false) const;
- /// EvaluateAsFloat - Return true if this is a constant which we can fold and
- /// convert to a fixed point value.
+ /// EvaluateAsFixedPoint - Return true if this is a constant which we can fold
+ /// and convert to a fixed point value.
bool EvaluateAsFixedPoint(EvalResult &Result, const ASTContext &Ctx,
SideEffectsKind AllowSideEffects = SE_NoSideEffects,
bool InConstantContext = false) const;
@@ -697,7 +721,8 @@ public:
/// notes will be produced if the expression is not a constant expression.
bool EvaluateAsInitializer(APValue &Result, const ASTContext &Ctx,
const VarDecl *VD,
- SmallVectorImpl<PartialDiagnosticAt> &Notes) const;
+ SmallVectorImpl<PartialDiagnosticAt> &Notes,
+ bool IsConstantInitializer) const;
/// EvaluateWithSubstitution - Evaluate an expression as if from the context
/// of a call to the given function with the given arguments, inside an
@@ -739,6 +764,17 @@ public:
bool tryEvaluateObjectSize(uint64_t &Result, ASTContext &Ctx,
unsigned Type) const;
+ /// If the current Expr is a pointer, this will try to statically
+ /// determine the strlen of the string pointed to.
+ /// Returns true if all of the above holds and we were able to figure out the
+ /// strlen, false otherwise.
+ bool tryEvaluateStrLen(uint64_t &Result, ASTContext &Ctx) const;
+
+ bool EvaluateCharRangeAsString(std::string &Result,
+ const Expr *SizeExpression,
+ const Expr *PtrExpression, ASTContext &Ctx,
+ EvalResult &Status) const;
+
/// Enumeration used to describe the kind of Null pointer constant
/// returned from \c isNullPointerConstant().
enum NullPointerConstantKind {
@@ -796,7 +832,7 @@ public:
/// member expression.
static QualType findBoundMemberType(const Expr *expr);
- /// Skip past any invisble AST nodes which might surround this
+ /// Skip past any invisible AST nodes which might surround this
/// statement, such as ExprWithCleanups or ImplicitCastExpr nodes,
/// but also injected CXXMemberExpr and CXXConstructExpr which represent
/// implicit conversions.
@@ -900,7 +936,7 @@ public:
return const_cast<Expr *>(this)->IgnoreParenLValueCasts();
}
- /// Skip past any parenthese and casts which do not change the value
+ /// Skip past any parentheses and casts which do not change the value
/// (including ptr->int casts of the same size) until reaching a fixed point.
/// Skips:
/// * What IgnoreParens() skips
@@ -1014,6 +1050,9 @@ public:
}
};
+/// Describes the kind of result that can be tail-allocated.
+enum class ConstantResultStorageKind { None, Int64, APValue };
+
/// ConstantExpr - An expression that occurs in a constant context and
/// optionally the result of evaluating the expression.
class ConstantExpr final
@@ -1026,20 +1065,15 @@ class ConstantExpr final
friend class ASTStmtReader;
friend class ASTStmtWriter;
-public:
- /// Describes the kind of result that can be tail-allocated.
- enum ResultStorageKind { RSK_None, RSK_Int64, RSK_APValue };
-
-private:
size_t numTrailingObjects(OverloadToken<APValue>) const {
- return ConstantExprBits.ResultKind == ConstantExpr::RSK_APValue;
+ return getResultStorageKind() == ConstantResultStorageKind::APValue;
}
size_t numTrailingObjects(OverloadToken<uint64_t>) const {
- return ConstantExprBits.ResultKind == ConstantExpr::RSK_Int64;
+ return getResultStorageKind() == ConstantResultStorageKind::Int64;
}
uint64_t &Int64Result() {
- assert(ConstantExprBits.ResultKind == ConstantExpr::RSK_Int64 &&
+ assert(getResultStorageKind() == ConstantResultStorageKind::Int64 &&
"invalid accessor");
return *getTrailingObjects<uint64_t>();
}
@@ -1047,7 +1081,7 @@ private:
return const_cast<ConstantExpr *>(this)->Int64Result();
}
APValue &APValueResult() {
- assert(ConstantExprBits.ResultKind == ConstantExpr::RSK_APValue &&
+ assert(getResultStorageKind() == ConstantResultStorageKind::APValue &&
"invalid accessor");
return *getTrailingObjects<APValue>();
}
@@ -1055,22 +1089,23 @@ private:
return const_cast<ConstantExpr *>(this)->APValueResult();
}
- ConstantExpr(Expr *SubExpr, ResultStorageKind StorageKind,
+ ConstantExpr(Expr *SubExpr, ConstantResultStorageKind StorageKind,
bool IsImmediateInvocation);
- ConstantExpr(EmptyShell Empty, ResultStorageKind StorageKind);
+ ConstantExpr(EmptyShell Empty, ConstantResultStorageKind StorageKind);
public:
static ConstantExpr *Create(const ASTContext &Context, Expr *E,
const APValue &Result);
- static ConstantExpr *Create(const ASTContext &Context, Expr *E,
- ResultStorageKind Storage = RSK_None,
- bool IsImmediateInvocation = false);
+ static ConstantExpr *
+ Create(const ASTContext &Context, Expr *E,
+ ConstantResultStorageKind Storage = ConstantResultStorageKind::None,
+ bool IsImmediateInvocation = false);
static ConstantExpr *CreateEmpty(const ASTContext &Context,
- ResultStorageKind StorageKind);
+ ConstantResultStorageKind StorageKind);
- static ResultStorageKind getStorageKind(const APValue &Value);
- static ResultStorageKind getStorageKind(const Type *T,
- const ASTContext &Context);
+ static ConstantResultStorageKind getStorageKind(const APValue &Value);
+ static ConstantResultStorageKind getStorageKind(const Type *T,
+ const ASTContext &Context);
SourceLocation getBeginLoc() const LLVM_READONLY {
return SubExpr->getBeginLoc();
@@ -1091,8 +1126,8 @@ public:
APValue::ValueKind getResultAPValueKind() const {
return static_cast<APValue::ValueKind>(ConstantExprBits.APValueKind);
}
- ResultStorageKind getResultStorageKind() const {
- return static_cast<ResultStorageKind>(ConstantExprBits.ResultKind);
+ ConstantResultStorageKind getResultStorageKind() const {
+ return static_cast<ConstantResultStorageKind>(ConstantExprBits.ResultKind);
}
bool isImmediateInvocation() const {
return ConstantExprBits.IsImmediateInvocation;
@@ -1101,7 +1136,6 @@ public:
return ConstantExprBits.APValueKind != APValue::None;
}
APValue getAPValueResult() const;
- APValue &getResultAsAPValue() const { return APValueResult(); }
llvm::APSInt getResultAsAPSInt() const;
// Iterators
child_range children() { return child_range(&SubExpr, &SubExpr+1); }
@@ -1413,68 +1447,35 @@ public:
return DeclRefExprBits.RefersToEnclosingVariableOrCapture;
}
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == DeclRefExprClass;
+ bool isImmediateEscalating() const {
+ return DeclRefExprBits.IsImmediateEscalating;
}
- // Iterators
- child_range children() {
- return child_range(child_iterator(), child_iterator());
+ void setIsImmediateEscalating(bool Set) {
+ DeclRefExprBits.IsImmediateEscalating = Set;
}
- const_child_range children() const {
- return const_child_range(const_child_iterator(), const_child_iterator());
+ bool isCapturedByCopyInLambdaWithExplicitObjectParameter() const {
+ return DeclRefExprBits.CapturedByCopyInLambdaWithExplicitObjectParameter;
}
-};
-/// Used by IntegerLiteral/FloatingLiteral to store the numeric without
-/// leaking memory.
-///
-/// For large floats/integers, APFloat/APInt will allocate memory from the heap
-/// to represent these numbers. Unfortunately, when we use a BumpPtrAllocator
-/// to allocate IntegerLiteral/FloatingLiteral nodes the memory associated with
-/// the APFloat/APInt values will never get freed. APNumericStorage uses
-/// ASTContext's allocator for memory allocation.
-class APNumericStorage {
- union {
- uint64_t VAL; ///< Used to store the <= 64 bits integer value.
- uint64_t *pVal; ///< Used to store the >64 bits integer value.
- };
- unsigned BitWidth;
-
- bool hasAllocation() const { return llvm::APInt::getNumWords(BitWidth) > 1; }
-
- APNumericStorage(const APNumericStorage &) = delete;
- void operator=(const APNumericStorage &) = delete;
-
-protected:
- APNumericStorage() : VAL(0), BitWidth(0) { }
-
- llvm::APInt getIntValue() const {
- unsigned NumWords = llvm::APInt::getNumWords(BitWidth);
- if (NumWords > 1)
- return llvm::APInt(BitWidth, NumWords, pVal);
- else
- return llvm::APInt(BitWidth, VAL);
+ void setCapturedByCopyInLambdaWithExplicitObjectParameter(
+ bool Set, const ASTContext &Context) {
+ DeclRefExprBits.CapturedByCopyInLambdaWithExplicitObjectParameter = Set;
+ setDependence(computeDependence(this, Context));
}
- void setIntValue(const ASTContext &C, const llvm::APInt &Val);
-};
-class APIntStorage : private APNumericStorage {
-public:
- llvm::APInt getValue() const { return getIntValue(); }
- void setValue(const ASTContext &C, const llvm::APInt &Val) {
- setIntValue(C, Val);
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == DeclRefExprClass;
}
-};
-class APFloatStorage : private APNumericStorage {
-public:
- llvm::APFloat getValue(const llvm::fltSemantics &Semantics) const {
- return llvm::APFloat(Semantics, getIntValue());
+ // Iterators
+ child_range children() {
+ return child_range(child_iterator(), child_iterator());
}
- void setValue(const ASTContext &C, const llvm::APFloat &Val) {
- setIntValue(C, Val.bitcastToAPInt());
+
+ const_child_range children() const {
+ return const_child_range(const_child_iterator(), const_child_iterator());
}
};
@@ -1568,26 +1569,18 @@ class FixedPointLiteral : public Expr, public APIntStorage {
}
};
-class CharacterLiteral : public Expr {
-public:
- enum CharacterKind {
- Ascii,
- Wide,
- UTF8,
- UTF16,
- UTF32
- };
+enum class CharacterLiteralKind { Ascii, Wide, UTF8, UTF16, UTF32 };
-private:
+class CharacterLiteral : public Expr {
unsigned Value;
SourceLocation Loc;
public:
// type should be IntTy
- CharacterLiteral(unsigned value, CharacterKind kind, QualType type,
+ CharacterLiteral(unsigned value, CharacterLiteralKind kind, QualType type,
SourceLocation l)
: Expr(CharacterLiteralClass, type, VK_PRValue, OK_Ordinary),
Value(value), Loc(l) {
- CharacterLiteralBits.Kind = kind;
+ CharacterLiteralBits.Kind = llvm::to_underlying(kind);
setDependence(ExprDependence::None);
}
@@ -1595,8 +1588,8 @@ public:
CharacterLiteral(EmptyShell Empty) : Expr(CharacterLiteralClass, Empty) { }
SourceLocation getLocation() const { return Loc; }
- CharacterKind getKind() const {
- return static_cast<CharacterKind>(CharacterLiteralBits.Kind);
+ CharacterLiteralKind getKind() const {
+ return static_cast<CharacterLiteralKind>(CharacterLiteralBits.Kind);
}
SourceLocation getBeginLoc() const LLVM_READONLY { return Loc; }
@@ -1605,14 +1598,16 @@ public:
unsigned getValue() const { return Value; }
void setLocation(SourceLocation Location) { Loc = Location; }
- void setKind(CharacterKind kind) { CharacterLiteralBits.Kind = kind; }
+ void setKind(CharacterLiteralKind kind) {
+ CharacterLiteralBits.Kind = llvm::to_underlying(kind);
+ }
void setValue(unsigned Val) { Value = Val; }
static bool classof(const Stmt *T) {
return T->getStmtClass() == CharacterLiteralClass;
}
- static void print(unsigned val, CharacterKind Kind, raw_ostream &OS);
+ static void print(unsigned val, CharacterLiteralKind Kind, raw_ostream &OS);
// Iterators
child_range children() {
@@ -1734,6 +1729,15 @@ public:
}
};
+enum class StringLiteralKind {
+ Ordinary,
+ Wide,
+ UTF8,
+ UTF16,
+ UTF32,
+ Unevaluated
+};
+
/// StringLiteral - This represents a string literal expression, e.g. "foo"
/// or L"bar" (wide strings). The actual string data can be obtained with
/// getBytes() and is NOT null-terminated. The length of the string data is
@@ -1772,10 +1776,6 @@ class StringLiteral final
///
/// * An array of getByteLength() char used to store the string data.
-public:
- enum StringKind { Ascii, Wide, UTF8, UTF16, UTF32 };
-
-private:
unsigned numTrailingObjects(OverloadToken<unsigned>) const { return 1; }
unsigned numTrailingObjects(OverloadToken<SourceLocation>) const {
return getNumConcatenated();
@@ -1797,7 +1797,7 @@ private:
}
/// Build a string literal.
- StringLiteral(const ASTContext &Ctx, StringRef Str, StringKind Kind,
+ StringLiteral(const ASTContext &Ctx, StringRef Str, StringLiteralKind Kind,
bool Pascal, QualType Ty, const SourceLocation *Loc,
unsigned NumConcatenated);
@@ -1806,7 +1806,8 @@ private:
unsigned CharByteWidth);
/// Map a target and string kind to the appropriate character width.
- static unsigned mapCharByteWidth(TargetInfo const &Target, StringKind SK);
+ static unsigned mapCharByteWidth(TargetInfo const &Target,
+ StringLiteralKind SK);
/// Set one of the string literal token.
void setStrTokenLoc(unsigned TokNum, SourceLocation L) {
@@ -1818,13 +1819,13 @@ public:
/// This is the "fully general" constructor that allows representation of
/// strings formed from multiple concatenated tokens.
static StringLiteral *Create(const ASTContext &Ctx, StringRef Str,
- StringKind Kind, bool Pascal, QualType Ty,
+ StringLiteralKind Kind, bool Pascal, QualType Ty,
const SourceLocation *Loc,
unsigned NumConcatenated);
/// Simple constructor for string literals made from one token.
static StringLiteral *Create(const ASTContext &Ctx, StringRef Str,
- StringKind Kind, bool Pascal, QualType Ty,
+ StringLiteralKind Kind, bool Pascal, QualType Ty,
SourceLocation Loc) {
return Create(Ctx, Str, Kind, Pascal, Ty, &Loc, 1);
}
@@ -1835,7 +1836,7 @@ public:
unsigned CharByteWidth);
StringRef getString() const {
- assert(getCharByteWidth() == 1 &&
+ assert((isUnevaluated() || getCharByteWidth() == 1) &&
"This function is used in places that assume strings use char");
return StringRef(getStrDataAsChar(), getByteLength());
}
@@ -1866,15 +1867,16 @@ public:
unsigned getLength() const { return *getTrailingObjects<unsigned>(); }
unsigned getCharByteWidth() const { return StringLiteralBits.CharByteWidth; }
- StringKind getKind() const {
- return static_cast<StringKind>(StringLiteralBits.Kind);
+ StringLiteralKind getKind() const {
+ return static_cast<StringLiteralKind>(StringLiteralBits.Kind);
}
- bool isAscii() const { return getKind() == Ascii; }
- bool isWide() const { return getKind() == Wide; }
- bool isUTF8() const { return getKind() == UTF8; }
- bool isUTF16() const { return getKind() == UTF16; }
- bool isUTF32() const { return getKind() == UTF32; }
+ bool isOrdinary() const { return getKind() == StringLiteralKind::Ordinary; }
+ bool isWide() const { return getKind() == StringLiteralKind::Wide; }
+ bool isUTF8() const { return getKind() == StringLiteralKind::UTF8; }
+ bool isUTF16() const { return getKind() == StringLiteralKind::UTF16; }
+ bool isUTF32() const { return getKind() == StringLiteralKind::UTF32; }
+ bool isUnevaluated() const { return getKind() == StringLiteralKind::Unevaluated; }
bool isPascal() const { return StringLiteralBits.IsPascal; }
bool containsNonAscii() const {
@@ -1942,6 +1944,19 @@ public:
}
};
+enum class PredefinedIdentKind {
+ Func,
+ Function,
+ LFunction, // Same as Function, but as wide string.
+ FuncDName,
+ FuncSig,
+ LFuncSig, // Same as FuncSig, but as wide string
+ PrettyFunction,
+ /// The same as PrettyFunction, except that the
+ /// 'virtual' keyword is omitted for virtual member functions.
+ PrettyFunctionNoVirtual
+};
+
/// [C99 6.4.2.2] - A predefined identifier such as __func__.
class PredefinedExpr final
: public Expr,
@@ -1953,23 +1968,8 @@ class PredefinedExpr final
// "Stmt *" for the predefined identifier. It is present if and only if
// hasFunctionName() is true and is always a "StringLiteral *".
-public:
- enum IdentKind {
- Func,
- Function,
- LFunction, // Same as Function, but as wide string.
- FuncDName,
- FuncSig,
- LFuncSig, // Same as FuncSig, but as as wide string
- PrettyFunction,
- /// The same as PrettyFunction, except that the
- /// 'virtual' keyword is omitted for virtual member functions.
- PrettyFunctionNoVirtual
- };
-
-private:
- PredefinedExpr(SourceLocation L, QualType FNTy, IdentKind IK,
- StringLiteral *SL);
+ PredefinedExpr(SourceLocation L, QualType FNTy, PredefinedIdentKind IK,
+ bool IsTransparent, StringLiteral *SL);
explicit PredefinedExpr(EmptyShell Empty, bool HasFunctionName);
@@ -1984,17 +1984,23 @@ private:
public:
/// Create a PredefinedExpr.
+ ///
+ /// If IsTransparent, the PredefinedExpr is transparently handled as a
+ /// StringLiteral.
static PredefinedExpr *Create(const ASTContext &Ctx, SourceLocation L,
- QualType FNTy, IdentKind IK, StringLiteral *SL);
+ QualType FNTy, PredefinedIdentKind IK,
+ bool IsTransparent, StringLiteral *SL);
/// Create an empty PredefinedExpr.
static PredefinedExpr *CreateEmpty(const ASTContext &Ctx,
bool HasFunctionName);
- IdentKind getIdentKind() const {
- return static_cast<IdentKind>(PredefinedExprBits.Kind);
+ PredefinedIdentKind getIdentKind() const {
+ return static_cast<PredefinedIdentKind>(PredefinedExprBits.Kind);
}
+ bool isTransparent() const { return PredefinedExprBits.IsTransparent; }
+
SourceLocation getLocation() const { return PredefinedExprBits.Loc; }
void setLocation(SourceLocation L) { PredefinedExprBits.Loc = L; }
@@ -2010,12 +2016,13 @@ public:
: nullptr;
}
- static StringRef getIdentKindName(IdentKind IK);
+ static StringRef getIdentKindName(PredefinedIdentKind IK);
StringRef getIdentKindName() const {
return getIdentKindName(getIdentKind());
}
- static std::string ComputeName(IdentKind IK, const Decl *CurrentDecl);
+ static std::string ComputeName(PredefinedIdentKind IK,
+ const Decl *CurrentDecl);
SourceLocation getBeginLoc() const { return getLocation(); }
SourceLocation getEndLoc() const { return getLocation(); }
@@ -2210,14 +2217,14 @@ public:
bool canOverflow() const { return UnaryOperatorBits.CanOverflow; }
void setCanOverflow(bool C) { UnaryOperatorBits.CanOverflow = C; }
- // Get the FP contractability status of this operator. Only meaningful for
- // operations on floating point types.
+ /// Get the FP contractability status of this operator. Only meaningful for
+ /// operations on floating point types.
bool isFPContractableWithinStatement(const LangOptions &LO) const {
return getFPFeaturesInEffect(LO).allowFPContractWithinStatement();
}
- // Get the FENV_ACCESS status of this operator. Only meaningful for
- // operations on floating point types.
+ /// Get the FENV_ACCESS status of this operator. Only meaningful for
+ /// operations on floating point types.
bool isFEnvAccessOn(const LangOptions &LO) const {
return getFPFeaturesInEffect(LO).getAllowFEnvAccess();
}
@@ -2298,12 +2305,12 @@ public:
}
protected:
- /// Set FPFeatures in trailing storage, used only by Serialization
+ /// Set FPFeatures in trailing storage, used by Serialization & ASTImporter.
void setStoredFPFeatures(FPOptionsOverride F) { getTrailingFPFeatures() = F; }
public:
- // Get the FP features status of this operator. Only meaningful for
- // operations on floating point types.
+ /// Get the FP features status of this operator. Only meaningful for
+ /// operations on floating point types.
FPOptions getFPFeaturesInEffect(const LangOptions &LO) const {
if (UnaryOperatorBits.HasFPFeatures)
return getStoredFPFeatures().applyOverrides(LO);
@@ -2316,6 +2323,7 @@ public:
}
friend TrailingObjects;
+ friend class ASTNodeImporter;
friend class ASTReader;
friend class ASTStmtReader;
friend class ASTStmtWriter;
@@ -2375,7 +2383,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); }
@@ -2791,7 +2799,7 @@ class CallExpr : public Expr {
/// The number of arguments in the call expression.
unsigned NumArgs;
- /// The location of the right parenthese. This has a different meaning for
+ /// The location of the right parentheses. This has a different meaning for
/// the derived classes of CallExpr.
SourceLocation RParenLoc;
@@ -2997,7 +3005,7 @@ public:
/// Compute and set dependence bits.
void computeDependence() {
setDependence(clang::computeDependence(
- this, llvm::makeArrayRef(
+ this, llvm::ArrayRef(
reinterpret_cast<Expr **>(getTrailingStmts() + PREARGS_START),
getNumPreArgs())));
}
@@ -3044,14 +3052,10 @@ public:
/// interface. This provides efficient reverse iteration of the
/// subexpressions. This is currently used for CFG construction.
ArrayRef<Stmt *> getRawSubExprs() {
- return llvm::makeArrayRef(getTrailingStmts(),
- PREARGS_START + getNumPreArgs() + getNumArgs());
+ return llvm::ArrayRef(getTrailingStmts(),
+ PREARGS_START + getNumPreArgs() + getNumArgs());
}
- /// getNumCommas - Return the number of commas that must have been present in
- /// this function call.
- unsigned getNumCommas() const { return getNumArgs() ? getNumArgs() - 1 : 0; }
-
/// Get FPOptionsOverride from trailing storage.
FPOptionsOverride getStoredFPFeatures() const {
assert(hasStoredFPFeatures());
@@ -3063,8 +3067,8 @@ public:
*getTrailingFPFeatures() = F;
}
- // Get the FP features status of this operator. Only meaningful for
- // operations on floating point types.
+ /// Get the FP features status of this operator. Only meaningful for
+ /// operations on floating point types.
FPOptions getFPFeaturesInEffect(const LangOptions &LO) const {
if (hasStoredFPFeatures())
return getStoredFPFeatures().applyOverrides(LO);
@@ -3115,11 +3119,7 @@ public:
setDependence(getDependence() | ExprDependence::TypeValueInstantiation);
}
- bool isCallToStdMove() const {
- const FunctionDecl *FD = getDirectCallee();
- return getNumArgs() == 1 && FD && FD->isInStdNamespace() &&
- FD->getIdentifier() && FD->getIdentifier()->isStr("move");
- }
+ bool isCallToStdMove() const;
static bool classof(const Stmt *T) {
return T->getStmtClass() >= firstCallExprConstant &&
@@ -3484,7 +3484,6 @@ protected:
CastExprBits.BasePathSize = BasePathSize;
assert((CastExprBits.BasePathSize == BasePathSize) &&
"BasePathSize overflow!");
- setDependence(computeDependence(this));
assert(CastConsistency());
CastExprBits.HasFPFeatures = HasFPFeatures;
}
@@ -3559,8 +3558,8 @@ public:
return *getTrailingFPFeatures();
}
- // Get the FP features status of this operation. Only meaningful for
- // operations on floating point types.
+ /// Get the FP features status of this operation. Only meaningful for
+ /// operations on floating point types.
FPOptions getFPFeaturesInEffect(const LangOptions &LO) const {
if (hasStoredFPFeatures())
return getStoredFPFeatures().applyOverrides(LO);
@@ -3573,6 +3572,19 @@ public:
return FPOptionsOverride();
}
+ /// Return
+ // True : if this conversion changes the volatile-ness of a gl-value.
+ // Qualification conversions on gl-values currently use CK_NoOp, but
+ // it's important to recognize volatile-changing conversions in
+ // clients code generation that normally eagerly peephole loads. Note
+ // that the query is answering for this specific node; Sema may
+ // produce multiple cast nodes for any particular conversion sequence.
+ // False : Otherwise.
+ bool changesVolatileQualification() const {
+ return (isGLValue() && (getType().isVolatileQualified() !=
+ getSubExpr()->getType().isVolatileQualified()));
+ }
+
static const FieldDecl *getTargetFieldForToUnionCast(QualType unionType,
QualType opType);
static const FieldDecl *getTargetFieldForToUnionCast(const RecordDecl *RD,
@@ -3618,6 +3630,7 @@ class ImplicitCastExpr final
ExprValueKind VK)
: CastExpr(ImplicitCastExprClass, ty, VK, kind, op, BasePathLength,
FPO.requiresTrailingStorage()) {
+ setDependence(computeDependence(this));
if (hasStoredFPFeatures())
*getTrailingFPFeatures() = FPO;
}
@@ -3695,7 +3708,9 @@ protected:
CastKind kind, Expr *op, unsigned PathSize,
bool HasFPFeatures, TypeSourceInfo *writtenTy)
: CastExpr(SC, exprTy, VK, kind, op, PathSize, HasFPFeatures),
- TInfo(writtenTy) {}
+ TInfo(writtenTy) {
+ setDependence(computeDependence(this));
+ }
/// Construct an empty explicit cast.
ExplicitCastExpr(StmtClass SC, EmptyShell Shell, unsigned PathSize,
@@ -3954,11 +3969,12 @@ public:
return isShiftAssignOp(getOpcode());
}
- // Return true if a binary operator using the specified opcode and operands
- // would match the 'p = (i8*)nullptr + n' idiom for casting a pointer-sized
- // integer to a pointer.
+ /// Return true if a binary operator using the specified opcode and operands
+ /// would match the 'p = (i8*)nullptr + n' idiom for casting a pointer-sized
+ /// integer to a pointer.
static bool isNullPointerArithmeticExtension(ASTContext &Ctx, Opcode Opc,
- Expr *LHS, Expr *RHS);
+ const Expr *LHS,
+ const Expr *RHS);
static bool classof(const Stmt *S) {
return S->getStmtClass() >= firstBinaryOperatorConstant &&
@@ -3989,8 +4005,8 @@ public:
*getTrailingFPFeatures() = F;
}
- // Get the FP features status of this operator. Only meaningful for
- // operations on floating point types.
+ /// Get the FP features status of this operator. Only meaningful for
+ /// operations on floating point types.
FPOptions getFPFeaturesInEffect(const LangOptions &LO) const {
if (BinaryOperatorBits.HasFPFeatures)
return getStoredFPFeatures().applyOverrides(LO);
@@ -3998,20 +4014,20 @@ public:
}
// This is used in ASTImporter
- FPOptionsOverride getFPFeatures(const LangOptions &LO) const {
+ FPOptionsOverride getFPFeatures() const {
if (BinaryOperatorBits.HasFPFeatures)
return getStoredFPFeatures();
return FPOptionsOverride();
}
- // Get the FP contractability status of this operator. Only meaningful for
- // operations on floating point types.
+ /// Get the FP contractability status of this operator. Only meaningful for
+ /// operations on floating point types.
bool isFPContractableWithinStatement(const LangOptions &LO) const {
return getFPFeaturesInEffect(LO).allowFPContractWithinStatement();
}
- // Get the FENV_ACCESS status of this operator. Only meaningful for
- // operations on floating point types.
+ /// Get the FENV_ACCESS status of this operator. Only meaningful for
+ /// operations on floating point types.
bool isFEnvAccessOn(const LangOptions &LO) const {
return getFPFeaturesInEffect(LO).getAllowFEnvAccess();
}
@@ -4107,17 +4123,17 @@ protected:
: Expr(SC, Empty) { }
public:
- // getCond - Return the expression representing the condition for
- // the ?: operator.
+ /// getCond - Return the expression representing the condition for
+ /// the ?: operator.
Expr *getCond() const;
- // getTrueExpr - Return the subexpression representing the value of
- // the expression if the condition evaluates to true.
+ /// getTrueExpr - Return the subexpression representing the value of
+ /// the expression if the condition evaluates to true.
Expr *getTrueExpr() const;
- // getFalseExpr - Return the subexpression representing the value of
- // the expression if the condition evaluates to false. This is
- // the same as getRHS.
+ /// getFalseExpr - Return the subexpression representing the value of
+ /// the expression if the condition evaluates to false. This is
+ /// the same as getRHS.
Expr *getFalseExpr() const;
SourceLocation getQuestionLoc() const { return QuestionLoc; }
@@ -4152,17 +4168,17 @@ public:
explicit ConditionalOperator(EmptyShell Empty)
: AbstractConditionalOperator(ConditionalOperatorClass, Empty) { }
- // getCond - Return the expression representing the condition for
- // the ?: operator.
+ /// getCond - Return the expression representing the condition for
+ /// the ?: operator.
Expr *getCond() const { return cast<Expr>(SubExprs[COND]); }
- // getTrueExpr - Return the subexpression representing the value of
- // the expression if the condition evaluates to true.
+ /// getTrueExpr - Return the subexpression representing the value of
+ /// the expression if the condition evaluates to true.
Expr *getTrueExpr() const { return cast<Expr>(SubExprs[LHS]); }
- // getFalseExpr - Return the subexpression representing the value of
- // the expression if the condition evaluates to false. This is
- // the same as getRHS.
+ /// getFalseExpr - Return the subexpression representing the value of
+ /// the expression if the condition evaluates to false. This is
+ /// the same as getRHS.
Expr *getFalseExpr() const { return cast<Expr>(SubExprs[RHS]); }
Expr *getLHS() const { return cast<Expr>(SubExprs[LHS]); }
@@ -4666,16 +4682,26 @@ public:
}
};
+enum class SourceLocIdentKind {
+ Function,
+ FuncSig,
+ File,
+ FileName,
+ Line,
+ Column,
+ SourceLocStruct
+};
+
/// Represents a function call to one of __builtin_LINE(), __builtin_COLUMN(),
-/// __builtin_FUNCTION(), or __builtin_FILE().
+/// __builtin_FUNCTION(), __builtin_FUNCSIG(), __builtin_FILE(),
+/// __builtin_FILE_NAME() or __builtin_source_location().
class SourceLocExpr final : public Expr {
SourceLocation BuiltinLoc, RParenLoc;
DeclContext *ParentContext;
public:
- enum IdentKind { Function, File, Line, Column };
-
- SourceLocExpr(const ASTContext &Ctx, IdentKind Type, SourceLocation BLoc,
+ SourceLocExpr(const ASTContext &Ctx, SourceLocIdentKind Type,
+ QualType ResultTy, SourceLocation BLoc,
SourceLocation RParenLoc, DeclContext *Context);
/// Build an empty call expression.
@@ -4689,22 +4715,24 @@ public:
/// Return a string representing the name of the specific builtin function.
StringRef getBuiltinStr() const;
- IdentKind getIdentKind() const {
- return static_cast<IdentKind>(SourceLocExprBits.Kind);
+ SourceLocIdentKind getIdentKind() const {
+ return static_cast<SourceLocIdentKind>(SourceLocExprBits.Kind);
}
- bool isStringType() const {
+ bool isIntType() const {
switch (getIdentKind()) {
- case File:
- case Function:
- return true;
- case Line:
- case Column:
+ case SourceLocIdentKind::File:
+ case SourceLocIdentKind::FileName:
+ case SourceLocIdentKind::Function:
+ case SourceLocIdentKind::FuncSig:
+ case SourceLocIdentKind::SourceLocStruct:
return false;
+ case SourceLocIdentKind::Line:
+ case SourceLocIdentKind::Column:
+ return true;
}
llvm_unreachable("unknown source location expression kind");
}
- bool isIntType() const LLVM_READONLY { return !isStringType(); }
/// If the SourceLocExpr has been resolved return the subexpression
/// representing the resolved value. Otherwise return null.
@@ -4727,6 +4755,17 @@ public:
return T->getStmtClass() == SourceLocExprClass;
}
+ static bool MayBeDependent(SourceLocIdentKind Kind) {
+ switch (Kind) {
+ case SourceLocIdentKind::Function:
+ case SourceLocIdentKind::FuncSig:
+ case SourceLocIdentKind::SourceLocStruct:
+ return true;
+ default:
+ return false;
+ }
+ }
+
private:
friend class ASTStmtReader;
};
@@ -4816,12 +4855,10 @@ public:
return reinterpret_cast<Expr * const *>(InitExprs.data());
}
- ArrayRef<Expr *> inits() {
- return llvm::makeArrayRef(getInits(), getNumInits());
- }
+ ArrayRef<Expr *> inits() { return llvm::ArrayRef(getInits(), getNumInits()); }
ArrayRef<Expr *> inits() const {
- return llvm::makeArrayRef(getInits(), getNumInits());
+ return llvm::ArrayRef(getInits(), getNumInits());
}
const Expr *getInit(unsigned Init) const {
@@ -4884,6 +4921,13 @@ public:
/// has been set.
bool hasArrayFiller() const { return getArrayFiller(); }
+ /// Determine whether this initializer list contains a designated initializer.
+ bool hasDesignatedInit() const {
+ return std::any_of(begin(), end(), [](const Stmt *S) {
+ return isa<DesignatedInitExpr>(S);
+ });
+ }
+
/// If this initializes a union, specifies which field in the
/// union to initialize.
///
@@ -4912,8 +4956,8 @@ public:
return LBraceLoc.isValid() && RBraceLoc.isValid();
}
- // Is this an initializer for an array of characters, initialized by a string
- // literal or an @encode?
+ /// Is this an initializer for an array of characters, initialized by a string
+ /// literal or an @encode?
bool isStringLiteralInit() const;
/// Is this a transparent initializer list (that is, an InitListExpr that is
@@ -5028,6 +5072,7 @@ private:
/// Whether this designated initializer used the GNU deprecated
/// syntax rather than the C99 '=' syntax.
+ LLVM_PREFERRED_TYPE(bool)
unsigned GNUSyntax : 1;
/// The number of designators in this initializer expression.
@@ -5052,37 +5097,6 @@ private:
NumDesignators(0), NumSubExprs(NumSubExprs), Designators(nullptr) { }
public:
- /// A field designator, e.g., ".x".
- struct FieldDesignator {
- /// Refers to the field that is being initialized. The low bit
- /// of this field determines whether this is actually a pointer
- /// to an IdentifierInfo (if 1) or a FieldDecl (if 0). When
- /// initially constructed, a field designator will store an
- /// IdentifierInfo*. After semantic analysis has resolved that
- /// name, the field designator will instead store a FieldDecl*.
- uintptr_t NameOrField;
-
- /// The location of the '.' in the designated initializer.
- SourceLocation DotLoc;
-
- /// The location of the field name in the designated initializer.
- SourceLocation FieldLoc;
- };
-
- /// An array or GNU array-range designator, e.g., "[9]" or "[10..15]".
- struct ArrayOrRangeDesignator {
- /// Location of the first index expression within the designated
- /// initializer expression's list of subexpressions.
- unsigned Index;
- /// The location of the '[' starting the array range designator.
- SourceLocation LBracketLoc;
- /// The location of the ellipsis separating the start and end
- /// indices. Only valid for GNU array-range designators.
- SourceLocation EllipsisLoc;
- /// The location of the ']' terminating the array range designator.
- SourceLocation RBracketLoc;
- };
-
/// Represents a single C99 designator.
///
/// @todo This class is infuriatingly similar to clang::Designator,
@@ -5090,118 +5104,177 @@ public:
/// keep us from reusing it. Try harder, later, to rectify these
/// differences.
class Designator {
+ /// A field designator, e.g., ".x".
+ struct FieldDesignatorInfo {
+ /// Refers to the field that is being initialized. The low bit
+ /// of this field determines whether this is actually a pointer
+ /// to an IdentifierInfo (if 1) or a FieldDecl (if 0). When
+ /// initially constructed, a field designator will store an
+ /// IdentifierInfo*. After semantic analysis has resolved that
+ /// name, the field designator will instead store a FieldDecl*.
+ uintptr_t NameOrField;
+
+ /// The location of the '.' in the designated initializer.
+ SourceLocation DotLoc;
+
+ /// The location of the field name in the designated initializer.
+ SourceLocation FieldLoc;
+
+ FieldDesignatorInfo(const IdentifierInfo *II, SourceLocation DotLoc,
+ SourceLocation FieldLoc)
+ : NameOrField(reinterpret_cast<uintptr_t>(II) | 0x1), DotLoc(DotLoc),
+ FieldLoc(FieldLoc) {}
+ };
+
+ /// An array or GNU array-range designator, e.g., "[9]" or "[10...15]".
+ struct ArrayOrRangeDesignatorInfo {
+ /// Location of the first index expression within the designated
+ /// initializer expression's list of subexpressions.
+ unsigned Index;
+
+ /// The location of the '[' starting the array range designator.
+ SourceLocation LBracketLoc;
+
+ /// The location of the ellipsis separating the start and end
+ /// indices. Only valid for GNU array-range designators.
+ SourceLocation EllipsisLoc;
+
+ /// The location of the ']' terminating the array range designator.
+ SourceLocation RBracketLoc;
+
+ ArrayOrRangeDesignatorInfo(unsigned Index, SourceLocation LBracketLoc,
+ SourceLocation RBracketLoc)
+ : Index(Index), LBracketLoc(LBracketLoc), RBracketLoc(RBracketLoc) {}
+
+ ArrayOrRangeDesignatorInfo(unsigned Index,
+ SourceLocation LBracketLoc,
+ SourceLocation EllipsisLoc,
+ SourceLocation RBracketLoc)
+ : Index(Index), LBracketLoc(LBracketLoc), EllipsisLoc(EllipsisLoc),
+ RBracketLoc(RBracketLoc) {}
+ };
+
/// The kind of designator this describes.
- enum {
+ enum DesignatorKind {
FieldDesignator,
ArrayDesignator,
ArrayRangeDesignator
- } Kind;
+ };
+
+ DesignatorKind Kind;
union {
/// A field designator, e.g., ".x".
- struct FieldDesignator Field;
+ struct FieldDesignatorInfo FieldInfo;
+
/// An array or GNU array-range designator, e.g., "[9]" or "[10..15]".
- struct ArrayOrRangeDesignator ArrayOrRange;
+ struct ArrayOrRangeDesignatorInfo ArrayOrRangeInfo;
};
- friend class DesignatedInitExpr;
+
+ Designator(DesignatorKind Kind) : Kind(Kind) {}
public:
Designator() {}
- /// Initializes a field designator.
- Designator(const IdentifierInfo *FieldName, SourceLocation DotLoc,
- SourceLocation FieldLoc)
- : Kind(FieldDesignator) {
- new (&Field) DesignatedInitExpr::FieldDesignator;
- Field.NameOrField = reinterpret_cast<uintptr_t>(FieldName) | 0x01;
- Field.DotLoc = DotLoc;
- Field.FieldLoc = FieldLoc;
- }
-
- /// Initializes an array designator.
- Designator(unsigned Index, SourceLocation LBracketLoc,
- SourceLocation RBracketLoc)
- : Kind(ArrayDesignator) {
- new (&ArrayOrRange) DesignatedInitExpr::ArrayOrRangeDesignator;
- ArrayOrRange.Index = Index;
- ArrayOrRange.LBracketLoc = LBracketLoc;
- ArrayOrRange.EllipsisLoc = SourceLocation();
- ArrayOrRange.RBracketLoc = RBracketLoc;
- }
-
- /// Initializes a GNU array-range designator.
- Designator(unsigned Index, SourceLocation LBracketLoc,
- SourceLocation EllipsisLoc, SourceLocation RBracketLoc)
- : Kind(ArrayRangeDesignator) {
- new (&ArrayOrRange) DesignatedInitExpr::ArrayOrRangeDesignator;
- ArrayOrRange.Index = Index;
- ArrayOrRange.LBracketLoc = LBracketLoc;
- ArrayOrRange.EllipsisLoc = EllipsisLoc;
- ArrayOrRange.RBracketLoc = RBracketLoc;
- }
-
bool isFieldDesignator() const { return Kind == FieldDesignator; }
bool isArrayDesignator() const { return Kind == ArrayDesignator; }
bool isArrayRangeDesignator() const { return Kind == ArrayRangeDesignator; }
- IdentifierInfo *getFieldName() const;
+ //===------------------------------------------------------------------===//
+ // FieldDesignatorInfo
+
+ /// Creates a field designator.
+ static Designator CreateFieldDesignator(const IdentifierInfo *FieldName,
+ SourceLocation DotLoc,
+ SourceLocation FieldLoc) {
+ Designator D(FieldDesignator);
+ new (&D.FieldInfo) FieldDesignatorInfo(FieldName, DotLoc, FieldLoc);
+ return D;
+ }
- FieldDecl *getField() const {
- assert(Kind == FieldDesignator && "Only valid on a field designator");
- if (Field.NameOrField & 0x01)
+ const IdentifierInfo *getFieldName() const;
+
+ FieldDecl *getFieldDecl() const {
+ assert(isFieldDesignator() && "Only valid on a field designator");
+ if (FieldInfo.NameOrField & 0x01)
return nullptr;
- else
- return reinterpret_cast<FieldDecl *>(Field.NameOrField);
+ return reinterpret_cast<FieldDecl *>(FieldInfo.NameOrField);
}
- void setField(FieldDecl *FD) {
- assert(Kind == FieldDesignator && "Only valid on a field designator");
- Field.NameOrField = reinterpret_cast<uintptr_t>(FD);
+ void setFieldDecl(FieldDecl *FD) {
+ assert(isFieldDesignator() && "Only valid on a field designator");
+ FieldInfo.NameOrField = reinterpret_cast<uintptr_t>(FD);
}
SourceLocation getDotLoc() const {
- assert(Kind == FieldDesignator && "Only valid on a field designator");
- return Field.DotLoc;
+ assert(isFieldDesignator() && "Only valid on a field designator");
+ return FieldInfo.DotLoc;
}
SourceLocation getFieldLoc() const {
- assert(Kind == FieldDesignator && "Only valid on a field designator");
- return Field.FieldLoc;
+ assert(isFieldDesignator() && "Only valid on a field designator");
+ return FieldInfo.FieldLoc;
}
- SourceLocation getLBracketLoc() const {
- assert((Kind == ArrayDesignator || Kind == ArrayRangeDesignator) &&
+ //===------------------------------------------------------------------===//
+ // ArrayOrRangeDesignator
+
+ /// Creates an array designator.
+ static Designator CreateArrayDesignator(unsigned Index,
+ SourceLocation LBracketLoc,
+ SourceLocation RBracketLoc) {
+ Designator D(ArrayDesignator);
+ new (&D.ArrayOrRangeInfo) ArrayOrRangeDesignatorInfo(Index, LBracketLoc,
+ RBracketLoc);
+ return D;
+ }
+
+ /// Creates a GNU array-range designator.
+ static Designator CreateArrayRangeDesignator(unsigned Index,
+ SourceLocation LBracketLoc,
+ SourceLocation EllipsisLoc,
+ SourceLocation RBracketLoc) {
+ Designator D(ArrayRangeDesignator);
+ new (&D.ArrayOrRangeInfo) ArrayOrRangeDesignatorInfo(Index, LBracketLoc,
+ EllipsisLoc,
+ RBracketLoc);
+ return D;
+ }
+
+ unsigned getArrayIndex() const {
+ assert((isArrayDesignator() || isArrayRangeDesignator()) &&
"Only valid on an array or array-range designator");
- return ArrayOrRange.LBracketLoc;
+ return ArrayOrRangeInfo.Index;
}
- SourceLocation getRBracketLoc() const {
- assert((Kind == ArrayDesignator || Kind == ArrayRangeDesignator) &&
+ SourceLocation getLBracketLoc() const {
+ assert((isArrayDesignator() || isArrayRangeDesignator()) &&
"Only valid on an array or array-range designator");
- return ArrayOrRange.RBracketLoc;
+ return ArrayOrRangeInfo.LBracketLoc;
}
SourceLocation getEllipsisLoc() const {
- assert(Kind == ArrayRangeDesignator &&
+ assert(isArrayRangeDesignator() &&
"Only valid on an array-range designator");
- return ArrayOrRange.EllipsisLoc;
+ return ArrayOrRangeInfo.EllipsisLoc;
}
- unsigned getFirstExprIndex() const {
- assert((Kind == ArrayDesignator || Kind == ArrayRangeDesignator) &&
+ SourceLocation getRBracketLoc() const {
+ assert((isArrayDesignator() || isArrayRangeDesignator()) &&
"Only valid on an array or array-range designator");
- return ArrayOrRange.Index;
+ return ArrayOrRangeInfo.RBracketLoc;
}
SourceLocation getBeginLoc() const LLVM_READONLY {
- if (Kind == FieldDesignator)
- return getDotLoc().isInvalid()? getFieldLoc() : getDotLoc();
- else
- return getLBracketLoc();
+ if (isFieldDesignator())
+ return getDotLoc().isInvalid() ? getFieldLoc() : getDotLoc();
+ return getLBracketLoc();
}
+
SourceLocation getEndLoc() const LLVM_READONLY {
- return Kind == FieldDesignator ? getFieldLoc() : getRBracketLoc();
+ return isFieldDesignator() ? getFieldLoc() : getRBracketLoc();
}
+
SourceRange getSourceRange() const LLVM_READONLY {
return SourceRange(getBeginLoc(), getEndLoc());
}
@@ -5563,9 +5636,7 @@ public:
return reinterpret_cast<Expr **>(getTrailingObjects<Stmt *>());
}
- ArrayRef<Expr *> exprs() {
- return llvm::makeArrayRef(getExprs(), getNumExprs());
- }
+ ArrayRef<Expr *> exprs() { return llvm::ArrayRef(getExprs(), getNumExprs()); }
SourceLocation getLParenLoc() const { return LParenLoc; }
SourceLocation getRParenLoc() const { return RParenLoc; }
@@ -5613,6 +5684,12 @@ public:
/// which names a dependent type in its association list is result-dependent,
/// which means that the choice of result expression is dependent.
/// Result-dependent generic associations are both type- and value-dependent.
+///
+/// We also allow an extended form in both C and C++ where the controlling
+/// predicate for the selection expression is a type rather than an expression.
+/// This type argument form does not perform any conversions for the
+/// controlling type, which makes it suitable for use with qualified type
+/// associations, which is not possible with the expression form.
class GenericSelectionExpr final
: public Expr,
private llvm::TrailingObjects<GenericSelectionExpr, Stmt *,
@@ -5625,31 +5702,68 @@ class GenericSelectionExpr final
/// expression in the case where the generic selection expression is not
/// result-dependent. The result index is equal to ResultDependentIndex
/// if and only if the generic selection expression is result-dependent.
- unsigned NumAssocs, ResultIndex;
+ unsigned NumAssocs : 15;
+ unsigned ResultIndex : 15; // NB: ResultDependentIndex is tied to this width.
+ LLVM_PREFERRED_TYPE(bool)
+ unsigned IsExprPredicate : 1;
enum : unsigned {
- ResultDependentIndex = std::numeric_limits<unsigned>::max(),
- ControllingIndex = 0,
- AssocExprStartIndex = 1
+ ResultDependentIndex = 0x7FFF
};
+ unsigned getIndexOfControllingExpression() const {
+ // If controlled by an expression, the first offset into the Stmt *
+ // trailing array is the controlling expression, the associated expressions
+ // follow this.
+ assert(isExprPredicate() && "Asking for the controlling expression of a "
+ "selection expr predicated by a type");
+ return 0;
+ }
+
+ unsigned getIndexOfControllingType() const {
+ // If controlled by a type, the first offset into the TypeSourceInfo *
+ // trailing array is the controlling type, the associated types follow this.
+ assert(isTypePredicate() && "Asking for the controlling type of a "
+ "selection expr predicated by an expression");
+ return 0;
+ }
+
+ unsigned getIndexOfStartOfAssociatedExprs() const {
+ // If the predicate is a type, then the associated expressions are the only
+ // Stmt * in the trailing array, otherwise we need to offset past the
+ // predicate expression.
+ return (int)isExprPredicate();
+ }
+
+ unsigned getIndexOfStartOfAssociatedTypes() const {
+ // If the predicate is a type, then the associated types follow it in the
+ // trailing array. Otherwise, the associated types are the only
+ // TypeSourceInfo * in the trailing array.
+ return (int)isTypePredicate();
+ }
+
+
/// The location of the "default" and of the right parenthesis.
SourceLocation DefaultLoc, RParenLoc;
// GenericSelectionExpr is followed by several trailing objects.
// They are (in order):
//
- // * A single Stmt * for the controlling expression.
+ // * A single Stmt * for the controlling expression or a TypeSourceInfo * for
+ // the controlling type, depending on the result of isTypePredicate() or
+ // isExprPredicate().
// * An array of getNumAssocs() Stmt * for the association expressions.
// * An array of getNumAssocs() TypeSourceInfo *, one for each of the
// association expressions.
unsigned numTrailingObjects(OverloadToken<Stmt *>) const {
// Add one to account for the controlling expression; the remainder
// are the associated expressions.
- return 1 + getNumAssocs();
+ return getNumAssocs() + (int)isExprPredicate();
}
unsigned numTrailingObjects(OverloadToken<TypeSourceInfo *>) const {
- return getNumAssocs();
+ // Add one to account for the controlling type predicate, the remainder
+ // are the associated types.
+ return getNumAssocs() + (int)isTypePredicate();
}
template <bool Const> class AssociationIteratorTy;
@@ -5730,7 +5844,8 @@ class GenericSelectionExpr final
bool operator==(AssociationIteratorTy Other) const { return E == Other.E; }
}; // class AssociationIterator
- /// Build a non-result-dependent generic selection expression.
+ /// Build a non-result-dependent generic selection expression accepting an
+ /// expression predicate.
GenericSelectionExpr(const ASTContext &Context, SourceLocation GenericLoc,
Expr *ControllingExpr,
ArrayRef<TypeSourceInfo *> AssocTypes,
@@ -5739,7 +5854,8 @@ class GenericSelectionExpr final
bool ContainsUnexpandedParameterPack,
unsigned ResultIndex);
- /// Build a result-dependent generic selection expression.
+ /// Build a result-dependent generic selection expression accepting an
+ /// expression predicate.
GenericSelectionExpr(const ASTContext &Context, SourceLocation GenericLoc,
Expr *ControllingExpr,
ArrayRef<TypeSourceInfo *> AssocTypes,
@@ -5747,11 +5863,31 @@ class GenericSelectionExpr final
SourceLocation RParenLoc,
bool ContainsUnexpandedParameterPack);
+ /// Build a non-result-dependent generic selection expression accepting a
+ /// type predicate.
+ GenericSelectionExpr(const ASTContext &Context, SourceLocation GenericLoc,
+ TypeSourceInfo *ControllingType,
+ ArrayRef<TypeSourceInfo *> AssocTypes,
+ ArrayRef<Expr *> AssocExprs, SourceLocation DefaultLoc,
+ SourceLocation RParenLoc,
+ bool ContainsUnexpandedParameterPack,
+ unsigned ResultIndex);
+
+ /// Build a result-dependent generic selection expression accepting a type
+ /// predicate.
+ GenericSelectionExpr(const ASTContext &Context, SourceLocation GenericLoc,
+ TypeSourceInfo *ControllingType,
+ ArrayRef<TypeSourceInfo *> AssocTypes,
+ ArrayRef<Expr *> AssocExprs, SourceLocation DefaultLoc,
+ SourceLocation RParenLoc,
+ bool ContainsUnexpandedParameterPack);
+
/// Build an empty generic selection expression for deserialization.
explicit GenericSelectionExpr(EmptyShell Empty, unsigned NumAssocs);
public:
- /// Create a non-result-dependent generic selection expression.
+ /// Create a non-result-dependent generic selection expression accepting an
+ /// expression predicate.
static GenericSelectionExpr *
Create(const ASTContext &Context, SourceLocation GenericLoc,
Expr *ControllingExpr, ArrayRef<TypeSourceInfo *> AssocTypes,
@@ -5759,13 +5895,31 @@ public:
SourceLocation RParenLoc, bool ContainsUnexpandedParameterPack,
unsigned ResultIndex);
- /// Create a result-dependent generic selection expression.
+ /// Create a result-dependent generic selection expression accepting an
+ /// expression predicate.
static GenericSelectionExpr *
Create(const ASTContext &Context, SourceLocation GenericLoc,
Expr *ControllingExpr, ArrayRef<TypeSourceInfo *> AssocTypes,
ArrayRef<Expr *> AssocExprs, SourceLocation DefaultLoc,
SourceLocation RParenLoc, bool ContainsUnexpandedParameterPack);
+ /// Create a non-result-dependent generic selection expression accepting a
+ /// type predicate.
+ static GenericSelectionExpr *
+ Create(const ASTContext &Context, SourceLocation GenericLoc,
+ TypeSourceInfo *ControllingType, ArrayRef<TypeSourceInfo *> AssocTypes,
+ ArrayRef<Expr *> AssocExprs, SourceLocation DefaultLoc,
+ SourceLocation RParenLoc, bool ContainsUnexpandedParameterPack,
+ unsigned ResultIndex);
+
+ /// Create a result-dependent generic selection expression accepting a type
+ /// predicate
+ static GenericSelectionExpr *
+ Create(const ASTContext &Context, SourceLocation GenericLoc,
+ TypeSourceInfo *ControllingType, ArrayRef<TypeSourceInfo *> AssocTypes,
+ ArrayRef<Expr *> AssocExprs, SourceLocation DefaultLoc,
+ SourceLocation RParenLoc, bool ContainsUnexpandedParameterPack);
+
/// Create an empty generic selection expression for deserialization.
static GenericSelectionExpr *CreateEmpty(const ASTContext &Context,
unsigned NumAssocs);
@@ -5793,32 +5947,56 @@ public:
/// Whether this generic selection is result-dependent.
bool isResultDependent() const { return ResultIndex == ResultDependentIndex; }
+ /// Whether this generic selection uses an expression as its controlling
+ /// argument.
+ bool isExprPredicate() const { return IsExprPredicate; }
+ /// Whether this generic selection uses a type as its controlling argument.
+ bool isTypePredicate() const { return !IsExprPredicate; }
+
/// Return the controlling expression of this generic selection expression.
+ /// Only valid to call if the selection expression used an expression as its
+ /// controlling argument.
Expr *getControllingExpr() {
- return cast<Expr>(getTrailingObjects<Stmt *>()[ControllingIndex]);
+ return cast<Expr>(
+ getTrailingObjects<Stmt *>()[getIndexOfControllingExpression()]);
}
const Expr *getControllingExpr() const {
- return cast<Expr>(getTrailingObjects<Stmt *>()[ControllingIndex]);
+ return cast<Expr>(
+ getTrailingObjects<Stmt *>()[getIndexOfControllingExpression()]);
+ }
+
+ /// Return the controlling type of this generic selection expression. Only
+ /// valid to call if the selection expression used a type as its controlling
+ /// argument.
+ TypeSourceInfo *getControllingType() {
+ return getTrailingObjects<TypeSourceInfo *>()[getIndexOfControllingType()];
+ }
+ const TypeSourceInfo* getControllingType() const {
+ return getTrailingObjects<TypeSourceInfo *>()[getIndexOfControllingType()];
}
/// Return the result expression of this controlling expression. Defined if
/// and only if the generic selection expression is not result-dependent.
Expr *getResultExpr() {
return cast<Expr>(
- getTrailingObjects<Stmt *>()[AssocExprStartIndex + getResultIndex()]);
+ getTrailingObjects<Stmt *>()[getIndexOfStartOfAssociatedExprs() +
+ getResultIndex()]);
}
const Expr *getResultExpr() const {
return cast<Expr>(
- getTrailingObjects<Stmt *>()[AssocExprStartIndex + getResultIndex()]);
+ getTrailingObjects<Stmt *>()[getIndexOfStartOfAssociatedExprs() +
+ getResultIndex()]);
}
ArrayRef<Expr *> getAssocExprs() const {
return {reinterpret_cast<Expr *const *>(getTrailingObjects<Stmt *>() +
- AssocExprStartIndex),
+ getIndexOfStartOfAssociatedExprs()),
NumAssocs};
}
ArrayRef<TypeSourceInfo *> getAssocTypeSourceInfos() const {
- return {getTrailingObjects<TypeSourceInfo *>(), NumAssocs};
+ return {getTrailingObjects<TypeSourceInfo *>() +
+ getIndexOfStartOfAssociatedTypes(),
+ NumAssocs};
}
/// Return the Ith association expression with its TypeSourceInfo,
@@ -5827,23 +6005,30 @@ public:
assert(I < getNumAssocs() &&
"Out-of-range index in GenericSelectionExpr::getAssociation!");
return Association(
- cast<Expr>(getTrailingObjects<Stmt *>()[AssocExprStartIndex + I]),
- getTrailingObjects<TypeSourceInfo *>()[I],
+ cast<Expr>(
+ getTrailingObjects<Stmt *>()[getIndexOfStartOfAssociatedExprs() +
+ I]),
+ getTrailingObjects<
+ TypeSourceInfo *>()[getIndexOfStartOfAssociatedTypes() + I],
!isResultDependent() && (getResultIndex() == I));
}
ConstAssociation getAssociation(unsigned I) const {
assert(I < getNumAssocs() &&
"Out-of-range index in GenericSelectionExpr::getAssociation!");
return ConstAssociation(
- cast<Expr>(getTrailingObjects<Stmt *>()[AssocExprStartIndex + I]),
- getTrailingObjects<TypeSourceInfo *>()[I],
+ cast<Expr>(
+ getTrailingObjects<Stmt *>()[getIndexOfStartOfAssociatedExprs() +
+ I]),
+ getTrailingObjects<
+ TypeSourceInfo *>()[getIndexOfStartOfAssociatedTypes() + I],
!isResultDependent() && (getResultIndex() == I));
}
association_range associations() {
AssociationIterator Begin(getTrailingObjects<Stmt *>() +
- AssocExprStartIndex,
- getTrailingObjects<TypeSourceInfo *>(),
+ getIndexOfStartOfAssociatedExprs(),
+ getTrailingObjects<TypeSourceInfo *>() +
+ getIndexOfStartOfAssociatedTypes(),
/*Offset=*/0, ResultIndex);
AssociationIterator End(Begin.E + NumAssocs, Begin.TSI + NumAssocs,
/*Offset=*/NumAssocs, ResultIndex);
@@ -5852,8 +6037,9 @@ public:
const_association_range associations() const {
ConstAssociationIterator Begin(getTrailingObjects<Stmt *>() +
- AssocExprStartIndex,
- getTrailingObjects<TypeSourceInfo *>(),
+ getIndexOfStartOfAssociatedExprs(),
+ getTrailingObjects<TypeSourceInfo *>() +
+ getIndexOfStartOfAssociatedTypes(),
/*Offset=*/0, ResultIndex);
ConstAssociationIterator End(Begin.E + NumAssocs, Begin.TSI + NumAssocs,
/*Offset=*/NumAssocs, ResultIndex);
@@ -6166,11 +6352,11 @@ public:
return getSubExprsBuffer() + getNumSubExprs();
}
- llvm::iterator_range<semantics_iterator> semantics() {
- return llvm::make_range(semantics_begin(), semantics_end());
+ ArrayRef<Expr*> semantics() {
+ return ArrayRef(semantics_begin(), semantics_end());
}
- llvm::iterator_range<const_semantics_iterator> semantics() const {
- return llvm::make_range(semantics_begin(), semantics_end());
+ ArrayRef<const Expr*> semantics() const {
+ return ArrayRef(semantics_begin(), semantics_end());
}
Expr *getSemanticExpr(unsigned index) {
@@ -6272,7 +6458,7 @@ public:
return cast<Expr>(SubExprs[ORDER_FAIL]);
}
Expr *getVal2() const {
- if (Op == AO__atomic_exchange)
+ if (Op == AO__atomic_exchange || Op == AO__scoped_atomic_exchange)
return cast<Expr>(SubExprs[ORDER_FAIL]);
assert(NumSubExprs > VAL2);
return cast<Expr>(SubExprs[VAL2]);
@@ -6284,6 +6470,16 @@ public:
QualType getValueType() const;
AtomicOp getOp() const { return Op; }
+ StringRef getOpAsString() const {
+ switch (Op) {
+#define BUILTIN(ID, TYPE, ATTRS)
+#define ATOMIC_BUILTIN(ID, TYPE, ATTRS) \
+ case AO##ID: \
+ return #ID;
+#include "clang/Basic/Builtins.def"
+ }
+ llvm_unreachable("not an atomic operator?");
+ }
unsigned getNumSubExprs() const { return NumSubExprs; }
Expr **getSubExprs() { return reinterpret_cast<Expr **>(SubExprs); }
@@ -6298,10 +6494,14 @@ public:
bool isCmpXChg() const {
return getOp() == AO__c11_atomic_compare_exchange_strong ||
getOp() == AO__c11_atomic_compare_exchange_weak ||
+ getOp() == AO__hip_atomic_compare_exchange_strong ||
getOp() == AO__opencl_atomic_compare_exchange_strong ||
getOp() == AO__opencl_atomic_compare_exchange_weak ||
+ getOp() == AO__hip_atomic_compare_exchange_weak ||
getOp() == AO__atomic_compare_exchange ||
- getOp() == AO__atomic_compare_exchange_n;
+ getOp() == AO__atomic_compare_exchange_n ||
+ getOp() == AO__scoped_atomic_compare_exchange ||
+ getOp() == AO__scoped_atomic_compare_exchange_n;
}
bool isOpenCL() const {
@@ -6331,11 +6531,13 @@ public:
/// \return empty atomic scope model if the atomic op code does not have
/// scope operand.
static std::unique_ptr<AtomicScopeModel> getScopeModel(AtomicOp Op) {
- auto Kind =
- (Op >= AO__opencl_atomic_load && Op <= AO__opencl_atomic_fetch_max)
- ? AtomicScopeModelKind::OpenCL
- : AtomicScopeModelKind::None;
- return AtomicScopeModel::create(Kind);
+ if (Op >= AO__opencl_atomic_load && Op <= AO__opencl_atomic_fetch_max)
+ return AtomicScopeModel::create(AtomicScopeModelKind::OpenCL);
+ else if (Op >= AO__hip_atomic_load && Op <= AO__hip_atomic_fetch_max)
+ return AtomicScopeModel::create(AtomicScopeModelKind::HIP);
+ else if (Op >= AO__scoped_atomic_load && Op <= AO__scoped_atomic_fetch_max)
+ return AtomicScopeModel::create(AtomicScopeModelKind::Generic);
+ return AtomicScopeModel::create(AtomicScopeModelKind::None);
}
/// Get atomic scope model.
@@ -6412,7 +6614,7 @@ public:
ArrayRef<Expr *> subExpressions() {
auto *B = getTrailingObjects<Expr *>();
- return llvm::makeArrayRef(B, B + NumExprs);
+ return llvm::ArrayRef(B, B + NumExprs);
}
ArrayRef<const Expr *> subExpressions() const {
diff --git a/contrib/llvm-project/clang/include/clang/AST/ExprCXX.h b/contrib/llvm-project/clang/include/clang/AST/ExprCXX.h
index 161287adce4c..9a7c632c36c5 100644
--- a/contrib/llvm-project/clang/include/clang/AST/ExprCXX.h
+++ b/contrib/llvm-project/clang/include/clang/AST/ExprCXX.h
@@ -40,8 +40,6 @@
#include "clang/Basic/Specifiers.h"
#include "clang/Basic/TypeTraits.h"
#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/None.h"
-#include "llvm/ADT/Optional.h"
#include "llvm/ADT/PointerUnion.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/iterator_range.h"
@@ -52,6 +50,7 @@
#include <cstddef>
#include <cstdint>
#include <memory>
+#include <optional>
namespace clang {
@@ -730,6 +729,11 @@ public:
explicit CXXBoolLiteralExpr(EmptyShell Empty)
: Expr(CXXBoolLiteralExprClass, Empty) {}
+ static CXXBoolLiteralExpr *Create(const ASTContext &C, bool Val, QualType Ty,
+ SourceLocation Loc) {
+ return new (C) CXXBoolLiteralExpr(Val, Ty, Loc);
+ }
+
bool getValue() const { return CXXBoolLiteralExprBits.Value; }
void setValue(bool V) { CXXBoolLiteralExprBits.Value = V; }
@@ -756,6 +760,8 @@ public:
/// The null pointer literal (C++11 [lex.nullptr])
///
/// Introduced in C++11, the only literal of type \c nullptr_t is \c nullptr.
+/// This also implements the null pointer literal in C23 (C23 6.4.1) which is
+/// intended to have the same semantics as the feature in C++.
class CXXNullPtrLiteralExpr : public Expr {
public:
CXXNullPtrLiteralExpr(QualType Ty, SourceLocation Loc)
@@ -1140,9 +1146,8 @@ public:
/// };
/// \endcode
class CXXThisExpr : public Expr {
-public:
- CXXThisExpr(SourceLocation L, QualType Ty, bool IsImplicit)
- : Expr(CXXThisExprClass, Ty, VK_PRValue, OK_Ordinary) {
+ CXXThisExpr(SourceLocation L, QualType Ty, bool IsImplicit, ExprValueKind VK)
+ : Expr(CXXThisExprClass, Ty, VK, OK_Ordinary) {
CXXThisExprBits.IsImplicit = IsImplicit;
CXXThisExprBits.Loc = L;
setDependence(computeDependence(this));
@@ -1150,6 +1155,12 @@ public:
CXXThisExpr(EmptyShell Empty) : Expr(CXXThisExprClass, Empty) {}
+public:
+ static CXXThisExpr *Create(const ASTContext &Ctx, SourceLocation L,
+ QualType Ty, bool IsImplicit);
+
+ static CXXThisExpr *CreateEmpty(const ASTContext &Ctx);
+
SourceLocation getLocation() const { return CXXThisExprBits.Loc; }
void setLocation(SourceLocation L) { CXXThisExprBits.Loc = L; }
@@ -1238,8 +1249,12 @@ public:
/// This wraps up a function call argument that was created from the
/// corresponding parameter's default argument, when the call did not
/// explicitly supply arguments for all of the parameters.
-class CXXDefaultArgExpr final : public Expr {
+class CXXDefaultArgExpr final
+ : public Expr,
+ private llvm::TrailingObjects<CXXDefaultArgExpr, Expr *> {
friend class ASTStmtReader;
+ friend class ASTReader;
+ friend TrailingObjects;
/// The parameter whose default is being used.
ParmVarDecl *Param;
@@ -1248,7 +1263,7 @@ class CXXDefaultArgExpr final : public Expr {
DeclContext *UsedContext;
CXXDefaultArgExpr(StmtClass SC, SourceLocation Loc, ParmVarDecl *Param,
- DeclContext *UsedContext)
+ Expr *RewrittenExpr, DeclContext *UsedContext)
: Expr(SC,
Param->hasUnparsedDefaultArg()
? Param->getType().getNonReferenceType()
@@ -1257,28 +1272,54 @@ class CXXDefaultArgExpr final : public Expr {
Param->getDefaultArg()->getObjectKind()),
Param(Param), UsedContext(UsedContext) {
CXXDefaultArgExprBits.Loc = Loc;
+ CXXDefaultArgExprBits.HasRewrittenInit = RewrittenExpr != nullptr;
+ if (RewrittenExpr)
+ *getTrailingObjects<Expr *>() = RewrittenExpr;
setDependence(computeDependence(this));
}
+ CXXDefaultArgExpr(EmptyShell Empty, bool HasRewrittenInit)
+ : Expr(CXXDefaultArgExprClass, Empty) {
+ CXXDefaultArgExprBits.HasRewrittenInit = HasRewrittenInit;
+ }
+
public:
- CXXDefaultArgExpr(EmptyShell Empty) : Expr(CXXDefaultArgExprClass, Empty) {}
+ static CXXDefaultArgExpr *CreateEmpty(const ASTContext &C,
+ bool HasRewrittenInit);
// \p Param is the parameter whose default argument is used by this
// expression.
static CXXDefaultArgExpr *Create(const ASTContext &C, SourceLocation Loc,
- ParmVarDecl *Param,
- DeclContext *UsedContext) {
- return new (C)
- CXXDefaultArgExpr(CXXDefaultArgExprClass, Loc, Param, UsedContext);
- }
-
+ ParmVarDecl *Param, Expr *RewrittenExpr,
+ DeclContext *UsedContext);
// Retrieve the parameter that the argument was created from.
const ParmVarDecl *getParam() const { return Param; }
ParmVarDecl *getParam() { return Param; }
- // Retrieve the actual argument to the function call.
- const Expr *getExpr() const { return getParam()->getDefaultArg(); }
- Expr *getExpr() { return getParam()->getDefaultArg(); }
+ bool hasRewrittenInit() const {
+ return CXXDefaultArgExprBits.HasRewrittenInit;
+ }
+
+ // Retrieve the argument to the function call.
+ Expr *getExpr();
+ const Expr *getExpr() const {
+ return const_cast<CXXDefaultArgExpr *>(this)->getExpr();
+ }
+
+ Expr *getRewrittenExpr() {
+ return hasRewrittenInit() ? *getTrailingObjects<Expr *>() : nullptr;
+ }
+
+ const Expr *getRewrittenExpr() const {
+ return const_cast<CXXDefaultArgExpr *>(this)->getRewrittenExpr();
+ }
+
+ // Retrieve the rewritten init expression (for an init expression containing
+ // immediate calls) with the top level FullExpr and ConstantExpr stripped off.
+ Expr *getAdjustedRewrittenExpr();
+ const Expr *getAdjustedRewrittenExpr() const {
+ return const_cast<CXXDefaultArgExpr *>(this)->getAdjustedRewrittenExpr();
+ }
const DeclContext *getUsedContext() const { return UsedContext; }
DeclContext *getUsedContext() { return UsedContext; }
@@ -1315,10 +1356,13 @@ public:
/// is implicitly used in a mem-initializer-list in a constructor
/// (C++11 [class.base.init]p8) or in aggregate initialization
/// (C++1y [dcl.init.aggr]p7).
-class CXXDefaultInitExpr : public Expr {
- friend class ASTReader;
- friend class ASTStmtReader;
+class CXXDefaultInitExpr final
+ : public Expr,
+ private llvm::TrailingObjects<CXXDefaultInitExpr, Expr *> {
+ friend class ASTStmtReader;
+ friend class ASTReader;
+ friend TrailingObjects;
/// The field whose default is being used.
FieldDecl *Field;
@@ -1326,16 +1370,25 @@ class CXXDefaultInitExpr : public Expr {
DeclContext *UsedContext;
CXXDefaultInitExpr(const ASTContext &Ctx, SourceLocation Loc,
- FieldDecl *Field, QualType Ty, DeclContext *UsedContext);
+ FieldDecl *Field, QualType Ty, DeclContext *UsedContext,
+ Expr *RewrittenInitExpr);
- CXXDefaultInitExpr(EmptyShell Empty) : Expr(CXXDefaultInitExprClass, Empty) {}
+ CXXDefaultInitExpr(EmptyShell Empty, bool HasRewrittenInit)
+ : Expr(CXXDefaultInitExprClass, Empty) {
+ CXXDefaultInitExprBits.HasRewrittenInit = HasRewrittenInit;
+ }
public:
+ static CXXDefaultInitExpr *CreateEmpty(const ASTContext &C,
+ bool HasRewrittenInit);
/// \p Field is the non-static data member whose default initializer is used
/// by this expression.
static CXXDefaultInitExpr *Create(const ASTContext &Ctx, SourceLocation Loc,
- FieldDecl *Field, DeclContext *UsedContext) {
- return new (Ctx) CXXDefaultInitExpr(Ctx, Loc, Field, Field->getType(), UsedContext);
+ FieldDecl *Field, DeclContext *UsedContext,
+ Expr *RewrittenInitExpr);
+
+ bool hasRewrittenInit() const {
+ return CXXDefaultInitExprBits.HasRewrittenInit;
}
/// Get the field whose initializer will be used.
@@ -1343,13 +1396,23 @@ public:
const FieldDecl *getField() const { return Field; }
/// Get the initialization expression that will be used.
+ Expr *getExpr();
const Expr *getExpr() const {
- assert(Field->getInClassInitializer() && "initializer hasn't been parsed");
- return Field->getInClassInitializer();
+ return const_cast<CXXDefaultInitExpr *>(this)->getExpr();
}
- Expr *getExpr() {
- assert(Field->getInClassInitializer() && "initializer hasn't been parsed");
- return Field->getInClassInitializer();
+
+ /// Retrieve the initializing expression with evaluated immediate calls, if
+ /// any.
+ const Expr *getRewrittenExpr() const {
+ assert(hasRewrittenInit() && "expected a rewritten init expression");
+ return *getTrailingObjects<Expr *>();
+ }
+
+ /// Retrieve the initializing expression with evaluated immediate calls, if
+ /// any.
+ Expr *getRewrittenExpr() {
+ assert(hasRewrittenInit() && "expected a rewritten init expression");
+ return *getTrailingObjects<Expr *>();
}
const DeclContext *getUsedContext() const { return UsedContext; }
@@ -1456,19 +1519,17 @@ public:
}
};
+enum class CXXConstructionKind {
+ Complete,
+ NonVirtualBase,
+ VirtualBase,
+ Delegating
+};
+
/// Represents a call to a C++ constructor.
class CXXConstructExpr : public Expr {
friend class ASTStmtReader;
-public:
- enum ConstructionKind {
- CK_Complete,
- CK_NonVirtualBase,
- CK_VirtualBase,
- CK_Delegating
- };
-
-private:
/// A pointer to the constructor which will be ultimately called.
CXXConstructorDecl *Constructor;
@@ -1504,7 +1565,7 @@ protected:
CXXConstructorDecl *Ctor, bool Elidable,
ArrayRef<Expr *> Args, bool HadMultipleCandidates,
bool ListInitialization, bool StdInitListInitialization,
- bool ZeroInitialization, ConstructionKind ConstructKind,
+ bool ZeroInitialization, CXXConstructionKind ConstructKind,
SourceRange ParenOrBraceRange);
/// Build an empty C++ construction expression.
@@ -1523,7 +1584,7 @@ public:
CXXConstructorDecl *Ctor, bool Elidable, ArrayRef<Expr *> Args,
bool HadMultipleCandidates, bool ListInitialization,
bool StdInitListInitialization, bool ZeroInitialization,
- ConstructionKind ConstructKind, SourceRange ParenOrBraceRange);
+ CXXConstructionKind ConstructKind, SourceRange ParenOrBraceRange);
/// Create an empty C++ construction expression.
static CXXConstructExpr *CreateEmpty(const ASTContext &Ctx, unsigned NumArgs);
@@ -1577,11 +1638,12 @@ public:
/// Determine whether this constructor is actually constructing
/// a base class (rather than a complete object).
- ConstructionKind getConstructionKind() const {
- return static_cast<ConstructionKind>(CXXConstructExprBits.ConstructionKind);
+ CXXConstructionKind getConstructionKind() const {
+ return static_cast<CXXConstructionKind>(
+ CXXConstructExprBits.ConstructionKind);
}
- void setConstructionKind(ConstructionKind CK) {
- CXXConstructExprBits.ConstructionKind = CK;
+ void setConstructionKind(CXXConstructionKind CK) {
+ CXXConstructExprBits.ConstructionKind = llvm::to_underlying(CK);
}
using arg_iterator = ExprIterator;
@@ -1623,6 +1685,14 @@ public:
getArgs()[Arg] = ArgExpr;
}
+ bool isImmediateEscalating() const {
+ return CXXConstructExprBits.IsImmediateEscalating;
+ }
+
+ void setIsImmediateEscalating(bool Set) {
+ CXXConstructExprBits.IsImmediateEscalating = Set;
+ }
+
SourceLocation getBeginLoc() const LLVM_READONLY;
SourceLocation getEndLoc() const LLVM_READONLY;
SourceRange getParenOrBraceRange() const { return ParenOrBraceRange; }
@@ -1656,10 +1726,12 @@ private:
SourceLocation Loc;
/// Whether this is the construction of a virtual base.
+ LLVM_PREFERRED_TYPE(bool)
unsigned ConstructsVirtualBase : 1;
/// Whether the constructor is inherited from a virtual base class of the
/// class that we construct.
+ LLVM_PREFERRED_TYPE(bool)
unsigned InheritedFromVirtualBase : 1;
public:
@@ -1688,9 +1760,9 @@ public:
/// Determine whether this constructor is actually constructing
/// a base class (rather than a complete object).
bool constructsVBase() const { return ConstructsVirtualBase; }
- CXXConstructExpr::ConstructionKind getConstructionKind() const {
- return ConstructsVirtualBase ? CXXConstructExpr::CK_VirtualBase
- : CXXConstructExpr::CK_NonVirtualBase;
+ CXXConstructionKind getConstructionKind() const {
+ return ConstructsVirtualBase ? CXXConstructionKind::VirtualBase
+ : CXXConstructionKind::NonVirtualBase;
}
/// Determine whether the inherited constructor is inherited from a
@@ -2134,6 +2206,17 @@ public:
}
};
+enum class CXXNewInitializationStyle {
+ /// New-expression has no initializer as written.
+ None,
+
+ /// New-expression has a C++98 paren-delimited initializer.
+ Parens,
+
+ /// New-expression has a C++11 list-initializer.
+ Braces
+};
+
/// Represents a new-expression for memory allocation and constructor
/// calls, e.g: "new CXXNewExpr(foo)".
class CXXNewExpr final
@@ -2187,25 +2270,12 @@ class CXXNewExpr final
return isParenTypeId();
}
-public:
- enum InitializationStyle {
- /// New-expression has no initializer as written.
- NoInit,
-
- /// New-expression has a C++98 paren-delimited initializer.
- CallInit,
-
- /// New-expression has a C++11 list-initializer.
- ListInit
- };
-
-private:
/// Build a c++ new expression.
CXXNewExpr(bool IsGlobalNew, FunctionDecl *OperatorNew,
FunctionDecl *OperatorDelete, bool ShouldPassAlignment,
bool UsualArrayDeleteWantsSize, ArrayRef<Expr *> PlacementArgs,
- SourceRange TypeIdParens, Optional<Expr *> ArraySize,
- InitializationStyle InitializationStyle, Expr *Initializer,
+ SourceRange TypeIdParens, std::optional<Expr *> ArraySize,
+ CXXNewInitializationStyle InitializationStyle, Expr *Initializer,
QualType Ty, TypeSourceInfo *AllocatedTypeInfo, SourceRange Range,
SourceRange DirectInitRange);
@@ -2219,8 +2289,8 @@ public:
Create(const ASTContext &Ctx, bool IsGlobalNew, FunctionDecl *OperatorNew,
FunctionDecl *OperatorDelete, bool ShouldPassAlignment,
bool UsualArrayDeleteWantsSize, ArrayRef<Expr *> PlacementArgs,
- SourceRange TypeIdParens, Optional<Expr *> ArraySize,
- InitializationStyle InitializationStyle, Expr *Initializer,
+ SourceRange TypeIdParens, std::optional<Expr *> ArraySize,
+ CXXNewInitializationStyle InitializationStyle, Expr *Initializer,
QualType Ty, TypeSourceInfo *AllocatedTypeInfo, SourceRange Range,
SourceRange DirectInitRange);
@@ -2261,15 +2331,32 @@ public:
bool isArray() const { return CXXNewExprBits.IsArray; }
- Optional<Expr *> getArraySize() {
+ /// This might return std::nullopt even if isArray() returns true,
+ /// since there might not be an array size expression.
+ /// If the result is not std::nullopt, it will never wrap a nullptr.
+ std::optional<Expr *> getArraySize() {
if (!isArray())
- return None;
- return cast_or_null<Expr>(getTrailingObjects<Stmt *>()[arraySizeOffset()]);
+ return std::nullopt;
+
+ if (auto *Result =
+ cast_or_null<Expr>(getTrailingObjects<Stmt *>()[arraySizeOffset()]))
+ return Result;
+
+ return std::nullopt;
}
- Optional<const Expr *> getArraySize() const {
+
+ /// This might return std::nullopt even if isArray() returns true,
+ /// since there might not be an array size expression.
+ /// If the result is not std::nullopt, it will never wrap a nullptr.
+ std::optional<const Expr *> getArraySize() const {
if (!isArray())
- return None;
- return cast_or_null<Expr>(getTrailingObjects<Stmt *>()[arraySizeOffset()]);
+ return std::nullopt;
+
+ if (auto *Result =
+ cast_or_null<Expr>(getTrailingObjects<Stmt *>()[arraySizeOffset()]))
+ return Result;
+
+ return std::nullopt;
}
unsigned getNumPlacementArgs() const {
@@ -2298,16 +2385,12 @@ public:
bool isGlobalNew() const { return CXXNewExprBits.IsGlobalNew; }
/// Whether this new-expression has any initializer at all.
- bool hasInitializer() const {
- return CXXNewExprBits.StoredInitializationStyle > 0;
- }
+ bool hasInitializer() const { return CXXNewExprBits.HasInitializer; }
/// The kind of initializer this new-expression has.
- InitializationStyle getInitializationStyle() const {
- if (CXXNewExprBits.StoredInitializationStyle == 0)
- return NoInit;
- return static_cast<InitializationStyle>(
- CXXNewExprBits.StoredInitializationStyle - 1);
+ CXXNewInitializationStyle getInitializationStyle() const {
+ return static_cast<CXXNewInitializationStyle>(
+ CXXNewExprBits.StoredInitializationStyle);
}
/// The initializer of this new-expression.
@@ -2522,6 +2605,7 @@ class CXXPseudoDestructorExpr : public Expr {
/// Whether the operator was an arrow ('->'); otherwise, it was a
/// period ('.').
+ LLVM_PREFERRED_TYPE(bool)
bool IsArrow : 1;
/// The location of the '.' or '->' operator.
@@ -2721,8 +2805,7 @@ public:
/// Retrieve the argument types.
ArrayRef<TypeSourceInfo *> getArgs() const {
- return llvm::makeArrayRef(getTrailingObjects<TypeSourceInfo *>(),
- getNumArgs());
+ return llvm::ArrayRef(getTrailingObjects<TypeSourceInfo *>(), getNumArgs());
}
SourceLocation getBeginLoc() const LLVM_READONLY { return Loc; }
@@ -2752,6 +2835,7 @@ public:
/// \endcode
class ArrayTypeTraitExpr : public Expr {
/// The trait. An ArrayTypeTrait enum in MSVC compat unsigned.
+ LLVM_PREFERRED_TYPE(ArrayTypeTrait)
unsigned ATT : 2;
/// The value of the type trait. Unspecified if dependent.
@@ -2822,9 +2906,11 @@ public:
/// \endcode
class ExpressionTraitExpr : public Expr {
/// The trait. A ExpressionTrait enum in MSVC compatible unsigned.
+ LLVM_PREFERRED_TYPE(ExpressionTrait)
unsigned ET : 31;
/// The value of the type trait. Unspecified if dependent.
+ LLVM_PREFERRED_TYPE(bool)
unsigned Value : 1;
/// The location of the type trait keyword.
@@ -3104,7 +3190,8 @@ class UnresolvedLookupExpr final
const DeclarationNameInfo &NameInfo, bool RequiresADL,
bool Overloaded,
const TemplateArgumentListInfo *TemplateArgs,
- UnresolvedSetIterator Begin, UnresolvedSetIterator End);
+ UnresolvedSetIterator Begin, UnresolvedSetIterator End,
+ bool KnownDependent);
UnresolvedLookupExpr(EmptyShell Empty, unsigned NumResults,
bool HasTemplateKWAndArgsInfo);
@@ -3124,12 +3211,15 @@ public:
const DeclarationNameInfo &NameInfo, bool RequiresADL, bool Overloaded,
UnresolvedSetIterator Begin, UnresolvedSetIterator End);
+ // After canonicalization, there may be dependent template arguments in
+ // CanonicalConverted But none of Args is dependent. When any of
+ // CanonicalConverted dependent, KnownDependent is true.
static UnresolvedLookupExpr *
Create(const ASTContext &Context, CXXRecordDecl *NamingClass,
NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateKWLoc,
const DeclarationNameInfo &NameInfo, bool RequiresADL,
const TemplateArgumentListInfo *Args, UnresolvedSetIterator Begin,
- UnresolvedSetIterator End);
+ UnresolvedSetIterator End, bool KnownDependent);
static UnresolvedLookupExpr *CreateEmpty(const ASTContext &Context,
unsigned NumResults,
@@ -3368,8 +3458,7 @@ public:
ArrayRef<CleanupObject> objects);
ArrayRef<CleanupObject> getObjects() const {
- return llvm::makeArrayRef(getTrailingObjects<CleanupObject>(),
- getNumObjects());
+ return llvm::ArrayRef(getTrailingObjects<CleanupObject>(), getNumObjects());
}
unsigned getNumObjects() const { return ExprWithCleanupsBits.NumObjects; }
@@ -3431,8 +3520,9 @@ class CXXUnresolvedConstructExpr final
friend class ASTStmtReader;
friend TrailingObjects;
- /// The type being constructed.
- TypeSourceInfo *TSI;
+ /// The type being constructed, and whether the construct expression models
+ /// list initialization or not.
+ llvm::PointerIntPair<TypeSourceInfo *, 1> TypeAndInitForm;
/// The location of the left parentheses ('(').
SourceLocation LParenLoc;
@@ -3442,30 +3532,31 @@ class CXXUnresolvedConstructExpr final
CXXUnresolvedConstructExpr(QualType T, TypeSourceInfo *TSI,
SourceLocation LParenLoc, ArrayRef<Expr *> Args,
- SourceLocation RParenLoc);
+ SourceLocation RParenLoc, bool IsListInit);
CXXUnresolvedConstructExpr(EmptyShell Empty, unsigned NumArgs)
- : Expr(CXXUnresolvedConstructExprClass, Empty), TSI(nullptr) {
+ : Expr(CXXUnresolvedConstructExprClass, Empty) {
CXXUnresolvedConstructExprBits.NumArgs = NumArgs;
}
public:
- static CXXUnresolvedConstructExpr *Create(const ASTContext &Context,
- QualType T, TypeSourceInfo *TSI,
- SourceLocation LParenLoc,
- ArrayRef<Expr *> Args,
- SourceLocation RParenLoc);
+ static CXXUnresolvedConstructExpr *
+ Create(const ASTContext &Context, QualType T, TypeSourceInfo *TSI,
+ SourceLocation LParenLoc, ArrayRef<Expr *> Args,
+ SourceLocation RParenLoc, bool IsListInit);
static CXXUnresolvedConstructExpr *CreateEmpty(const ASTContext &Context,
unsigned NumArgs);
/// Retrieve the type that is being constructed, as specified
/// in the source code.
- QualType getTypeAsWritten() const { return TSI->getType(); }
+ QualType getTypeAsWritten() const { return getTypeSourceInfo()->getType(); }
/// Retrieve the type source information for the type being
/// constructed.
- TypeSourceInfo *getTypeSourceInfo() const { return TSI; }
+ TypeSourceInfo *getTypeSourceInfo() const {
+ return TypeAndInitForm.getPointer();
+ }
/// Retrieve the location of the left parentheses ('(') that
/// precedes the argument list.
@@ -3480,7 +3571,7 @@ public:
/// Determine whether this expression models list-initialization.
/// If so, there will be exactly one subexpression, which will be
/// an InitListExpr.
- bool isListInitialization() const { return LParenLoc.isInvalid(); }
+ bool isListInitialization() const { return TypeAndInitForm.getInt(); }
/// Retrieve the number of arguments.
unsigned getNumArgs() const { return CXXUnresolvedConstructExprBits.NumArgs; }
@@ -4065,7 +4156,7 @@ class PackExpansionExpr : public Expr {
public:
PackExpansionExpr(QualType T, Expr *Pattern, SourceLocation EllipsisLoc,
- Optional<unsigned> NumExpansions)
+ std::optional<unsigned> NumExpansions)
: Expr(PackExpansionExprClass, T, Pattern->getValueKind(),
Pattern->getObjectKind()),
EllipsisLoc(EllipsisLoc),
@@ -4088,11 +4179,11 @@ public:
/// Determine the number of expansions that will be produced when
/// this pack expansion is instantiated, if already known.
- Optional<unsigned> getNumExpansions() const {
+ std::optional<unsigned> getNumExpansions() const {
if (NumExpansions)
return NumExpansions - 1;
- return None;
+ return std::nullopt;
}
SourceLocation getBeginLoc() const LLVM_READONLY {
@@ -4159,7 +4250,7 @@ class SizeOfPackExpr final
/// the given parameter pack.
SizeOfPackExpr(QualType SizeType, SourceLocation OperatorLoc, NamedDecl *Pack,
SourceLocation PackLoc, SourceLocation RParenLoc,
- Optional<unsigned> Length,
+ std::optional<unsigned> Length,
ArrayRef<TemplateArgument> PartialArgs)
: Expr(SizeOfPackExprClass, SizeType, VK_PRValue, OK_Ordinary),
OperatorLoc(OperatorLoc), PackLoc(PackLoc), RParenLoc(RParenLoc),
@@ -4177,11 +4268,11 @@ class SizeOfPackExpr final
: Expr(SizeOfPackExprClass, Empty), Length(NumPartialArgs) {}
public:
- static SizeOfPackExpr *Create(ASTContext &Context, SourceLocation OperatorLoc,
- NamedDecl *Pack, SourceLocation PackLoc,
- SourceLocation RParenLoc,
- Optional<unsigned> Length = None,
- ArrayRef<TemplateArgument> PartialArgs = None);
+ static SizeOfPackExpr *
+ Create(ASTContext &Context, SourceLocation OperatorLoc, NamedDecl *Pack,
+ SourceLocation PackLoc, SourceLocation RParenLoc,
+ std::optional<unsigned> Length = std::nullopt,
+ ArrayRef<TemplateArgument> PartialArgs = std::nullopt);
static SizeOfPackExpr *CreateDeserialized(ASTContext &Context,
unsigned NumPartialArgs);
@@ -4220,7 +4311,7 @@ public:
ArrayRef<TemplateArgument> getPartialArguments() const {
assert(isPartiallySubstituted());
const auto *Args = getTrailingObjects<TemplateArgument>();
- return llvm::makeArrayRef(Args, Args + Length);
+ return llvm::ArrayRef(Args, Args + Length);
}
SourceLocation getBeginLoc() const LLVM_READONLY { return OperatorLoc; }
@@ -4246,24 +4337,30 @@ class SubstNonTypeTemplateParmExpr : public Expr {
friend class ASTReader;
friend class ASTStmtReader;
- /// The replaced parameter and a flag indicating if it was a reference
+ /// The replacement expression.
+ Stmt *Replacement;
+
+ /// The associated declaration and a flag indicating if it was a reference
/// parameter. For class NTTPs, we can't determine that based on the value
/// category alone.
- llvm::PointerIntPair<NonTypeTemplateParmDecl*, 1, bool> ParamAndRef;
+ llvm::PointerIntPair<Decl *, 1, bool> AssociatedDeclAndRef;
- /// The replacement expression.
- Stmt *Replacement;
+ unsigned Index : 15;
+ unsigned PackIndex : 16;
explicit SubstNonTypeTemplateParmExpr(EmptyShell Empty)
: Expr(SubstNonTypeTemplateParmExprClass, Empty) {}
public:
SubstNonTypeTemplateParmExpr(QualType Ty, ExprValueKind ValueKind,
- SourceLocation Loc,
- NonTypeTemplateParmDecl *Param, bool RefParam,
- Expr *Replacement)
+ SourceLocation Loc, Expr *Replacement,
+ Decl *AssociatedDecl, unsigned Index,
+ std::optional<unsigned> PackIndex, bool RefParam)
: Expr(SubstNonTypeTemplateParmExprClass, Ty, ValueKind, OK_Ordinary),
- ParamAndRef(Param, RefParam), Replacement(Replacement) {
+ Replacement(Replacement),
+ AssociatedDeclAndRef(AssociatedDecl, RefParam), Index(Index),
+ PackIndex(PackIndex ? *PackIndex + 1 : 0) {
+ assert(AssociatedDecl != nullptr);
SubstNonTypeTemplateParmExprBits.NameLoc = Loc;
setDependence(computeDependence(this));
}
@@ -4276,11 +4373,23 @@ public:
Expr *getReplacement() const { return cast<Expr>(Replacement); }
- NonTypeTemplateParmDecl *getParameter() const {
- return ParamAndRef.getPointer();
+ /// A template-like entity which owns the whole pattern being substituted.
+ /// This will own a set of template parameters.
+ Decl *getAssociatedDecl() const { return AssociatedDeclAndRef.getPointer(); }
+
+ /// Returns the index of the replaced parameter in the associated declaration.
+ /// This should match the result of `getParameter()->getIndex()`.
+ unsigned getIndex() const { return Index; }
+
+ std::optional<unsigned> getPackIndex() const {
+ if (PackIndex == 0)
+ return std::nullopt;
+ return PackIndex - 1;
}
- bool isReferenceParameter() const { return ParamAndRef.getInt(); }
+ NonTypeTemplateParmDecl *getParameter() const;
+
+ bool isReferenceParameter() const { return AssociatedDeclAndRef.getInt(); }
/// Determine the substituted type of the template parameter.
QualType getParameterType(const ASTContext &Ctx) const;
@@ -4314,14 +4423,16 @@ class SubstNonTypeTemplateParmPackExpr : public Expr {
friend class ASTStmtReader;
/// The non-type template parameter pack itself.
- NonTypeTemplateParmDecl *Param;
+ Decl *AssociatedDecl;
/// A pointer to the set of template arguments that this
/// parameter pack is instantiated with.
const TemplateArgument *Arguments;
/// The number of template arguments in \c Arguments.
- unsigned NumArguments;
+ unsigned NumArguments : 16;
+
+ unsigned Index : 16;
/// The location of the non-type template parameter pack reference.
SourceLocation NameLoc;
@@ -4330,14 +4441,21 @@ class SubstNonTypeTemplateParmPackExpr : public Expr {
: Expr(SubstNonTypeTemplateParmPackExprClass, Empty) {}
public:
- SubstNonTypeTemplateParmPackExpr(QualType T,
- ExprValueKind ValueKind,
- NonTypeTemplateParmDecl *Param,
+ SubstNonTypeTemplateParmPackExpr(QualType T, ExprValueKind ValueKind,
SourceLocation NameLoc,
- const TemplateArgument &ArgPack);
+ const TemplateArgument &ArgPack,
+ Decl *AssociatedDecl, unsigned Index);
+
+ /// A template-like entity which owns the whole pattern being substituted.
+ /// This will own a set of template parameters.
+ Decl *getAssociatedDecl() const { return AssociatedDecl; }
+
+ /// Returns the index of the replaced parameter in the associated declaration.
+ /// This should match the result of `getParameterPack()->getIndex()`.
+ unsigned getIndex() const { return Index; }
/// Retrieve the non-type template parameter pack being substituted.
- NonTypeTemplateParmDecl *getParameterPack() const { return Param; }
+ NonTypeTemplateParmDecl *getParameterPack() const;
/// Retrieve the location of the parameter pack name.
SourceLocation getParameterPackLocation() const { return NameLoc; }
@@ -4590,7 +4708,7 @@ public:
CXXFoldExpr(QualType T, UnresolvedLookupExpr *Callee,
SourceLocation LParenLoc, Expr *LHS, BinaryOperatorKind Opcode,
SourceLocation EllipsisLoc, Expr *RHS, SourceLocation RParenLoc,
- Optional<unsigned> NumExpansions)
+ std::optional<unsigned> NumExpansions)
: Expr(CXXFoldExprClass, T, VK_PRValue, OK_Ordinary),
LParenLoc(LParenLoc), EllipsisLoc(EllipsisLoc), RParenLoc(RParenLoc),
NumExpansions(NumExpansions ? *NumExpansions + 1 : 0), Opcode(Opcode) {
@@ -4627,10 +4745,10 @@ public:
SourceLocation getEllipsisLoc() const { return EllipsisLoc; }
BinaryOperatorKind getOperator() const { return Opcode; }
- Optional<unsigned> getNumExpansions() const {
+ std::optional<unsigned> getNumExpansions() const {
if (NumExpansions)
return NumExpansions - 1;
- return None;
+ return std::nullopt;
}
SourceLocation getBeginLoc() const LLVM_READONLY {
@@ -4663,6 +4781,140 @@ public:
}
};
+/// Represents a list-initialization with parenthesis.
+///
+/// As per P0960R3, this is a C++20 feature that allows aggregate to
+/// be initialized with a parenthesized list of values:
+/// ```
+/// struct A {
+/// int a;
+/// double b;
+/// };
+///
+/// void foo() {
+/// A a1(0); // Well-formed in C++20
+/// A a2(1.5, 1.0); // Well-formed in C++20
+/// }
+/// ```
+/// It has some sort of similiarity to braced
+/// list-initialization, with some differences such as
+/// it allows narrowing conversion whilst braced
+/// list-initialization doesn't.
+/// ```
+/// struct A {
+/// char a;
+/// };
+/// void foo() {
+/// A a(1.5); // Well-formed in C++20
+/// A b{1.5}; // Ill-formed !
+/// }
+/// ```
+class CXXParenListInitExpr final
+ : public Expr,
+ private llvm::TrailingObjects<CXXParenListInitExpr, Expr *> {
+ friend class TrailingObjects;
+ friend class ASTStmtReader;
+ friend class ASTStmtWriter;
+
+ unsigned NumExprs;
+ unsigned NumUserSpecifiedExprs;
+ SourceLocation InitLoc, LParenLoc, RParenLoc;
+ llvm::PointerUnion<Expr *, FieldDecl *> ArrayFillerOrUnionFieldInit;
+
+ CXXParenListInitExpr(ArrayRef<Expr *> Args, QualType T,
+ unsigned NumUserSpecifiedExprs, SourceLocation InitLoc,
+ SourceLocation LParenLoc, SourceLocation RParenLoc)
+ : Expr(CXXParenListInitExprClass, T, getValueKindForType(T), OK_Ordinary),
+ NumExprs(Args.size()), NumUserSpecifiedExprs(NumUserSpecifiedExprs),
+ InitLoc(InitLoc), LParenLoc(LParenLoc), RParenLoc(RParenLoc) {
+ std::copy(Args.begin(), Args.end(), getTrailingObjects<Expr *>());
+ assert(NumExprs >= NumUserSpecifiedExprs &&
+ "number of user specified inits is greater than the number of "
+ "passed inits");
+ setDependence(computeDependence(this));
+ }
+
+ size_t numTrailingObjects(OverloadToken<Expr *>) const { return NumExprs; }
+
+public:
+ static CXXParenListInitExpr *
+ Create(ASTContext &C, ArrayRef<Expr *> Args, QualType T,
+ unsigned NumUserSpecifiedExprs, SourceLocation InitLoc,
+ SourceLocation LParenLoc, SourceLocation RParenLoc);
+
+ static CXXParenListInitExpr *CreateEmpty(ASTContext &C, unsigned numExprs,
+ EmptyShell Empty);
+
+ explicit CXXParenListInitExpr(EmptyShell Empty, unsigned NumExprs)
+ : Expr(CXXParenListInitExprClass, Empty), NumExprs(NumExprs),
+ NumUserSpecifiedExprs(0) {}
+
+ void updateDependence() { setDependence(computeDependence(this)); }
+
+ ArrayRef<Expr *> getInitExprs() {
+ return ArrayRef(getTrailingObjects<Expr *>(), NumExprs);
+ }
+
+ const ArrayRef<Expr *> getInitExprs() const {
+ return ArrayRef(getTrailingObjects<Expr *>(), NumExprs);
+ }
+
+ ArrayRef<Expr *> getUserSpecifiedInitExprs() {
+ return ArrayRef(getTrailingObjects<Expr *>(), NumUserSpecifiedExprs);
+ }
+
+ const ArrayRef<Expr *> getUserSpecifiedInitExprs() const {
+ return ArrayRef(getTrailingObjects<Expr *>(), NumUserSpecifiedExprs);
+ }
+
+ SourceLocation getBeginLoc() const LLVM_READONLY { return LParenLoc; }
+
+ SourceLocation getEndLoc() const LLVM_READONLY { return RParenLoc; }
+
+ SourceLocation getInitLoc() const LLVM_READONLY { return InitLoc; }
+
+ SourceRange getSourceRange() const LLVM_READONLY {
+ return SourceRange(getBeginLoc(), getEndLoc());
+ }
+
+ void setArrayFiller(Expr *E) { ArrayFillerOrUnionFieldInit = E; }
+
+ Expr *getArrayFiller() {
+ return ArrayFillerOrUnionFieldInit.dyn_cast<Expr *>();
+ }
+
+ const Expr *getArrayFiller() const {
+ return ArrayFillerOrUnionFieldInit.dyn_cast<Expr *>();
+ }
+
+ void setInitializedFieldInUnion(FieldDecl *FD) {
+ ArrayFillerOrUnionFieldInit = FD;
+ }
+
+ FieldDecl *getInitializedFieldInUnion() {
+ return ArrayFillerOrUnionFieldInit.dyn_cast<FieldDecl *>();
+ }
+
+ const FieldDecl *getInitializedFieldInUnion() const {
+ return ArrayFillerOrUnionFieldInit.dyn_cast<FieldDecl *>();
+ }
+
+ child_range children() {
+ Stmt **Begin = reinterpret_cast<Stmt **>(getTrailingObjects<Expr *>());
+ return child_range(Begin, Begin + NumExprs);
+ }
+
+ const_child_range children() const {
+ Stmt *const *Begin =
+ reinterpret_cast<Stmt *const *>(getTrailingObjects<Expr *>());
+ return const_child_range(Begin, Begin + NumExprs);
+ }
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == CXXParenListInitExprClass;
+ }
+};
+
/// Represents an expression that might suspend coroutine execution;
/// either a co_await or co_yield expression.
///
@@ -4681,18 +4933,19 @@ class CoroutineSuspendExpr : public Expr {
SourceLocation KeywordLoc;
- enum SubExpr { Common, Ready, Suspend, Resume, Count };
+ enum SubExpr { Operand, Common, Ready, Suspend, Resume, Count };
Stmt *SubExprs[SubExpr::Count];
OpaqueValueExpr *OpaqueValue = nullptr;
public:
- CoroutineSuspendExpr(StmtClass SC, SourceLocation KeywordLoc, Expr *Common,
- Expr *Ready, Expr *Suspend, Expr *Resume,
+ CoroutineSuspendExpr(StmtClass SC, SourceLocation KeywordLoc, Expr *Operand,
+ Expr *Common, Expr *Ready, Expr *Suspend, Expr *Resume,
OpaqueValueExpr *OpaqueValue)
: Expr(SC, Resume->getType(), Resume->getValueKind(),
Resume->getObjectKind()),
KeywordLoc(KeywordLoc), OpaqueValue(OpaqueValue) {
+ SubExprs[SubExpr::Operand] = Operand;
SubExprs[SubExpr::Common] = Common;
SubExprs[SubExpr::Ready] = Ready;
SubExprs[SubExpr::Suspend] = Suspend;
@@ -4701,10 +4954,11 @@ public:
}
CoroutineSuspendExpr(StmtClass SC, SourceLocation KeywordLoc, QualType Ty,
- Expr *Common)
+ Expr *Operand, Expr *Common)
: Expr(SC, Ty, VK_PRValue, OK_Ordinary), KeywordLoc(KeywordLoc) {
assert(Common->isTypeDependent() && Ty->isDependentType() &&
"wrong constructor for non-dependent co_await/co_yield expression");
+ SubExprs[SubExpr::Operand] = Operand;
SubExprs[SubExpr::Common] = Common;
SubExprs[SubExpr::Ready] = nullptr;
SubExprs[SubExpr::Suspend] = nullptr;
@@ -4713,14 +4967,13 @@ public:
}
CoroutineSuspendExpr(StmtClass SC, EmptyShell Empty) : Expr(SC, Empty) {
+ SubExprs[SubExpr::Operand] = nullptr;
SubExprs[SubExpr::Common] = nullptr;
SubExprs[SubExpr::Ready] = nullptr;
SubExprs[SubExpr::Suspend] = nullptr;
SubExprs[SubExpr::Resume] = nullptr;
}
- SourceLocation getKeywordLoc() const { return KeywordLoc; }
-
Expr *getCommonExpr() const {
return static_cast<Expr*>(SubExprs[SubExpr::Common]);
}
@@ -4740,10 +4993,17 @@ public:
return static_cast<Expr*>(SubExprs[SubExpr::Resume]);
}
+ // The syntactic operand written in the code
+ Expr *getOperand() const {
+ return static_cast<Expr *>(SubExprs[SubExpr::Operand]);
+ }
+
+ SourceLocation getKeywordLoc() const { return KeywordLoc; }
+
SourceLocation getBeginLoc() const LLVM_READONLY { return KeywordLoc; }
SourceLocation getEndLoc() const LLVM_READONLY {
- return getCommonExpr()->getEndLoc();
+ return getOperand()->getEndLoc();
}
child_range children() {
@@ -4765,28 +5025,24 @@ class CoawaitExpr : public CoroutineSuspendExpr {
friend class ASTStmtReader;
public:
- CoawaitExpr(SourceLocation CoawaitLoc, Expr *Operand, Expr *Ready,
- Expr *Suspend, Expr *Resume, OpaqueValueExpr *OpaqueValue,
- bool IsImplicit = false)
- : CoroutineSuspendExpr(CoawaitExprClass, CoawaitLoc, Operand, Ready,
- Suspend, Resume, OpaqueValue) {
+ CoawaitExpr(SourceLocation CoawaitLoc, Expr *Operand, Expr *Common,
+ Expr *Ready, Expr *Suspend, Expr *Resume,
+ OpaqueValueExpr *OpaqueValue, bool IsImplicit = false)
+ : CoroutineSuspendExpr(CoawaitExprClass, CoawaitLoc, Operand, Common,
+ Ready, Suspend, Resume, OpaqueValue) {
CoawaitBits.IsImplicit = IsImplicit;
}
CoawaitExpr(SourceLocation CoawaitLoc, QualType Ty, Expr *Operand,
- bool IsImplicit = false)
- : CoroutineSuspendExpr(CoawaitExprClass, CoawaitLoc, Ty, Operand) {
+ Expr *Common, bool IsImplicit = false)
+ : CoroutineSuspendExpr(CoawaitExprClass, CoawaitLoc, Ty, Operand,
+ Common) {
CoawaitBits.IsImplicit = IsImplicit;
}
CoawaitExpr(EmptyShell Empty)
: CoroutineSuspendExpr(CoawaitExprClass, Empty) {}
- Expr *getOperand() const {
- // FIXME: Dig out the actual operand or store it.
- return getCommonExpr();
- }
-
bool isImplicit() const { return CoawaitBits.IsImplicit; }
void setIsImplicit(bool value = true) { CoawaitBits.IsImplicit = value; }
@@ -4850,20 +5106,18 @@ class CoyieldExpr : public CoroutineSuspendExpr {
friend class ASTStmtReader;
public:
- CoyieldExpr(SourceLocation CoyieldLoc, Expr *Operand, Expr *Ready,
- Expr *Suspend, Expr *Resume, OpaqueValueExpr *OpaqueValue)
- : CoroutineSuspendExpr(CoyieldExprClass, CoyieldLoc, Operand, Ready,
- Suspend, Resume, OpaqueValue) {}
- CoyieldExpr(SourceLocation CoyieldLoc, QualType Ty, Expr *Operand)
- : CoroutineSuspendExpr(CoyieldExprClass, CoyieldLoc, Ty, Operand) {}
+ CoyieldExpr(SourceLocation CoyieldLoc, Expr *Operand, Expr *Common,
+ Expr *Ready, Expr *Suspend, Expr *Resume,
+ OpaqueValueExpr *OpaqueValue)
+ : CoroutineSuspendExpr(CoyieldExprClass, CoyieldLoc, Operand, Common,
+ Ready, Suspend, Resume, OpaqueValue) {}
+ CoyieldExpr(SourceLocation CoyieldLoc, QualType Ty, Expr *Operand,
+ Expr *Common)
+ : CoroutineSuspendExpr(CoyieldExprClass, CoyieldLoc, Ty, Operand,
+ Common) {}
CoyieldExpr(EmptyShell Empty)
: CoroutineSuspendExpr(CoyieldExprClass, Empty) {}
- Expr *getOperand() const {
- // FIXME: Dig out the actual operand or store it.
- return getCommonExpr();
- }
-
static bool classof(const Stmt *T) {
return T->getStmtClass() == CoyieldExprClass;
}
diff --git a/contrib/llvm-project/clang/include/clang/AST/ExprConcepts.h b/contrib/llvm-project/clang/include/clang/AST/ExprConcepts.h
index 1544c498ef66..29913fd84c58 100644
--- a/contrib/llvm-project/clang/include/clang/AST/ExprConcepts.h
+++ b/contrib/llvm-project/clang/include/clang/AST/ExprConcepts.h
@@ -14,19 +14,21 @@
#ifndef LLVM_CLANG_AST_EXPRCONCEPTS_H
#define LLVM_CLANG_AST_EXPRCONCEPTS_H
-#include "clang/AST/ASTContext.h"
#include "clang/AST/ASTConcept.h"
+#include "clang/AST/ASTContext.h"
#include "clang/AST/Decl.h"
-#include "clang/AST/DeclarationName.h"
#include "clang/AST/DeclTemplate.h"
+#include "clang/AST/DeclarationName.h"
#include "clang/AST/Expr.h"
#include "clang/AST/NestedNameSpecifier.h"
#include "clang/AST/TemplateBase.h"
#include "clang/AST/Type.h"
#include "clang/Basic/SourceLocation.h"
+#include "llvm/ADT/STLFunctionalExtras.h"
+#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/TrailingObjects.h"
-#include <utility>
#include <string>
+#include <utility>
namespace clang {
class ASTStmtReader;
@@ -37,74 +39,91 @@ class ASTStmtWriter;
///
/// According to C++2a [expr.prim.id]p3 an id-expression that denotes the
/// specialization of a concept results in a prvalue of type bool.
-class ConceptSpecializationExpr final : public Expr, public ConceptReference,
- private llvm::TrailingObjects<ConceptSpecializationExpr,
- TemplateArgument> {
+class ConceptSpecializationExpr final : public Expr {
+ friend class ASTReader;
friend class ASTStmtReader;
- friend TrailingObjects;
-public:
- using SubstitutionDiagnostic = std::pair<SourceLocation, std::string>;
-protected:
- /// \brief The number of template arguments in the tail-allocated list of
- /// converted template arguments.
- unsigned NumTemplateArgs;
+private:
+ ConceptReference *ConceptRef;
+
+ /// \brief The Implicit Concept Specialization Decl, which holds the template
+ /// arguments for this specialization.
+ ImplicitConceptSpecializationDecl *SpecDecl;
/// \brief Information about the satisfaction of the named concept with the
/// given arguments. If this expression is value dependent, this is to be
/// ignored.
ASTConstraintSatisfaction *Satisfaction;
- ConceptSpecializationExpr(const ASTContext &C, NestedNameSpecifierLoc NNS,
- SourceLocation TemplateKWLoc,
- DeclarationNameInfo ConceptNameInfo,
- NamedDecl *FoundDecl, ConceptDecl *NamedConcept,
- const ASTTemplateArgumentListInfo *ArgsAsWritten,
- ArrayRef<TemplateArgument> ConvertedArgs,
+ ConceptSpecializationExpr(const ASTContext &C, ConceptReference *ConceptRef,
+ ImplicitConceptSpecializationDecl *SpecDecl,
const ConstraintSatisfaction *Satisfaction);
- ConceptSpecializationExpr(const ASTContext &C, ConceptDecl *NamedConcept,
- ArrayRef<TemplateArgument> ConvertedArgs,
+ ConceptSpecializationExpr(const ASTContext &C, ConceptReference *ConceptRef,
+ ImplicitConceptSpecializationDecl *SpecDecl,
const ConstraintSatisfaction *Satisfaction,
bool Dependent,
bool ContainsUnexpandedParameterPack);
-
- ConceptSpecializationExpr(EmptyShell Empty, unsigned NumTemplateArgs);
+ ConceptSpecializationExpr(EmptyShell Empty);
public:
-
static ConceptSpecializationExpr *
- Create(const ASTContext &C, NestedNameSpecifierLoc NNS,
- SourceLocation TemplateKWLoc, DeclarationNameInfo ConceptNameInfo,
- NamedDecl *FoundDecl, ConceptDecl *NamedConcept,
- const ASTTemplateArgumentListInfo *ArgsAsWritten,
- ArrayRef<TemplateArgument> ConvertedArgs,
+ Create(const ASTContext &C, ConceptReference *ConceptRef,
+ ImplicitConceptSpecializationDecl *SpecDecl,
const ConstraintSatisfaction *Satisfaction);
static ConceptSpecializationExpr *
- Create(const ASTContext &C, ConceptDecl *NamedConcept,
- ArrayRef<TemplateArgument> ConvertedArgs,
- const ConstraintSatisfaction *Satisfaction,
- bool Dependent,
+ Create(const ASTContext &C, ConceptReference *ConceptRef,
+ ImplicitConceptSpecializationDecl *SpecDecl,
+ const ConstraintSatisfaction *Satisfaction, bool Dependent,
bool ContainsUnexpandedParameterPack);
- static ConceptSpecializationExpr *
- Create(ASTContext &C, EmptyShell Empty, unsigned NumTemplateArgs);
-
ArrayRef<TemplateArgument> getTemplateArguments() const {
- return ArrayRef<TemplateArgument>(getTrailingObjects<TemplateArgument>(),
- NumTemplateArgs);
+ return SpecDecl->getTemplateArguments();
+ }
+
+ ConceptReference *getConceptReference() const { return ConceptRef; }
+
+ ConceptDecl *getNamedConcept() const { return ConceptRef->getNamedConcept(); }
+
+ // FIXME: Several of the following functions can be removed. Instead the
+ // caller can directly work with the ConceptReference.
+ bool hasExplicitTemplateArgs() const {
+ return ConceptRef->hasExplicitTemplateArgs();
+ }
+
+ SourceLocation getConceptNameLoc() const {
+ return ConceptRef->getConceptNameLoc();
+ }
+ const ASTTemplateArgumentListInfo *getTemplateArgsAsWritten() const {
+ return ConceptRef->getTemplateArgsAsWritten();
+ }
+
+ const NestedNameSpecifierLoc &getNestedNameSpecifierLoc() const {
+ return ConceptRef->getNestedNameSpecifierLoc();
+ }
+
+ SourceLocation getTemplateKWLoc() const {
+ return ConceptRef->getTemplateKWLoc();
}
- /// \brief Set new template arguments for this concept specialization.
- void setTemplateArguments(ArrayRef<TemplateArgument> Converted);
+ NamedDecl *getFoundDecl() const { return ConceptRef->getFoundDecl(); }
+
+ const DeclarationNameInfo &getConceptNameInfo() const {
+ return ConceptRef->getConceptNameInfo();
+ }
+
+ const ImplicitConceptSpecializationDecl *getSpecializationDecl() const {
+ assert(SpecDecl && "Template Argument Decl not initialized");
+ return SpecDecl;
+ }
/// \brief Whether or not the concept with the given arguments was satisfied
/// when the expression was created.
/// The expression must not be dependent.
bool isSatisfied() const {
- assert(!isValueDependent()
- && "isSatisfied called on a dependent ConceptSpecializationExpr");
+ assert(!isValueDependent() &&
+ "isSatisfied called on a dependent ConceptSpecializationExpr");
return Satisfaction->IsSatisfied;
}
@@ -112,8 +131,8 @@ public:
/// satisfaction of the named concept.
/// The expression must not be dependent.
const ASTConstraintSatisfaction &getSatisfaction() const {
- assert(!isValueDependent()
- && "getSatisfaction called on dependent ConceptSpecializationExpr");
+ assert(!isValueDependent() &&
+ "getSatisfaction called on dependent ConceptSpecializationExpr");
return *Satisfaction;
}
@@ -122,15 +141,15 @@ public:
}
SourceLocation getBeginLoc() const LLVM_READONLY {
- return ConceptName.getBeginLoc();
+ return ConceptRef->getBeginLoc();
}
SourceLocation getEndLoc() const LLVM_READONLY {
- // If the ConceptSpecializationExpr is the ImmediatelyDeclaredConstraint
- // of a TypeConstraint written syntactically as a constrained-parameter,
- // there may not be a template argument list.
- return ArgsAsWritten->RAngleLoc.isValid() ? ArgsAsWritten->RAngleLoc
- : ConceptName.getEndLoc();
+ return ConceptRef->getEndLoc();
+ }
+
+ SourceLocation getExprLoc() const LLVM_READONLY {
+ return ConceptRef->getLocation();
}
// Iterators
@@ -154,8 +173,11 @@ public:
private:
const RequirementKind Kind;
// FIXME: use RequirementDependence to model dependence?
+ LLVM_PREFERRED_TYPE(bool)
bool Dependent : 1;
+ LLVM_PREFERRED_TYPE(bool)
bool ContainsUnexpandedParameterPack : 1;
+ LLVM_PREFERRED_TYPE(bool)
bool Satisfied : 1;
public:
struct SubstitutionDiagnostic {
@@ -275,12 +297,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
@@ -405,57 +427,61 @@ public:
/// \brief A requires-expression requirement which is satisfied when a general
/// constraint expression is satisfied ('nested' requirements).
class NestedRequirement : public Requirement {
- llvm::PointerUnion<Expr *, SubstitutionDiagnostic *> Value;
+ Expr *Constraint = nullptr;
const ASTConstraintSatisfaction *Satisfaction = nullptr;
+ bool HasInvalidConstraint = false;
+ StringRef InvalidConstraintEntity;
public:
friend ASTStmtReader;
friend ASTStmtWriter;
- NestedRequirement(SubstitutionDiagnostic *SubstDiag) :
- Requirement(RK_Nested, /*Dependent=*/false,
- /*ContainsUnexpandedParameterPack*/false,
- /*Satisfied=*/false), Value(SubstDiag) {}
-
- NestedRequirement(Expr *Constraint) :
- Requirement(RK_Nested, /*Dependent=*/true,
- Constraint->containsUnexpandedParameterPack()),
- Value(Constraint) {
+ NestedRequirement(Expr *Constraint)
+ : Requirement(RK_Nested, /*IsDependent=*/true,
+ Constraint->containsUnexpandedParameterPack()),
+ Constraint(Constraint) {
assert(Constraint->isInstantiationDependent() &&
"Nested requirement with non-dependent constraint must be "
"constructed with a ConstraintSatisfaction object");
}
NestedRequirement(ASTContext &C, Expr *Constraint,
- const ConstraintSatisfaction &Satisfaction) :
- Requirement(RK_Nested, Constraint->isInstantiationDependent(),
- Constraint->containsUnexpandedParameterPack(),
- Satisfaction.IsSatisfied),
- Value(Constraint),
- Satisfaction(ASTConstraintSatisfaction::Create(C, Satisfaction)) {}
-
- bool isSubstitutionFailure() const {
- return Value.is<SubstitutionDiagnostic *>();
- }
-
- SubstitutionDiagnostic *getSubstitutionDiagnostic() const {
- assert(isSubstitutionFailure() &&
- "getSubstitutionDiagnostic() may not be called when there was no "
- "substitution failure.");
- return Value.get<SubstitutionDiagnostic *>();
+ const ConstraintSatisfaction &Satisfaction)
+ : Requirement(RK_Nested, Constraint->isInstantiationDependent(),
+ Constraint->containsUnexpandedParameterPack(),
+ Satisfaction.IsSatisfied),
+ Constraint(Constraint),
+ Satisfaction(ASTConstraintSatisfaction::Create(C, Satisfaction)) {}
+
+ NestedRequirement(StringRef InvalidConstraintEntity,
+ const ASTConstraintSatisfaction *Satisfaction)
+ : Requirement(RK_Nested,
+ /*IsDependent=*/false,
+ /*ContainsUnexpandedParameterPack*/ false,
+ Satisfaction->IsSatisfied),
+ Satisfaction(Satisfaction), HasInvalidConstraint(true),
+ InvalidConstraintEntity(InvalidConstraintEntity) {}
+
+ NestedRequirement(ASTContext &C, StringRef InvalidConstraintEntity,
+ const ConstraintSatisfaction &Satisfaction)
+ : NestedRequirement(InvalidConstraintEntity,
+ ASTConstraintSatisfaction::Create(C, Satisfaction)) {}
+
+ bool hasInvalidConstraint() const { return HasInvalidConstraint; }
+
+ StringRef getInvalidConstraintEntity() {
+ assert(hasInvalidConstraint());
+ return InvalidConstraintEntity;
}
Expr *getConstraintExpr() const {
- assert(!isSubstitutionFailure() && "getConstraintExpr() may not be called "
- "on nested requirements with "
- "substitution failures.");
- return Value.get<Expr *>();
+ assert(!hasInvalidConstraint() &&
+ "getConstraintExpr() may not be called "
+ "on nested requirements with invalid constraint.");
+ return Constraint;
}
const ASTConstraintSatisfaction &getConstraintSatisfaction() const {
- assert(!isSubstitutionFailure() && "getConstraintSatisfaction() may not be "
- "called on nested requirements with "
- "substitution failures.");
return *Satisfaction;
}
@@ -464,6 +490,13 @@ public:
}
};
+using EntityPrinter = llvm::function_ref<void(llvm::raw_ostream &)>;
+
+/// \brief create a Requirement::SubstitutionDiagnostic with only a
+/// SubstitutedEntity and DiagLoc using Sema's allocator.
+Requirement::SubstitutionDiagnostic *
+createSubstDiagAt(Sema &S, SourceLocation Location, EntityPrinter Printer);
+
} // namespace concepts
/// C++2a [expr.prim.req]:
@@ -481,6 +514,8 @@ class RequiresExpr final : public Expr,
unsigned NumLocalParameters;
unsigned NumRequirements;
RequiresExprBodyDecl *Body;
+ SourceLocation LParenLoc;
+ SourceLocation RParenLoc;
SourceLocation RBraceLoc;
unsigned numTrailingObjects(OverloadToken<ParmVarDecl *>) const {
@@ -492,19 +527,22 @@ class RequiresExpr final : public Expr,
}
RequiresExpr(ASTContext &C, SourceLocation RequiresKWLoc,
- RequiresExprBodyDecl *Body,
+ RequiresExprBodyDecl *Body, SourceLocation LParenLoc,
ArrayRef<ParmVarDecl *> LocalParameters,
+ SourceLocation RParenLoc,
ArrayRef<concepts::Requirement *> Requirements,
SourceLocation RBraceLoc);
RequiresExpr(ASTContext &C, EmptyShell Empty, unsigned NumLocalParameters,
unsigned NumRequirements);
public:
- static RequiresExpr *
- Create(ASTContext &C, SourceLocation RequiresKWLoc,
- RequiresExprBodyDecl *Body, ArrayRef<ParmVarDecl *> LocalParameters,
- ArrayRef<concepts::Requirement *> Requirements,
- SourceLocation RBraceLoc);
+ static RequiresExpr *Create(ASTContext &C, SourceLocation RequiresKWLoc,
+ RequiresExprBodyDecl *Body,
+ SourceLocation LParenLoc,
+ ArrayRef<ParmVarDecl *> LocalParameters,
+ SourceLocation RParenLoc,
+ ArrayRef<concepts::Requirement *> Requirements,
+ SourceLocation RBraceLoc);
static RequiresExpr *
Create(ASTContext &C, EmptyShell Empty, unsigned NumLocalParameters,
unsigned NumRequirements);
@@ -527,10 +565,18 @@ public:
return RequiresExprBits.IsSatisfied;
}
+ void setSatisfied(bool IsSatisfied) {
+ assert(!isValueDependent() &&
+ "setSatisfied called on a dependent RequiresExpr");
+ RequiresExprBits.IsSatisfied = IsSatisfied;
+ }
+
SourceLocation getRequiresKWLoc() const {
return RequiresExprBits.RequiresKWLoc;
}
+ SourceLocation getLParenLoc() const { return LParenLoc; }
+ SourceLocation getRParenLoc() const { return RParenLoc; }
SourceLocation getRBraceLoc() const { return RBraceLoc; }
static bool classof(const Stmt *T) {
diff --git a/contrib/llvm-project/clang/include/clang/AST/ExprObjC.h b/contrib/llvm-project/clang/include/clang/AST/ExprObjC.h
index b0f057dbaa02..f833916c91aa 100644
--- a/contrib/llvm-project/clang/include/clang/AST/ExprObjC.h
+++ b/contrib/llvm-project/clang/include/clang/AST/ExprObjC.h
@@ -27,8 +27,6 @@
#include "clang/Basic/SourceLocation.h"
#include "clang/Basic/Specifiers.h"
#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/None.h"
-#include "llvm/ADT/Optional.h"
#include "llvm/ADT/PointerIntPair.h"
#include "llvm/ADT/PointerUnion.h"
#include "llvm/ADT/StringRef.h"
@@ -41,6 +39,7 @@
#include <cassert>
#include <cstddef>
#include <cstdint>
+#include <optional>
namespace clang {
@@ -272,7 +271,7 @@ struct ObjCDictionaryElement {
/// The number of elements this pack expansion will expand to, if
/// this is a pack expansion and is known.
- Optional<unsigned> NumExpansions;
+ std::optional<unsigned> NumExpansions;
/// Determines whether this dictionary element is a pack expansion.
bool isPackExpansion() const { return EllipsisLoc.isValid(); }
@@ -318,6 +317,7 @@ class ObjCDictionaryLiteral final
/// key/value pairs, which provide the locations of the ellipses (if
/// any) and number of elements in the expansion (if known). If
/// there are no pack expansions, we optimize away this storage.
+ LLVM_PREFERRED_TYPE(bool)
unsigned HasPackExpansions : 1;
SourceRange Range;
@@ -362,7 +362,8 @@ public:
ObjCDictionaryElement getKeyValueElement(unsigned Index) const {
assert((Index < NumElements) && "Arg access out of range!");
const KeyValuePair &KV = getTrailingObjects<KeyValuePair>()[Index];
- ObjCDictionaryElement Result = { KV.Key, KV.Value, SourceLocation(), None };
+ ObjCDictionaryElement Result = {KV.Key, KV.Value, SourceLocation(),
+ std::nullopt};
if (HasPackExpansions) {
const ExpansionData &Expansion =
getTrailingObjects<ExpansionData>()[Index];
@@ -554,9 +555,11 @@ class ObjCIvarRefExpr : public Expr {
SourceLocation OpLoc;
// True if this is "X->F", false if this is "X.F".
+ LLVM_PREFERRED_TYPE(bool)
bool IsArrow : 1;
// True if ivar reference has no base (self assumed).
+ LLVM_PREFERRED_TYPE(bool)
bool IsFreeIvar : 1;
public:
@@ -940,6 +943,23 @@ private:
class ObjCMessageExpr final
: public Expr,
private llvm::TrailingObjects<ObjCMessageExpr, void *, SourceLocation> {
+public:
+ /// The kind of receiver this message is sending to.
+ enum ReceiverKind {
+ /// The receiver is a class.
+ Class = 0,
+
+ /// The receiver is an object instance.
+ Instance,
+
+ /// The receiver is a superclass.
+ SuperClass,
+
+ /// The receiver is the instance of the superclass object.
+ SuperInstance
+ };
+
+private:
/// Stores either the selector that this message is sending
/// to (when \c HasMethod is zero) or an \c ObjCMethodDecl pointer
/// referring to the method that we type-checked against.
@@ -955,6 +975,7 @@ class ObjCMessageExpr final
/// ReceiverKind values.
///
/// We pad this out to a byte to avoid excessive masking and shifting.
+ LLVM_PREFERRED_TYPE(ReceiverKind)
unsigned Kind : 8;
/// Whether we have an actual method prototype in \c
@@ -962,18 +983,22 @@ class ObjCMessageExpr final
///
/// When non-zero, we have a method declaration; otherwise, we just
/// have a selector.
+ LLVM_PREFERRED_TYPE(bool)
unsigned HasMethod : 1;
/// Whether this message send is a "delegate init call",
/// i.e. a call of an init method on self from within an init method.
+ LLVM_PREFERRED_TYPE(bool)
unsigned IsDelegateInitCall : 1;
/// Whether this message send was implicitly generated by
/// the implementation rather than explicitly written by the user.
+ LLVM_PREFERRED_TYPE(bool)
unsigned IsImplicit : 1;
/// Whether the locations of the selector identifiers are in a
/// "standard" position, a enum SelectorLocationsKind.
+ LLVM_PREFERRED_TYPE(SelectorLocationsKind)
unsigned SelLocsKind : 2;
/// When the message expression is a send to 'super', this is
@@ -1082,21 +1107,6 @@ public:
friend class ASTStmtWriter;
friend TrailingObjects;
- /// The kind of receiver this message is sending to.
- enum ReceiverKind {
- /// The receiver is a class.
- Class = 0,
-
- /// The receiver is an object instance.
- Instance,
-
- /// The receiver is a superclass.
- SuperClass,
-
- /// The receiver is the instance of the superclass object.
- SuperInstance
- };
-
/// Create a message send to super.
///
/// \param Context The ASTContext in which this expression will be created.
@@ -1415,11 +1425,10 @@ public:
SourceLocation getSelectorLoc(unsigned Index) const {
assert(Index < getNumSelectorLocs() && "Index out of range!");
if (hasStandardSelLocs())
- return getStandardSelectorLoc(Index, getSelector(),
- getSelLocsKind() == SelLoc_StandardWithSpace,
- llvm::makeArrayRef(const_cast<Expr**>(getArgs()),
- getNumArgs()),
- RBracLoc);
+ return getStandardSelectorLoc(
+ Index, getSelector(), getSelLocsKind() == SelLoc_StandardWithSpace,
+ llvm::ArrayRef(const_cast<Expr **>(getArgs()), getNumArgs()),
+ RBracLoc);
return getStoredSelLocs()[Index];
}
@@ -1632,6 +1641,7 @@ class ObjCBridgedCastExpr final
SourceLocation LParenLoc;
SourceLocation BridgeKeywordLoc;
+ LLVM_PREFERRED_TYPE(ObjCBridgeCastKind)
unsigned Kind : 2;
public:
@@ -1706,7 +1716,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/ExprOpenMP.h b/contrib/llvm-project/clang/include/clang/AST/ExprOpenMP.h
index be5dda992334..be5b1f3fdd11 100644
--- a/contrib/llvm-project/clang/include/clang/AST/ExprOpenMP.h
+++ b/contrib/llvm-project/clang/include/clang/AST/ExprOpenMP.h
@@ -202,12 +202,12 @@ public:
/// Fetches the dimensions for array shaping expression.
ArrayRef<Expr *> getDimensions() const {
- return llvm::makeArrayRef(getTrailingObjects<Expr *>(), NumDims);
+ return llvm::ArrayRef(getTrailingObjects<Expr *>(), NumDims);
}
/// Fetches source ranges for the brackets os the array shaping expression.
ArrayRef<SourceRange> getBracketsRanges() const {
- return llvm::makeArrayRef(getTrailingObjects<SourceRange>(), NumDims);
+ return llvm::ArrayRef(getTrailingObjects<SourceRange>(), NumDims);
}
/// Fetches base expression of array shaping expression.
diff --git a/contrib/llvm-project/clang/include/clang/AST/ExternalASTMerger.h b/contrib/llvm-project/clang/include/clang/AST/ExternalASTMerger.h
index 0230495a5ef3..ec4cfbe2175c 100644
--- a/contrib/llvm-project/clang/include/clang/AST/ExternalASTMerger.h
+++ b/contrib/llvm-project/clang/include/clang/AST/ExternalASTMerger.h
@@ -118,7 +118,7 @@ public:
/// Asks all connected ASTImporters if any of them imported the given
/// declaration. If any ASTImporter did import the given declaration,
/// then this function returns the declaration that D was imported from.
- /// Returns nullptr if no ASTImporter did import import D.
+ /// Returns nullptr if no ASTImporter did import D.
Decl *FindOriginalDecl(Decl *D);
/// Add a set of ASTContexts as possible origins.
diff --git a/contrib/llvm-project/clang/include/clang/AST/ExternalASTSource.h b/contrib/llvm-project/clang/include/clang/AST/ExternalASTSource.h
index b1851afcda37..8e573965b0a3 100644
--- a/contrib/llvm-project/clang/include/clang/AST/ExternalASTSource.h
+++ b/contrib/llvm-project/clang/include/clang/AST/ExternalASTSource.h
@@ -20,7 +20,6 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/IntrusiveRefCntPtr.h"
-#include "llvm/ADT/Optional.h"
#include "llvm/ADT/PointerUnion.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallVector.h"
@@ -30,6 +29,7 @@
#include <cstddef>
#include <cstdint>
#include <iterator>
+#include <optional>
#include <utility>
namespace clang {
@@ -160,7 +160,7 @@ public:
virtual Module *getModule(unsigned ID) { return nullptr; }
/// Return a descriptor for the corresponding module, if one exists.
- virtual llvm::Optional<ASTSourceDescriptor> getSourceDescriptor(unsigned ID);
+ virtual std::optional<ASTSourceDescriptor> getSourceDescriptor(unsigned ID);
enum ExtKind { EK_Always, EK_Never, EK_ReplyHazy };
@@ -371,7 +371,7 @@ public:
/// \param Source the external AST source.
///
/// \returns a pointer to the AST node.
- T* get(ExternalASTSource *Source) const {
+ T *get(ExternalASTSource *Source) const {
if (isOffset()) {
assert(Source &&
"Cannot deserialize a lazy pointer without an AST source");
@@ -379,6 +379,14 @@ public:
}
return reinterpret_cast<T*>(Ptr);
}
+
+ /// Retrieve the address of the AST node pointer. Deserializes the pointee if
+ /// necessary.
+ T **getAddressOfPointer(ExternalASTSource *Source) const {
+ // Ensure the integer is in pointer form.
+ (void)get(Source);
+ return reinterpret_cast<T**>(&Ptr);
+ }
};
/// A lazy value (of type T) that is within an AST node of type Owner,
diff --git a/contrib/llvm-project/clang/include/clang/AST/FormatString.h b/contrib/llvm-project/clang/include/clang/AST/FormatString.h
index 8c944451f796..5c4ad9baaef6 100644
--- a/contrib/llvm-project/clang/include/clang/AST/FormatString.h
+++ b/contrib/llvm-project/clang/include/clang/AST/FormatString.h
@@ -15,10 +15,11 @@
//
//===----------------------------------------------------------------------===//
-#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"
+#include <optional>
namespace clang {
@@ -127,8 +128,12 @@ public:
dArg,
DArg, // Apple extension
iArg,
+ // C23 conversion specifiers.
+ bArg,
+ BArg,
+
IntArgBeg = dArg,
- IntArgEnd = iArg,
+ IntArgEnd = BArg,
oArg,
OArg, // Apple extension
@@ -237,7 +242,7 @@ public:
bool isPrintfKind() const { return IsPrintf; }
- Optional<ConversionSpecifier> getStandardSpecifier() const;
+ std::optional<ConversionSpecifier> getStandardSpecifier() const;
protected:
bool IsPrintf;
@@ -257,8 +262,14 @@ public:
/// instance, "%d" and float.
NoMatch = 0,
/// The conversion specifier and the argument type are compatible. For
- /// instance, "%d" and _Bool.
+ /// instance, "%d" and int.
Match = 1,
+ /// The conversion specifier and the argument type are compatible because of
+ /// default argument promotions. For instance, "%hhd" and int.
+ MatchPromotion,
+ /// The conversion specifier and the argument type are compatible but still
+ /// seems likely to be an error. For instanace, "%hhd" and short.
+ NoMatchPromotionTypeConfusion,
/// The conversion specifier and the argument type are disallowed by the C
/// standard, but are in practice harmless. For instance, "%p" and int*.
NoMatchPedantic,
@@ -332,11 +343,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),
@@ -456,7 +467,7 @@ public:
bool hasStandardLengthModifier() const;
- Optional<LengthModifier> getCorrectedLengthModifier() const;
+ std::optional<LengthModifier> getCorrectedLengthModifier() const;
bool hasStandardConversionSpecifier(const LangOptions &LangOpt) const;
@@ -726,7 +737,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/GlobalDecl.h b/contrib/llvm-project/clang/include/clang/AST/GlobalDecl.h
index 8cb56fb4ae90..88abba28c991 100644
--- a/contrib/llvm-project/clang/include/clang/AST/GlobalDecl.h
+++ b/contrib/llvm-project/clang/include/clang/AST/GlobalDecl.h
@@ -18,6 +18,7 @@
#include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclObjC.h"
#include "clang/AST/DeclOpenMP.h"
+#include "clang/AST/DeclTemplate.h"
#include "clang/Basic/ABI.h"
#include "clang/Basic/LLVM.h"
#include "llvm/ADT/DenseMapInfo.h"
@@ -129,8 +130,12 @@ public:
}
KernelReferenceKind getKernelReferenceKind() const {
- assert(isa<FunctionDecl>(getDecl()) &&
- cast<FunctionDecl>(getDecl())->hasAttr<CUDAGlobalAttr>() &&
+ assert(((isa<FunctionDecl>(getDecl()) &&
+ cast<FunctionDecl>(getDecl())->hasAttr<CUDAGlobalAttr>()) ||
+ (isa<FunctionTemplateDecl>(getDecl()) &&
+ cast<FunctionTemplateDecl>(getDecl())
+ ->getTemplatedDecl()
+ ->hasAttr<CUDAGlobalAttr>())) &&
"Decl is not a GPU kernel!");
return static_cast<KernelReferenceKind>(Value.getInt());
}
diff --git a/contrib/llvm-project/clang/include/clang/AST/IgnoreExpr.h b/contrib/llvm-project/clang/include/clang/AST/IgnoreExpr.h
index a7e9b07bef6c..917bada61fa6 100644
--- a/contrib/llvm-project/clang/include/clang/AST/IgnoreExpr.h
+++ b/contrib/llvm-project/clang/include/clang/AST/IgnoreExpr.h
@@ -23,7 +23,8 @@ namespace detail {
inline Expr *IgnoreExprNodesImpl(Expr *E) { return E; }
template <typename FnTy, typename... FnTys>
Expr *IgnoreExprNodesImpl(Expr *E, FnTy &&Fn, FnTys &&... Fns) {
- return IgnoreExprNodesImpl(Fn(E), std::forward<FnTys>(Fns)...);
+ return IgnoreExprNodesImpl(std::forward<FnTy>(Fn)(E),
+ std::forward<FnTys>(Fns)...);
}
} // namespace detail
@@ -165,6 +166,11 @@ inline Expr *IgnoreParensSingleStep(Expr *E) {
return CE->getChosenSubExpr();
}
+ else if (auto *PE = dyn_cast<PredefinedExpr>(E)) {
+ if (PE->isTransparent() && PE->getFunctionName())
+ return PE->getFunctionName();
+ }
+
return E;
}
diff --git a/contrib/llvm-project/clang/include/clang/AST/JSONNodeDumper.h b/contrib/llvm-project/clang/include/clang/AST/JSONNodeDumper.h
index a96e21993e20..4def5389137f 100644
--- a/contrib/llvm-project/clang/include/clang/AST/JSONNodeDumper.h
+++ b/contrib/llvm-project/clang/include/clang/AST/JSONNodeDumper.h
@@ -1,9 +1,8 @@
//===--- JSONNodeDumper.h - Printing of AST nodes to JSON -----------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// 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
//
//===----------------------------------------------------------------------===//
//
@@ -161,6 +160,7 @@ class JSONNodeDumper
std::string createPointerRepresentation(const void *Ptr);
llvm::json::Object createQualType(QualType QT, bool Desugar = true);
llvm::json::Object createBareDeclRef(const Decl *D);
+ llvm::json::Object createFPOptions(FPOptionsOverride FPO);
void writeBareDeclRef(const Decl *D);
llvm::json::Object createCXXRecordDefinitionData(const CXXRecordDecl *RD);
llvm::json::Object createCXXBaseSpecifier(const CXXBaseSpecifier &BS);
@@ -208,7 +208,16 @@ public:
void Visit(const concepts::Requirement *R);
void Visit(const APValue &Value, QualType Ty);
+ void VisitAliasAttr(const AliasAttr *AA);
+ void VisitCleanupAttr(const CleanupAttr *CA);
+ void VisitDeprecatedAttr(const DeprecatedAttr *DA);
+ void VisitUnavailableAttr(const UnavailableAttr *UA);
+ void VisitSectionAttr(const SectionAttr *SA);
+ void VisitVisibilityAttr(const VisibilityAttr *VA);
+ void VisitTLSModelAttr(const TLSModelAttr *TA);
+
void VisitTypedefType(const TypedefType *TT);
+ void VisitUsingType(const UsingType *TT);
void VisitFunctionType(const FunctionType *T);
void VisitFunctionProtoType(const FunctionProtoType *T);
void VisitRValueReferenceType(const ReferenceType *RT);
@@ -220,6 +229,9 @@ public:
void VisitUnaryTransformType(const UnaryTransformType *UTT);
void VisitTagType(const TagType *TT);
void VisitTemplateTypeParmType(const TemplateTypeParmType *TTPT);
+ void VisitSubstTemplateTypeParmType(const SubstTemplateTypeParmType *STTPT);
+ void
+ VisitSubstTemplateTypeParmPackType(const SubstTemplateTypeParmPackType *T);
void VisitAutoType(const AutoType *AT);
void VisitTemplateSpecializationType(const TemplateSpecializationType *TST);
void VisitInjectedClassNameType(const InjectedClassNameType *ICNT);
@@ -245,6 +257,7 @@ public:
void VisitEnumConstantDecl(const EnumConstantDecl *ECD);
void VisitRecordDecl(const RecordDecl *RD);
void VisitCXXRecordDecl(const CXXRecordDecl *RD);
+ void VisitHLSLBufferDecl(const HLSLBufferDecl *D);
void VisitTemplateTypeParmDecl(const TemplateTypeParmDecl *D);
void VisitNonTypeTemplateParmDecl(const NonTypeTemplateParmDecl *D);
void VisitTemplateTemplateParmDecl(const TemplateTemplateParmDecl *D);
@@ -272,6 +285,7 @@ public:
void VisitBinaryOperator(const BinaryOperator *BO);
void VisitCompoundAssignOperator(const CompoundAssignOperator *CAO);
void VisitMemberExpr(const MemberExpr *ME);
+ void VisitAtomicExpr(const AtomicExpr *AE);
void VisitCXXNewExpr(const CXXNewExpr *NE);
void VisitCXXDeleteExpr(const CXXDeleteExpr *DE);
void VisitCXXThisExpr(const CXXThisExpr *TE);
@@ -318,6 +332,7 @@ public:
void VisitGotoStmt(const GotoStmt *GS);
void VisitWhileStmt(const WhileStmt *WS);
void VisitObjCAtCatchStmt(const ObjCAtCatchStmt *OACS);
+ void VisitCompoundStmt(const CompoundStmt *IS);
void VisitNullTemplateArgument(const TemplateArgument &TA);
void VisitTypeTemplateArgument(const TemplateArgument &TA);
@@ -379,7 +394,7 @@ class JSONDumper : public ASTNodeTraverser<JSONDumper, JSONNodeDumper> {
case TSK_ExplicitInstantiationDefinition:
if (!DumpExplicitInst)
break;
- LLVM_FALLTHROUGH;
+ [[fallthrough]];
case TSK_Undeclared:
case TSK_ImplicitInstantiation:
if (DumpRefOnly)
diff --git a/contrib/llvm-project/clang/include/clang/AST/LambdaCapture.h b/contrib/llvm-project/clang/include/clang/AST/LambdaCapture.h
index 8e2806545dd6..62e7716ed369 100644
--- a/contrib/llvm-project/clang/include/clang/AST/LambdaCapture.h
+++ b/contrib/llvm-project/clang/include/clang/AST/LambdaCapture.h
@@ -71,7 +71,7 @@ public:
/// capture that is a pack expansion, or an invalid source
/// location to indicate that this is not a pack expansion.
LambdaCapture(SourceLocation Loc, bool Implicit, LambdaCaptureKind Kind,
- VarDecl *Var = nullptr,
+ ValueDecl *Var = nullptr,
SourceLocation EllipsisLoc = SourceLocation());
/// Determine the kind of capture.
@@ -86,7 +86,7 @@ public:
/// Determine whether this capture handles a variable.
bool capturesVariable() const {
- return dyn_cast_or_null<VarDecl>(DeclAndBits.getPointer());
+ return isa_and_nonnull<ValueDecl>(DeclAndBits.getPointer());
}
/// Determine whether this captures a variable length array bound
@@ -101,9 +101,9 @@ public:
///
/// This operation is only valid if this capture is a variable capture
/// (other than a capture of \c this).
- VarDecl *getCapturedVar() const {
+ ValueDecl *getCapturedVar() const {
assert(capturesVariable() && "No variable available for capture");
- return static_cast<VarDecl *>(DeclAndBits.getPointer());
+ return static_cast<ValueDecl *>(DeclAndBits.getPointer());
}
/// Determine whether this was an implicit capture (not
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/Mangle.h b/contrib/llvm-project/clang/include/clang/AST/Mangle.h
index 7d02f08e0120..e586b0cec43d 100644
--- a/contrib/llvm-project/clang/include/clang/AST/Mangle.h
+++ b/contrib/llvm-project/clang/include/clang/AST/Mangle.h
@@ -19,6 +19,7 @@
#include "clang/Basic/ABI.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/Support/Casting.h"
+#include <optional>
namespace llvm {
class raw_ostream;
@@ -54,18 +55,23 @@ private:
ASTContext &Context;
DiagnosticsEngine &Diags;
const ManglerKind Kind;
+ /// For aux target. If true, uses mangling number for aux target from
+ /// ASTContext.
+ bool IsAux = false;
llvm::DenseMap<const BlockDecl*, unsigned> GlobalBlockIds;
llvm::DenseMap<const BlockDecl*, unsigned> LocalBlockIds;
llvm::DenseMap<const NamedDecl*, uint64_t> AnonStructIds;
+ llvm::DenseMap<const FunctionDecl*, unsigned> FuncAnonStructSize;
public:
ManglerKind getKind() const { return Kind; }
- explicit MangleContext(ASTContext &Context,
- DiagnosticsEngine &Diags,
- ManglerKind Kind)
- : Context(Context), Diags(Diags), Kind(Kind) {}
+ bool isAux() const { return IsAux; }
+
+ explicit MangleContext(ASTContext &Context, DiagnosticsEngine &Diags,
+ ManglerKind Kind, bool IsAux = false)
+ : Context(Context), Diags(Diags), Kind(Kind), IsAux(IsAux) {}
virtual ~MangleContext() { }
@@ -83,9 +89,17 @@ public:
return Result.first->second;
}
- uint64_t getAnonymousStructId(const NamedDecl *D) {
+ uint64_t getAnonymousStructId(const NamedDecl *D,
+ const FunctionDecl *FD = nullptr) {
+ auto FindResult = AnonStructIds.find(D);
+ if (FindResult != AnonStructIds.end())
+ return FindResult->second;
+
+ // If FunctionDecl is passed in, the anonymous structID will be per-function
+ // based.
+ unsigned Id = FD ? FuncAnonStructSize[FD]++ : AnonStructIds.size();
std::pair<llvm::DenseMap<const NamedDecl *, uint64_t>::iterator, bool>
- Result = AnonStructIds.insert(std::make_pair(D, AnonStructIds.size()));
+ Result = AnonStructIds.insert(std::make_pair(D, Id));
return Result.first->second;
}
@@ -126,7 +140,8 @@ public:
unsigned ManglingNumber,
raw_ostream &) = 0;
virtual void mangleCXXRTTI(QualType T, raw_ostream &) = 0;
- virtual void mangleCXXRTTIName(QualType T, raw_ostream &) = 0;
+ virtual void mangleCXXRTTIName(QualType T, raw_ostream &,
+ bool NormalizeIntegers = false) = 0;
virtual void mangleStringLiteral(const StringLiteral *SL, raw_ostream &) = 0;
virtual void mangleMSGuidDecl(const MSGuidDecl *GD, raw_ostream&);
@@ -153,17 +168,18 @@ public:
virtual void mangleDynamicAtExitDestructor(const VarDecl *D,
raw_ostream &) = 0;
- virtual void mangleSEHFilterExpression(const NamedDecl *EnclosingDecl,
+ virtual void mangleSEHFilterExpression(GlobalDecl EnclosingDecl,
raw_ostream &Out) = 0;
- virtual void mangleSEHFinallyBlock(const NamedDecl *EnclosingDecl,
+ virtual void mangleSEHFinallyBlock(GlobalDecl EnclosingDecl,
raw_ostream &Out) = 0;
/// Generates a unique string for an externally visible type for use with TBAA
/// or type uniquing.
/// TODO: Extend this to internal types by generating names that are unique
/// across translation units so it can be used with LTO.
- virtual void mangleTypeName(QualType T, raw_ostream &) = 0;
+ virtual void mangleCanonicalTypeName(QualType T, raw_ostream &,
+ bool NormalizeIntegers = false) = 0;
/// @}
};
@@ -171,9 +187,10 @@ public:
class ItaniumMangleContext : public MangleContext {
public:
using DiscriminatorOverrideTy =
- llvm::Optional<unsigned> (*)(ASTContext &, const NamedDecl *);
- explicit ItaniumMangleContext(ASTContext &C, DiagnosticsEngine &D)
- : MangleContext(C, D, MK_Itanium) {}
+ std::optional<unsigned> (*)(ASTContext &, const NamedDecl *);
+ explicit ItaniumMangleContext(ASTContext &C, DiagnosticsEngine &D,
+ bool IsAux = false)
+ : MangleContext(C, D, MK_Itanium, IsAux) {}
virtual void mangleCXXVTable(const CXXRecordDecl *RD, raw_ostream &) = 0;
virtual void mangleCXXVTT(const CXXRecordDecl *RD, raw_ostream &) = 0;
@@ -194,6 +211,8 @@ public:
virtual void mangleDynamicStermFinalizer(const VarDecl *D, raw_ostream &) = 0;
+ virtual void mangleModuleInitializer(const Module *Module, raw_ostream &) = 0;
+
// This has to live here, otherwise the CXXNameMangler won't have access to
// it.
virtual DiscriminatorOverrideTy getDiscriminatorOverride() const = 0;
@@ -201,17 +220,19 @@ public:
return C->getKind() == MK_Itanium;
}
- static ItaniumMangleContext *create(ASTContext &Context,
- DiagnosticsEngine &Diags);
+ static ItaniumMangleContext *
+ create(ASTContext &Context, DiagnosticsEngine &Diags, bool IsAux = false);
static ItaniumMangleContext *create(ASTContext &Context,
DiagnosticsEngine &Diags,
- DiscriminatorOverrideTy Discriminator);
+ DiscriminatorOverrideTy Discriminator,
+ bool IsAux = false);
};
class MicrosoftMangleContext : public MangleContext {
public:
- explicit MicrosoftMangleContext(ASTContext &C, DiagnosticsEngine &D)
- : MangleContext(C, D, MK_Microsoft) {}
+ explicit MicrosoftMangleContext(ASTContext &C, DiagnosticsEngine &D,
+ bool IsAux = false)
+ : MangleContext(C, D, MK_Microsoft, IsAux) {}
/// Mangle vftable symbols. Only a subset of the bases along the path
/// to the vftable are included in the name. It's up to the caller to pick
@@ -270,8 +291,8 @@ public:
return C->getKind() == MK_Microsoft;
}
- static MicrosoftMangleContext *create(ASTContext &Context,
- DiagnosticsEngine &Diags);
+ static MicrosoftMangleContext *
+ create(ASTContext &Context, DiagnosticsEngine &Diags, bool IsAux = false);
};
class ASTNameGenerator {
diff --git a/contrib/llvm-project/clang/include/clang/AST/MangleNumberingContext.h b/contrib/llvm-project/clang/include/clang/AST/MangleNumberingContext.h
index eb33759682d6..1313c94eb122 100644
--- a/contrib/llvm-project/clang/include/clang/AST/MangleNumberingContext.h
+++ b/contrib/llvm-project/clang/include/clang/AST/MangleNumberingContext.h
@@ -21,14 +21,15 @@ 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
/// literals within a particular context.
class MangleNumberingContext {
+ // The index of the next lambda we encounter in this context.
+ unsigned LambdaIndex = 0;
+
public:
virtual ~MangleNumberingContext() {}
@@ -57,6 +58,11 @@ public:
/// given call operator within the device context. No device number is
/// assigned if there's no device numbering context is associated.
virtual unsigned getDeviceManglingNumber(const CXXMethodDecl *) { return 0; }
+
+ // Retrieve the index of the next lambda appearing in this context, which is
+ // used for deduplicating lambdas across modules. Note that this is a simple
+ // sequence number and is not ABI-dependent.
+ unsigned getNextLambdaIndex() { return LambdaIndex++; }
};
} // end namespace clang
diff --git a/contrib/llvm-project/clang/include/clang/AST/NSAPI.h b/contrib/llvm-project/clang/include/clang/AST/NSAPI.h
index a8bd2d0f17e6..d411c34191ed 100644
--- a/contrib/llvm-project/clang/include/clang/AST/NSAPI.h
+++ b/contrib/llvm-project/clang/include/clang/AST/NSAPI.h
@@ -11,7 +11,7 @@
#include "clang/Basic/IdentifierTable.h"
#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/Optional.h"
+#include <optional>
namespace clang {
class ASTContext;
@@ -89,7 +89,7 @@ public:
Selector getNSArraySelector(NSArrayMethodKind MK) const;
/// Return NSArrayMethodKind if \p Sel is such a selector.
- Optional<NSArrayMethodKind> getNSArrayMethodKind(Selector Sel);
+ std::optional<NSArrayMethodKind> getNSArrayMethodKind(Selector Sel);
/// Enumerates the NSDictionary/NSMutableDictionary methods used
/// to generate literals and to apply some checks.
@@ -114,7 +114,7 @@ public:
Selector getNSDictionarySelector(NSDictionaryMethodKind MK) const;
/// Return NSDictionaryMethodKind if \p Sel is such a selector.
- Optional<NSDictionaryMethodKind> getNSDictionaryMethodKind(Selector Sel);
+ std::optional<NSDictionaryMethodKind> getNSDictionaryMethodKind(Selector Sel);
/// Enumerates the NSMutableSet/NSOrderedSet methods used
/// to apply some checks.
@@ -131,7 +131,7 @@ public:
Selector getNSSetSelector(NSSetMethodKind MK) const;
/// Return NSSetMethodKind if \p Sel is such a selector.
- Optional<NSSetMethodKind> getNSSetMethodKind(Selector Sel);
+ std::optional<NSSetMethodKind> getNSSetMethodKind(Selector Sel);
/// Returns selector for "objectForKeyedSubscript:".
Selector getObjectForKeyedSubscriptSelector() const {
@@ -203,13 +203,13 @@ public:
}
/// Return NSNumberLiteralMethodKind if \p Sel is such a selector.
- Optional<NSNumberLiteralMethodKind>
- getNSNumberLiteralMethodKind(Selector Sel) const;
+ std::optional<NSNumberLiteralMethodKind>
+ getNSNumberLiteralMethodKind(Selector Sel) const;
/// Determine the appropriate NSNumber factory method kind for a
/// literal of the given type.
- Optional<NSNumberLiteralMethodKind>
- getNSNumberFactoryMethodKind(QualType T) const;
+ std::optional<NSNumberLiteralMethodKind>
+ getNSNumberFactoryMethodKind(QualType T) const;
/// Returns true if \param T is a typedef of "BOOL" in objective-c.
bool isObjCBOOLType(QualType T) const;
diff --git a/contrib/llvm-project/clang/include/clang/AST/NestedNameSpecifier.h b/contrib/llvm-project/clang/include/clang/AST/NestedNameSpecifier.h
index 8bc3e25c0f4b..3b6cf9721185 100644
--- a/contrib/llvm-project/clang/include/clang/AST/NestedNameSpecifier.h
+++ b/contrib/llvm-project/clang/include/clang/AST/NestedNameSpecifier.h
@@ -162,7 +162,7 @@ public:
/// Return the prefix of this nested name specifier.
///
/// The prefix contains all of the parts of the nested name
- /// specifier that preced this current specifier. For example, for a
+ /// specifier that precede this current specifier. For example, for a
/// nested name specifier that represents "foo::bar::", the current
/// specifier will contain "bar::" and the prefix will contain
/// "foo::".
@@ -521,7 +521,7 @@ public:
/// NestedNameSpecifiers into a diagnostic with <<.
inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB,
NestedNameSpecifier *NNS) {
- DB.AddTaggedVal(reinterpret_cast<intptr_t>(NNS),
+ DB.AddTaggedVal(reinterpret_cast<uint64_t>(NNS),
DiagnosticsEngine::ak_nestednamespec);
return DB;
}
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/ODRDiagsEmitter.h b/contrib/llvm-project/clang/include/clang/AST/ODRDiagsEmitter.h
new file mode 100644
index 000000000000..1f7faaa06e54
--- /dev/null
+++ b/contrib/llvm-project/clang/include/clang/AST/ODRDiagsEmitter.h
@@ -0,0 +1,203 @@
+//===- ODRDiagsEmitter.h - Emits diagnostic for ODR mismatches --*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_ODRDIAGSEMITTER_H
+#define LLVM_CLANG_AST_ODRDIAGSEMITTER_H
+
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/DeclCXX.h"
+#include "clang/AST/DeclObjC.h"
+#include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/LangOptions.h"
+
+namespace clang {
+
+class ODRDiagsEmitter {
+public:
+ ODRDiagsEmitter(DiagnosticsEngine &Diags, const ASTContext &Context,
+ const LangOptions &LangOpts)
+ : Diags(Diags), Context(Context), LangOpts(LangOpts) {}
+
+ /// Diagnose ODR mismatch between 2 FunctionDecl.
+ ///
+ /// Returns true if found a mismatch and diagnosed it.
+ bool diagnoseMismatch(const FunctionDecl *FirstFunction,
+ const FunctionDecl *SecondFunction) const;
+
+ /// Diagnose ODR mismatch between 2 EnumDecl.
+ ///
+ /// Returns true if found a mismatch and diagnosed it.
+ bool diagnoseMismatch(const EnumDecl *FirstEnum,
+ const EnumDecl *SecondEnum) const;
+
+ /// Diagnose ODR mismatch between 2 CXXRecordDecl.
+ ///
+ /// Returns true if found a mismatch and diagnosed it.
+ /// To compare 2 declarations with merged and identical definition data
+ /// you need to provide pre-merge definition data in \p SecondDD.
+ bool
+ diagnoseMismatch(const CXXRecordDecl *FirstRecord,
+ const CXXRecordDecl *SecondRecord,
+ const struct CXXRecordDecl::DefinitionData *SecondDD) const;
+
+ /// Diagnose ODR mismatch between 2 RecordDecl that are not CXXRecordDecl.
+ ///
+ /// Returns true if found a mismatch and diagnosed it.
+ bool diagnoseMismatch(const RecordDecl *FirstRecord,
+ const RecordDecl *SecondRecord) const;
+
+ /// Diagnose ODR mismatch between 2 ObjCInterfaceDecl.
+ ///
+ /// Returns true if found a mismatch and diagnosed it.
+ bool diagnoseMismatch(
+ const ObjCInterfaceDecl *FirstID, const ObjCInterfaceDecl *SecondID,
+ const struct ObjCInterfaceDecl::DefinitionData *SecondDD) const;
+
+ /// Diagnose ODR mismatch between ObjCInterfaceDecl with different
+ /// definitions.
+ bool diagnoseMismatch(const ObjCInterfaceDecl *FirstID,
+ const ObjCInterfaceDecl *SecondID) const {
+ assert(FirstID->data().Definition != SecondID->data().Definition &&
+ "Don't diagnose differences when definitions are merged already");
+ return diagnoseMismatch(FirstID, SecondID, &SecondID->data());
+ }
+
+ /// Diagnose ODR mismatch between 2 ObjCProtocolDecl.
+ ///
+ /// Returns true if found a mismatch and diagnosed it.
+ /// To compare 2 declarations with merged and identical definition data
+ /// you need to provide pre-merge definition data in \p SecondDD.
+ bool diagnoseMismatch(
+ const ObjCProtocolDecl *FirstProtocol,
+ const ObjCProtocolDecl *SecondProtocol,
+ const struct ObjCProtocolDecl::DefinitionData *SecondDD) const;
+
+ /// Diagnose ODR mismatch between ObjCProtocolDecl with different definitions.
+ bool diagnoseMismatch(const ObjCProtocolDecl *FirstProtocol,
+ const ObjCProtocolDecl *SecondProtocol) const {
+ assert(FirstProtocol->data().Definition !=
+ SecondProtocol->data().Definition &&
+ "Don't diagnose differences when definitions are merged already");
+ return diagnoseMismatch(FirstProtocol, SecondProtocol,
+ &SecondProtocol->data());
+ }
+
+ /// Get the best name we know for the module that owns the given
+ /// declaration, or an empty string if the declaration is not from a module.
+ static std::string getOwningModuleNameForDiagnostic(const Decl *D);
+
+private:
+ using DeclHashes = llvm::SmallVector<std::pair<const Decl *, unsigned>, 4>;
+
+ // Used with err_module_odr_violation_mismatch_decl,
+ // note_module_odr_violation_mismatch_decl,
+ // err_module_odr_violation_mismatch_decl_unknown,
+ // and note_module_odr_violation_mismatch_decl_unknown
+ // This list should be the same Decl's as in ODRHash::isSubDeclToBeProcessed
+ enum ODRMismatchDecl {
+ EndOfClass,
+ PublicSpecifer,
+ PrivateSpecifer,
+ ProtectedSpecifer,
+ StaticAssert,
+ Field,
+ CXXMethod,
+ TypeAlias,
+ TypeDef,
+ Var,
+ Friend,
+ FunctionTemplate,
+ ObjCMethod,
+ ObjCIvar,
+ ObjCProperty,
+ Other
+ };
+
+ struct DiffResult {
+ const Decl *FirstDecl = nullptr, *SecondDecl = nullptr;
+ ODRMismatchDecl FirstDiffType = Other, SecondDiffType = Other;
+ };
+
+ // If there is a diagnoseable difference, FirstDiffType and
+ // SecondDiffType will not be Other and FirstDecl and SecondDecl will be
+ // filled in if not EndOfClass.
+ static DiffResult FindTypeDiffs(DeclHashes &FirstHashes,
+ DeclHashes &SecondHashes);
+
+ DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID) const {
+ return Diags.Report(Loc, DiagID);
+ }
+
+ // Use this to diagnose that an unexpected Decl was encountered
+ // or no difference was detected. This causes a generic error
+ // message to be emitted.
+ void diagnoseSubMismatchUnexpected(DiffResult &DR,
+ const NamedDecl *FirstRecord,
+ StringRef FirstModule,
+ const NamedDecl *SecondRecord,
+ StringRef SecondModule) const;
+
+ void diagnoseSubMismatchDifferentDeclKinds(DiffResult &DR,
+ const NamedDecl *FirstRecord,
+ StringRef FirstModule,
+ const NamedDecl *SecondRecord,
+ StringRef SecondModule) const;
+
+ bool diagnoseSubMismatchField(const NamedDecl *FirstRecord,
+ StringRef FirstModule, StringRef SecondModule,
+ const FieldDecl *FirstField,
+ const FieldDecl *SecondField) const;
+
+ bool diagnoseSubMismatchTypedef(const NamedDecl *FirstRecord,
+ StringRef FirstModule, StringRef SecondModule,
+ const TypedefNameDecl *FirstTD,
+ const TypedefNameDecl *SecondTD,
+ bool IsTypeAlias) const;
+
+ bool diagnoseSubMismatchVar(const NamedDecl *FirstRecord,
+ StringRef FirstModule, StringRef SecondModule,
+ const VarDecl *FirstVD,
+ const VarDecl *SecondVD) const;
+
+ /// Check if protocol lists are the same and diagnose if they are different.
+ ///
+ /// Returns true if found a mismatch and diagnosed it.
+ bool diagnoseSubMismatchProtocols(const ObjCProtocolList &FirstProtocols,
+ const ObjCContainerDecl *FirstContainer,
+ StringRef FirstModule,
+ const ObjCProtocolList &SecondProtocols,
+ const ObjCContainerDecl *SecondContainer,
+ StringRef SecondModule) const;
+
+ /// Check if Objective-C methods are the same and diagnose if different.
+ ///
+ /// Returns true if found a mismatch and diagnosed it.
+ bool diagnoseSubMismatchObjCMethod(const NamedDecl *FirstObjCContainer,
+ StringRef FirstModule,
+ StringRef SecondModule,
+ const ObjCMethodDecl *FirstMethod,
+ const ObjCMethodDecl *SecondMethod) const;
+
+ /// Check if Objective-C properties are the same and diagnose if different.
+ ///
+ /// Returns true if found a mismatch and diagnosed it.
+ bool
+ diagnoseSubMismatchObjCProperty(const NamedDecl *FirstObjCContainer,
+ StringRef FirstModule, StringRef SecondModule,
+ const ObjCPropertyDecl *FirstProp,
+ const ObjCPropertyDecl *SecondProp) const;
+
+private:
+ DiagnosticsEngine &Diags;
+ const ASTContext &Context;
+ const LangOptions &LangOpts;
+};
+
+} // namespace clang
+
+#endif
diff --git a/contrib/llvm-project/clang/include/clang/AST/ODRHash.h b/contrib/llvm-project/clang/include/clang/AST/ODRHash.h
index 2e8593e0b835..a1caa6d39a87 100644
--- a/contrib/llvm-project/clang/include/clang/AST/ODRHash.h
+++ b/contrib/llvm-project/clang/include/clang/AST/ODRHash.h
@@ -25,6 +25,7 @@
namespace clang {
+class APValue;
class Decl;
class IdentifierInfo;
class NestedNameSpecifier;
@@ -55,6 +56,14 @@ public:
// more information than the AddDecl class.
void AddCXXRecordDecl(const CXXRecordDecl *Record);
+ // Use this for ODR checking records in C/Objective-C between modules. This
+ // method compares more information than the AddDecl class.
+ void AddRecordDecl(const RecordDecl *Record);
+
+ // Use this for ODR checking ObjC interfaces. This
+ // method compares more information than the AddDecl class.
+ void AddObjCInterfaceDecl(const ObjCInterfaceDecl *Record);
+
// Use this for ODR checking functions between modules. This method compares
// more information than the AddDecl class. SkipBody will process the
// hash as if the function has no body.
@@ -64,6 +73,10 @@ public:
// more information than the AddDecl class.
void AddEnumDecl(const EnumDecl *Enum);
+ // Use this for ODR checking ObjC protocols. This
+ // method compares more information than the AddDecl class.
+ void AddObjCProtocolDecl(const ObjCProtocolDecl *P);
+
// Process SubDecls of the main Decl. This method calls the DeclVisitor
// while AddDecl does not.
void AddSubDecl(const Decl *D);
@@ -89,7 +102,9 @@ public:
// Save booleans until the end to lower the size of data to process.
void AddBoolean(bool value);
- static bool isDeclToBeProcessed(const Decl* D, const DeclContext *Parent);
+ void AddStructuralValue(const APValue &);
+
+ static bool isSubDeclToBeProcessed(const Decl *D, const DeclContext *Parent);
private:
void AddDeclarationNameImpl(DeclarationName Name);
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 aaddcfa307da..924ca189381b 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"
@@ -106,6 +107,89 @@ public:
static bool classof(const OMPClause *) { return true; }
};
+template <OpenMPClauseKind ClauseKind>
+struct OMPNoChildClause : public OMPClause {
+ /// Build '\p ClauseKind' clause.
+ ///
+ /// \param StartLoc Starting location of the clause.
+ /// \param EndLoc Ending location of the clause.
+ OMPNoChildClause(SourceLocation StartLoc, SourceLocation EndLoc)
+ : OMPClause(ClauseKind, StartLoc, EndLoc) {}
+
+ /// Build an empty clause.
+ OMPNoChildClause()
+ : OMPClause(ClauseKind, SourceLocation(), SourceLocation()) {}
+
+ child_range children() {
+ return child_range(child_iterator(), child_iterator());
+ }
+
+ const_child_range children() const {
+ return const_child_range(const_child_iterator(), const_child_iterator());
+ }
+
+ child_range used_children() {
+ return child_range(child_iterator(), child_iterator());
+ }
+ const_child_range used_children() const {
+ return const_child_range(const_child_iterator(), const_child_iterator());
+ }
+
+ static bool classof(const OMPClause *T) {
+ return T->getClauseKind() == ClauseKind;
+ }
+};
+
+template <OpenMPClauseKind ClauseKind, class Base>
+class OMPOneStmtClause : public Base {
+
+ /// Location of '('.
+ SourceLocation LParenLoc;
+
+ /// Sub-expression.
+ Stmt *S = nullptr;
+
+protected:
+ void setStmt(Stmt *S) { this->S = S; }
+
+public:
+ OMPOneStmtClause(Stmt *S, SourceLocation StartLoc, SourceLocation LParenLoc,
+ SourceLocation EndLoc)
+ : Base(ClauseKind, StartLoc, EndLoc), LParenLoc(LParenLoc), S(S) {}
+
+ OMPOneStmtClause() : Base(ClauseKind, SourceLocation(), SourceLocation()) {}
+
+ /// Return the associated statement, potentially casted to \p T.
+ template <typename T> T *getStmtAs() const { return cast_or_null<T>(S); }
+
+ /// Sets the location of '('.
+ void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
+
+ /// Returns the location of '('.
+ SourceLocation getLParenLoc() const { return LParenLoc; }
+
+ using child_iterator = StmtIterator;
+ using const_child_iterator = ConstStmtIterator;
+ using child_range = llvm::iterator_range<child_iterator>;
+ using const_child_range = llvm::iterator_range<const_child_iterator>;
+
+ child_range children() { return child_range(&S, &S + 1); }
+
+ const_child_range children() const { return const_child_range(&S, &S + 1); }
+
+ // TODO: Consider making the getAddrOfExprAsWritten version the default.
+ child_range used_children() {
+ return child_range(child_iterator(), child_iterator());
+ }
+ const_child_range used_children() const {
+ return const_child_range(const_child_iterator(), const_child_iterator());
+ }
+
+ static bool classof(const OMPClause *T) {
+ return T->getClauseKind() == ClauseKind;
+ }
+};
+
/// Class that handles pre-initialization statement for some clauses, like
/// 'shedule', 'firstprivate' etc.
class OMPClauseWithPreInit {
@@ -252,7 +336,7 @@ public:
/// Fetches list of all variables in the clause.
ArrayRef<const Expr *> getVarRefs() const {
- return llvm::makeArrayRef(
+ return llvm::ArrayRef(
static_cast<const T *>(this)->template getTrailingObjects<Expr *>(),
NumVars);
}
@@ -266,17 +350,12 @@ public:
/// \endcode
/// In this example directive '#pragma omp allocate' has simple 'allocator'
/// clause with the allocator 'omp_default_mem_alloc'.
-class OMPAllocatorClause : public OMPClause {
+class OMPAllocatorClause final
+ : public OMPOneStmtClause<llvm::omp::OMPC_allocator, OMPClause> {
friend class OMPClauseReader;
- /// Location of '('.
- SourceLocation LParenLoc;
-
- /// Expression with the allocator.
- Stmt *Allocator = nullptr;
-
/// Set allocator.
- void setAllocator(Expr *A) { Allocator = A; }
+ void setAllocator(Expr *A) { setStmt(A); }
public:
/// Build 'allocator' clause with the given allocator.
@@ -287,39 +366,58 @@ public:
/// \param EndLoc Ending location of the clause.
OMPAllocatorClause(Expr *A, SourceLocation StartLoc, SourceLocation LParenLoc,
SourceLocation EndLoc)
- : OMPClause(llvm::omp::OMPC_allocator, StartLoc, EndLoc),
- LParenLoc(LParenLoc), Allocator(A) {}
+ : OMPOneStmtClause(A, StartLoc, LParenLoc, EndLoc) {}
/// Build an empty clause.
- OMPAllocatorClause()
- : OMPClause(llvm::omp::OMPC_allocator, SourceLocation(),
- SourceLocation()) {}
+ OMPAllocatorClause() : OMPOneStmtClause() {}
- /// Sets the location of '('.
- void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
+ /// Returns allocator.
+ Expr *getAllocator() const { return getStmtAs<Expr>(); }
+};
- /// Returns the location of '('.
- SourceLocation getLParenLoc() const { return LParenLoc; }
+/// This represents the 'align' clause in the '#pragma omp allocate'
+/// directive.
+///
+/// \code
+/// #pragma omp allocate(a) allocator(omp_default_mem_alloc) align(8)
+/// \endcode
+/// In this example directive '#pragma omp allocate' has simple 'allocator'
+/// clause with the allocator 'omp_default_mem_alloc' and align clause with
+/// value of 8.
+class OMPAlignClause final
+ : public OMPOneStmtClause<llvm::omp::OMPC_align, OMPClause> {
+ friend class OMPClauseReader;
- /// Returns allocator.
- Expr *getAllocator() const { return cast_or_null<Expr>(Allocator); }
+ /// Set alignment value.
+ void setAlignment(Expr *A) { setStmt(A); }
- child_range children() { return child_range(&Allocator, &Allocator + 1); }
+ /// Build 'align' clause with the given alignment
+ ///
+ /// \param A Alignment value.
+ /// \param StartLoc Starting location of the clause.
+ /// \param LParenLoc Location of '('.
+ /// \param EndLoc Ending location of the clause.
+ OMPAlignClause(Expr *A, SourceLocation StartLoc, SourceLocation LParenLoc,
+ SourceLocation EndLoc)
+ : OMPOneStmtClause(A, StartLoc, LParenLoc, EndLoc) {}
- const_child_range children() const {
- return const_child_range(&Allocator, &Allocator + 1);
- }
+ /// Build an empty clause.
+ OMPAlignClause() : OMPOneStmtClause() {}
- child_range used_children() {
- return child_range(child_iterator(), child_iterator());
- }
- const_child_range used_children() const {
- return const_child_range(const_child_iterator(), const_child_iterator());
- }
+public:
+ /// Build 'align' clause with the given alignment
+ ///
+ /// \param A Alignment value.
+ /// \param StartLoc Starting location of the clause.
+ /// \param LParenLoc Location of '('.
+ /// \param EndLoc Ending location of the clause.
+ static OMPAlignClause *Create(const ASTContext &C, Expr *A,
+ SourceLocation StartLoc,
+ SourceLocation LParenLoc,
+ SourceLocation EndLoc);
- static bool classof(const OMPClause *T) {
- return T->getClauseKind() == llvm::omp::OMPC_allocator;
- }
+ /// Returns alignment
+ Expr *getAlignment() const { return getStmtAs<Expr>(); }
};
/// This represents clause 'allocate' in the '#pragma omp ...' directives.
@@ -527,17 +625,13 @@ public:
/// \endcode
/// In this example directive '#pragma omp task' has simple 'final'
/// clause with condition 'a > 5'.
-class OMPFinalClause : public OMPClause, public OMPClauseWithPreInit {
+class OMPFinalClause final
+ : public OMPOneStmtClause<llvm::omp::OMPC_final, OMPClause>,
+ public OMPClauseWithPreInit {
friend class OMPClauseReader;
- /// Location of '('.
- SourceLocation LParenLoc;
-
- /// Condition of the 'if' clause.
- Stmt *Condition = nullptr;
-
/// Set condition.
- void setCondition(Expr *Cond) { Condition = Cond; }
+ void setCondition(Expr *Cond) { setStmt(Cond); }
public:
/// Build 'final' clause with condition \a Cond.
@@ -552,42 +646,23 @@ public:
OMPFinalClause(Expr *Cond, Stmt *HelperCond,
OpenMPDirectiveKind CaptureRegion, SourceLocation StartLoc,
SourceLocation LParenLoc, SourceLocation EndLoc)
- : OMPClause(llvm::omp::OMPC_final, StartLoc, EndLoc),
- OMPClauseWithPreInit(this), LParenLoc(LParenLoc), Condition(Cond) {
+ : OMPOneStmtClause(Cond, StartLoc, LParenLoc, EndLoc),
+ OMPClauseWithPreInit(this) {
setPreInitStmt(HelperCond, CaptureRegion);
}
/// Build an empty clause.
- OMPFinalClause()
- : OMPClause(llvm::omp::OMPC_final, SourceLocation(), SourceLocation()),
- OMPClauseWithPreInit(this) {}
-
- /// Sets the location of '('.
- void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
-
- /// Returns the location of '('.
- SourceLocation getLParenLoc() const { return LParenLoc; }
+ OMPFinalClause() : OMPOneStmtClause(), OMPClauseWithPreInit(this) {}
/// Returns condition.
- Expr *getCondition() const { return cast_or_null<Expr>(Condition); }
-
- child_range children() { return child_range(&Condition, &Condition + 1); }
-
- const_child_range children() const {
- return const_child_range(&Condition, &Condition + 1);
- }
+ Expr *getCondition() const { return getStmtAs<Expr>(); }
child_range used_children();
const_child_range used_children() const {
auto Children = const_cast<OMPFinalClause *>(this)->used_children();
return const_child_range(Children.begin(), Children.end());
}
-
- static bool classof(const OMPClause *T) {
- return T->getClauseKind() == llvm::omp::OMPC_final;
- }
};
-
/// This represents 'num_threads' clause in the '#pragma omp ...'
/// directive.
///
@@ -596,17 +671,13 @@ public:
/// \endcode
/// In this example directive '#pragma omp parallel' has simple 'num_threads'
/// clause with number of threads '6'.
-class OMPNumThreadsClause : public OMPClause, public OMPClauseWithPreInit {
+class OMPNumThreadsClause final
+ : public OMPOneStmtClause<llvm::omp::OMPC_num_threads, OMPClause>,
+ public OMPClauseWithPreInit {
friend class OMPClauseReader;
- /// Location of '('.
- SourceLocation LParenLoc;
-
- /// Condition of the 'num_threads' clause.
- Stmt *NumThreads = nullptr;
-
/// Set condition.
- void setNumThreads(Expr *NThreads) { NumThreads = NThreads; }
+ void setNumThreads(Expr *NThreads) { setStmt(NThreads); }
public:
/// Build 'num_threads' clause with condition \a NumThreads.
@@ -622,43 +693,16 @@ public:
OpenMPDirectiveKind CaptureRegion,
SourceLocation StartLoc, SourceLocation LParenLoc,
SourceLocation EndLoc)
- : OMPClause(llvm::omp::OMPC_num_threads, StartLoc, EndLoc),
- OMPClauseWithPreInit(this), LParenLoc(LParenLoc),
- NumThreads(NumThreads) {
+ : OMPOneStmtClause(NumThreads, StartLoc, LParenLoc, EndLoc),
+ OMPClauseWithPreInit(this) {
setPreInitStmt(HelperNumThreads, CaptureRegion);
}
/// Build an empty clause.
- OMPNumThreadsClause()
- : OMPClause(llvm::omp::OMPC_num_threads, SourceLocation(),
- SourceLocation()),
- OMPClauseWithPreInit(this) {}
-
- /// Sets the location of '('.
- void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
-
- /// Returns the location of '('.
- SourceLocation getLParenLoc() const { return LParenLoc; }
+ OMPNumThreadsClause() : OMPOneStmtClause(), OMPClauseWithPreInit(this) {}
/// Returns number of threads.
- Expr *getNumThreads() const { return cast_or_null<Expr>(NumThreads); }
-
- child_range children() { return child_range(&NumThreads, &NumThreads + 1); }
-
- const_child_range children() const {
- return const_child_range(&NumThreads, &NumThreads + 1);
- }
-
- child_range used_children() {
- return child_range(child_iterator(), child_iterator());
- }
- const_child_range used_children() const {
- return const_child_range(const_child_iterator(), const_child_iterator());
- }
-
- static bool classof(const OMPClause *T) {
- return T->getClauseKind() == llvm::omp::OMPC_num_threads;
- }
+ Expr *getNumThreads() const { return getStmtAs<Expr>(); }
};
/// This represents 'safelen' clause in the '#pragma omp ...'
@@ -673,17 +717,12 @@ public:
/// concurrently with SIMD instructions can have a greater distance
/// in the logical iteration space than its value. The parameter of
/// the safelen clause must be a constant positive integer expression.
-class OMPSafelenClause : public OMPClause {
+class OMPSafelenClause final
+ : public OMPOneStmtClause<llvm::omp::OMPC_safelen, OMPClause> {
friend class OMPClauseReader;
- /// Location of '('.
- SourceLocation LParenLoc;
-
- /// Safe iteration space distance.
- Stmt *Safelen = nullptr;
-
/// Set safelen.
- void setSafelen(Expr *Len) { Safelen = Len; }
+ void setSafelen(Expr *Len) { setStmt(Len); }
public:
/// Build 'safelen' clause.
@@ -693,39 +732,13 @@ public:
/// \param EndLoc Ending location of the clause.
OMPSafelenClause(Expr *Len, SourceLocation StartLoc, SourceLocation LParenLoc,
SourceLocation EndLoc)
- : OMPClause(llvm::omp::OMPC_safelen, StartLoc, EndLoc),
- LParenLoc(LParenLoc), Safelen(Len) {}
+ : OMPOneStmtClause(Len, StartLoc, LParenLoc, EndLoc) {}
/// Build an empty clause.
- explicit OMPSafelenClause()
- : OMPClause(llvm::omp::OMPC_safelen, SourceLocation(), SourceLocation()) {
- }
-
- /// Sets the location of '('.
- void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
-
- /// Returns the location of '('.
- SourceLocation getLParenLoc() const { return LParenLoc; }
+ explicit OMPSafelenClause() : OMPOneStmtClause() {}
/// Return safe iteration space distance.
- Expr *getSafelen() const { return cast_or_null<Expr>(Safelen); }
-
- child_range children() { return child_range(&Safelen, &Safelen + 1); }
-
- const_child_range children() const {
- return const_child_range(&Safelen, &Safelen + 1);
- }
-
- child_range used_children() {
- return child_range(child_iterator(), child_iterator());
- }
- const_child_range used_children() const {
- return const_child_range(const_child_iterator(), const_child_iterator());
- }
-
- static bool classof(const OMPClause *T) {
- return T->getClauseKind() == llvm::omp::OMPC_safelen;
- }
+ Expr *getSafelen() const { return getStmtAs<Expr>(); }
};
/// This represents 'simdlen' clause in the '#pragma omp ...'
@@ -739,17 +752,12 @@ public:
/// If the 'simdlen' clause is used then it specifies the preferred number of
/// iterations to be executed concurrently. The parameter of the 'simdlen'
/// clause must be a constant positive integer expression.
-class OMPSimdlenClause : public OMPClause {
+class OMPSimdlenClause final
+ : public OMPOneStmtClause<llvm::omp::OMPC_simdlen, OMPClause> {
friend class OMPClauseReader;
- /// Location of '('.
- SourceLocation LParenLoc;
-
- /// Safe iteration space distance.
- Stmt *Simdlen = nullptr;
-
/// Set simdlen.
- void setSimdlen(Expr *Len) { Simdlen = Len; }
+ void setSimdlen(Expr *Len) { setStmt(Len); }
public:
/// Build 'simdlen' clause.
@@ -759,39 +767,13 @@ public:
/// \param EndLoc Ending location of the clause.
OMPSimdlenClause(Expr *Len, SourceLocation StartLoc, SourceLocation LParenLoc,
SourceLocation EndLoc)
- : OMPClause(llvm::omp::OMPC_simdlen, StartLoc, EndLoc),
- LParenLoc(LParenLoc), Simdlen(Len) {}
+ : OMPOneStmtClause(Len, StartLoc, LParenLoc, EndLoc) {}
/// Build an empty clause.
- explicit OMPSimdlenClause()
- : OMPClause(llvm::omp::OMPC_simdlen, SourceLocation(), SourceLocation()) {
- }
-
- /// Sets the location of '('.
- void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
-
- /// Returns the location of '('.
- SourceLocation getLParenLoc() const { return LParenLoc; }
+ explicit OMPSimdlenClause() : OMPOneStmtClause() {}
/// Return safe iteration space distance.
- Expr *getSimdlen() const { return cast_or_null<Expr>(Simdlen); }
-
- child_range children() { return child_range(&Simdlen, &Simdlen + 1); }
-
- const_child_range children() const {
- return const_child_range(&Simdlen, &Simdlen + 1);
- }
-
- child_range used_children() {
- return child_range(child_iterator(), child_iterator());
- }
- const_child_range used_children() const {
- return const_child_range(const_child_iterator(), const_child_iterator());
- }
-
- static bool classof(const OMPClause *T) {
- return T->getClauseKind() == llvm::omp::OMPC_simdlen;
- }
+ Expr *getSimdlen() const { return getStmtAs<Expr>(); }
};
/// This represents the 'sizes' clause in the '#pragma omp tile' directive.
@@ -894,11 +876,11 @@ public:
/// #pragma omp unroll full
/// for (int i = 0; i < 64; ++i)
/// \endcode
-class OMPFullClause final : public OMPClause {
+class OMPFullClause final : public OMPNoChildClause<llvm::omp::OMPC_full> {
friend class OMPClauseReader;
/// Build an empty clause.
- explicit OMPFullClause() : OMPClause(llvm::omp::OMPC_full, {}, {}) {}
+ explicit OMPFullClause() : OMPNoChildClause() {}
public:
/// Build an AST node for a 'full' clause.
@@ -913,22 +895,6 @@ public:
///
/// \param C Context of the AST.
static OMPFullClause *CreateEmpty(const ASTContext &C);
-
- child_range children() { return {child_iterator(), child_iterator()}; }
- const_child_range children() const {
- return {const_child_iterator(), const_child_iterator()};
- }
-
- child_range used_children() {
- return child_range(child_iterator(), child_iterator());
- }
- const_child_range used_children() const {
- return const_child_range(const_child_iterator(), const_child_iterator());
- }
-
- static bool classof(const OMPClause *T) {
- return T->getClauseKind() == llvm::omp::OMPC_full;
- }
};
/// Representation of the 'partial' clause of the '#pragma omp unroll'
@@ -1007,17 +973,12 @@ public:
/// The parameter must be a constant positive integer expression, it specifies
/// the number of nested loops that should be collapsed into a single iteration
/// space.
-class OMPCollapseClause : public OMPClause {
+class OMPCollapseClause final
+ : public OMPOneStmtClause<llvm::omp::OMPC_collapse, OMPClause> {
friend class OMPClauseReader;
- /// Location of '('.
- SourceLocation LParenLoc;
-
- /// Number of for-loops.
- Stmt *NumForLoops = nullptr;
-
/// Set the number of associated for-loops.
- void setNumForLoops(Expr *Num) { NumForLoops = Num; }
+ void setNumForLoops(Expr *Num) { setStmt(Num); }
public:
/// Build 'collapse' clause.
@@ -1028,39 +989,13 @@ public:
/// \param EndLoc Ending location of the clause.
OMPCollapseClause(Expr *Num, SourceLocation StartLoc,
SourceLocation LParenLoc, SourceLocation EndLoc)
- : OMPClause(llvm::omp::OMPC_collapse, StartLoc, EndLoc),
- LParenLoc(LParenLoc), NumForLoops(Num) {}
+ : OMPOneStmtClause(Num, StartLoc, LParenLoc, EndLoc) {}
/// Build an empty clause.
- explicit OMPCollapseClause()
- : OMPClause(llvm::omp::OMPC_collapse, SourceLocation(),
- SourceLocation()) {}
-
- /// Sets the location of '('.
- void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
-
- /// Returns the location of '('.
- SourceLocation getLParenLoc() const { return LParenLoc; }
+ explicit OMPCollapseClause() : OMPOneStmtClause() {}
/// Return the number of associated for-loops.
- Expr *getNumForLoops() const { return cast_or_null<Expr>(NumForLoops); }
-
- child_range children() { return child_range(&NumForLoops, &NumForLoops + 1); }
-
- const_child_range children() const {
- return const_child_range(&NumForLoops, &NumForLoops + 1);
- }
-
- child_range used_children() {
- return child_range(child_iterator(), child_iterator());
- }
- const_child_range used_children() const {
- return const_child_range(const_child_iterator(), const_child_iterator());
- }
-
- static bool classof(const OMPClause *T) {
- return T->getClauseKind() == llvm::omp::OMPC_collapse;
- }
+ Expr *getNumForLoops() const { return getStmtAs<Expr>(); }
};
/// This represents 'default' clause in the '#pragma omp ...' directive.
@@ -1233,7 +1168,8 @@ public:
/// \endcode
/// In this example directive '#pragma omp requires' has 'unified_address'
/// clause.
-class OMPUnifiedAddressClause final : public OMPClause {
+class OMPUnifiedAddressClause final
+ : public OMPNoChildClause<llvm::omp::OMPC_unified_address> {
public:
friend class OMPClauseReader;
/// Build 'unified_address' clause.
@@ -1241,31 +1177,10 @@ public:
/// \param StartLoc Starting location of the clause.
/// \param EndLoc Ending location of the clause.
OMPUnifiedAddressClause(SourceLocation StartLoc, SourceLocation EndLoc)
- : OMPClause(llvm::omp::OMPC_unified_address, StartLoc, EndLoc) {}
+ : OMPNoChildClause(StartLoc, EndLoc) {}
/// Build an empty clause.
- OMPUnifiedAddressClause()
- : OMPClause(llvm::omp::OMPC_unified_address, SourceLocation(),
- SourceLocation()) {}
-
- child_range children() {
- return child_range(child_iterator(), child_iterator());
- }
-
- const_child_range children() const {
- return const_child_range(const_child_iterator(), const_child_iterator());
- }
-
- child_range used_children() {
- return child_range(child_iterator(), child_iterator());
- }
- const_child_range used_children() const {
- return const_child_range(const_child_iterator(), const_child_iterator());
- }
-
- static bool classof(const OMPClause *T) {
- return T->getClauseKind() == llvm::omp::OMPC_unified_address;
- }
+ OMPUnifiedAddressClause() : OMPNoChildClause() {}
};
/// This represents 'unified_shared_memory' clause in the '#pragma omp requires'
@@ -1487,6 +1402,231 @@ public:
}
};
+/// This represents 'at' clause in the '#pragma omp error' directive
+///
+/// \code
+/// #pragma omp error at(compilation)
+/// \endcode
+/// In this example directive '#pragma omp error' has simple
+/// 'at' clause with kind 'complilation'.
+class OMPAtClause final : public OMPClause {
+ friend class OMPClauseReader;
+
+ /// Location of '('
+ SourceLocation LParenLoc;
+
+ /// A kind of the 'at' clause.
+ OpenMPAtClauseKind Kind = OMPC_AT_unknown;
+
+ /// Start location of the kind in source code.
+ SourceLocation KindKwLoc;
+
+ /// Set kind of the clause.
+ ///
+ /// \param K Kind of clause.
+ void setAtKind(OpenMPAtClauseKind K) { Kind = K; }
+
+ /// Set clause kind location.
+ ///
+ /// \param KLoc Kind location.
+ void setAtKindKwLoc(SourceLocation KLoc) { KindKwLoc = KLoc; }
+
+ /// Sets the location of '('.
+ void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
+
+public:
+ /// Build 'at' clause with argument \a A ('compilation' or 'execution').
+ ///
+ /// \param A Argument of the clause ('compilation' or 'execution').
+ /// \param ALoc Starting location of the argument.
+ /// \param StartLoc Starting location of the clause.
+ /// \param LParenLoc Location of '('.
+ /// \param EndLoc Ending location of the clause.
+ OMPAtClause(OpenMPAtClauseKind A, SourceLocation ALoc,
+ SourceLocation StartLoc, SourceLocation LParenLoc,
+ SourceLocation EndLoc)
+ : OMPClause(llvm::omp::OMPC_at, StartLoc, EndLoc), LParenLoc(LParenLoc),
+ Kind(A), KindKwLoc(ALoc) {}
+
+ /// Build an empty clause.
+ OMPAtClause()
+ : OMPClause(llvm::omp::OMPC_at, SourceLocation(), SourceLocation()) {}
+
+ /// Returns the locaiton of '('.
+ SourceLocation getLParenLoc() const { return LParenLoc; }
+
+ /// Returns kind of the clause.
+ OpenMPAtClauseKind getAtKind() const { return Kind; }
+
+ /// Returns location of clause kind.
+ SourceLocation getAtKindKwLoc() const { return KindKwLoc; }
+
+ child_range children() {
+ return child_range(child_iterator(), child_iterator());
+ }
+
+ const_child_range children() const {
+ return const_child_range(const_child_iterator(), const_child_iterator());
+ }
+
+ child_range used_children() {
+ return child_range(child_iterator(), child_iterator());
+ }
+ const_child_range used_children() const {
+ return const_child_range(const_child_iterator(), const_child_iterator());
+ }
+
+ static bool classof(const OMPClause *T) {
+ return T->getClauseKind() == llvm::omp::OMPC_at;
+ }
+};
+
+/// This represents 'severity' clause in the '#pragma omp error' directive
+///
+/// \code
+/// #pragma omp error severity(fatal)
+/// \endcode
+/// In this example directive '#pragma omp error' has simple
+/// 'severity' clause with kind 'fatal'.
+class OMPSeverityClause final : public OMPClause {
+ friend class OMPClauseReader;
+
+ /// Location of '('
+ SourceLocation LParenLoc;
+
+ /// A kind of the 'severity' clause.
+ OpenMPSeverityClauseKind Kind = OMPC_SEVERITY_unknown;
+
+ /// Start location of the kind in source code.
+ SourceLocation KindKwLoc;
+
+ /// Set kind of the clause.
+ ///
+ /// \param K Kind of clause.
+ void setSeverityKind(OpenMPSeverityClauseKind K) { Kind = K; }
+
+ /// Set clause kind location.
+ ///
+ /// \param KLoc Kind location.
+ void setSeverityKindKwLoc(SourceLocation KLoc) { KindKwLoc = KLoc; }
+
+ /// Sets the location of '('.
+ void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
+
+public:
+ /// Build 'severity' clause with argument \a A ('fatal' or 'warning').
+ ///
+ /// \param A Argument of the clause ('fatal' or 'warning').
+ /// \param ALoc Starting location of the argument.
+ /// \param StartLoc Starting location of the clause.
+ /// \param LParenLoc Location of '('.
+ /// \param EndLoc Ending location of the clause.
+ OMPSeverityClause(OpenMPSeverityClauseKind A, SourceLocation ALoc,
+ SourceLocation StartLoc, SourceLocation LParenLoc,
+ SourceLocation EndLoc)
+ : OMPClause(llvm::omp::OMPC_severity, StartLoc, EndLoc),
+ LParenLoc(LParenLoc), Kind(A), KindKwLoc(ALoc) {}
+
+ /// Build an empty clause.
+ OMPSeverityClause()
+ : OMPClause(llvm::omp::OMPC_severity, SourceLocation(),
+ SourceLocation()) {}
+
+ /// Returns the locaiton of '('.
+ SourceLocation getLParenLoc() const { return LParenLoc; }
+
+ /// Returns kind of the clause.
+ OpenMPSeverityClauseKind getSeverityKind() const { return Kind; }
+
+ /// Returns location of clause kind.
+ SourceLocation getSeverityKindKwLoc() const { return KindKwLoc; }
+
+ child_range children() {
+ return child_range(child_iterator(), child_iterator());
+ }
+
+ const_child_range children() const {
+ return const_child_range(const_child_iterator(), const_child_iterator());
+ }
+
+ child_range used_children() {
+ return child_range(child_iterator(), child_iterator());
+ }
+ const_child_range used_children() const {
+ return const_child_range(const_child_iterator(), const_child_iterator());
+ }
+
+ static bool classof(const OMPClause *T) {
+ return T->getClauseKind() == llvm::omp::OMPC_severity;
+ }
+};
+
+/// This represents 'message' clause in the '#pragma omp error' directive
+///
+/// \code
+/// #pragma omp error message("GNU compiler required.")
+/// \endcode
+/// In this example directive '#pragma omp error' has simple
+/// 'message' clause with user error message of "GNU compiler required.".
+class OMPMessageClause final : public OMPClause {
+ friend class OMPClauseReader;
+
+ /// Location of '('
+ SourceLocation LParenLoc;
+
+ // Expression of the 'message' clause.
+ Stmt *MessageString = nullptr;
+
+ /// Set message string of the clause.
+ void setMessageString(Expr *MS) { MessageString = MS; }
+
+ /// Sets the location of '('.
+ void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
+
+public:
+ /// Build 'message' clause with message string argument
+ ///
+ /// \param MS Argument of the clause (message string).
+ /// \param StartLoc Starting location of the clause.
+ /// \param LParenLoc Location of '('.
+ /// \param EndLoc Ending location of the clause.
+ OMPMessageClause(Expr *MS, SourceLocation StartLoc, SourceLocation LParenLoc,
+ SourceLocation EndLoc)
+ : OMPClause(llvm::omp::OMPC_message, StartLoc, EndLoc),
+ LParenLoc(LParenLoc), MessageString(MS) {}
+
+ /// Build an empty clause.
+ OMPMessageClause()
+ : OMPClause(llvm::omp::OMPC_message, SourceLocation(), SourceLocation()) {
+ }
+
+ /// Returns the locaiton of '('.
+ SourceLocation getLParenLoc() const { return LParenLoc; }
+
+ /// Returns message string of the clause.
+ Expr *getMessageString() const { return cast_or_null<Expr>(MessageString); }
+
+ child_range children() {
+ return child_range(&MessageString, &MessageString + 1);
+ }
+
+ const_child_range children() const {
+ return const_child_range(&MessageString, &MessageString + 1);
+ }
+
+ child_range used_children() {
+ return child_range(child_iterator(), child_iterator());
+ }
+
+ const_child_range used_children() const {
+ return const_child_range(const_child_iterator(), const_child_iterator());
+ }
+
+ static bool classof(const OMPClause *T) {
+ return T->getClauseKind() == llvm::omp::OMPC_message;
+ }
+};
+
/// This represents 'schedule' clause in the '#pragma omp ...' directive.
///
/// \code
@@ -1782,37 +1922,15 @@ public:
/// #pragma omp for nowait
/// \endcode
/// In this example directive '#pragma omp for' has 'nowait' clause.
-class OMPNowaitClause : public OMPClause {
+class OMPNowaitClause final : public OMPNoChildClause<llvm::omp::OMPC_nowait> {
public:
/// Build 'nowait' clause.
///
/// \param StartLoc Starting location of the clause.
/// \param EndLoc Ending location of the clause.
- OMPNowaitClause(SourceLocation StartLoc, SourceLocation EndLoc)
- : OMPClause(llvm::omp::OMPC_nowait, StartLoc, EndLoc) {}
-
- /// Build an empty clause.
- OMPNowaitClause()
- : OMPClause(llvm::omp::OMPC_nowait, SourceLocation(), SourceLocation()) {}
-
- child_range children() {
- return child_range(child_iterator(), child_iterator());
- }
-
- const_child_range children() const {
- return const_child_range(const_child_iterator(), const_child_iterator());
- }
-
- child_range used_children() {
- return child_range(child_iterator(), child_iterator());
- }
- const_child_range used_children() const {
- return const_child_range(const_child_iterator(), const_child_iterator());
- }
-
- static bool classof(const OMPClause *T) {
- return T->getClauseKind() == llvm::omp::OMPC_nowait;
- }
+ OMPNowaitClause(SourceLocation StartLoc = SourceLocation(),
+ SourceLocation EndLoc = SourceLocation())
+ : OMPNoChildClause(StartLoc, EndLoc) {}
};
/// This represents 'untied' clause in the '#pragma omp ...' directive.
@@ -2005,13 +2123,13 @@ class OMPUpdateClause final
return IsExtended ? 2 : 0;
}
- /// Sets the the location of '(' in clause for 'depobj' directive.
+ /// Sets the location of '(' in clause for 'depobj' directive.
void setLParenLoc(SourceLocation Loc) {
assert(IsExtended && "Expected extended clause.");
*getTrailingObjects<SourceLocation>() = Loc;
}
- /// Sets the the location of '(' in clause for 'depobj' directive.
+ /// Sets the location of '(' in clause for 'depobj' directive.
void setArgumentLoc(SourceLocation Loc) {
assert(IsExtended && "Expected extended clause.");
*std::next(getTrailingObjects<SourceLocation>(), 1) = Loc;
@@ -2085,13 +2203,13 @@ public:
return const_child_range(const_child_iterator(), const_child_iterator());
}
- /// Gets the the location of '(' in clause for 'depobj' directive.
+ /// Gets the location of '(' in clause for 'depobj' directive.
SourceLocation getLParenLoc() const {
assert(IsExtended && "Expected extended clause.");
return *getTrailingObjects<SourceLocation>();
}
- /// Gets the the location of argument in clause for 'depobj' directive.
+ /// Gets the location of argument in clause for 'depobj' directive.
SourceLocation getArgumentLoc() const {
assert(IsExtended && "Expected extended clause.");
return *std::next(getTrailingObjects<SourceLocation>(), 1);
@@ -2149,6 +2267,47 @@ public:
}
};
+/// This represents 'compare' clause in the '#pragma omp atomic'
+/// directive.
+///
+/// \code
+/// #pragma omp atomic compare
+/// \endcode
+/// In this example directive '#pragma omp atomic' has 'compare' clause.
+class OMPCompareClause final : public OMPClause {
+public:
+ /// Build 'compare' clause.
+ ///
+ /// \param StartLoc Starting location of the clause.
+ /// \param EndLoc Ending location of the clause.
+ OMPCompareClause(SourceLocation StartLoc, SourceLocation EndLoc)
+ : OMPClause(llvm::omp::OMPC_compare, StartLoc, EndLoc) {}
+
+ /// Build an empty clause.
+ OMPCompareClause()
+ : OMPClause(llvm::omp::OMPC_compare, SourceLocation(), SourceLocation()) {
+ }
+
+ child_range children() {
+ return child_range(child_iterator(), child_iterator());
+ }
+
+ const_child_range children() const {
+ return const_child_range(const_child_iterator(), const_child_iterator());
+ }
+
+ child_range used_children() {
+ return child_range(child_iterator(), child_iterator());
+ }
+ const_child_range used_children() const {
+ return const_child_range(const_child_iterator(), const_child_iterator());
+ }
+
+ static bool classof(const OMPClause *T) {
+ return T->getClauseKind() == llvm::omp::OMPC_compare;
+ }
+};
+
/// This represents 'seq_cst' clause in the '#pragma omp atomic'
/// directive.
///
@@ -2354,6 +2513,89 @@ public:
}
};
+/// This represents 'fail' clause in the '#pragma omp atomic'
+/// directive.
+///
+/// \code
+/// #pragma omp atomic compare fail
+/// \endcode
+/// In this example directive '#pragma omp atomic compare' has 'fail' clause.
+class OMPFailClause final : public OMPClause {
+
+ // FailParameter is a memory-order-clause. Storing the ClauseKind is
+ // sufficient for our purpose.
+ OpenMPClauseKind FailParameter = llvm::omp::Clause::OMPC_unknown;
+ SourceLocation FailParameterLoc;
+ SourceLocation LParenLoc;
+
+ friend class OMPClauseReader;
+
+ /// Sets the location of '(' in fail clause.
+ void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
+
+ /// Sets the location of memoryOrder clause argument in fail clause.
+ void setFailParameterLoc(SourceLocation Loc) { FailParameterLoc = Loc; }
+
+ /// Sets the mem_order clause for 'atomic compare fail' directive.
+ void setFailParameter(OpenMPClauseKind FailParameter) {
+ this->FailParameter = FailParameter;
+ assert(checkFailClauseParameter(FailParameter) &&
+ "Invalid fail clause parameter");
+ }
+
+public:
+ /// Build 'fail' clause.
+ ///
+ /// \param StartLoc Starting location of the clause.
+ /// \param EndLoc Ending location of the clause.
+ OMPFailClause(SourceLocation StartLoc, SourceLocation EndLoc)
+ : OMPClause(llvm::omp::OMPC_fail, StartLoc, EndLoc) {}
+
+ OMPFailClause(OpenMPClauseKind FailParameter, SourceLocation FailParameterLoc,
+ SourceLocation StartLoc, SourceLocation LParenLoc,
+ SourceLocation EndLoc)
+ : OMPClause(llvm::omp::OMPC_fail, StartLoc, EndLoc),
+ FailParameterLoc(FailParameterLoc), LParenLoc(LParenLoc) {
+
+ setFailParameter(FailParameter);
+ }
+
+ /// Build an empty clause.
+ OMPFailClause()
+ : OMPClause(llvm::omp::OMPC_fail, SourceLocation(), SourceLocation()) {}
+
+ child_range children() {
+ return child_range(child_iterator(), child_iterator());
+ }
+
+ const_child_range children() const {
+ return const_child_range(const_child_iterator(), const_child_iterator());
+ }
+
+ child_range used_children() {
+ return child_range(child_iterator(), child_iterator());
+ }
+ const_child_range used_children() const {
+ return const_child_range(const_child_iterator(), const_child_iterator());
+ }
+
+ static bool classof(const OMPClause *T) {
+ return T->getClauseKind() == llvm::omp::OMPC_fail;
+ }
+
+ /// Gets the location of '(' (for the parameter) in fail clause.
+ SourceLocation getLParenLoc() const {
+ return LParenLoc;
+ }
+
+ /// Gets the location of Fail Parameter (type memory-order-clause) in
+ /// fail clause.
+ SourceLocation getFailParameterLoc() const { return FailParameterLoc; }
+
+ /// Gets the parameter (type memory-order-clause) in Fail clause.
+ OpenMPClauseKind getFailParameter() const { return FailParameter; }
+};
+
/// This represents clause 'private' in the '#pragma omp ...' directives.
///
/// \code
@@ -2398,7 +2640,7 @@ class OMPPrivateClause final
return MutableArrayRef<Expr *>(varlist_end(), varlist_size());
}
ArrayRef<const Expr *> getPrivateCopies() const {
- return llvm::makeArrayRef(varlist_end(), varlist_size());
+ return llvm::ArrayRef(varlist_end(), varlist_size());
}
public:
@@ -2507,7 +2749,7 @@ class OMPFirstprivateClause final
return MutableArrayRef<Expr *>(varlist_end(), varlist_size());
}
ArrayRef<const Expr *> getPrivateCopies() const {
- return llvm::makeArrayRef(varlist_end(), varlist_size());
+ return llvm::ArrayRef(varlist_end(), varlist_size());
}
/// Sets the list of references to initializer variables for new
@@ -2521,7 +2763,7 @@ class OMPFirstprivateClause final
return MutableArrayRef<Expr *>(getPrivateCopies().end(), varlist_size());
}
ArrayRef<const Expr *> getInits() const {
- return llvm::makeArrayRef(getPrivateCopies().end(), varlist_size());
+ return llvm::ArrayRef(getPrivateCopies().end(), varlist_size());
}
public:
@@ -2669,7 +2911,7 @@ class OMPLastprivateClause final
return MutableArrayRef<Expr *>(varlist_end(), varlist_size());
}
ArrayRef<const Expr *> getPrivateCopies() const {
- return llvm::makeArrayRef(varlist_end(), varlist_size());
+ return llvm::ArrayRef(varlist_end(), varlist_size());
}
/// Set list of helper expressions, required for proper codegen of the
@@ -2683,7 +2925,7 @@ class OMPLastprivateClause final
return MutableArrayRef<Expr *>(getPrivateCopies().end(), varlist_size());
}
ArrayRef<const Expr *> getSourceExprs() const {
- return llvm::makeArrayRef(getPrivateCopies().end(), varlist_size());
+ return llvm::ArrayRef(getPrivateCopies().end(), varlist_size());
}
/// Set list of helper expressions, required for proper codegen of the
@@ -2697,7 +2939,7 @@ class OMPLastprivateClause final
return MutableArrayRef<Expr *>(getSourceExprs().end(), varlist_size());
}
ArrayRef<const Expr *> getDestinationExprs() const {
- return llvm::makeArrayRef(getSourceExprs().end(), varlist_size());
+ return llvm::ArrayRef(getSourceExprs().end(), varlist_size());
}
/// Set list of helper assignment expressions, required for proper
@@ -2710,7 +2952,7 @@ class OMPLastprivateClause final
return MutableArrayRef<Expr *>(getDestinationExprs().end(), varlist_size());
}
ArrayRef<const Expr *> getAssignmentOps() const {
- return llvm::makeArrayRef(getDestinationExprs().end(), varlist_size());
+ return llvm::ArrayRef(getDestinationExprs().end(), varlist_size());
}
/// Sets lastprivate kind.
@@ -2998,7 +3240,7 @@ class OMPReductionClause final
return MutableArrayRef<Expr *>(varlist_end(), varlist_size());
}
ArrayRef<const Expr *> getPrivates() const {
- return llvm::makeArrayRef(varlist_end(), varlist_size());
+ return llvm::ArrayRef(varlist_end(), varlist_size());
}
/// Set list of helper expressions, required for proper codegen of the
@@ -3011,7 +3253,7 @@ class OMPReductionClause final
return MutableArrayRef<Expr *>(getPrivates().end(), varlist_size());
}
ArrayRef<const Expr *> getLHSExprs() const {
- return llvm::makeArrayRef(getPrivates().end(), varlist_size());
+ return llvm::ArrayRef(getPrivates().end(), varlist_size());
}
/// Set list of helper expressions, required for proper codegen of the
@@ -3026,7 +3268,7 @@ class OMPReductionClause final
return MutableArrayRef<Expr *>(getLHSExprs().end(), varlist_size());
}
ArrayRef<const Expr *> getRHSExprs() const {
- return llvm::makeArrayRef(getLHSExprs().end(), varlist_size());
+ return llvm::ArrayRef(getLHSExprs().end(), varlist_size());
}
/// Set list of helper reduction expressions, required for proper
@@ -3040,7 +3282,7 @@ class OMPReductionClause final
return MutableArrayRef<Expr *>(getRHSExprs().end(), varlist_size());
}
ArrayRef<const Expr *> getReductionOps() const {
- return llvm::makeArrayRef(getRHSExprs().end(), varlist_size());
+ return llvm::ArrayRef(getRHSExprs().end(), varlist_size());
}
/// Set list of helper copy operations for inscan reductions.
@@ -3052,7 +3294,7 @@ class OMPReductionClause final
return MutableArrayRef<Expr *>(getReductionOps().end(), varlist_size());
}
ArrayRef<const Expr *> getInscanCopyOps() const {
- return llvm::makeArrayRef(getReductionOps().end(), varlist_size());
+ return llvm::ArrayRef(getReductionOps().end(), varlist_size());
}
/// Set list of helper temp vars for inscan copy array operations.
@@ -3063,7 +3305,7 @@ class OMPReductionClause final
return MutableArrayRef<Expr *>(getInscanCopyOps().end(), varlist_size());
}
ArrayRef<const Expr *> getInscanCopyArrayTemps() const {
- return llvm::makeArrayRef(getInscanCopyOps().end(), varlist_size());
+ return llvm::ArrayRef(getInscanCopyOps().end(), varlist_size());
}
/// Set list of helper temp elements vars for inscan copy array operations.
@@ -3075,7 +3317,7 @@ class OMPReductionClause final
varlist_size());
}
ArrayRef<const Expr *> getInscanCopyArrayElems() const {
- return llvm::makeArrayRef(getInscanCopyArrayTemps().end(), varlist_size());
+ return llvm::ArrayRef(getInscanCopyArrayTemps().end(), varlist_size());
}
public:
@@ -3317,7 +3559,7 @@ class OMPTaskReductionClause final
return MutableArrayRef<Expr *>(varlist_end(), varlist_size());
}
ArrayRef<const Expr *> getPrivates() const {
- return llvm::makeArrayRef(varlist_end(), varlist_size());
+ return llvm::ArrayRef(varlist_end(), varlist_size());
}
/// Set list of helper expressions, required for proper codegen of the clause.
@@ -3330,7 +3572,7 @@ class OMPTaskReductionClause final
return MutableArrayRef<Expr *>(getPrivates().end(), varlist_size());
}
ArrayRef<const Expr *> getLHSExprs() const {
- return llvm::makeArrayRef(getPrivates().end(), varlist_size());
+ return llvm::ArrayRef(getPrivates().end(), varlist_size());
}
/// Set list of helper expressions, required for proper codegen of the clause.
@@ -3344,7 +3586,7 @@ class OMPTaskReductionClause final
return MutableArrayRef<Expr *>(getLHSExprs().end(), varlist_size());
}
ArrayRef<const Expr *> getRHSExprs() const {
- return llvm::makeArrayRef(getLHSExprs().end(), varlist_size());
+ return llvm::ArrayRef(getLHSExprs().end(), varlist_size());
}
/// Set list of helper reduction expressions, required for proper
@@ -3358,7 +3600,7 @@ class OMPTaskReductionClause final
return MutableArrayRef<Expr *>(getRHSExprs().end(), varlist_size());
}
ArrayRef<const Expr *> getReductionOps() const {
- return llvm::makeArrayRef(getRHSExprs().end(), varlist_size());
+ return llvm::ArrayRef(getRHSExprs().end(), varlist_size());
}
public:
@@ -3548,7 +3790,7 @@ class OMPInReductionClause final
return MutableArrayRef<Expr *>(varlist_end(), varlist_size());
}
ArrayRef<const Expr *> getPrivates() const {
- return llvm::makeArrayRef(varlist_end(), varlist_size());
+ return llvm::ArrayRef(varlist_end(), varlist_size());
}
/// Set list of helper expressions, required for proper codegen of the clause.
@@ -3561,7 +3803,7 @@ class OMPInReductionClause final
return MutableArrayRef<Expr *>(getPrivates().end(), varlist_size());
}
ArrayRef<const Expr *> getLHSExprs() const {
- return llvm::makeArrayRef(getPrivates().end(), varlist_size());
+ return llvm::ArrayRef(getPrivates().end(), varlist_size());
}
/// Set list of helper expressions, required for proper codegen of the clause.
@@ -3575,7 +3817,7 @@ class OMPInReductionClause final
return MutableArrayRef<Expr *>(getLHSExprs().end(), varlist_size());
}
ArrayRef<const Expr *> getRHSExprs() const {
- return llvm::makeArrayRef(getLHSExprs().end(), varlist_size());
+ return llvm::ArrayRef(getLHSExprs().end(), varlist_size());
}
/// Set list of helper reduction expressions, required for proper
@@ -3589,7 +3831,7 @@ class OMPInReductionClause final
return MutableArrayRef<Expr *>(getRHSExprs().end(), varlist_size());
}
ArrayRef<const Expr *> getReductionOps() const {
- return llvm::makeArrayRef(getRHSExprs().end(), varlist_size());
+ return llvm::ArrayRef(getRHSExprs().end(), varlist_size());
}
/// Set list of helper reduction taskgroup descriptors.
@@ -3600,7 +3842,7 @@ class OMPInReductionClause final
return MutableArrayRef<Expr *>(getReductionOps().end(), varlist_size());
}
ArrayRef<const Expr *> getTaskgroupDescriptors() const {
- return llvm::makeArrayRef(getReductionOps().end(), varlist_size());
+ return llvm::ArrayRef(getReductionOps().end(), varlist_size());
}
public:
@@ -3759,6 +4001,9 @@ class OMPLinearClause final
/// Location of ':'.
SourceLocation ColonLoc;
+ /// Location of 'step' modifier.
+ SourceLocation StepModifierLoc;
+
/// Sets the linear step for clause.
void setStep(Expr *Step) { *(getFinals().end()) = Step; }
@@ -3770,16 +4015,18 @@ class OMPLinearClause final
/// \param StartLoc Starting location of the clause.
/// \param LParenLoc Location of '('.
/// \param ColonLoc Location of ':'.
+ /// \param StepModifierLoc Location of 'step' modifier.
/// \param EndLoc Ending location of the clause.
/// \param NumVars Number of variables.
OMPLinearClause(SourceLocation StartLoc, SourceLocation LParenLoc,
OpenMPLinearClauseKind Modifier, SourceLocation ModifierLoc,
- SourceLocation ColonLoc, SourceLocation EndLoc,
- unsigned NumVars)
+ SourceLocation ColonLoc, SourceLocation StepModifierLoc,
+ SourceLocation EndLoc, unsigned NumVars)
: OMPVarListClause<OMPLinearClause>(llvm::omp::OMPC_linear, StartLoc,
LParenLoc, EndLoc, NumVars),
OMPClauseWithPostUpdate(this), Modifier(Modifier),
- ModifierLoc(ModifierLoc), ColonLoc(ColonLoc) {}
+ ModifierLoc(ModifierLoc), ColonLoc(ColonLoc),
+ StepModifierLoc(StepModifierLoc) {}
/// Build an empty clause.
///
@@ -3806,14 +4053,14 @@ class OMPLinearClause final
return MutableArrayRef<Expr *>(varlist_end(), varlist_size());
}
ArrayRef<const Expr *> getPrivates() const {
- return llvm::makeArrayRef(varlist_end(), varlist_size());
+ return llvm::ArrayRef(varlist_end(), varlist_size());
}
MutableArrayRef<Expr *> getInits() {
return MutableArrayRef<Expr *>(getPrivates().end(), varlist_size());
}
ArrayRef<const Expr *> getInits() const {
- return llvm::makeArrayRef(getPrivates().end(), varlist_size());
+ return llvm::ArrayRef(getPrivates().end(), varlist_size());
}
/// Sets the list of update expressions for linear variables.
@@ -3821,7 +4068,7 @@ class OMPLinearClause final
return MutableArrayRef<Expr *>(getInits().end(), varlist_size());
}
ArrayRef<const Expr *> getUpdates() const {
- return llvm::makeArrayRef(getInits().end(), varlist_size());
+ return llvm::ArrayRef(getInits().end(), varlist_size());
}
/// Sets the list of final update expressions for linear variables.
@@ -3829,7 +4076,7 @@ class OMPLinearClause final
return MutableArrayRef<Expr *>(getUpdates().end(), varlist_size());
}
ArrayRef<const Expr *> getFinals() const {
- return llvm::makeArrayRef(getUpdates().end(), varlist_size());
+ return llvm::ArrayRef(getUpdates().end(), varlist_size());
}
/// Gets the list of used expressions for linear variables.
@@ -3837,7 +4084,7 @@ class OMPLinearClause final
return MutableArrayRef<Expr *>(getFinals().end() + 2, varlist_size() + 1);
}
ArrayRef<const Expr *> getUsedExprs() const {
- return llvm::makeArrayRef(getFinals().end() + 2, varlist_size() + 1);
+ return llvm::ArrayRef(getFinals().end() + 2, varlist_size() + 1);
}
/// Sets the list of the copies of original linear variables.
@@ -3858,6 +4105,7 @@ public:
/// \param Modifier Modifier of 'linear' clause.
/// \param ModifierLoc Modifier location.
/// \param ColonLoc Location of ':'.
+ /// \param StepModifierLoc Location of 'step' modifier.
/// \param EndLoc Ending location of the clause.
/// \param VL List of references to the variables.
/// \param PL List of private copies of original variables.
@@ -3871,9 +4119,10 @@ public:
static OMPLinearClause *
Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
OpenMPLinearClauseKind Modifier, SourceLocation ModifierLoc,
- SourceLocation ColonLoc, SourceLocation EndLoc, ArrayRef<Expr *> VL,
- ArrayRef<Expr *> PL, ArrayRef<Expr *> IL, Expr *Step, Expr *CalcStep,
- Stmt *PreInit, Expr *PostUpdate);
+ SourceLocation ColonLoc, SourceLocation StepModifierLoc,
+ SourceLocation EndLoc, ArrayRef<Expr *> VL, ArrayRef<Expr *> PL,
+ ArrayRef<Expr *> IL, Expr *Step, Expr *CalcStep, Stmt *PreInit,
+ Expr *PostUpdate);
/// Creates an empty clause with the place for \a NumVars variables.
///
@@ -3896,9 +4145,15 @@ public:
/// Sets the location of ':'.
void setColonLoc(SourceLocation Loc) { ColonLoc = Loc; }
+ /// Sets the location of 'step' modifier.
+ void setStepModifierLoc(SourceLocation Loc) { StepModifierLoc = Loc; }
+
/// Returns the location of ':'.
SourceLocation getColonLoc() const { return ColonLoc; }
+ /// Returns the location of 'step' modifier.
+ SourceLocation getStepModifierLoc() const { return StepModifierLoc; }
+
/// Returns linear step.
Expr *getStep() { return *(getFinals().end()); }
@@ -4166,7 +4421,7 @@ class OMPCopyinClause final
return MutableArrayRef<Expr *>(varlist_end(), varlist_size());
}
ArrayRef<const Expr *> getSourceExprs() const {
- return llvm::makeArrayRef(varlist_end(), varlist_size());
+ return llvm::ArrayRef(varlist_end(), varlist_size());
}
/// Set list of helper expressions, required for proper codegen of the
@@ -4179,7 +4434,7 @@ class OMPCopyinClause final
return MutableArrayRef<Expr *>(getSourceExprs().end(), varlist_size());
}
ArrayRef<const Expr *> getDestinationExprs() const {
- return llvm::makeArrayRef(getSourceExprs().end(), varlist_size());
+ return llvm::ArrayRef(getSourceExprs().end(), varlist_size());
}
/// Set list of helper assignment expressions, required for proper
@@ -4193,7 +4448,7 @@ class OMPCopyinClause final
return MutableArrayRef<Expr *>(getDestinationExprs().end(), varlist_size());
}
ArrayRef<const Expr *> getAssignmentOps() const {
- return llvm::makeArrayRef(getDestinationExprs().end(), varlist_size());
+ return llvm::ArrayRef(getDestinationExprs().end(), varlist_size());
}
public:
@@ -4331,7 +4586,7 @@ class OMPCopyprivateClause final
return MutableArrayRef<Expr *>(varlist_end(), varlist_size());
}
ArrayRef<const Expr *> getSourceExprs() const {
- return llvm::makeArrayRef(varlist_end(), varlist_size());
+ return llvm::ArrayRef(varlist_end(), varlist_size());
}
/// Set list of helper expressions, required for proper codegen of the
@@ -4344,7 +4599,7 @@ class OMPCopyprivateClause final
return MutableArrayRef<Expr *>(getSourceExprs().end(), varlist_size());
}
ArrayRef<const Expr *> getDestinationExprs() const {
- return llvm::makeArrayRef(getSourceExprs().end(), varlist_size());
+ return llvm::ArrayRef(getSourceExprs().end(), varlist_size());
}
/// Set list of helper assignment expressions, required for proper
@@ -4358,7 +4613,7 @@ class OMPCopyprivateClause final
return MutableArrayRef<Expr *>(getDestinationExprs().end(), varlist_size());
}
ArrayRef<const Expr *> getAssignmentOps() const {
- return llvm::makeArrayRef(getDestinationExprs().end(), varlist_size());
+ return llvm::ArrayRef(getDestinationExprs().end(), varlist_size());
}
public:
@@ -4629,14 +4884,24 @@ class OMPDependClause final
friend OMPVarListClause;
friend TrailingObjects;
- /// Dependency type (one of in, out, inout).
- OpenMPDependClauseKind DepKind = OMPC_DEPEND_unknown;
+public:
+ struct DependDataTy final {
+ /// Dependency type (one of in, out, inout).
+ OpenMPDependClauseKind DepKind = OMPC_DEPEND_unknown;
- /// Dependency type location.
- SourceLocation DepLoc;
+ /// Dependency type location.
+ SourceLocation DepLoc;
- /// Colon location.
- SourceLocation ColonLoc;
+ /// Colon location.
+ SourceLocation ColonLoc;
+
+ /// Location of 'omp_all_memory'.
+ SourceLocation OmpAllMemoryLoc;
+ };
+
+private:
+ /// Dependency type and source locations.
+ DependDataTy Data;
/// Number of loops, associated with the depend clause.
unsigned NumLoops = 0;
@@ -4667,13 +4932,16 @@ class OMPDependClause final
NumLoops(NumLoops) {}
/// Set dependency kind.
- void setDependencyKind(OpenMPDependClauseKind K) { DepKind = K; }
+ void setDependencyKind(OpenMPDependClauseKind K) { Data.DepKind = K; }
/// Set dependency kind and its location.
- void setDependencyLoc(SourceLocation Loc) { DepLoc = Loc; }
+ void setDependencyLoc(SourceLocation Loc) { Data.DepLoc = Loc; }
/// Set colon location.
- void setColonLoc(SourceLocation Loc) { ColonLoc = Loc; }
+ void setColonLoc(SourceLocation Loc) { Data.ColonLoc = Loc; }
+
+ /// Set the 'omp_all_memory' location.
+ void setOmpAllMemoryLoc(SourceLocation Loc) { Data.OmpAllMemoryLoc = Loc; }
/// Sets optional dependency modifier.
void setModifier(Expr *DepModifier);
@@ -4685,18 +4953,15 @@ public:
/// \param StartLoc Starting location of the clause.
/// \param LParenLoc Location of '('.
/// \param EndLoc Ending location of the clause.
- /// \param DepKind Dependency type.
- /// \param DepLoc Location of the dependency type.
- /// \param ColonLoc Colon location.
+ /// \param Data Dependency type and source locations.
/// \param VL List of references to the variables.
/// \param NumLoops Number of loops that is associated with this depend
/// clause.
static OMPDependClause *Create(const ASTContext &C, SourceLocation StartLoc,
SourceLocation LParenLoc,
- SourceLocation EndLoc, Expr *DepModifier,
- OpenMPDependClauseKind DepKind,
- SourceLocation DepLoc, SourceLocation ColonLoc,
- ArrayRef<Expr *> VL, unsigned NumLoops);
+ SourceLocation EndLoc, DependDataTy Data,
+ Expr *DepModifier, ArrayRef<Expr *> VL,
+ unsigned NumLoops);
/// Creates an empty clause with \a N variables.
///
@@ -4708,7 +4973,16 @@ public:
unsigned NumLoops);
/// Get dependency type.
- OpenMPDependClauseKind getDependencyKind() const { return DepKind; }
+ OpenMPDependClauseKind getDependencyKind() const { return Data.DepKind; }
+
+ /// Get dependency type location.
+ SourceLocation getDependencyLoc() const { return Data.DepLoc; }
+
+ /// Get colon location.
+ SourceLocation getColonLoc() const { return Data.ColonLoc; }
+
+ /// Get 'omp_all_memory' location.
+ SourceLocation getOmpAllMemoryLoc() const { return Data.OmpAllMemoryLoc; }
/// Return optional depend modifier.
Expr *getModifier();
@@ -4716,12 +4990,6 @@ public:
return const_cast<OMPDependClause *>(this)->getModifier();
}
- /// Get dependency type location.
- SourceLocation getDependencyLoc() const { return DepLoc; }
-
- /// Get colon location.
- SourceLocation getColonLoc() const { return ColonLoc; }
-
/// Get number of loops associated with the clause.
unsigned getNumLoops() const { return NumLoops; }
@@ -4857,38 +5125,18 @@ public:
/// #pragma omp ordered threads
/// \endcode
/// In this example directive '#pragma omp ordered' has simple 'threads' clause.
-class OMPThreadsClause : public OMPClause {
+class OMPThreadsClause final
+ : public OMPNoChildClause<llvm::omp::OMPC_threads> {
public:
/// Build 'threads' clause.
///
/// \param StartLoc Starting location of the clause.
/// \param EndLoc Ending location of the clause.
OMPThreadsClause(SourceLocation StartLoc, SourceLocation EndLoc)
- : OMPClause(llvm::omp::OMPC_threads, StartLoc, EndLoc) {}
+ : OMPNoChildClause(StartLoc, EndLoc) {}
/// Build an empty clause.
- OMPThreadsClause()
- : OMPClause(llvm::omp::OMPC_threads, SourceLocation(), SourceLocation()) {
- }
-
- child_range children() {
- return child_range(child_iterator(), child_iterator());
- }
-
- const_child_range children() const {
- return const_child_range(const_child_iterator(), const_child_iterator());
- }
-
- child_range used_children() {
- return child_range(child_iterator(), child_iterator());
- }
- const_child_range used_children() const {
- return const_child_range(const_child_iterator(), const_child_iterator());
- }
-
- static bool classof(const OMPClause *T) {
- return T->getClauseKind() == llvm::omp::OMPC_threads;
- }
+ OMPThreadsClause() : OMPNoChildClause() {}
};
/// This represents 'simd' clause in the '#pragma omp ...' directive.
@@ -5273,7 +5521,7 @@ protected:
MutableArrayRef<Expr *> getUDMapperRefs() {
assert(SupportsMapper &&
"Must be a clause that is possible to have user-defined mappers");
- return llvm::makeMutableArrayRef<Expr *>(
+ return llvm::MutableArrayRef<Expr *>(
static_cast<T *>(this)->template getTrailingObjects<Expr *>() +
OMPVarListClause<T>::varlist_size(),
OMPVarListClause<T>::varlist_size());
@@ -5284,7 +5532,7 @@ protected:
ArrayRef<Expr *> getUDMapperRefs() const {
assert(SupportsMapper &&
"Must be a clause that is possible to have user-defined mappers");
- return llvm::makeArrayRef<Expr *>(
+ return llvm::ArrayRef<Expr *>(
static_cast<const T *>(this)->template getTrailingObjects<Expr *>() +
OMPVarListClause<T>::varlist_size(),
OMPVarListClause<T>::varlist_size());
@@ -5483,14 +5731,14 @@ public:
return const_component_lists_iterator(
getUniqueDeclsRef(), getDeclNumListsRef(), getComponentListSizesRef(),
getComponentsRef(), SupportsMapper,
- SupportsMapper ? getUDMapperRefs() : llvm::None);
+ SupportsMapper ? getUDMapperRefs() : std::nullopt);
}
const_component_lists_iterator component_lists_end() const {
return const_component_lists_iterator(
ArrayRef<ValueDecl *>(), ArrayRef<unsigned>(), ArrayRef<unsigned>(),
MappableExprComponentListRef(getComponentsRef().end(),
getComponentsRef().end()),
- SupportsMapper, llvm::None);
+ SupportsMapper, std::nullopt);
}
const_component_lists_range component_lists() const {
return {component_lists_begin(), component_lists_end()};
@@ -5503,7 +5751,7 @@ public:
return const_component_lists_iterator(
VD, getUniqueDeclsRef(), getDeclNumListsRef(),
getComponentListSizesRef(), getComponentsRef(), SupportsMapper,
- SupportsMapper ? getUDMapperRefs() : llvm::None);
+ SupportsMapper ? getUDMapperRefs() : std::nullopt);
}
const_component_lists_iterator decl_component_lists_end() const {
return component_lists_end();
@@ -5593,7 +5841,7 @@ class OMPMapClause final : public OMPMappableExprListClause<OMPMapClause>,
size_t numTrailingObjects(OverloadToken<Expr *>) const {
// There are varlist_size() of expressions, and varlist_size() of
// user-defined mappers.
- return 2 * varlist_size();
+ return 2 * varlist_size() + 1;
}
size_t numTrailingObjects(OverloadToken<ValueDecl *>) const {
return getUniqueDeclarationsNum();
@@ -5606,6 +5854,7 @@ private:
/// Map-type-modifiers for the 'map' clause.
OpenMPMapModifierKind MapTypeModifiers[NumberOfOMPMapClauseModifiers] = {
OMPC_MAP_MODIFIER_unknown, OMPC_MAP_MODIFIER_unknown,
+ OMPC_MAP_MODIFIER_unknown, OMPC_MAP_MODIFIER_unknown,
OMPC_MAP_MODIFIER_unknown, OMPC_MAP_MODIFIER_unknown};
/// Location of map-type-modifiers for the 'map' clause.
@@ -5654,12 +5903,11 @@ private:
/*SupportsMapper=*/true, &MapperQualifierLoc,
&MapperIdInfo),
MapType(MapType), MapTypeIsImplicit(MapTypeIsImplicit), MapLoc(MapLoc) {
- assert(llvm::array_lengthof(MapTypeModifiers) == MapModifiers.size() &&
+ assert(std::size(MapTypeModifiers) == MapModifiers.size() &&
"Unexpected number of map type modifiers.");
llvm::copy(MapModifiers, std::begin(MapTypeModifiers));
- assert(llvm::array_lengthof(MapTypeModifiersLoc) ==
- MapModifiersLoc.size() &&
+ assert(std::size(MapTypeModifiersLoc) == MapModifiersLoc.size() &&
"Unexpected number of map type modifier locations.");
llvm::copy(MapModifiersLoc, std::begin(MapTypeModifiersLoc));
}
@@ -5708,6 +5956,11 @@ private:
/// Set colon location.
void setColonLoc(SourceLocation Loc) { ColonLoc = Loc; }
+ /// Set iterator modifier.
+ void setIteratorModifier(Expr *IteratorModifier) {
+ getTrailingObjects<Expr *>()[2 * varlist_size()] = IteratorModifier;
+ }
+
public:
/// Creates clause with a list of variables \a VL.
///
@@ -5720,6 +5973,7 @@ public:
/// \param ComponentLists Component lists used in the clause.
/// \param UDMapperRefs References to user-defined mappers associated with
/// expressions used in the clause.
+ /// \param IteratorModifier Iterator modifier.
/// \param MapModifiers Map-type-modifiers.
/// \param MapModifiersLoc Location of map-type-modifiers.
/// \param UDMQualifierLoc C++ nested name specifier for the associated
@@ -5732,7 +5986,7 @@ public:
Create(const ASTContext &C, const OMPVarListLocTy &Locs,
ArrayRef<Expr *> Vars, ArrayRef<ValueDecl *> Declarations,
MappableExprComponentListsRef ComponentLists,
- ArrayRef<Expr *> UDMapperRefs,
+ ArrayRef<Expr *> UDMapperRefs, Expr *IteratorModifier,
ArrayRef<OpenMPMapModifierKind> MapModifiers,
ArrayRef<SourceLocation> MapModifiersLoc,
NestedNameSpecifierLoc UDMQualifierLoc, DeclarationNameInfo MapperId,
@@ -5751,6 +6005,11 @@ public:
static OMPMapClause *CreateEmpty(const ASTContext &C,
const OMPMappableExprListSizeTy &Sizes);
+ /// Fetches Expr * of iterator modifier.
+ Expr *getIteratorModifier() {
+ return getTrailingObjects<Expr *>()[2 * varlist_size()];
+ }
+
/// Fetches mapping kind for the clause.
OpenMPMapClauseKind getMapType() const LLVM_READONLY { return MapType; }
@@ -5782,12 +6041,12 @@ public:
/// Fetches ArrayRef of map-type-modifiers.
ArrayRef<OpenMPMapModifierKind> getMapTypeModifiers() const LLVM_READONLY {
- return llvm::makeArrayRef(MapTypeModifiers);
+ return llvm::ArrayRef(MapTypeModifiers);
}
/// Fetches ArrayRef of location of map-type-modifiers.
ArrayRef<SourceLocation> getMapTypeModifiersLoc() const LLVM_READONLY {
- return llvm::makeArrayRef(MapTypeModifiersLoc);
+ return llvm::ArrayRef(MapTypeModifiersLoc);
}
/// Fetches location of clause mapping kind.
@@ -6065,26 +6324,43 @@ class OMPGrainsizeClause : public OMPClause, public OMPClauseWithPreInit {
/// Location of '('.
SourceLocation LParenLoc;
+ /// Modifiers for 'grainsize' clause.
+ OpenMPGrainsizeClauseModifier Modifier = OMPC_GRAINSIZE_unknown;
+
+ /// Location of the modifier.
+ SourceLocation ModifierLoc;
+
/// Safe iteration space distance.
Stmt *Grainsize = nullptr;
/// Set safelen.
void setGrainsize(Expr *Size) { Grainsize = Size; }
+ /// Sets modifier.
+ void setModifier(OpenMPGrainsizeClauseModifier M) { Modifier = M; }
+
+ /// Sets modifier location.
+ void setModifierLoc(SourceLocation Loc) { ModifierLoc = Loc; }
+
public:
/// Build 'grainsize' clause.
///
+ /// \param Modifier Clause modifier.
/// \param Size Expression associated with this clause.
/// \param HelperSize Helper grainsize for the construct.
/// \param CaptureRegion Innermost OpenMP region where expressions in this
/// clause must be captured.
/// \param StartLoc Starting location of the clause.
+ /// \param ModifierLoc Modifier location.
+ /// \param LParenLoc Location of '('.
/// \param EndLoc Ending location of the clause.
- OMPGrainsizeClause(Expr *Size, Stmt *HelperSize,
- OpenMPDirectiveKind CaptureRegion, SourceLocation StartLoc,
- SourceLocation LParenLoc, SourceLocation EndLoc)
+ OMPGrainsizeClause(OpenMPGrainsizeClauseModifier Modifier, Expr *Size,
+ Stmt *HelperSize, OpenMPDirectiveKind CaptureRegion,
+ SourceLocation StartLoc, SourceLocation LParenLoc,
+ SourceLocation ModifierLoc, SourceLocation EndLoc)
: OMPClause(llvm::omp::OMPC_grainsize, StartLoc, EndLoc),
- OMPClauseWithPreInit(this), LParenLoc(LParenLoc), Grainsize(Size) {
+ OMPClauseWithPreInit(this), LParenLoc(LParenLoc), Modifier(Modifier),
+ ModifierLoc(ModifierLoc), Grainsize(Size) {
setPreInitStmt(HelperSize, CaptureRegion);
}
@@ -6103,6 +6379,12 @@ public:
/// Return safe iteration space distance.
Expr *getGrainsize() const { return cast_or_null<Expr>(Grainsize); }
+ /// Gets modifier.
+ OpenMPGrainsizeClauseModifier getModifier() const { return Modifier; }
+
+ /// Gets modifier location.
+ SourceLocation getModifierLoc() const { return ModifierLoc; }
+
child_range children() { return child_range(&Grainsize, &Grainsize + 1); }
const_child_range children() const {
@@ -6174,26 +6456,43 @@ class OMPNumTasksClause : public OMPClause, public OMPClauseWithPreInit {
/// Location of '('.
SourceLocation LParenLoc;
+ /// Modifiers for 'num_tasks' clause.
+ OpenMPNumTasksClauseModifier Modifier = OMPC_NUMTASKS_unknown;
+
+ /// Location of the modifier.
+ SourceLocation ModifierLoc;
+
/// Safe iteration space distance.
Stmt *NumTasks = nullptr;
/// Set safelen.
void setNumTasks(Expr *Size) { NumTasks = Size; }
+ /// Sets modifier.
+ void setModifier(OpenMPNumTasksClauseModifier M) { Modifier = M; }
+
+ /// Sets modifier location.
+ void setModifierLoc(SourceLocation Loc) { ModifierLoc = Loc; }
+
public:
/// Build 'num_tasks' clause.
///
+ /// \param Modifier Clause modifier.
/// \param Size Expression associated with this clause.
/// \param HelperSize Helper grainsize for the construct.
/// \param CaptureRegion Innermost OpenMP region where expressions in this
/// clause must be captured.
/// \param StartLoc Starting location of the clause.
/// \param EndLoc Ending location of the clause.
- OMPNumTasksClause(Expr *Size, Stmt *HelperSize,
- OpenMPDirectiveKind CaptureRegion, SourceLocation StartLoc,
- SourceLocation LParenLoc, SourceLocation EndLoc)
+ /// \param ModifierLoc Modifier location.
+ /// \param LParenLoc Location of '('.
+ OMPNumTasksClause(OpenMPNumTasksClauseModifier Modifier, Expr *Size,
+ Stmt *HelperSize, OpenMPDirectiveKind CaptureRegion,
+ SourceLocation StartLoc, SourceLocation LParenLoc,
+ SourceLocation ModifierLoc, SourceLocation EndLoc)
: OMPClause(llvm::omp::OMPC_num_tasks, StartLoc, EndLoc),
- OMPClauseWithPreInit(this), LParenLoc(LParenLoc), NumTasks(Size) {
+ OMPClauseWithPreInit(this), LParenLoc(LParenLoc), Modifier(Modifier),
+ ModifierLoc(ModifierLoc), NumTasks(Size) {
setPreInitStmt(HelperSize, CaptureRegion);
}
@@ -6212,6 +6511,12 @@ public:
/// Return safe iteration space distance.
Expr *getNumTasks() const { return cast_or_null<Expr>(NumTasks); }
+ /// Gets modifier.
+ OpenMPNumTasksClauseModifier getModifier() const { return Modifier; }
+
+ /// Gets modifier location.
+ SourceLocation getModifierLoc() const { return ModifierLoc; }
+
child_range children() { return child_range(&NumTasks, &NumTasks + 1); }
const_child_range children() const {
@@ -6576,12 +6881,11 @@ class OMPToClause final : public OMPMappableExprListClause<OMPToClause>,
: OMPMappableExprListClause(llvm::omp::OMPC_to, Locs, Sizes,
/*SupportsMapper=*/true, &MapperQualifierLoc,
&MapperIdInfo) {
- assert(llvm::array_lengthof(MotionModifiers) == TheMotionModifiers.size() &&
+ assert(std::size(MotionModifiers) == TheMotionModifiers.size() &&
"Unexpected number of motion modifiers.");
llvm::copy(TheMotionModifiers, std::begin(MotionModifiers));
- assert(llvm::array_lengthof(MotionModifiersLoc) ==
- TheMotionModifiersLoc.size() &&
+ assert(std::size(MotionModifiersLoc) == TheMotionModifiersLoc.size() &&
"Unexpected number of motion modifier locations.");
llvm::copy(TheMotionModifiersLoc, std::begin(MotionModifiersLoc));
}
@@ -6693,12 +6997,12 @@ public:
/// Fetches ArrayRef of motion-modifiers.
ArrayRef<OpenMPMotionModifierKind> getMotionModifiers() const LLVM_READONLY {
- return llvm::makeArrayRef(MotionModifiers);
+ return llvm::ArrayRef(MotionModifiers);
}
/// Fetches ArrayRef of location of motion-modifiers.
ArrayRef<SourceLocation> getMotionModifiersLoc() const LLVM_READONLY {
- return llvm::makeArrayRef(MotionModifiersLoc);
+ return llvm::ArrayRef(MotionModifiersLoc);
}
/// Get colon location.
@@ -6778,12 +7082,11 @@ class OMPFromClause final
: OMPMappableExprListClause(llvm::omp::OMPC_from, Locs, Sizes,
/*SupportsMapper=*/true, &MapperQualifierLoc,
&MapperIdInfo) {
- assert(llvm::array_lengthof(MotionModifiers) == TheMotionModifiers.size() &&
+ assert(std::size(MotionModifiers) == TheMotionModifiers.size() &&
"Unexpected number of motion modifiers.");
llvm::copy(TheMotionModifiers, std::begin(MotionModifiers));
- assert(llvm::array_lengthof(MotionModifiersLoc) ==
- TheMotionModifiersLoc.size() &&
+ assert(std::size(MotionModifiersLoc) == TheMotionModifiersLoc.size() &&
"Unexpected number of motion modifier locations.");
llvm::copy(TheMotionModifiersLoc, std::begin(MotionModifiersLoc));
}
@@ -6894,12 +7197,12 @@ public:
/// Fetches ArrayRef of motion-modifiers.
ArrayRef<OpenMPMotionModifierKind> getMotionModifiers() const LLVM_READONLY {
- return llvm::makeArrayRef(MotionModifiers);
+ return llvm::ArrayRef(MotionModifiers);
}
/// Fetches ArrayRef of location of motion-modifiers.
ArrayRef<SourceLocation> getMotionModifiersLoc() const LLVM_READONLY {
- return llvm::makeArrayRef(MotionModifiersLoc);
+ return llvm::ArrayRef(MotionModifiersLoc);
}
/// Get colon location.
@@ -6994,7 +7297,7 @@ class OMPUseDevicePtrClause final
return MutableArrayRef<Expr *>(varlist_end(), varlist_size());
}
ArrayRef<const Expr *> getPrivateCopies() const {
- return llvm::makeArrayRef(varlist_end(), varlist_size());
+ return llvm::ArrayRef(varlist_end(), varlist_size());
}
/// Sets the list of references to initializer variables for new private
@@ -7008,7 +7311,7 @@ class OMPUseDevicePtrClause final
return MutableArrayRef<Expr *>(getPrivateCopies().end(), varlist_size());
}
ArrayRef<const Expr *> getInits() const {
- return llvm::makeArrayRef(getPrivateCopies().end(), varlist_size());
+ return llvm::ArrayRef(getPrivateCopies().end(), varlist_size());
}
public:
@@ -7298,6 +7601,110 @@ public:
}
};
+/// This represents clause 'has_device_ptr' in the '#pragma omp ...'
+/// directives.
+///
+/// \code
+/// #pragma omp target has_device_addr(a,b)
+/// \endcode
+/// In this example directive '#pragma omp target' has clause
+/// 'has_device_ptr' with the variables 'a' and 'b'.
+class OMPHasDeviceAddrClause final
+ : public OMPMappableExprListClause<OMPHasDeviceAddrClause>,
+ private llvm::TrailingObjects<
+ OMPHasDeviceAddrClause, Expr *, ValueDecl *, unsigned,
+ OMPClauseMappableExprCommon::MappableComponent> {
+ friend class OMPClauseReader;
+ friend OMPMappableExprListClause;
+ friend OMPVarListClause;
+ friend TrailingObjects;
+
+ /// Build clause with number of variables \a NumVars.
+ ///
+ /// \param Locs Locations needed to build a mappable clause. It includes 1)
+ /// StartLoc: starting location of the clause (the clause keyword); 2)
+ /// LParenLoc: location of '('; 3) EndLoc: ending location of the clause.
+ /// \param Sizes All required sizes to build a mappable clause. It includes 1)
+ /// NumVars: number of expressions listed in this clause; 2)
+ /// NumUniqueDeclarations: number of unique base declarations in this clause;
+ /// 3) NumComponentLists: number of component lists in this clause; and 4)
+ /// NumComponents: total number of expression components in the clause.
+ explicit OMPHasDeviceAddrClause(const OMPVarListLocTy &Locs,
+ const OMPMappableExprListSizeTy &Sizes)
+ : OMPMappableExprListClause(llvm::omp::OMPC_has_device_addr, Locs,
+ Sizes) {}
+
+ /// Build an empty clause.
+ ///
+ /// \param Sizes All required sizes to build a mappable clause. It includes 1)
+ /// NumVars: number of expressions listed in this clause; 2)
+ /// NumUniqueDeclarations: number of unique base declarations in this clause;
+ /// 3) NumComponentLists: number of component lists in this clause; and 4)
+ /// NumComponents: total number of expression components in the clause.
+ explicit OMPHasDeviceAddrClause(const OMPMappableExprListSizeTy &Sizes)
+ : OMPMappableExprListClause(llvm::omp::OMPC_has_device_addr,
+ OMPVarListLocTy(), Sizes) {}
+
+ /// Define the sizes of each trailing object array except the last one. This
+ /// is required for TrailingObjects to work properly.
+ size_t numTrailingObjects(OverloadToken<Expr *>) const {
+ return varlist_size();
+ }
+ size_t numTrailingObjects(OverloadToken<ValueDecl *>) const {
+ return getUniqueDeclarationsNum();
+ }
+ size_t numTrailingObjects(OverloadToken<unsigned>) const {
+ return getUniqueDeclarationsNum() + getTotalComponentListNum();
+ }
+
+public:
+ /// Creates clause with a list of variables \a Vars.
+ ///
+ /// \param C AST context.
+ /// \param Locs Locations needed to build a mappable clause. It includes 1)
+ /// StartLoc: starting location of the clause (the clause keyword); 2)
+ /// LParenLoc: location of '('; 3) EndLoc: ending location of the clause.
+ /// \param Vars The original expression used in the clause.
+ /// \param Declarations Declarations used in the clause.
+ /// \param ComponentLists Component lists used in the clause.
+ static OMPHasDeviceAddrClause *
+ Create(const ASTContext &C, const OMPVarListLocTy &Locs,
+ ArrayRef<Expr *> Vars, ArrayRef<ValueDecl *> Declarations,
+ MappableExprComponentListsRef ComponentLists);
+
+ /// Creates an empty clause with the place for \a NumVars variables.
+ ///
+ /// \param C AST context.
+ /// \param Sizes All required sizes to build a mappable clause. It includes 1)
+ /// NumVars: number of expressions listed in this clause; 2)
+ /// NumUniqueDeclarations: number of unique base declarations in this clause;
+ /// 3) NumComponentLists: number of component lists in this clause; and 4)
+ /// NumComponents: total number of expression components in the clause.
+ static OMPHasDeviceAddrClause *
+ CreateEmpty(const ASTContext &C, const OMPMappableExprListSizeTy &Sizes);
+
+ child_range children() {
+ return child_range(reinterpret_cast<Stmt **>(varlist_begin()),
+ reinterpret_cast<Stmt **>(varlist_end()));
+ }
+
+ const_child_range children() const {
+ auto Children = const_cast<OMPHasDeviceAddrClause *>(this)->children();
+ return const_child_range(Children.begin(), Children.end());
+ }
+
+ child_range used_children() {
+ return child_range(child_iterator(), child_iterator());
+ }
+ const_child_range used_children() const {
+ return const_child_range(const_child_iterator(), const_child_iterator());
+ }
+
+ static bool classof(const OMPClause *T) {
+ return T->getClauseKind() == llvm::omp::OMPC_has_device_addr;
+ }
+};
+
/// This represents clause 'nontemporal' in the '#pragma omp ...' directives.
///
/// \code
@@ -7338,7 +7745,7 @@ class OMPNontemporalClause final
return MutableArrayRef<Expr *>(varlist_end(), varlist_size());
}
ArrayRef<const Expr *> getPrivateRefs() const {
- return llvm::makeArrayRef(varlist_end(), varlist_size());
+ return llvm::ArrayRef(varlist_end(), varlist_size());
}
public:
@@ -7408,12 +7815,18 @@ class OMPOrderClause final : public OMPClause {
/// Location of '('.
SourceLocation LParenLoc;
- /// A kind of the 'default' clause.
+ /// A kind of the 'order' clause.
OpenMPOrderClauseKind Kind = OMPC_ORDER_unknown;
/// Start location of the kind in source code.
SourceLocation KindKwLoc;
+ /// A modifier for order clause
+ OpenMPOrderClauseModifier Modifier = OMPC_ORDER_MODIFIER_unknown;
+
+ /// Start location of the modifier in source code.
+ SourceLocation ModifierKwLoc;
+
/// Set kind of the clause.
///
/// \param K Argument of clause.
@@ -7424,6 +7837,16 @@ class OMPOrderClause final : public OMPClause {
/// \param KLoc Argument location.
void setKindKwLoc(SourceLocation KLoc) { KindKwLoc = KLoc; }
+ /// Set modifier of the clause.
+ ///
+ /// \param M Argument of clause.
+ void setModifier(OpenMPOrderClauseModifier M) { Modifier = M; }
+
+ /// Set modifier location.
+ ///
+ /// \param MLoc Modifier keyword location.
+ void setModifierKwLoc(SourceLocation MLoc) { ModifierKwLoc = MLoc; }
+
public:
/// Build 'order' clause with argument \p A ('concurrent').
///
@@ -7432,11 +7855,15 @@ public:
/// \param StartLoc Starting location of the clause.
/// \param LParenLoc Location of '('.
/// \param EndLoc Ending location of the clause.
+ /// \param Modifier The modifier applied to 'order' clause.
+ /// \param MLoc Location of the modifier
OMPOrderClause(OpenMPOrderClauseKind A, SourceLocation ALoc,
SourceLocation StartLoc, SourceLocation LParenLoc,
- SourceLocation EndLoc)
+ SourceLocation EndLoc, OpenMPOrderClauseModifier Modifier,
+ SourceLocation MLoc)
: OMPClause(llvm::omp::OMPC_order, StartLoc, EndLoc),
- LParenLoc(LParenLoc), Kind(A), KindKwLoc(ALoc) {}
+ LParenLoc(LParenLoc), Kind(A), KindKwLoc(ALoc), Modifier(Modifier),
+ ModifierKwLoc(MLoc) {}
/// Build an empty clause.
OMPOrderClause()
@@ -7454,6 +7881,12 @@ public:
/// Returns location of clause kind.
SourceLocation getKindKwLoc() const { return KindKwLoc; }
+ /// Returns Modifier of the clause.
+ OpenMPOrderClauseModifier getModifier() const { return Modifier; }
+
+ /// Returns location of clause modifier.
+ SourceLocation getModifierKwLoc() const { return ModifierKwLoc; }
+
child_range children() {
return child_range(child_iterator(), child_iterator());
}
@@ -7528,16 +7961,14 @@ public:
///
/// \param C AST context.
/// \param InteropVar The interop variable.
- /// \param PrefExprs The list of preference expressions.
- /// \param IsTarget Uses the 'target' interop-type.
- /// \param IsTargetSync Uses the 'targetsync' interop-type.
+ /// \param InteropInfo The interop-type and prefer_type list.
/// \param StartLoc Starting location of the clause.
/// \param LParenLoc Location of '('.
/// \param VarLoc Location of the interop variable.
/// \param EndLoc Ending location of the clause.
static OMPInitClause *Create(const ASTContext &C, Expr *InteropVar,
- ArrayRef<Expr *> PrefExprs, bool IsTarget,
- bool IsTargetSync, SourceLocation StartLoc,
+ OMPInteropInfo &InteropInfo,
+ SourceLocation StartLoc,
SourceLocation LParenLoc, SourceLocation VarLoc,
SourceLocation EndLoc);
@@ -7764,21 +8195,13 @@ public:
/// \endcode
/// In this example directive '#pragma omp dispatch' has simple 'novariants'
/// clause with condition 'a > 5'.
-class OMPNovariantsClause final : public OMPClause,
- public OMPClauseWithPreInit {
+class OMPNovariantsClause final
+ : public OMPOneStmtClause<llvm::omp::OMPC_novariants, OMPClause>,
+ public OMPClauseWithPreInit {
friend class OMPClauseReader;
- /// Location of '('.
- SourceLocation LParenLoc;
-
- /// Condition of the 'if' clause.
- Stmt *Condition = nullptr;
-
/// Set condition.
- void setCondition(Expr *Cond) { Condition = Cond; }
-
- /// Sets the location of '('.
- void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
+ void setCondition(Expr *Cond) { setStmt(Cond); }
public:
/// Build 'novariants' clause with condition \a Cond.
@@ -7794,38 +8217,22 @@ public:
OpenMPDirectiveKind CaptureRegion,
SourceLocation StartLoc, SourceLocation LParenLoc,
SourceLocation EndLoc)
- : OMPClause(llvm::omp::OMPC_novariants, StartLoc, EndLoc),
- OMPClauseWithPreInit(this), LParenLoc(LParenLoc), Condition(Cond) {
+ : OMPOneStmtClause(Cond, StartLoc, LParenLoc, EndLoc),
+ OMPClauseWithPreInit(this) {
setPreInitStmt(HelperCond, CaptureRegion);
}
/// Build an empty clause.
- OMPNovariantsClause()
- : OMPClause(llvm::omp::OMPC_novariants, SourceLocation(),
- SourceLocation()),
- OMPClauseWithPreInit(this) {}
-
- /// Returns the location of '('.
- SourceLocation getLParenLoc() const { return LParenLoc; }
+ OMPNovariantsClause() : OMPOneStmtClause(), OMPClauseWithPreInit(this) {}
/// Returns condition.
- Expr *getCondition() const { return cast_or_null<Expr>(Condition); }
-
- child_range children() { return child_range(&Condition, &Condition + 1); }
-
- const_child_range children() const {
- return const_child_range(&Condition, &Condition + 1);
- }
+ Expr *getCondition() const { return getStmtAs<Expr>(); }
child_range used_children();
const_child_range used_children() const {
auto Children = const_cast<OMPNovariantsClause *>(this)->used_children();
return const_child_range(Children.begin(), Children.end());
}
-
- static bool classof(const OMPClause *T) {
- return T->getClauseKind() == llvm::omp::OMPC_novariants;
- }
};
/// This represents 'nocontext' clause in the '#pragma omp ...' directive.
@@ -7835,20 +8242,13 @@ public:
/// \endcode
/// In this example directive '#pragma omp dispatch' has simple 'nocontext'
/// clause with condition 'a > 5'.
-class OMPNocontextClause final : public OMPClause, public OMPClauseWithPreInit {
+class OMPNocontextClause final
+ : public OMPOneStmtClause<llvm::omp::OMPC_nocontext, OMPClause>,
+ public OMPClauseWithPreInit {
friend class OMPClauseReader;
- /// Location of '('.
- SourceLocation LParenLoc;
-
- /// Condition of the 'if' clause.
- Stmt *Condition = nullptr;
-
/// Set condition.
- void setCondition(Expr *Cond) { Condition = Cond; }
-
- /// Sets the location of '('.
- void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
+ void setCondition(Expr *Cond) { setStmt(Cond); }
public:
/// Build 'nocontext' clause with condition \a Cond.
@@ -7863,38 +8263,22 @@ public:
OMPNocontextClause(Expr *Cond, Stmt *HelperCond,
OpenMPDirectiveKind CaptureRegion, SourceLocation StartLoc,
SourceLocation LParenLoc, SourceLocation EndLoc)
- : OMPClause(llvm::omp::OMPC_nocontext, StartLoc, EndLoc),
- OMPClauseWithPreInit(this), LParenLoc(LParenLoc), Condition(Cond) {
+ : OMPOneStmtClause(Cond, StartLoc, LParenLoc, EndLoc),
+ OMPClauseWithPreInit(this) {
setPreInitStmt(HelperCond, CaptureRegion);
}
/// Build an empty clause.
- OMPNocontextClause()
- : OMPClause(llvm::omp::OMPC_nocontext, SourceLocation(),
- SourceLocation()),
- OMPClauseWithPreInit(this) {}
-
- /// Returns the location of '('.
- SourceLocation getLParenLoc() const { return LParenLoc; }
+ OMPNocontextClause() : OMPOneStmtClause(), OMPClauseWithPreInit(this) {}
/// Returns condition.
- Expr *getCondition() const { return cast_or_null<Expr>(Condition); }
-
- child_range children() { return child_range(&Condition, &Condition + 1); }
-
- const_child_range children() const {
- return const_child_range(&Condition, &Condition + 1);
- }
+ Expr *getCondition() const { return getStmtAs<Expr>(); }
child_range used_children();
const_child_range used_children() const {
auto Children = const_cast<OMPNocontextClause *>(this)->used_children();
return const_child_range(Children.begin(), Children.end());
}
-
- static bool classof(const OMPClause *T) {
- return T->getClauseKind() == llvm::omp::OMPC_nocontext;
- }
};
/// This represents 'detach' clause in the '#pragma omp task' directive.
@@ -7904,20 +8288,12 @@ public:
/// \endcode
/// In this example directive '#pragma omp detach' has simple 'detach' clause
/// with the variable 'evt'.
-class OMPDetachClause final : public OMPClause {
+class OMPDetachClause final
+ : public OMPOneStmtClause<llvm::omp::OMPC_detach, OMPClause> {
friend class OMPClauseReader;
- /// Location of '('.
- SourceLocation LParenLoc;
-
- /// Expression of the 'detach' clause.
- Stmt *Evt = nullptr;
-
/// Set condition.
- void setEventHandler(Expr *E) { Evt = E; }
-
- /// Sets the location of '('.
- void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
+ void setEventHandler(Expr *E) { setStmt(E); }
public:
/// Build 'detach' clause with event-handler \a Evt.
@@ -7928,35 +8304,13 @@ public:
/// \param EndLoc Ending location of the clause.
OMPDetachClause(Expr *Evt, SourceLocation StartLoc, SourceLocation LParenLoc,
SourceLocation EndLoc)
- : OMPClause(llvm::omp::OMPC_detach, StartLoc, EndLoc),
- LParenLoc(LParenLoc), Evt(Evt) {}
+ : OMPOneStmtClause(Evt, StartLoc, LParenLoc, EndLoc) {}
/// Build an empty clause.
- OMPDetachClause()
- : OMPClause(llvm::omp::OMPC_detach, SourceLocation(), SourceLocation()) {}
-
- /// Returns the location of '('.
- SourceLocation getLParenLoc() const { return LParenLoc; }
+ OMPDetachClause() : OMPOneStmtClause() {}
/// Returns event-handler expression.
- Expr *getEventHandler() const { return cast_or_null<Expr>(Evt); }
-
- child_range children() { return child_range(&Evt, &Evt + 1); }
-
- const_child_range children() const {
- return const_child_range(&Evt, &Evt + 1);
- }
-
- child_range used_children() {
- return child_range(child_iterator(), child_iterator());
- }
- const_child_range used_children() const {
- return const_child_range(const_child_iterator(), const_child_iterator());
- }
-
- static bool classof(const OMPClause *T) {
- return T->getClauseKind() == llvm::omp::OMPC_detach;
- }
+ Expr *getEventHandler() const { return getStmtAs<Expr>(); }
};
/// This represents clause 'inclusive' in the '#pragma omp scan' directive.
@@ -8156,14 +8510,14 @@ private:
/// \param StartLoc Starting location of the clause.
/// \param LParenLoc Location of '('.
/// \param EndLoc Ending location of the clause.
- /// \param N Number of allocators asssociated with the clause.
+ /// \param N Number of allocators associated with the clause.
OMPUsesAllocatorsClause(SourceLocation StartLoc, SourceLocation LParenLoc,
SourceLocation EndLoc, unsigned N)
: OMPClause(llvm::omp::OMPC_uses_allocators, StartLoc, EndLoc),
LParenLoc(LParenLoc), NumOfAllocators(N) {}
/// Build an empty clause.
- /// \param N Number of allocators asssociated with the clause.
+ /// \param N Number of allocators associated with the clause.
///
explicit OMPUsesAllocatorsClause(unsigned N)
: OMPClause(llvm::omp::OMPC_uses_allocators, SourceLocation(),
@@ -8257,14 +8611,14 @@ class OMPAffinityClause final
/// \param LParenLoc Location of '('.
/// \param ColonLoc Location of ':'.
/// \param EndLoc Ending location of the clause.
- /// \param N Number of locators asssociated with the clause.
+ /// \param N Number of locators associated with the clause.
OMPAffinityClause(SourceLocation StartLoc, SourceLocation LParenLoc,
SourceLocation ColonLoc, SourceLocation EndLoc, unsigned N)
: OMPVarListClause<OMPAffinityClause>(llvm::omp::OMPC_affinity, StartLoc,
LParenLoc, EndLoc, N) {}
/// Build an empty clause.
- /// \param N Number of locators asssociated with the clause.
+ /// \param N Number of locators associated with the clause.
///
explicit OMPAffinityClause(unsigned N)
: OMPVarListClause<OMPAffinityClause>(llvm::omp::OMPC_affinity,
@@ -8340,20 +8694,13 @@ public:
/// \endcode
/// In this example directive '#pragma omp masked' has 'filter' clause with
/// thread id.
-class OMPFilterClause final : public OMPClause, public OMPClauseWithPreInit {
+class OMPFilterClause final
+ : public OMPOneStmtClause<llvm::omp::OMPC_filter, OMPClause>,
+ public OMPClauseWithPreInit {
friend class OMPClauseReader;
- /// Location of '('.
- SourceLocation LParenLoc;
-
- /// Express of the 'filter' clause.
- Stmt *ThreadID = nullptr;
-
/// Sets the thread identifier.
- void setThreadID(Expr *TID) { ThreadID = TID; }
-
- /// Sets the location of '('.
- void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
+ void setThreadID(Expr *TID) { setStmt(TID); }
public:
/// Build 'filter' clause with thread-id \a ThreadID.
@@ -8368,40 +8715,89 @@ public:
OMPFilterClause(Expr *ThreadID, Stmt *HelperE,
OpenMPDirectiveKind CaptureRegion, SourceLocation StartLoc,
SourceLocation LParenLoc, SourceLocation EndLoc)
- : OMPClause(llvm::omp::OMPC_filter, StartLoc, EndLoc),
- OMPClauseWithPreInit(this), LParenLoc(LParenLoc), ThreadID(ThreadID) {
+ : OMPOneStmtClause(ThreadID, StartLoc, LParenLoc, EndLoc),
+ OMPClauseWithPreInit(this) {
setPreInitStmt(HelperE, CaptureRegion);
}
/// Build an empty clause.
- OMPFilterClause()
- : OMPClause(llvm::omp::OMPC_filter, SourceLocation(), SourceLocation()),
- OMPClauseWithPreInit(this) {}
- /// Returns the location of '('.
- SourceLocation getLParenLoc() const { return LParenLoc; }
+ OMPFilterClause() : OMPOneStmtClause(), OMPClauseWithPreInit(this) {}
/// Return thread identifier.
- Expr *getThreadID() { return cast<Expr>(ThreadID); }
+ Expr *getThreadID() const { return getStmtAs<Expr>(); }
/// Return thread identifier.
- Expr *getThreadID() const { return cast<Expr>(ThreadID); }
+ Expr *getThreadID() { return getStmtAs<Expr>(); }
+};
+
+/// This represents 'bind' clause in the '#pragma omp ...' directives.
+///
+/// \code
+/// #pragma omp loop bind(parallel)
+/// \endcode
+class OMPBindClause final : public OMPNoChildClause<llvm::omp::OMPC_bind> {
+ friend class OMPClauseReader;
- child_range children() { return child_range(&ThreadID, &ThreadID + 1); }
+ /// Location of '('.
+ SourceLocation LParenLoc;
- const_child_range children() const {
- return const_child_range(&ThreadID, &ThreadID + 1);
- }
+ /// The binding kind of 'bind' clause.
+ OpenMPBindClauseKind Kind = OMPC_BIND_unknown;
- child_range used_children() {
- return child_range(child_iterator(), child_iterator());
- }
- const_child_range used_children() const {
- return const_child_range(const_child_iterator(), const_child_iterator());
- }
+ /// Start location of the kind in source code.
+ SourceLocation KindLoc;
- static bool classof(const OMPClause *T) {
- return T->getClauseKind() == llvm::omp::OMPC_filter;
- }
+ /// Sets the location of '('.
+ void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
+
+ /// Set the binding kind.
+ void setBindKind(OpenMPBindClauseKind K) { Kind = K; }
+
+ /// Set the binding kind location.
+ void setBindKindLoc(SourceLocation KLoc) { KindLoc = KLoc; }
+
+ /// Build 'bind' clause with kind \a K ('teams', 'parallel', or 'thread').
+ ///
+ /// \param K Binding kind of the clause ('teams', 'parallel' or 'thread').
+ /// \param KLoc Starting location of the binding kind.
+ /// \param StartLoc Starting location of the clause.
+ /// \param LParenLoc Location of '('.
+ /// \param EndLoc Ending location of the clause.
+ OMPBindClause(OpenMPBindClauseKind K, SourceLocation KLoc,
+ SourceLocation StartLoc, SourceLocation LParenLoc,
+ SourceLocation EndLoc)
+ : OMPNoChildClause(StartLoc, EndLoc), LParenLoc(LParenLoc), Kind(K),
+ KindLoc(KLoc) {}
+
+ /// Build an empty clause.
+ OMPBindClause() : OMPNoChildClause() {}
+
+public:
+ /// Build 'bind' clause with kind \a K ('teams', 'parallel', or 'thread').
+ ///
+ /// \param C AST context
+ /// \param K Binding kind of the clause ('teams', 'parallel' or 'thread').
+ /// \param KLoc Starting location of the binding kind.
+ /// \param StartLoc Starting location of the clause.
+ /// \param LParenLoc Location of '('.
+ /// \param EndLoc Ending location of the clause.
+ static OMPBindClause *Create(const ASTContext &C, OpenMPBindClauseKind K,
+ SourceLocation KLoc, SourceLocation StartLoc,
+ SourceLocation LParenLoc, SourceLocation EndLoc);
+
+ /// Build an empty 'bind' clause.
+ ///
+ /// \param C AST context
+ static OMPBindClause *CreateEmpty(const ASTContext &C);
+
+ /// Returns the location of '('.
+ SourceLocation getLParenLoc() const { return LParenLoc; }
+
+ /// Returns kind of the clause.
+ OpenMPBindClauseKind getBindKind() const { return Kind; }
+
+ /// Returns location of clause kind.
+ SourceLocation getBindKindLoc() const { return KindLoc; }
};
/// This class implements a simple visitor for OMPClause
@@ -8546,10 +8942,11 @@ llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const OMPTraitInfo *TI);
/// Clang specific specialization of the OMPContext to lookup target features.
struct TargetOMPContext final : public llvm::omp::OMPContext {
-
TargetOMPContext(ASTContext &ASTCtx,
std::function<void(StringRef)> &&DiagUnknownTrait,
- const FunctionDecl *CurrentFunctionDecl);
+ const FunctionDecl *CurrentFunctionDecl,
+ ArrayRef<llvm::omp::TraitProperty> ConstructTraits);
+
virtual ~TargetOMPContext() = default;
/// See llvm::omp::OMPContext::matchesISATrait
@@ -8630,7 +9027,7 @@ public:
/// Get the clauses storage.
MutableArrayRef<OMPClause *> getClauses() {
- return llvm::makeMutableArrayRef(getTrailingObjects<OMPClause *>(),
+ return llvm::MutableArrayRef(getTrailingObjects<OMPClause *>(),
NumClauses);
}
ArrayRef<OMPClause *> getClauses() const {
@@ -8644,9 +9041,7 @@ public:
const CapturedStmt *
getCapturedStmt(OpenMPDirectiveKind RegionKind,
ArrayRef<OpenMPDirectiveKind> CaptureRegions) const {
- assert(llvm::any_of(
- CaptureRegions,
- [=](const OpenMPDirectiveKind K) { return K == RegionKind; }) &&
+ assert(llvm::is_contained(CaptureRegions, RegionKind) &&
"RegionKind not found in OpenMP CaptureRegions.");
auto *CS = cast<CapturedStmt>(getAssociatedStmt());
for (auto ThisCaptureRegion : CaptureRegions) {
@@ -8705,6 +9100,243 @@ public:
}
};
+/// This represents 'ompx_dyn_cgroup_mem' clause in the '#pragma omp target ...'
+/// directive.
+///
+/// \code
+/// #pragma omp target [...] ompx_dyn_cgroup_mem(N)
+/// \endcode
+class OMPXDynCGroupMemClause
+ : public OMPOneStmtClause<llvm::omp::OMPC_ompx_dyn_cgroup_mem, OMPClause>,
+ public OMPClauseWithPreInit {
+ friend class OMPClauseReader;
+
+ /// Set size.
+ void setSize(Expr *E) { setStmt(E); }
+
+public:
+ /// Build 'ompx_dyn_cgroup_mem' clause.
+ ///
+ /// \param Size Size expression.
+ /// \param HelperSize Helper Size expression
+ /// \param CaptureRegion Innermost OpenMP region where expressions in this
+ /// \param StartLoc Starting location of the clause.
+ /// \param LParenLoc Location of '('.
+ /// \param EndLoc Ending location of the clause.
+ OMPXDynCGroupMemClause(Expr *Size, Stmt *HelperSize,
+ OpenMPDirectiveKind CaptureRegion,
+ SourceLocation StartLoc, SourceLocation LParenLoc,
+ SourceLocation EndLoc)
+ : OMPOneStmtClause(Size, StartLoc, LParenLoc, EndLoc),
+ OMPClauseWithPreInit(this) {
+ setPreInitStmt(HelperSize, CaptureRegion);
+ }
+
+ /// Build an empty clause.
+ OMPXDynCGroupMemClause() : OMPOneStmtClause(), OMPClauseWithPreInit(this) {}
+
+ /// Return the size expression.
+ Expr *getSize() { return getStmtAs<Expr>(); }
+
+ /// Return the size expression.
+ Expr *getSize() const { return getStmtAs<Expr>(); }
+};
+
+/// This represents the 'doacross' clause for the '#pragma omp ordered'
+/// directive.
+///
+/// \code
+/// #pragma omp ordered doacross(sink: i-1, j-1)
+/// \endcode
+/// In this example directive '#pragma omp ordered' with clause 'doacross' with
+/// a dependence-type 'sink' and loop-iteration vector expressions i-1 and j-1.
+class OMPDoacrossClause final
+ : public OMPVarListClause<OMPDoacrossClause>,
+ private llvm::TrailingObjects<OMPDoacrossClause, Expr *> {
+ friend class OMPClauseReader;
+ friend OMPVarListClause;
+ friend TrailingObjects;
+
+ /// Dependence type (sink or source).
+ OpenMPDoacrossClauseModifier DepType = OMPC_DOACROSS_unknown;
+
+ /// Dependence type location.
+ SourceLocation DepLoc;
+
+ /// Colon location.
+ SourceLocation ColonLoc;
+
+ /// Number of loops, associated with the doacross clause.
+ unsigned NumLoops = 0;
+
+ /// Build clause with number of expressions \a N.
+ ///
+ /// \param StartLoc Starting location of the clause.
+ /// \param LParenLoc Location of '('.
+ /// \param EndLoc Ending location of the clause.
+ /// \param N Number of expressions in the clause.
+ /// \param NumLoops Number of loops associated with the clause.
+ OMPDoacrossClause(SourceLocation StartLoc, SourceLocation LParenLoc,
+ SourceLocation EndLoc, unsigned N, unsigned NumLoops)
+ : OMPVarListClause<OMPDoacrossClause>(llvm::omp::OMPC_doacross, StartLoc,
+ LParenLoc, EndLoc, N),
+ NumLoops(NumLoops) {}
+
+ /// Build an empty clause.
+ ///
+ /// \param N Number of expressions in the clause.
+ /// \param NumLoops Number of loops associated with the clause.
+ explicit OMPDoacrossClause(unsigned N, unsigned NumLoops)
+ : OMPVarListClause<OMPDoacrossClause>(llvm::omp::OMPC_doacross,
+ SourceLocation(), SourceLocation(),
+ SourceLocation(), N),
+ NumLoops(NumLoops) {}
+
+ /// Set dependence type.
+ void setDependenceType(OpenMPDoacrossClauseModifier M) { DepType = M; }
+
+ /// Set dependence type location.
+ void setDependenceLoc(SourceLocation Loc) { DepLoc = Loc; }
+
+ /// Set colon location.
+ void setColonLoc(SourceLocation Loc) { ColonLoc = Loc; }
+
+public:
+ /// Creates clause with a list of expressions \a VL.
+ ///
+ /// \param C AST context.
+ /// \param StartLoc Starting location of the clause.
+ /// \param LParenLoc Location of '('.
+ /// \param EndLoc Ending location of the clause.
+ /// \param DepType The dependence type.
+ /// \param DepLoc Location of the dependence type.
+ /// \param ColonLoc Location of ':'.
+ /// \param VL List of references to the expressions.
+ /// \param NumLoops Number of loops that associated with the clause.
+ static OMPDoacrossClause *
+ Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
+ SourceLocation EndLoc, OpenMPDoacrossClauseModifier DepType,
+ SourceLocation DepLoc, SourceLocation ColonLoc, ArrayRef<Expr *> VL,
+ unsigned NumLoops);
+
+ /// Creates an empty clause with \a N expressions.
+ ///
+ /// \param C AST context.
+ /// \param N The number of expressions.
+ /// \param NumLoops Number of loops that is associated with this clause.
+ static OMPDoacrossClause *CreateEmpty(const ASTContext &C, unsigned N,
+ unsigned NumLoops);
+
+ /// Get dependence type.
+ OpenMPDoacrossClauseModifier getDependenceType() const { return DepType; }
+
+ /// Get dependence type location.
+ SourceLocation getDependenceLoc() const { return DepLoc; }
+
+ /// Get colon location.
+ SourceLocation getColonLoc() const { return ColonLoc; }
+
+ /// Get number of loops associated with the clause.
+ unsigned getNumLoops() const { return NumLoops; }
+
+ /// Set the loop data.
+ void setLoopData(unsigned NumLoop, Expr *Cnt);
+
+ /// Get the loop data.
+ Expr *getLoopData(unsigned NumLoop);
+ const Expr *getLoopData(unsigned NumLoop) const;
+
+ child_range children() {
+ return child_range(reinterpret_cast<Stmt **>(varlist_begin()),
+ reinterpret_cast<Stmt **>(varlist_end()));
+ }
+
+ const_child_range children() const {
+ auto Children = const_cast<OMPDoacrossClause *>(this)->children();
+ return const_child_range(Children.begin(), Children.end());
+ }
+
+ child_range used_children() {
+ return child_range(child_iterator(), child_iterator());
+ }
+ const_child_range used_children() const {
+ return const_child_range(const_child_iterator(), const_child_iterator());
+ }
+
+ static bool classof(const OMPClause *T) {
+ return T->getClauseKind() == llvm::omp::OMPC_doacross;
+ }
+};
+
+/// This represents 'ompx_attribute' clause in a directive that might generate
+/// an outlined function. An example is given below.
+///
+/// \code
+/// #pragma omp target [...] ompx_attribute(flatten)
+/// \endcode
+class OMPXAttributeClause
+ : public OMPNoChildClause<llvm::omp::OMPC_ompx_attribute> {
+ friend class OMPClauseReader;
+
+ /// Location of '('.
+ SourceLocation LParenLoc;
+
+ /// The parsed attributes (clause arguments)
+ SmallVector<const Attr *> Attrs;
+
+public:
+ /// Build 'ompx_attribute' clause.
+ ///
+ /// \param Attrs The parsed attributes (clause arguments)
+ /// \param StartLoc Starting location of the clause.
+ /// \param LParenLoc Location of '('.
+ /// \param EndLoc Ending location of the clause.
+ OMPXAttributeClause(ArrayRef<const Attr *> Attrs, SourceLocation StartLoc,
+ SourceLocation LParenLoc, SourceLocation EndLoc)
+ : OMPNoChildClause(StartLoc, EndLoc), LParenLoc(LParenLoc), Attrs(Attrs) {
+ }
+
+ /// Build an empty clause.
+ OMPXAttributeClause() : OMPNoChildClause() {}
+
+ /// Sets the location of '('.
+ void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
+
+ /// Returns the location of '('.
+ SourceLocation getLParenLoc() const { return LParenLoc; }
+
+ /// Returned the attributes parsed from this clause.
+ ArrayRef<const Attr *> getAttrs() const { return Attrs; }
+
+private:
+ /// Replace the attributes with \p NewAttrs.
+ void setAttrs(ArrayRef<Attr *> NewAttrs) {
+ Attrs.clear();
+ Attrs.append(NewAttrs.begin(), NewAttrs.end());
+ }
+};
+
+/// This represents 'ompx_bare' clause in the '#pragma omp target teams ...'
+/// directive.
+///
+/// \code
+/// #pragma omp target teams ompx_bare
+/// \endcode
+/// In this example directive '#pragma omp target teams' has a 'ompx_bare'
+/// clause.
+class OMPXBareClause : public OMPNoChildClause<llvm::omp::OMPC_ompx_bare> {
+public:
+ /// Build 'ompx_bare' clause.
+ ///
+ /// \param StartLoc Starting location of the clause.
+ /// \param EndLoc Ending location of the clause.
+ OMPXBareClause(SourceLocation StartLoc, SourceLocation EndLoc)
+ : OMPNoChildClause(StartLoc, EndLoc) {}
+
+ /// Build an empty clause.
+ OMPXBareClause() = default;
+};
+
} // namespace clang
#endif // LLVM_CLANG_AST_OPENMPCLAUSE_H
diff --git a/contrib/llvm-project/clang/include/clang/AST/OperationKinds.def b/contrib/llvm-project/clang/include/clang/AST/OperationKinds.def
index b05b9d81569e..8dd98730dff7 100644
--- a/contrib/llvm-project/clang/include/clang/AST/OperationKinds.def
+++ b/contrib/llvm-project/clang/include/clang/AST/OperationKinds.def
@@ -80,6 +80,7 @@ CAST_OPERATION(LValueToRValue)
/// (possibly) adding qualifiers or removing noexcept.
/// int -> int
/// char** -> const char * const *
+/// int[1] -> int[]
/// void () noexcept -> void ()
CAST_OPERATION(NoOp)
@@ -362,8 +363,8 @@ CAST_OPERATION(IntToOCLSampler)
//===- Binary Operations -------------------------------------------------===//
// Operators listed in order of precedence.
-// Note that additions to this should also update the StmtVisitor class and
-// BinaryOperator::getOverloadedOperator.
+// Note that additions to this should also update the StmtVisitor class,
+// BinaryOperator::getOverloadedOperator and CXBinaryOperatorKind enum.
// [C++ 5.5] Pointer-to-member operators.
BINARY_OPERATION(PtrMemD, ".*")
@@ -415,8 +416,8 @@ BINARY_OPERATION(Comma, ",")
//===- Unary Operations ---------------------------------------------------===//
-// Note that additions to this should also update the StmtVisitor class and
-// UnaryOperator::getOverloadedOperator.
+// Note that additions to this should also update the StmtVisitor class,
+// UnaryOperator::getOverloadedOperator and CXUnaryOperatorKind enum.
// [C99 6.5.2.4] Postfix increment and decrement
UNARY_OPERATION(PostInc, "++")
diff --git a/contrib/llvm-project/clang/include/clang/AST/ParentMapContext.h b/contrib/llvm-project/clang/include/clang/AST/ParentMapContext.h
index 2edbc987850d..d3b2e3986a99 100644
--- a/contrib/llvm-project/clang/include/clang/AST/ParentMapContext.h
+++ b/contrib/llvm-project/clang/include/clang/AST/ParentMapContext.h
@@ -77,7 +77,7 @@ class TraversalKindScope {
TraversalKind TK = TK_AsIs;
public:
- TraversalKindScope(ASTContext &ASTCtx, llvm::Optional<TraversalKind> ScopeTK)
+ TraversalKindScope(ASTContext &ASTCtx, std::optional<TraversalKind> ScopeTK)
: Ctx(ASTCtx.getParentMapContext()) {
TK = Ctx.getTraversalKind();
if (ScopeTK)
@@ -90,29 +90,27 @@ public:
/// Container for either a single DynTypedNode or for an ArrayRef to
/// DynTypedNode. For use with ParentMap.
class DynTypedNodeList {
- llvm::AlignedCharArrayUnion<DynTypedNode, ArrayRef<DynTypedNode>> Storage;
+ union {
+ DynTypedNode SingleNode;
+ ArrayRef<DynTypedNode> Nodes;
+ };
bool IsSingleNode;
public:
DynTypedNodeList(const DynTypedNode &N) : IsSingleNode(true) {
- new (&Storage) DynTypedNode(N);
+ new (&SingleNode) DynTypedNode(N);
}
DynTypedNodeList(ArrayRef<DynTypedNode> A) : IsSingleNode(false) {
- new (&Storage) ArrayRef<DynTypedNode>(A);
+ new (&Nodes) ArrayRef<DynTypedNode>(A);
}
const DynTypedNode *begin() const {
- if (!IsSingleNode)
- return reinterpret_cast<const ArrayRef<DynTypedNode> *>(&Storage)
- ->begin();
- return reinterpret_cast<const DynTypedNode *>(&Storage);
+ return !IsSingleNode ? Nodes.begin() : &SingleNode;
}
const DynTypedNode *end() const {
- if (!IsSingleNode)
- return reinterpret_cast<const ArrayRef<DynTypedNode> *>(&Storage)->end();
- return reinterpret_cast<const DynTypedNode *>(&Storage) + 1;
+ return !IsSingleNode ? Nodes.end() : &SingleNode + 1;
}
size_t size() const { return end() - begin(); }
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 3baf2b2ba94d..da276e26049b 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:
@@ -62,19 +60,24 @@ struct PrintingPolicy {
: Indentation(2), SuppressSpecifiers(false),
SuppressTagKeyword(LO.CPlusPlus), IncludeTagDefinition(false),
SuppressScope(false), SuppressUnwrittenScope(false),
- SuppressInlineNamespace(true), SuppressInitializers(false),
- ConstantArraySizeAsWritten(false), AnonymousTagLocations(true),
- SuppressStrongLifetime(false), SuppressLifetimeQualifiers(false),
+ SuppressInlineNamespace(true), SuppressElaboration(false),
+ SuppressInitializers(false), ConstantArraySizeAsWritten(false),
+ AnonymousTagLocations(true), SuppressStrongLifetime(false),
+ SuppressLifetimeQualifiers(false),
SuppressTemplateArgsInCXXConstructors(false),
SuppressDefaultTemplateArgs(true), Bool(LO.Bool),
- Nullptr(LO.CPlusPlus11), Restrict(LO.C99), Alignof(LO.CPlusPlus11),
- UnderscoreAlignof(LO.C11), UseVoidForZeroParams(!LO.CPlusPlus),
+ Nullptr(LO.CPlusPlus11 || LO.C23), NullptrTypeInNamespace(LO.CPlusPlus),
+ Restrict(LO.C99), Alignof(LO.CPlusPlus11), UnderscoreAlignof(LO.C11),
+ UseVoidForZeroParams(!LO.CPlusPlus),
SplitTemplateClosers(!LO.CPlusPlus11), TerseOutput(false),
PolishForDeclaration(false), Half(LO.Half),
MSWChar(LO.MicrosoftExt && !LO.WChar), IncludeNewlines(true),
MSVCFormatting(false), ConstantsAsWritten(false),
SuppressImplicitBase(false), FullyQualifiedName(false),
- PrintCanonicalTypes(false), PrintInjectedClassNameWithArguments(true) {}
+ PrintCanonicalTypes(false), PrintInjectedClassNameWithArguments(true),
+ UsePreferredNames(true), AlwaysIncludeTypeForTemplateArgument(false),
+ CleanUglifiedParameters(false), EntireContentsOfLargeArray(true),
+ UseEnumerators(true) {}
/// 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
@@ -103,6 +106,7 @@ struct PrintingPolicy {
/// declaration for "x", so that we will print "int *x"; it will be
/// \c true when we print "y", so that we suppress printing the
/// "const int" type specifier and instead only print the "*y".
+ LLVM_PREFERRED_TYPE(bool)
unsigned SuppressSpecifiers : 1;
/// Whether type printing should skip printing the tag keyword.
@@ -113,6 +117,7 @@ struct PrintingPolicy {
/// \code
/// struct Geometry::Point;
/// \endcode
+ LLVM_PREFERRED_TYPE(bool)
unsigned SuppressTagKeyword : 1;
/// When true, include the body of a tag definition.
@@ -123,20 +128,29 @@ struct PrintingPolicy {
/// \code
/// typedef struct { int x, y; } Point;
/// \endcode
+ LLVM_PREFERRED_TYPE(bool)
unsigned IncludeTagDefinition : 1;
/// Suppresses printing of scope specifiers.
+ LLVM_PREFERRED_TYPE(bool)
unsigned SuppressScope : 1;
/// Suppress printing parts of scope specifiers that are never
/// written, e.g., for anonymous namespaces.
+ LLVM_PREFERRED_TYPE(bool)
unsigned SuppressUnwrittenScope : 1;
/// Suppress printing parts of scope specifiers that correspond
/// to inline namespaces, where the name is unambiguous with the specifier
/// removed.
+ LLVM_PREFERRED_TYPE(bool)
unsigned SuppressInlineNamespace : 1;
+ /// Ignore qualifiers and tag keywords as specified by elaborated type sugar,
+ /// instead letting the underlying type print as normal.
+ LLVM_PREFERRED_TYPE(bool)
+ unsigned SuppressElaboration : 1;
+
/// Suppress printing of variable initializers.
///
/// This flag is used when printing the loop variable in a for-range
@@ -148,6 +162,7 @@ struct PrintingPolicy {
///
/// SuppressInitializers will be true when printing "auto x", so that the
/// internal initializer constructed for x will not be printed.
+ LLVM_PREFERRED_TYPE(bool)
unsigned SuppressInitializers : 1;
/// Whether we should print the sizes of constant array expressions as written
@@ -166,50 +181,67 @@ struct PrintingPolicy {
/// int a[104];
/// char a[9] = "A string";
/// \endcode
+ LLVM_PREFERRED_TYPE(bool)
unsigned ConstantArraySizeAsWritten : 1;
/// When printing an anonymous tag name, also print the location of that
/// entity (e.g., "enum <anonymous at t.h:10:5>"). Otherwise, just prints
/// "(anonymous)" for the name.
+ LLVM_PREFERRED_TYPE(bool)
unsigned AnonymousTagLocations : 1;
/// When true, suppress printing of the __strong lifetime qualifier in ARC.
+ LLVM_PREFERRED_TYPE(bool)
unsigned SuppressStrongLifetime : 1;
/// When true, suppress printing of lifetime qualifier in ARC.
+ LLVM_PREFERRED_TYPE(bool)
unsigned SuppressLifetimeQualifiers : 1;
/// When true, suppresses printing template arguments in names of C++
/// constructors.
+ LLVM_PREFERRED_TYPE(bool)
unsigned SuppressTemplateArgsInCXXConstructors : 1;
/// When true, attempt to suppress template arguments that match the default
/// argument for the parameter.
+ LLVM_PREFERRED_TYPE(bool)
unsigned SuppressDefaultTemplateArgs : 1;
/// Whether we can use 'bool' rather than '_Bool' (even if the language
/// doesn't actually have 'bool', because, e.g., it is defined as a macro).
+ LLVM_PREFERRED_TYPE(bool)
unsigned Bool : 1;
/// Whether we should use 'nullptr' rather than '0' as a null pointer
/// constant.
+ LLVM_PREFERRED_TYPE(bool)
unsigned Nullptr : 1;
+ /// Whether 'nullptr_t' is in namespace 'std' or not.
+ LLVM_PREFERRED_TYPE(bool)
+ unsigned NullptrTypeInNamespace : 1;
+
/// Whether we can use 'restrict' rather than '__restrict'.
+ LLVM_PREFERRED_TYPE(bool)
unsigned Restrict : 1;
/// Whether we can use 'alignof' rather than '__alignof'.
+ LLVM_PREFERRED_TYPE(bool)
unsigned Alignof : 1;
/// Whether we can use '_Alignof' rather than '__alignof'.
+ LLVM_PREFERRED_TYPE(bool)
unsigned UnderscoreAlignof : 1;
/// Whether we should use '(void)' rather than '()' for a function prototype
/// with zero parameters.
+ LLVM_PREFERRED_TYPE(bool)
unsigned UseVoidForZeroParams : 1;
/// Whether nested templates must be closed like 'a\<b\<c\> \>' rather than
/// 'a\<b\<c\>\>'.
+ LLVM_PREFERRED_TYPE(bool)
unsigned SplitTemplateClosers : 1;
/// Provide a 'terse' output.
@@ -217,27 +249,33 @@ struct PrintingPolicy {
/// For example, in this mode we don't print function bodies, class members,
/// declarations inside namespaces etc. Effectively, this should print
/// only the requested declaration.
+ LLVM_PREFERRED_TYPE(bool)
unsigned TerseOutput : 1;
/// When true, do certain refinement needed for producing proper declaration
/// tag; such as, do not print attributes attached to the declaration.
///
+ LLVM_PREFERRED_TYPE(bool)
unsigned PolishForDeclaration : 1;
/// When true, print the half-precision floating-point type as 'half'
/// instead of '__fp16'
+ LLVM_PREFERRED_TYPE(bool)
unsigned Half : 1;
/// When true, print the built-in wchar_t type as __wchar_t. For use in
/// Microsoft mode when wchar_t is not available.
+ LLVM_PREFERRED_TYPE(bool)
unsigned MSWChar : 1;
/// When true, include newlines after statements like "break", etc.
+ LLVM_PREFERRED_TYPE(bool)
unsigned IncludeNewlines : 1;
/// Use whitespace and punctuation like MSVC does. In particular, this prints
/// anonymous namespaces as `anonymous namespace' and does not insert spaces
/// after template arguments.
+ LLVM_PREFERRED_TYPE(bool)
unsigned MSVCFormatting : 1;
/// Whether we should print the constant expressions as written in the
@@ -256,23 +294,54 @@ struct PrintingPolicy {
/// 0x10
/// 2.5e3
/// \endcode
+ LLVM_PREFERRED_TYPE(bool)
unsigned ConstantsAsWritten : 1;
/// When true, don't print the implicit 'self' or 'this' expressions.
+ LLVM_PREFERRED_TYPE(bool)
unsigned SuppressImplicitBase : 1;
/// When true, print the fully qualified name of function declarations.
/// This is the opposite of SuppressScope and thus overrules it.
+ LLVM_PREFERRED_TYPE(bool)
unsigned FullyQualifiedName : 1;
/// Whether to print types as written or canonically.
+ LLVM_PREFERRED_TYPE(bool)
unsigned PrintCanonicalTypes : 1;
/// Whether to print an InjectedClassNameType with template arguments or as
/// written. When a template argument is unnamed, printing it results in
/// invalid C++ code.
+ LLVM_PREFERRED_TYPE(bool)
unsigned PrintInjectedClassNameWithArguments : 1;
+ /// Whether to use C++ template preferred_name attributes when printing
+ /// templates.
+ LLVM_PREFERRED_TYPE(bool)
+ unsigned UsePreferredNames : 1;
+
+ /// Whether to use type suffixes (eg: 1U) on integral non-type template
+ /// parameters.
+ LLVM_PREFERRED_TYPE(bool)
+ 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.
+ LLVM_PREFERRED_TYPE(bool)
+ unsigned CleanUglifiedParameters : 1;
+
+ /// Whether to print the entire array initializers, especially on non-type
+ /// template parameters, no matter how many elements there are.
+ LLVM_PREFERRED_TYPE(bool)
+ unsigned EntireContentsOfLargeArray : 1;
+
+ /// Whether to print enumerator non-type template parameters with a matching
+ /// enumerator name or via cast of an integer.
+ LLVM_PREFERRED_TYPE(bool)
+ unsigned UseEnumerators : 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/PropertiesBase.td b/contrib/llvm-project/clang/include/clang/AST/PropertiesBase.td
index a087cb406b29..0270c086d06b 100644
--- a/contrib/llvm-project/clang/include/clang/AST/PropertiesBase.td
+++ b/contrib/llvm-project/clang/include/clang/AST/PropertiesBase.td
@@ -41,7 +41,7 @@ class RefPropertyType<string className> : PropertyType<className # "*"> {
let PackOptional =
"value ? *value : nullptr";
let UnpackOptional =
- "value ? llvm::Optional<" # CXXName # ">(value) : llvm::None";
+ "value ? std::optional<" # CXXName # ">(value) : std::nullopt";
}
/// Property types that correspond to a specific subclass of another type.
@@ -58,7 +58,7 @@ class DefaultValuePropertyType<string typeName = ""> : PropertyType<typeName> {
let PackOptional =
"value ? *value : " # CXXName # "()";
let UnpackOptional =
- "value.isNull() ? llvm::None : llvm::Optional<" # CXXName # ">(value)";
+ "value.isNull() ? std::nullopt : std::optional<" # CXXName # ">(value)";
}
/// Property types that correspond to integer types and support optional
@@ -67,18 +67,19 @@ class CountPropertyType<string typeName = ""> : PropertyType<typeName> {
let PackOptional =
"value ? *value + 1 : 0";
let UnpackOptional =
- "value ? llvm::Optional<" # CXXName # ">(value - 1) : llvm::None";
+ "value ? std::optional<" # CXXName # ">(value - 1) : std::nullopt";
}
def APInt : PropertyType<"llvm::APInt"> { let PassByReference = 1; }
def APSInt : PropertyType<"llvm::APSInt"> { let PassByReference = 1; }
def APValue : PropertyType { let PassByReference = 1; }
def APValueKind : EnumPropertyType<"APValue::ValueKind">;
-def ArraySizeModifier : EnumPropertyType<"ArrayType::ArraySizeModifier">;
+def ArraySizeModifier : EnumPropertyType<"ArraySizeModifier">;
def AttrKind : EnumPropertyType<"attr::Kind">;
def AutoTypeKeyword : EnumPropertyType;
def Bool : PropertyType<"bool">;
def BuiltinTypeKind : EnumPropertyType<"BuiltinType::Kind">;
+def BTFTypeTagAttr : PropertyType<"const BTFTypeTagAttr *">;
def CallingConv : EnumPropertyType;
def DeclarationName : PropertyType;
def DeclarationNameKind : EnumPropertyType<"DeclarationName::NameKind">;
@@ -107,6 +108,8 @@ def DeclRef : RefPropertyType<"Decl"> { let ConstWhenWriting = 1; }
SubclassPropertyType<"TemplateTypeParmDecl", DeclRef>;
def TemplateTemplateParmDeclRef :
SubclassPropertyType<"TemplateTemplateParmDecl", DeclRef>;
+ def UsingShadowDeclRef :
+ SubclassPropertyType<"UsingShadowDecl", DeclRef>;
def ValueDeclRef :
SubclassPropertyType<"ValueDecl", DeclRef>;
def ElaboratedTypeKeyword : EnumPropertyType;
@@ -135,10 +138,11 @@ def TemplateArgument : PropertyType;
def TemplateArgumentKind : EnumPropertyType<"TemplateArgument::ArgKind">;
def TemplateName : DefaultValuePropertyType;
def TemplateNameKind : EnumPropertyType<"TemplateName::NameKind">;
+def TypeOfKind : EnumPropertyType<"TypeOfKind">;
def UInt32 : CountPropertyType<"uint32_t">;
def UInt64 : CountPropertyType<"uint64_t">;
def UnaryTypeTransformKind : EnumPropertyType<"UnaryTransformType::UTTKind">;
-def VectorKind : EnumPropertyType<"VectorType::VectorKind">;
+def VectorKind : EnumPropertyType<"VectorKind">;
def ExceptionSpecInfo : PropertyType<"FunctionProtoType::ExceptionSpecInfo"> {
let BufferElementTypes = [ QualType ];
@@ -151,7 +155,7 @@ class Array<PropertyType element> : PropertyType {
let BufferElementTypes = [ element ];
}
-/// llvm::Optional<T>. The corresponding C++ type is generally just the
+/// std::optional<T>. The corresponding C++ type is generally just the
/// corresponding C++ type of the element.
///
/// Optional<Unsigned> may restrict the range of the operand for some
@@ -446,10 +450,13 @@ let Class = PropertyTypeCase<APValue, "LValue"> in {
lvalueBase ? lvalueBase.dyn_cast<const Expr *>() : nullptr;
bool lvalueBaseIsExpr = (bool) expr;
bool lvalueBaseIsTypeInfo = lvalueBase.is<TypeInfoLValue>();
+ bool lvalueBaseIsDynamicAlloc = lvalueBase.is<DynamicAllocLValue>();
QualType elemTy;
if (lvalueBase) {
if (lvalueBaseIsTypeInfo) {
elemTy = lvalueBase.getTypeInfoType();
+ } else if (lvalueBaseIsDynamicAlloc) {
+ elemTy = lvalueBase.getDynamicAllocType();
} else if (lvalueBaseIsExpr) {
elemTy = expr->getType();
} else {
@@ -469,6 +476,9 @@ let Class = PropertyTypeCase<APValue, "LValue"> in {
def : Property<"isTypeInfo", Bool> {
let Read = [{ lvalueBaseIsTypeInfo }];
}
+ def : Property<"isDynamicAlloc", Bool> {
+ let Read = [{ lvalueBaseIsDynamicAlloc }];
+ }
def : Property<"hasBase", Bool> {
let Read = [{ static_cast<bool>(lvalueBase) }];
}
@@ -481,9 +491,17 @@ let Class = PropertyTypeCase<APValue, "LValue"> in {
QualType(node.getLValueBase().get<TypeInfoLValue>().getType(), 0)
}];
}
+ def : Property<"dynamicAlloc", UInt32> {
+ let Conditional = [{ hasBase && isDynamicAlloc }];
+ let Read = [{ node.getLValueBase().get<DynamicAllocLValue>().getIndex() }];
+ }
def : Property<"type", QualType> {
- let Conditional = [{ hasBase && isTypeInfo }];
- let Read = [{ node.getLValueBase().getTypeInfoType() }];
+ let Conditional = [{ hasBase && (isTypeInfo || isDynamicAlloc) }];
+ let Read = [{
+ isTypeInfo
+ ? node.getLValueBase().getTypeInfoType()
+ : node.getLValueBase().getDynamicAllocType()
+ }];
}
def : Property<"callIndex", UInt32> {
let Conditional = [{ hasBase && !isTypeInfo }];
@@ -498,7 +516,7 @@ let Class = PropertyTypeCase<APValue, "LValue"> in {
let Read = [{ const_cast<Expr *>(expr) }];
}
def : Property<"decl", DeclRef> {
- let Conditional = [{ hasBase && !isTypeInfo && !isExpr }];
+ let Conditional = [{ hasBase && !isTypeInfo && !isDynamicAlloc && !isExpr }];
let Read = [{ lvalueBase.get<const ValueDecl *>() }];
}
def : Property<"offsetQuantity", UInt32> {
@@ -513,20 +531,19 @@ let Class = PropertyTypeCase<APValue, "LValue"> in {
def : Creator<[{
(void)ctx;
APValue::LValueBase base;
- QualType elemTy;
if (hasBase) {
if (isTypeInfo) {
base = APValue::LValueBase::getTypeInfo(
- TypeInfoLValue(typeInfo.getValue().getTypePtr()), type.getValue());
- elemTy = base.getTypeInfoType();
+ TypeInfoLValue(typeInfo->getTypePtr()), *type);
+ } else if (isDynamicAlloc) {
+ base = APValue::LValueBase::getDynamicAlloc(
+ DynamicAllocLValue(*dynamicAlloc), *type);
} else if (isExpr) {
- base = APValue::LValueBase(cast<Expr>(stmt.getValue()),
- callIndex.getValue(), version.getValue());
- elemTy = base.get<const Expr *>()->getType();
+ base = APValue::LValueBase(cast<Expr>(*stmt),
+ *callIndex, *version);
} else {
- base = APValue::LValueBase(cast<ValueDecl>(decl.getValue()),
- callIndex.getValue(), version.getValue());
- elemTy = base.get<const ValueDecl *>()->getType();
+ base = APValue::LValueBase(cast<ValueDecl>(*decl),
+ *callIndex, *version);
}
}
CharUnits offset = CharUnits::fromQuantity(offsetQuantity);
@@ -539,7 +556,6 @@ let Class = PropertyTypeCase<APValue, "LValue"> in {
auto pathLength = lvaluePath->Path.size();
APValue::LValuePathEntry *path = result.setLValueUninit(
base, offset, pathLength, isLValueOnePastTheEnd, isNullPtr).data();
- assert(lvaluePath->getType() == elemTy && "Unexpected type reference!");
llvm::copy(lvaluePath->Path, path);
return result;
}]>;
@@ -617,6 +633,16 @@ let Class = PropertyTypeCase<TemplateName, "Template"> in {
return TemplateName(declaration);
}]>;
}
+
+let Class = PropertyTypeCase<TemplateName, "UsingTemplate"> in {
+ def : Property<"foundDecl", UsingShadowDeclRef> {
+ let Read = [{ node.getAsUsingShadowDecl() }];
+ }
+ def : Creator<[{
+ return TemplateName(foundDecl);
+ }]>;
+}
+
let Class = PropertyTypeCase<TemplateName, "OverloadedTemplate"> in {
def : Property<"overloads", Array<NamedDeclRef>> {
let Read = [{ node.getAsOverloadedTemplate()->decls() }];
@@ -650,12 +676,12 @@ let Class = PropertyTypeCase<TemplateName, "QualifiedTemplate"> in {
def : Property<"hasTemplateKeyword", Bool> {
let Read = [{ qtn->hasTemplateKeyword() }];
}
- def : Property<"declaration", TemplateDeclRef> {
- let Read = [{ qtn->getTemplateDecl() }];
+ def : Property<"underlyingTemplateName", TemplateName> {
+ let Read = [{ qtn->getUnderlyingTemplate() }];
}
def : Creator<[{
return ctx.getQualifiedTemplateName(qualifier, hasTemplateKeyword,
- declaration);
+ underlyingTemplateName);
}]>;
}
let Class = PropertyTypeCase<TemplateName, "DependentTemplate"> in {
@@ -687,28 +713,40 @@ let Class = PropertyTypeCase<TemplateName, "SubstTemplateTemplateParm"> in {
def : ReadHelper<[{
auto parm = node.getAsSubstTemplateTemplateParm();
}]>;
- def : Property<"parameter", TemplateTemplateParmDeclRef> {
- let Read = [{ parm->getParameter() }];
- }
def : Property<"replacement", TemplateName> {
let Read = [{ parm->getReplacement() }];
}
+ def : Property<"associatedDecl", DeclRef> {
+ let Read = [{ parm->getAssociatedDecl() }];
+ }
+ def : Property<"index", UInt32> {
+ let Read = [{ parm->getIndex() }];
+ }
+ def : Property<"packIndex", Optional<UInt32>> {
+ let Read = [{ parm->getPackIndex() }];
+ }
def : Creator<[{
- return ctx.getSubstTemplateTemplateParm(parameter, replacement);
+ return ctx.getSubstTemplateTemplateParm(replacement, associatedDecl, index, packIndex);
}]>;
}
let Class = PropertyTypeCase<TemplateName, "SubstTemplateTemplateParmPack"> in {
def : ReadHelper<[{
auto parm = node.getAsSubstTemplateTemplateParmPack();
}]>;
- def : Property<"parameterPack", TemplateTemplateParmDeclRef> {
- let Read = [{ parm->getParameterPack() }];
- }
def : Property<"argumentPack", TemplateArgument> {
let Read = [{ parm->getArgumentPack() }];
}
+ def : Property<"associatedDecl", DeclRef> {
+ let Read = [{ parm->getAssociatedDecl() }];
+ }
+ def : Property<"index", UInt32> {
+ let Read = [{ parm->getIndex() }];
+ }
+ def : Property<"final", Bool> {
+ let Read = [{ parm->getFinal() }];
+ }
def : Creator<[{
- return ctx.getSubstTemplateTemplateParmPack(parameterPack, argumentPack);
+ return ctx.getSubstTemplateTemplateParmPack(argumentPack, associatedDecl, index, final);
}]>;
}
@@ -724,8 +762,11 @@ let Class = PropertyTypeCase<TemplateArgument, "Type"> in {
def : Property<"type", QualType> {
let Read = [{ node.getAsType() }];
}
+ def : Property<"isDefaulted", Bool> {
+ let Read = [{ node.getIsDefaulted() }];
+ }
def : Creator<[{
- return TemplateArgument(type);
+ return TemplateArgument(type, /* isNullPtr */ false, isDefaulted);
}]>;
}
let Class = PropertyTypeCase<TemplateArgument, "Declaration"> in {
@@ -735,16 +776,22 @@ let Class = PropertyTypeCase<TemplateArgument, "Declaration"> in {
def : Property<"parameterType", QualType> {
let Read = [{ node.getParamTypeForDecl() }];
}
+ def : Property<"isDefaulted", Bool> {
+ let Read = [{ node.getIsDefaulted() }];
+ }
def : Creator<[{
- return TemplateArgument(declaration, parameterType);
+ return TemplateArgument(declaration, parameterType, isDefaulted);
}]>;
}
let Class = PropertyTypeCase<TemplateArgument, "NullPtr"> in {
def : Property<"type", QualType> {
let Read = [{ node.getNullPtrType() }];
}
+ def : Property<"isDefaulted", Bool> {
+ let Read = [{ node.getIsDefaulted() }];
+ }
def : Creator<[{
- return TemplateArgument(type, /*nullptr*/ true);
+ return TemplateArgument(type, /*nullptr*/ true, isDefaulted);
}]>;
}
let Class = PropertyTypeCase<TemplateArgument, "Integral"> in {
@@ -754,16 +801,36 @@ let Class = PropertyTypeCase<TemplateArgument, "Integral"> in {
def : Property<"type", QualType> {
let Read = [{ node.getIntegralType() }];
}
+ def : Property<"isDefaulted", Bool> {
+ let Read = [{ node.getIsDefaulted() }];
+ }
+ def : Creator<[{
+ return TemplateArgument(ctx, value, type, isDefaulted);
+ }]>;
+}
+let Class = PropertyTypeCase<TemplateArgument, "StructuralValue"> in {
+ def : Property<"value", APValue> {
+ let Read = [{ node.getAsStructuralValue() }];
+ }
+ def : Property<"type", QualType> {
+ let Read = [{ node.getStructuralValueType() }];
+ }
+ def : Property<"isDefaulted", Bool> {
+ let Read = [{ node.getIsDefaulted() }];
+ }
def : Creator<[{
- return TemplateArgument(ctx, value, type);
+ return TemplateArgument(ctx, type, value, isDefaulted);
}]>;
}
let Class = PropertyTypeCase<TemplateArgument, "Template"> in {
def : Property<"name", TemplateName> {
let Read = [{ node.getAsTemplateOrTemplatePattern() }];
}
+ def : Property<"isDefaulted", Bool> {
+ let Read = [{ node.getIsDefaulted() }];
+ }
def : Creator<[{
- return TemplateArgument(name);
+ return TemplateArgument(name, isDefaulted);
}]>;
}
let Class = PropertyTypeCase<TemplateArgument, "TemplateExpansion"> in {
@@ -773,22 +840,29 @@ let Class = PropertyTypeCase<TemplateArgument, "TemplateExpansion"> in {
def : Property<"numExpansions", Optional<UInt32>> {
let Read = [{
// Translate unsigned -> uint32_t just in case.
- node.getNumTemplateExpansions().map(
- [](unsigned i) { return uint32_t(i); })
+ llvm::transformOptional(node.getNumTemplateExpansions(),
+ [](unsigned i) { return uint32_t(i); })
}];
}
+ def : Property<"isDefaulted", Bool> {
+ let Read = [{ node.getIsDefaulted() }];
+ }
def : Creator<[{
- auto numExpansionsUnsigned =
- numExpansions.map([](uint32_t i) { return unsigned(i); });
- return TemplateArgument(name, numExpansionsUnsigned);
+ auto numExpansionsUnsigned = llvm::transformOptional(
+ numExpansions, [](uint32_t i) { return unsigned(i); });
+
+ return TemplateArgument(name, numExpansionsUnsigned, isDefaulted);
}]>;
}
let Class = PropertyTypeCase<TemplateArgument, "Expression"> in {
def : Property<"expression", ExprRef> {
let Read = [{ node.getAsExpr() }];
}
+ def : Property<"isDefaulted", Bool> {
+ let Read = [{ node.getIsDefaulted() }];
+ }
def : Creator<[{
- return TemplateArgument(expression);
+ return TemplateArgument(expression, isDefaulted);
}]>;
}
let Class = PropertyTypeCase<TemplateArgument, "Pack"> in {
@@ -800,6 +874,6 @@ let Class = PropertyTypeCase<TemplateArgument, "Pack"> in {
TemplateArgument *ctxElements = new (ctx) TemplateArgument[elements.size()];
for (size_t i = 0, e = elements.size(); i != e; ++i)
ctxElements[i] = elements[i];
- return TemplateArgument(llvm::makeArrayRef(ctxElements, elements.size()));
+ return TemplateArgument(llvm::ArrayRef(ctxElements, elements.size()));
}]>;
}
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/Randstruct.h b/contrib/llvm-project/clang/include/clang/AST/Randstruct.h
new file mode 100644
index 000000000000..d5eaf30919e3
--- /dev/null
+++ b/contrib/llvm-project/clang/include/clang/AST/Randstruct.h
@@ -0,0 +1,35 @@
+//===- Randstruct.h - Interfact for structure randomization -------*- 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 contains the interface for Clang's structure field layout
+// randomization.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_RANDSTRUCT_H
+#define LLVM_CLANG_AST_RANDSTRUCT_H
+
+namespace llvm {
+template <typename T> class SmallVectorImpl;
+} // end namespace llvm
+
+namespace clang {
+
+class ASTContext;
+class Decl;
+class RecordDecl;
+
+namespace randstruct {
+
+bool randomizeStructureLayout(const ASTContext &Context, RecordDecl *RD,
+ llvm::SmallVectorImpl<Decl *> &FinalOrdering);
+
+} // namespace randstruct
+} // namespace clang
+
+#endif // LLVM_CLANG_AST_RANDSTRUCT_H
diff --git a/contrib/llvm-project/clang/include/clang/AST/RawCommentList.h b/contrib/llvm-project/clang/include/clang/AST/RawCommentList.h
index a18432c2b768..53aae24fa7bb 100644
--- a/contrib/llvm-project/clang/include/clang/AST/RawCommentList.h
+++ b/contrib/llvm-project/clang/include/clang/AST/RawCommentList.h
@@ -115,6 +115,17 @@ public:
return extractBriefText(Context);
}
+ bool hasUnsupportedSplice(const SourceManager &SourceMgr) const {
+ if (!isInvalid())
+ return false;
+ StringRef Text = getRawText(SourceMgr);
+ if (Text.size() < 6 || Text[0] != '/')
+ return false;
+ if (Text[1] == '*')
+ return Text[Text.size() - 1] != '/' || Text[Text.size() - 2] != '*';
+ return Text[1] != '/';
+ }
+
/// Returns sanitized comment text, suitable for presentation in editor UIs.
/// E.g. will transform:
/// // This is a long multiline comment.
@@ -139,6 +150,21 @@ public:
std::string getFormattedText(const SourceManager &SourceMgr,
DiagnosticsEngine &Diags) const;
+ struct CommentLine {
+ std::string Text;
+ PresumedLoc Begin;
+ PresumedLoc End;
+
+ CommentLine(StringRef Text, PresumedLoc Begin, PresumedLoc End)
+ : Text(Text), Begin(Begin), End(End) {}
+ };
+
+ /// Returns sanitized comment text as separated lines with locations in
+ /// source, suitable for further processing and rendering requiring source
+ /// locations.
+ std::vector<CommentLine> getFormattedLines(const SourceManager &SourceMgr,
+ DiagnosticsEngine &Diags) const;
+
/// Parse the comment, assuming it is attached to decl \c D.
comments::FullComment *parse(const ASTContext &Context,
const Preprocessor *PP, const Decl *D) const;
@@ -147,11 +173,12 @@ private:
SourceRange Range;
mutable StringRef RawText;
- mutable const char *BriefText;
+ mutable const char *BriefText = nullptr;
mutable bool RawTextValid : 1; ///< True if RawText is valid
mutable bool BriefTextValid : 1; ///< True if BriefText is valid
+ LLVM_PREFERRED_TYPE(CommentKind)
unsigned Kind : 3;
/// True if comment is attached to a declaration in ASTContext.
diff --git a/contrib/llvm-project/clang/include/clang/AST/RecursiveASTVisitor.h b/contrib/llvm-project/clang/include/clang/AST/RecursiveASTVisitor.h
index 9bfa5b9c2326..2aee6a947141 100644
--- a/contrib/llvm-project/clang/include/clang/AST/RecursiveASTVisitor.h
+++ b/contrib/llvm-project/clang/include/clang/AST/RecursiveASTVisitor.h
@@ -13,18 +13,19 @@
#ifndef LLVM_CLANG_AST_RECURSIVEASTVISITOR_H
#define LLVM_CLANG_AST_RECURSIVEASTVISITOR_H
+#include "clang/AST/ASTConcept.h"
#include "clang/AST/Attr.h"
#include "clang/AST/Decl.h"
-#include "clang/AST/DeclarationName.h"
#include "clang/AST/DeclBase.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclFriend.h"
#include "clang/AST/DeclObjC.h"
#include "clang/AST/DeclOpenMP.h"
#include "clang/AST/DeclTemplate.h"
+#include "clang/AST/DeclarationName.h"
#include "clang/AST/Expr.h"
-#include "clang/AST/ExprConcepts.h"
#include "clang/AST/ExprCXX.h"
+#include "clang/AST/ExprConcepts.h"
#include "clang/AST/ExprObjC.h"
#include "clang/AST/ExprOpenMP.h"
#include "clang/AST/LambdaCapture.h"
@@ -68,30 +69,17 @@ template <typename T, typename U, typename R, typename... P>
struct has_same_member_pointer_type<R (T::*)(P...), R (U::*)(P...)>
: std::true_type {};
-template <bool has_same_type> struct is_same_method_impl {
- template <typename FirstMethodPtrTy, typename SecondMethodPtrTy>
- static bool isSameMethod(FirstMethodPtrTy FirstMethodPtr,
- SecondMethodPtrTy SecondMethodPtr) {
- return false;
- }
-};
-
-template <> struct is_same_method_impl<true> {
- template <typename FirstMethodPtrTy, typename SecondMethodPtrTy>
- static bool isSameMethod(FirstMethodPtrTy FirstMethodPtr,
- SecondMethodPtrTy SecondMethodPtr) {
- return FirstMethodPtr == SecondMethodPtr;
- }
-};
-
/// Returns true if and only if \p FirstMethodPtr and \p SecondMethodPtr
/// are pointers to the same non-static member function.
template <typename FirstMethodPtrTy, typename SecondMethodPtrTy>
-bool isSameMethod(FirstMethodPtrTy FirstMethodPtr,
- SecondMethodPtrTy SecondMethodPtr) {
- return is_same_method_impl<has_same_member_pointer_type<
- FirstMethodPtrTy,
- SecondMethodPtrTy>::value>::isSameMethod(FirstMethodPtr, SecondMethodPtr);
+LLVM_ATTRIBUTE_ALWAYS_INLINE LLVM_ATTRIBUTE_NODEBUG auto
+isSameMethod([[maybe_unused]] FirstMethodPtrTy FirstMethodPtr,
+ [[maybe_unused]] SecondMethodPtrTy SecondMethodPtr)
+ -> bool {
+ if constexpr (has_same_member_pointer_type<FirstMethodPtrTy,
+ SecondMethodPtrTy>::value)
+ return FirstMethodPtr == SecondMethodPtr;
+ return false;
}
} // end namespace detail
@@ -288,8 +276,7 @@ public:
///
/// \returns false if the visitation was terminated early, true otherwise.
// FIXME: take a TemplateArgumentLoc* (or TemplateArgumentListInfo) instead.
- bool TraverseTemplateArguments(const TemplateArgument *Args,
- unsigned NumArgs);
+ bool TraverseTemplateArguments(ArrayRef<TemplateArgument> Args);
/// Recursively visit a base specifier. This can be overridden by a
/// subclass.
@@ -319,11 +306,19 @@ public:
bool TraverseSynOrSemInitListExpr(InitListExpr *S,
DataRecursionQueue *Queue = nullptr);
- /// Recursively visit a reference to a concept with potential arguments.
+ /// Recursively visit an Objective-C protocol reference with location
+ /// information.
+ ///
+ /// \returns false if the visitation was terminated early, true otherwise.
+ bool TraverseObjCProtocolLoc(ObjCProtocolLoc ProtocolLoc);
+
+ /// Recursively visit concept reference with location information.
///
/// \returns false if the visitation was terminated early, true otherwise.
- bool TraverseConceptReference(const ConceptReference &C);
+ bool TraverseConceptReference(ConceptReference *CR);
+ // Visit concept reference.
+ bool VisitConceptReference(ConceptReference *CR) { return true; }
// ---- Methods on Attrs ----
// Visit an attribute.
@@ -469,6 +464,13 @@ public:
DEF_TRAVERSE_TMPL_INST(Function)
#undef DEF_TRAVERSE_TMPL_INST
+ bool TraverseTypeConstraint(const TypeConstraint *C);
+
+ bool TraverseConceptRequirement(concepts::Requirement *R);
+ bool TraverseConceptTypeRequirement(concepts::TypeRequirement *R);
+ bool TraverseConceptExprRequirement(concepts::ExprRequirement *R);
+ bool TraverseConceptNestedRequirement(concepts::NestedRequirement *R);
+
bool dataTraverseNode(Stmt *S, DataRecursionQueue *Queue);
private:
@@ -506,6 +508,43 @@ private:
};
template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseTypeConstraint(
+ const TypeConstraint *C) {
+ if (!getDerived().shouldVisitImplicitCode()) {
+ TRY_TO(TraverseConceptReference(C->getConceptReference()));
+ return true;
+ }
+ if (Expr *IDC = C->getImmediatelyDeclaredConstraint()) {
+ TRY_TO(TraverseStmt(IDC));
+ } else {
+ // Avoid traversing the ConceptReference in the TypeConstraint
+ // if we have an immediately-declared-constraint, otherwise
+ // we'll end up visiting the concept and the arguments in
+ // the TC twice.
+ TRY_TO(TraverseConceptReference(C->getConceptReference()));
+ }
+ return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseConceptRequirement(
+ concepts::Requirement *R) {
+ switch (R->getKind()) {
+ case concepts::Requirement::RK_Type:
+ return getDerived().TraverseConceptTypeRequirement(
+ cast<concepts::TypeRequirement>(R));
+ case concepts::Requirement::RK_Simple:
+ case concepts::Requirement::RK_Compound:
+ return getDerived().TraverseConceptExprRequirement(
+ cast<concepts::ExprRequirement>(R));
+ case concepts::Requirement::RK_Nested:
+ return getDerived().TraverseConceptNestedRequirement(
+ cast<concepts::NestedRequirement>(R));
+ }
+ llvm_unreachable("unexpected case");
+}
+
+template <typename Derived>
bool RecursiveASTVisitor<Derived>::dataTraverseNode(Stmt *S,
DataRecursionQueue *Queue) {
// Top switch stmt: dispatch to TraverseFooStmt for each concrete FooStmt.
@@ -525,6 +564,40 @@ bool RecursiveASTVisitor<Derived>::dataTraverseNode(Stmt *S,
#undef DISPATCH_STMT
template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseConceptTypeRequirement(
+ concepts::TypeRequirement *R) {
+ if (R->isSubstitutionFailure())
+ return true;
+ return getDerived().TraverseTypeLoc(R->getType()->getTypeLoc());
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseConceptExprRequirement(
+ concepts::ExprRequirement *R) {
+ if (!R->isExprSubstitutionFailure())
+ TRY_TO(TraverseStmt(R->getExpr()));
+ auto &RetReq = R->getReturnTypeRequirement();
+ if (RetReq.isTypeConstraint()) {
+ if (getDerived().shouldVisitImplicitCode()) {
+ TRY_TO(TraverseTemplateParameterListHelper(
+ RetReq.getTypeConstraintTemplateParameterList()));
+ } else {
+ // Template parameter list is implicit, visit constraint directly.
+ TRY_TO(TraverseTypeConstraint(RetReq.getTypeConstraint()));
+ }
+ }
+ return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseConceptNestedRequirement(
+ concepts::NestedRequirement *R) {
+ if (!R->hasInvalidConstraint())
+ return getDerived().TraverseStmt(R->getConstraintExpr());
+ return true;
+}
+
+template <typename Derived>
bool RecursiveASTVisitor<Derived>::PostVisitStmt(Stmt *S) {
// In pre-order traversal mode, each Traverse##STMT method is responsible for
// calling WalkUpFrom. Therefore, if the user overrides Traverse##STMT and
@@ -777,6 +850,7 @@ bool RecursiveASTVisitor<Derived>::TraverseTemplateArgument(
case TemplateArgument::Declaration:
case TemplateArgument::Integral:
case TemplateArgument::NullPtr:
+ case TemplateArgument::StructuralValue:
return true;
case TemplateArgument::Type:
@@ -791,8 +865,7 @@ bool RecursiveASTVisitor<Derived>::TraverseTemplateArgument(
return getDerived().TraverseStmt(Arg.getAsExpr());
case TemplateArgument::Pack:
- return getDerived().TraverseTemplateArguments(Arg.pack_begin(),
- Arg.pack_size());
+ return getDerived().TraverseTemplateArguments(Arg.pack_elements());
}
return true;
@@ -810,6 +883,7 @@ bool RecursiveASTVisitor<Derived>::TraverseTemplateArgumentLoc(
case TemplateArgument::Declaration:
case TemplateArgument::Integral:
case TemplateArgument::NullPtr:
+ case TemplateArgument::StructuralValue:
return true;
case TemplateArgument::Type: {
@@ -832,8 +906,7 @@ bool RecursiveASTVisitor<Derived>::TraverseTemplateArgumentLoc(
return getDerived().TraverseStmt(ArgLoc.getSourceExpression());
case TemplateArgument::Pack:
- return getDerived().TraverseTemplateArguments(Arg.pack_begin(),
- Arg.pack_size());
+ return getDerived().TraverseTemplateArguments(Arg.pack_elements());
}
return true;
@@ -841,10 +914,9 @@ bool RecursiveASTVisitor<Derived>::TraverseTemplateArgumentLoc(
template <typename Derived>
bool RecursiveASTVisitor<Derived>::TraverseTemplateArguments(
- const TemplateArgument *Args, unsigned NumArgs) {
- for (unsigned I = 0; I != NumArgs; ++I) {
- TRY_TO(TraverseTemplateArgument(Args[I]));
- }
+ ArrayRef<TemplateArgument> Args) {
+ for (const TemplateArgument &Arg : Args)
+ TRY_TO(TraverseTemplateArgument(Arg));
return true;
}
@@ -981,13 +1053,14 @@ DEF_TRAVERSE_TYPE(FunctionProtoType, {
TRY_TO(TraverseStmt(NE));
})
+DEF_TRAVERSE_TYPE(UsingType, {})
DEF_TRAVERSE_TYPE(UnresolvedUsingType, {})
DEF_TRAVERSE_TYPE(TypedefType, {})
DEF_TRAVERSE_TYPE(TypeOfExprType,
{ TRY_TO(TraverseStmt(T->getUnderlyingExpr())); })
-DEF_TRAVERSE_TYPE(TypeOfType, { TRY_TO(TraverseType(T->getUnderlyingType())); })
+DEF_TRAVERSE_TYPE(TypeOfType, { TRY_TO(TraverseType(T->getUnmodifiedType())); })
DEF_TRAVERSE_TYPE(DecltypeType,
{ TRY_TO(TraverseStmt(T->getUnderlyingExpr())); })
@@ -1000,8 +1073,7 @@ DEF_TRAVERSE_TYPE(UnaryTransformType, {
DEF_TRAVERSE_TYPE(AutoType, {
TRY_TO(TraverseType(T->getDeducedType()));
if (T->isConstrained()) {
- TRY_TO(TraverseDecl(T->getTypeConstraintConcept()));
- TRY_TO(TraverseTemplateArguments(T->getArgs(), T->getNumArgs()));
+ TRY_TO(TraverseTemplateArguments(T->getTypeConstraintArguments()));
}
})
DEF_TRAVERSE_TYPE(DeducedTemplateSpecializationType, {
@@ -1021,7 +1093,7 @@ DEF_TRAVERSE_TYPE(SubstTemplateTypeParmPackType, {
DEF_TRAVERSE_TYPE(TemplateSpecializationType, {
TRY_TO(TraverseTemplateName(T->getTemplateName()));
- TRY_TO(TraverseTemplateArguments(T->getArgs(), T->getNumArgs()));
+ TRY_TO(TraverseTemplateArguments(T->template_arguments()));
})
DEF_TRAVERSE_TYPE(InjectedClassNameType, {})
@@ -1029,6 +1101,9 @@ DEF_TRAVERSE_TYPE(InjectedClassNameType, {})
DEF_TRAVERSE_TYPE(AttributedType,
{ TRY_TO(TraverseType(T->getModifiedType())); })
+DEF_TRAVERSE_TYPE(BTFTagAttributedType,
+ { TRY_TO(TraverseType(T->getWrappedType())); })
+
DEF_TRAVERSE_TYPE(ParenType, { TRY_TO(TraverseType(T->getInnerType())); })
DEF_TRAVERSE_TYPE(MacroQualifiedType,
@@ -1046,7 +1121,7 @@ DEF_TRAVERSE_TYPE(DependentNameType,
DEF_TRAVERSE_TYPE(DependentTemplateSpecializationType, {
TRY_TO(TraverseNestedNameSpecifier(T->getQualifier()));
- TRY_TO(TraverseTemplateArguments(T->getArgs(), T->getNumArgs()));
+ TRY_TO(TraverseTemplateArguments(T->template_arguments()));
})
DEF_TRAVERSE_TYPE(PackExpansionType, { TRY_TO(TraverseType(T->getPattern())); })
@@ -1072,8 +1147,8 @@ DEF_TRAVERSE_TYPE(AtomicType, { TRY_TO(TraverseType(T->getValueType())); })
DEF_TRAVERSE_TYPE(PipeType, { TRY_TO(TraverseType(T->getElementType())); })
-DEF_TRAVERSE_TYPE(ExtIntType, {})
-DEF_TRAVERSE_TYPE(DependentExtIntType,
+DEF_TRAVERSE_TYPE(BitIntType, {})
+DEF_TRAVERSE_TYPE(DependentBitIntType,
{ TRY_TO(TraverseStmt(T->getNumBitsExpr())); })
#undef DEF_TRAVERSE_TYPE
@@ -1252,6 +1327,7 @@ DEF_TRAVERSE_TYPELOC(FunctionProtoType, {
TRY_TO(TraverseStmt(NE));
})
+DEF_TRAVERSE_TYPELOC(UsingType, {})
DEF_TRAVERSE_TYPELOC(UnresolvedUsingType, {})
DEF_TRAVERSE_TYPELOC(TypedefType, {})
@@ -1259,7 +1335,7 @@ DEF_TRAVERSE_TYPELOC(TypeOfExprType,
{ TRY_TO(TraverseStmt(TL.getUnderlyingExpr())); })
DEF_TRAVERSE_TYPELOC(TypeOfType, {
- TRY_TO(TraverseTypeLoc(TL.getUnderlyingTInfo()->getTypeLoc()));
+ TRY_TO(TraverseTypeLoc(TL.getUnmodifiedTInfo()->getTypeLoc()));
})
// FIXME: location of underlying expr
@@ -1274,10 +1350,7 @@ DEF_TRAVERSE_TYPELOC(UnaryTransformType, {
DEF_TRAVERSE_TYPELOC(AutoType, {
TRY_TO(TraverseType(TL.getTypePtr()->getDeducedType()));
if (TL.isConstrained()) {
- TRY_TO(TraverseNestedNameSpecifierLoc(TL.getNestedNameSpecifierLoc()));
- TRY_TO(TraverseDeclarationNameInfo(TL.getConceptNameInfo()));
- for (unsigned I = 0, E = TL.getNumArgs(); I != E; ++I)
- TRY_TO(TraverseTemplateArgumentLoc(TL.getArgLoc(I)));
+ TRY_TO(TraverseConceptReference(TL.getConceptReference()));
}
})
@@ -1314,6 +1387,9 @@ DEF_TRAVERSE_TYPELOC(MacroQualifiedType,
DEF_TRAVERSE_TYPELOC(AttributedType,
{ TRY_TO(TraverseTypeLoc(TL.getModifiedLoc())); })
+DEF_TRAVERSE_TYPELOC(BTFTagAttributedType,
+ { TRY_TO(TraverseTypeLoc(TL.getWrappedLoc())); })
+
DEF_TRAVERSE_TYPELOC(ElaboratedType, {
if (TL.getQualifierLoc()) {
TRY_TO(TraverseNestedNameSpecifierLoc(TL.getQualifierLoc()));
@@ -1338,7 +1414,12 @@ DEF_TRAVERSE_TYPELOC(DependentTemplateSpecializationType, {
DEF_TRAVERSE_TYPELOC(PackExpansionType,
{ TRY_TO(TraverseTypeLoc(TL.getPatternLoc())); })
-DEF_TRAVERSE_TYPELOC(ObjCTypeParamType, {})
+DEF_TRAVERSE_TYPELOC(ObjCTypeParamType, {
+ for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) {
+ ObjCProtocolLoc ProtocolLoc(TL.getProtocol(I), TL.getProtocolLoc(I));
+ TRY_TO(TraverseObjCProtocolLoc(ProtocolLoc));
+ }
+})
DEF_TRAVERSE_TYPELOC(ObjCInterfaceType, {})
@@ -1349,6 +1430,10 @@ DEF_TRAVERSE_TYPELOC(ObjCObjectType, {
TRY_TO(TraverseTypeLoc(TL.getBaseLoc()));
for (unsigned i = 0, n = TL.getNumTypeArgs(); i != n; ++i)
TRY_TO(TraverseTypeLoc(TL.getTypeArgTInfo(i)->getTypeLoc()));
+ for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) {
+ ObjCProtocolLoc ProtocolLoc(TL.getProtocol(I), TL.getProtocolLoc(I));
+ TRY_TO(TraverseObjCProtocolLoc(ProtocolLoc));
+ }
})
DEF_TRAVERSE_TYPELOC(ObjCObjectPointerType,
@@ -1358,8 +1443,8 @@ DEF_TRAVERSE_TYPELOC(AtomicType, { TRY_TO(TraverseTypeLoc(TL.getValueLoc())); })
DEF_TRAVERSE_TYPELOC(PipeType, { TRY_TO(TraverseTypeLoc(TL.getValueLoc())); })
-DEF_TRAVERSE_TYPELOC(ExtIntType, {})
-DEF_TRAVERSE_TYPELOC(DependentExtIntType, {
+DEF_TRAVERSE_TYPELOC(BitIntType, {})
+DEF_TRAVERSE_TYPELOC(DependentBitIntType, {
TRY_TO(TraverseStmt(TL.getTypePtr()->getNumBitsExpr()));
})
@@ -1440,6 +1525,8 @@ DEF_TRAVERSE_DECL(CapturedDecl, {
DEF_TRAVERSE_DECL(EmptyDecl, {})
+DEF_TRAVERSE_DECL(HLSLBufferDecl, {})
+
DEF_TRAVERSE_DECL(LifetimeExtendedTemporaryDecl, {
TRY_TO(TraverseStmt(D->getTemporaryExpr()));
})
@@ -1447,14 +1534,21 @@ DEF_TRAVERSE_DECL(LifetimeExtendedTemporaryDecl, {
DEF_TRAVERSE_DECL(FileScopeAsmDecl,
{ TRY_TO(TraverseStmt(D->getAsmString())); })
+DEF_TRAVERSE_DECL(TopLevelStmtDecl, { TRY_TO(TraverseStmt(D->getStmt())); })
+
DEF_TRAVERSE_DECL(ImportDecl, {})
DEF_TRAVERSE_DECL(FriendDecl, {
// Friend is either decl or a type.
- if (D->getFriendType())
+ if (D->getFriendType()) {
TRY_TO(TraverseTypeLoc(D->getFriendType()->getTypeLoc()));
- else
+ // Traverse any CXXRecordDecl owned by this type, since
+ // it will not be in the parent context:
+ if (auto *ET = D->getFriendType()->getType()->getAs<ElaboratedType>())
+ TRY_TO(TraverseDecl(ET->getOwnedTagDecl()));
+ } else {
TRY_TO(TraverseDecl(D->getFriendDecl()));
+ }
})
DEF_TRAVERSE_DECL(FriendTemplateDecl, {
@@ -1471,16 +1565,6 @@ DEF_TRAVERSE_DECL(FriendTemplateDecl, {
}
})
-DEF_TRAVERSE_DECL(ClassScopeFunctionSpecializationDecl, {
- TRY_TO(TraverseDecl(D->getSpecialization()));
-
- if (D->hasExplicitTemplateArgs()) {
- TRY_TO(TraverseTemplateArgumentLocsHelper(
- D->getTemplateArgsAsWritten()->getTemplateArgs(),
- D->getTemplateArgsAsWritten()->NumTemplateArgs));
- }
-})
-
DEF_TRAVERSE_DECL(LinkageSpecDecl, {})
DEF_TRAVERSE_DECL(ExportDecl, {})
@@ -1539,12 +1623,16 @@ DEF_TRAVERSE_DECL(
DEF_TRAVERSE_DECL(ObjCCompatibleAliasDecl, {// FIXME: implement
})
-DEF_TRAVERSE_DECL(ObjCCategoryDecl, {// FIXME: implement
+DEF_TRAVERSE_DECL(ObjCCategoryDecl, {
if (ObjCTypeParamList *typeParamList = D->getTypeParamList()) {
for (auto typeParam : *typeParamList) {
TRY_TO(TraverseObjCTypeParamDecl(typeParam));
}
}
+ for (auto It : llvm::zip(D->protocols(), D->protocol_locs())) {
+ ObjCProtocolLoc ProtocolLoc(std::get<0>(It), std::get<1>(It));
+ TRY_TO(TraverseObjCProtocolLoc(ProtocolLoc));
+ }
})
DEF_TRAVERSE_DECL(ObjCCategoryImplDecl, {// FIXME: implement
@@ -1553,7 +1641,7 @@ DEF_TRAVERSE_DECL(ObjCCategoryImplDecl, {// FIXME: implement
DEF_TRAVERSE_DECL(ObjCImplementationDecl, {// FIXME: implement
})
-DEF_TRAVERSE_DECL(ObjCInterfaceDecl, {// FIXME: implement
+DEF_TRAVERSE_DECL(ObjCInterfaceDecl, {
if (ObjCTypeParamList *typeParamList = D->getTypeParamListAsWritten()) {
for (auto typeParam : *typeParamList) {
TRY_TO(TraverseObjCTypeParamDecl(typeParam));
@@ -1563,10 +1651,22 @@ DEF_TRAVERSE_DECL(ObjCInterfaceDecl, {// FIXME: implement
if (TypeSourceInfo *superTInfo = D->getSuperClassTInfo()) {
TRY_TO(TraverseTypeLoc(superTInfo->getTypeLoc()));
}
+ if (D->isThisDeclarationADefinition()) {
+ for (auto It : llvm::zip(D->protocols(), D->protocol_locs())) {
+ ObjCProtocolLoc ProtocolLoc(std::get<0>(It), std::get<1>(It));
+ TRY_TO(TraverseObjCProtocolLoc(ProtocolLoc));
+ }
+ }
})
-DEF_TRAVERSE_DECL(ObjCProtocolDecl, {// FIXME: implement
- })
+DEF_TRAVERSE_DECL(ObjCProtocolDecl, {
+ if (D->isThisDeclarationADefinition()) {
+ for (auto It : llvm::zip(D->protocols(), D->protocol_locs())) {
+ ObjCProtocolLoc ProtocolLoc(std::get<0>(It), std::get<1>(It));
+ TRY_TO(TraverseObjCProtocolLoc(ProtocolLoc));
+ }
+ }
+})
DEF_TRAVERSE_DECL(ObjCMethodDecl, {
if (D->getReturnTypeSourceInfo()) {
@@ -1603,7 +1703,8 @@ DEF_TRAVERSE_DECL(UsingDecl, {
TRY_TO(TraverseDeclarationNameInfo(D->getNameInfo()));
})
-DEF_TRAVERSE_DECL(UsingEnumDecl, {})
+DEF_TRAVERSE_DECL(UsingEnumDecl,
+ { TRY_TO(TraverseTypeLoc(D->getEnumTypeLoc())); })
DEF_TRAVERSE_DECL(UsingPackDecl, {})
@@ -1681,10 +1782,7 @@ bool RecursiveASTVisitor<Derived>::TraverseTemplateInstantiations(
ClassTemplateDecl *D) {
for (auto *SD : D->specializations()) {
for (auto *RD : SD->redecls()) {
- // We don't want to visit injected-class-names in this traversal.
- if (cast<CXXRecordDecl>(RD)->isInjectedClassName())
- continue;
-
+ assert(!cast<CXXRecordDecl>(RD)->isInjectedClassName());
switch (
cast<ClassTemplateSpecializationDecl>(RD)->getSpecializationKind()) {
// Visit the implicit instantiations with the requested pattern.
@@ -1802,17 +1900,8 @@ DEF_TRAVERSE_DECL(BuiltinTemplateDecl, {
template <typename Derived>
bool RecursiveASTVisitor<Derived>::TraverseTemplateTypeParamDeclConstraints(
const TemplateTypeParmDecl *D) {
- if (const auto *TC = D->getTypeConstraint()) {
- if (Expr *IDC = TC->getImmediatelyDeclaredConstraint()) {
- TRY_TO(TraverseStmt(IDC));
- } else {
- // Avoid traversing the ConceptReference in the TypeCosntraint
- // if we have an immediately-declared-constraint, otherwise
- // we'll end up visiting the concept and the arguments in
- // the TC twice.
- TRY_TO(TraverseConceptReference(*TC));
- }
- }
+ if (const auto *TC = D->getTypeConstraint())
+ TRY_TO(TraverseTypeConstraint(TC));
return true;
}
@@ -1863,10 +1952,9 @@ DEF_TRAVERSE_DECL(UnresolvedUsingIfExistsDecl, {})
DEF_TRAVERSE_DECL(EnumDecl, {
TRY_TO(TraverseDeclTemplateParameterLists(D));
- if (D->getTypeForDecl())
- TRY_TO(TraverseType(QualType(D->getTypeForDecl(), 0)));
-
TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
+ if (auto *TSI = D->getIntegerTypeSourceInfo())
+ TRY_TO(TraverseTypeLoc(TSI->getTypeLoc()));
// The enumerators are already traversed by
// decls_begin()/decls_end().
})
@@ -1907,7 +1995,7 @@ DEF_TRAVERSE_DECL(RecordDecl, { TRY_TO(TraverseRecordHelper(D)); })
DEF_TRAVERSE_DECL(CXXRecordDecl, { TRY_TO(TraverseCXXRecordHelper(D)); })
-#define DEF_TRAVERSE_TMPL_SPEC_DECL(TMPLDECLKIND) \
+#define DEF_TRAVERSE_TMPL_SPEC_DECL(TMPLDECLKIND, DECLKIND) \
DEF_TRAVERSE_DECL(TMPLDECLKIND##TemplateSpecializationDecl, { \
/* For implicit instantiations ("set<int> x;"), we don't want to \
recurse at all, since the instatiated template isn't written in \
@@ -1920,18 +2008,23 @@ DEF_TRAVERSE_DECL(CXXRecordDecl, { TRY_TO(TraverseCXXRecordHelper(D)); })
if (TypeSourceInfo *TSI = D->getTypeAsWritten()) \
TRY_TO(TraverseTypeLoc(TSI->getTypeLoc())); \
\
- TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc())); \
- if (!getDerived().shouldVisitTemplateInstantiations() && \
- D->getTemplateSpecializationKind() != TSK_ExplicitSpecialization) \
+ if (getDerived().shouldVisitTemplateInstantiations() || \
+ D->getTemplateSpecializationKind() == TSK_ExplicitSpecialization) { \
+ /* Traverse base definition for explicit specializations */ \
+ TRY_TO(Traverse##DECLKIND##Helper(D)); \
+ } else { \
+ TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc())); \
+ \
/* Returning from here skips traversing the \
declaration context of the *TemplateSpecializationDecl \
(embedded in the DEF_TRAVERSE_DECL() macro) \
which contains the instantiated members of the template. */ \
return true; \
+ } \
})
-DEF_TRAVERSE_TMPL_SPEC_DECL(Class)
-DEF_TRAVERSE_TMPL_SPEC_DECL(Var)
+DEF_TRAVERSE_TMPL_SPEC_DECL(Class, CXXRecord)
+DEF_TRAVERSE_TMPL_SPEC_DECL(Var, Var)
template <typename Derived>
bool RecursiveASTVisitor<Derived>::TraverseTemplateArgumentLocsHelper(
@@ -1945,12 +2038,7 @@ bool RecursiveASTVisitor<Derived>::TraverseTemplateArgumentLocsHelper(
#define DEF_TRAVERSE_TMPL_PART_SPEC_DECL(TMPLDECLKIND, DECLKIND) \
DEF_TRAVERSE_DECL(TMPLDECLKIND##TemplatePartialSpecializationDecl, { \
/* The partial specialization. */ \
- if (TemplateParameterList *TPL = D->getTemplateParameters()) { \
- for (TemplateParameterList::iterator I = TPL->begin(), E = TPL->end(); \
- I != E; ++I) { \
- TRY_TO(TraverseDecl(*I)); \
- } \
- } \
+ TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters())); \
/* The args that remains unspecialized. */ \
TRY_TO(TraverseTemplateArgumentLocsHelper( \
D->getTemplateArgsAsWritten()->getTemplateArgs(), \
@@ -2004,6 +2092,7 @@ DEF_TRAVERSE_DECL(BindingDecl, {
DEF_TRAVERSE_DECL(MSPropertyDecl, { TRY_TO(TraverseDeclaratorHelper(D)); })
DEF_TRAVERSE_DECL(MSGuidDecl, {})
+DEF_TRAVERSE_DECL(UnnamedGlobalConstantDecl, {})
DEF_TRAVERSE_DECL(TemplateParamObjectDecl, {})
@@ -2011,7 +2100,7 @@ DEF_TRAVERSE_DECL(FieldDecl, {
TRY_TO(TraverseDeclaratorHelper(D));
if (D->isBitField())
TRY_TO(TraverseStmt(D->getBitWidth()));
- else if (D->hasInClassInitializer())
+ if (D->hasInClassInitializer())
TRY_TO(TraverseStmt(D->getInClassInitializer()));
})
@@ -2052,6 +2141,13 @@ bool RecursiveASTVisitor<Derived>::TraverseFunctionHelper(FunctionDecl *D) {
TALI->NumTemplateArgs));
}
}
+ } else if (const DependentFunctionTemplateSpecializationInfo *DFSI =
+ D->getDependentSpecializationInfo()) {
+ if (const ASTTemplateArgumentListInfo *TALI =
+ DFSI->TemplateArgumentsAsWritten) {
+ TRY_TO(TraverseTemplateArgumentLocsHelper(TALI->getTemplateArgs(),
+ TALI->NumTemplateArgs));
+ }
}
// Visit the function type itself, which can be either
@@ -2099,7 +2195,13 @@ bool RecursiveASTVisitor<Derived>::TraverseFunctionHelper(FunctionDecl *D) {
}
if (VisitBody) {
- TRY_TO(TraverseStmt(D->getBody())); // Function body.
+ TRY_TO(TraverseStmt(D->getBody()));
+ // Body may contain using declarations whose shadows are parented to the
+ // FunctionDecl itself.
+ for (auto *Child : D->decls()) {
+ if (isa<UsingShadowDecl>(Child))
+ TRY_TO(TraverseDecl(Child));
+ }
}
return true;
}
@@ -2183,6 +2285,10 @@ DEF_TRAVERSE_DECL(ParmVarDecl, {
DEF_TRAVERSE_DECL(RequiresExprBodyDecl, {})
+DEF_TRAVERSE_DECL(ImplicitConceptSpecializationDecl, {
+ TRY_TO(TraverseTemplateArguments(D->getTemplateArguments()));
+})
+
#undef DEF_TRAVERSE_DECL
// ----------------- Stmt traversal -----------------
@@ -2393,15 +2499,25 @@ bool RecursiveASTVisitor<Derived>::TraverseSynOrSemInitListExpr(
return true;
}
-template<typename Derived>
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseObjCProtocolLoc(
+ ObjCProtocolLoc ProtocolLoc) {
+ return true;
+}
+
+template <typename Derived>
bool RecursiveASTVisitor<Derived>::TraverseConceptReference(
- const ConceptReference &C) {
- TRY_TO(TraverseNestedNameSpecifierLoc(C.getNestedNameSpecifierLoc()));
- TRY_TO(TraverseDeclarationNameInfo(C.getConceptNameInfo()));
- if (C.hasExplicitTemplateArgs())
+ ConceptReference *CR) {
+ if (!getDerived().shouldTraversePostOrder())
+ TRY_TO(VisitConceptReference(CR));
+ TRY_TO(TraverseNestedNameSpecifierLoc(CR->getNestedNameSpecifierLoc()));
+ TRY_TO(TraverseDeclarationNameInfo(CR->getConceptNameInfo()));
+ if (CR->hasExplicitTemplateArgs())
TRY_TO(TraverseTemplateArgumentLocsHelper(
- C.getTemplateArgsAsWritten()->getTemplateArgs(),
- C.getTemplateArgsAsWritten()->NumTemplateArgs));
+ CR->getTemplateArgsAsWritten()->getTemplateArgs(),
+ CR->getTemplateArgsAsWritten()->NumTemplateArgs));
+ if (getDerived().shouldTraversePostOrder())
+ TRY_TO(VisitConceptReference(CR));
return true;
}
@@ -2436,7 +2552,11 @@ bool RecursiveASTVisitor<Derived>::TraverseInitListExpr(
// are interleaved. We also need to watch out for null types (default
// generic associations).
DEF_TRAVERSE_STMT(GenericSelectionExpr, {
- TRY_TO(TraverseStmt(S->getControllingExpr()));
+ if (S->isExprPredicate())
+ TRY_TO(TraverseStmt(S->getControllingExpr()));
+ else
+ TRY_TO(TraverseTypeLoc(S->getControllingType()->getTypeLoc()));
+
for (const GenericSelectionExpr::Association Assoc : S->associations()) {
if (TypeSourceInfo *TSI = Assoc.getTypeSourceInfo())
TRY_TO(TraverseTypeLoc(TSI->getTypeLoc()));
@@ -2606,7 +2726,11 @@ DEF_TRAVERSE_STMT(CXXDefaultArgExpr, {
TRY_TO(TraverseStmt(S->getExpr()));
})
-DEF_TRAVERSE_STMT(CXXDefaultInitExpr, {})
+DEF_TRAVERSE_STMT(CXXDefaultInitExpr, {
+ if (getDerived().shouldVisitImplicitCode())
+ TRY_TO(TraverseStmt(S->getExpr()));
+})
+
DEF_TRAVERSE_STMT(CXXDeleteExpr, {})
DEF_TRAVERSE_STMT(ExprWithCleanups, {})
DEF_TRAVERSE_STMT(CXXInheritedCtorInitExpr, {})
@@ -2735,6 +2859,7 @@ DEF_TRAVERSE_STMT(SubstNonTypeTemplateParmExpr, {})
DEF_TRAVERSE_STMT(FunctionParmPackExpr, {})
DEF_TRAVERSE_STMT(CXXFoldExpr, {})
DEF_TRAVERSE_STMT(AtomicExpr, {})
+DEF_TRAVERSE_STMT(CXXParenListInitExpr, {})
DEF_TRAVERSE_STMT(MaterializeTemporaryExpr, {
if (S->getLifetimeExtendedTemporaryDecl()) {
@@ -2778,7 +2903,7 @@ DEF_TRAVERSE_STMT(CoyieldExpr, {
})
DEF_TRAVERSE_STMT(ConceptSpecializationExpr, {
- TRY_TO(TraverseConceptReference(*S));
+ TRY_TO(TraverseConceptReference(S->getConceptReference()));
})
DEF_TRAVERSE_STMT(RequiresExpr, {
@@ -2786,21 +2911,7 @@ DEF_TRAVERSE_STMT(RequiresExpr, {
for (ParmVarDecl *Parm : S->getLocalParameters())
TRY_TO(TraverseDecl(Parm));
for (concepts::Requirement *Req : S->getRequirements())
- if (auto *TypeReq = dyn_cast<concepts::TypeRequirement>(Req)) {
- if (!TypeReq->isSubstitutionFailure())
- TRY_TO(TraverseTypeLoc(TypeReq->getType()->getTypeLoc()));
- } else if (auto *ExprReq = dyn_cast<concepts::ExprRequirement>(Req)) {
- if (!ExprReq->isExprSubstitutionFailure())
- TRY_TO(TraverseStmt(ExprReq->getExpr()));
- auto &RetReq = ExprReq->getReturnTypeRequirement();
- if (RetReq.isTypeConstraint())
- TRY_TO(TraverseTemplateParameterListHelper(
- RetReq.getTypeConstraintTemplateParameterList()));
- } else {
- auto *NestedReq = cast<concepts::NestedRequirement>(Req);
- if (!NestedReq->isSubstitutionFailure())
- TRY_TO(TraverseStmt(NestedReq->getConstraintExpr()));
- }
+ TRY_TO(TraverseConceptRequirement(Req));
})
// These literals (all of them) do not need any action.
@@ -2842,6 +2953,9 @@ RecursiveASTVisitor<Derived>::TraverseOMPLoopDirective(OMPLoopDirective *S) {
return TraverseOMPExecutableDirective(S);
}
+DEF_TRAVERSE_STMT(OMPMetaDirective,
+ { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
DEF_TRAVERSE_STMT(OMPParallelDirective,
{ TRY_TO(TraverseOMPExecutableDirective(S)); })
@@ -2866,6 +2980,9 @@ DEF_TRAVERSE_STMT(OMPSectionsDirective,
DEF_TRAVERSE_STMT(OMPSectionDirective,
{ TRY_TO(TraverseOMPExecutableDirective(S)); })
+DEF_TRAVERSE_STMT(OMPScopeDirective,
+ { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
DEF_TRAVERSE_STMT(OMPSingleDirective,
{ TRY_TO(TraverseOMPExecutableDirective(S)); })
@@ -2886,6 +3003,9 @@ DEF_TRAVERSE_STMT(OMPParallelForSimdDirective,
DEF_TRAVERSE_STMT(OMPParallelMasterDirective,
{ TRY_TO(TraverseOMPExecutableDirective(S)); })
+DEF_TRAVERSE_STMT(OMPParallelMaskedDirective,
+ { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
DEF_TRAVERSE_STMT(OMPParallelSectionsDirective,
{ TRY_TO(TraverseOMPExecutableDirective(S)); })
@@ -2967,6 +3087,18 @@ DEF_TRAVERSE_STMT(OMPParallelMasterTaskLoopDirective,
DEF_TRAVERSE_STMT(OMPParallelMasterTaskLoopSimdDirective,
{ TRY_TO(TraverseOMPExecutableDirective(S)); })
+DEF_TRAVERSE_STMT(OMPMaskedTaskLoopDirective,
+ { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
+DEF_TRAVERSE_STMT(OMPMaskedTaskLoopSimdDirective,
+ { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
+DEF_TRAVERSE_STMT(OMPParallelMaskedTaskLoopDirective,
+ { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
+DEF_TRAVERSE_STMT(OMPParallelMaskedTaskLoopSimdDirective,
+ { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
DEF_TRAVERSE_STMT(OMPDistributeDirective,
{ TRY_TO(TraverseOMPExecutableDirective(S)); })
@@ -3021,6 +3153,24 @@ DEF_TRAVERSE_STMT(OMPDispatchDirective,
DEF_TRAVERSE_STMT(OMPMaskedDirective,
{ TRY_TO(TraverseOMPExecutableDirective(S)); })
+DEF_TRAVERSE_STMT(OMPGenericLoopDirective,
+ { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
+DEF_TRAVERSE_STMT(OMPTeamsGenericLoopDirective,
+ { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
+DEF_TRAVERSE_STMT(OMPTargetTeamsGenericLoopDirective,
+ { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
+DEF_TRAVERSE_STMT(OMPParallelGenericLoopDirective,
+ { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
+DEF_TRAVERSE_STMT(OMPTargetParallelGenericLoopDirective,
+ { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
+DEF_TRAVERSE_STMT(OMPErrorDirective,
+ { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
// OpenMP clauses.
template <typename Derived>
bool RecursiveASTVisitor<Derived>::TraverseOMPClause(OMPClause *C) {
@@ -3092,6 +3242,12 @@ RecursiveASTVisitor<Derived>::VisitOMPNumThreadsClause(OMPNumThreadsClause *C) {
}
template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPAlignClause(OMPAlignClause *C) {
+ TRY_TO(TraverseStmt(C->getAlignment()));
+ return true;
+}
+
+template <typename Derived>
bool RecursiveASTVisitor<Derived>::VisitOMPSafelenClause(OMPSafelenClause *C) {
TRY_TO(TraverseStmt(C->getSafelen()));
return true;
@@ -3169,6 +3325,22 @@ bool RecursiveASTVisitor<Derived>::VisitOMPAtomicDefaultMemOrderClause(
}
template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPAtClause(OMPAtClause *) {
+ return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPSeverityClause(OMPSeverityClause *) {
+ return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPMessageClause(OMPMessageClause *C) {
+ TRY_TO(TraverseStmt(C->getMessageString()));
+ return true;
+}
+
+template <typename Derived>
bool
RecursiveASTVisitor<Derived>::VisitOMPScheduleClause(OMPScheduleClause *C) {
TRY_TO(VisitOMPClauseWithPreInit(C));
@@ -3219,6 +3391,16 @@ bool RecursiveASTVisitor<Derived>::VisitOMPCaptureClause(OMPCaptureClause *) {
}
template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPCompareClause(OMPCompareClause *) {
+ return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPFailClause(OMPFailClause *) {
+ return true;
+}
+
+template <typename Derived>
bool RecursiveASTVisitor<Derived>::VisitOMPSeqCstClause(OMPSeqCstClause *) {
return true;
}
@@ -3627,6 +3809,13 @@ bool RecursiveASTVisitor<Derived>::VisitOMPIsDevicePtrClause(
}
template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPHasDeviceAddrClause(
+ OMPHasDeviceAddrClause *C) {
+ TRY_TO(VisitOMPClauseList(C));
+ return true;
+}
+
+template <typename Derived>
bool RecursiveASTVisitor<Derived>::VisitOMPNontemporalClause(
OMPNontemporalClause *C) {
TRY_TO(VisitOMPClauseList(C));
@@ -3674,6 +3863,37 @@ bool RecursiveASTVisitor<Derived>::VisitOMPFilterClause(OMPFilterClause *C) {
return true;
}
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPBindClause(OMPBindClause *C) {
+ return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPXDynCGroupMemClause(
+ OMPXDynCGroupMemClause *C) {
+ TRY_TO(VisitOMPClauseWithPreInit(C));
+ TRY_TO(TraverseStmt(C->getSize()));
+ return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPDoacrossClause(
+ OMPDoacrossClause *C) {
+ TRY_TO(VisitOMPClauseList(C));
+ return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPXAttributeClause(
+ OMPXAttributeClause *C) {
+ return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPXBareClause(OMPXBareClause *C) {
+ return true;
+}
+
// FIXME: look at the following tricky-seeming exprs to see if we
// need to recurse on anything. These are ones that have methods
// returning decls or qualtypes or nestednamespecifier -- though I'm
diff --git a/contrib/llvm-project/clang/include/clang/AST/Redeclarable.h b/contrib/llvm-project/clang/include/clang/AST/Redeclarable.h
index 77b827c52bfb..091bb886f2d4 100644
--- a/contrib/llvm-project/clang/include/clang/AST/Redeclarable.h
+++ b/contrib/llvm-project/clang/include/clang/AST/Redeclarable.h
@@ -240,7 +240,7 @@ public:
class redecl_iterator {
/// Current - The current declaration.
decl_type *Current = nullptr;
- decl_type *Starter;
+ decl_type *Starter = nullptr;
bool PassedFirst = false;
public:
@@ -258,7 +258,8 @@ public:
redecl_iterator& operator++() {
assert(Current && "Advancing while iterator has reached end");
- // Sanity check to avoid infinite loop on invalid redecl chain.
+ // Make sure we don't infinitely loop on an invalid redecl chain. This
+ // should never happen.
if (Current->isFirstDecl()) {
if (PassedFirst) {
assert(0 && "Passed first decl twice, invalid redecl chain!");
diff --git a/contrib/llvm-project/clang/include/clang/AST/Stmt.h b/contrib/llvm-project/clang/include/clang/AST/Stmt.h
index 8e1d7df97096..55eca4007d17 100644
--- a/contrib/llvm-project/clang/include/clang/AST/Stmt.h
+++ b/contrib/llvm-project/clang/include/clang/AST/Stmt.h
@@ -13,13 +13,21 @@
#ifndef LLVM_CLANG_AST_STMT_H
#define LLVM_CLANG_AST_STMT_H
+#include "clang/AST/APValue.h"
#include "clang/AST/DeclGroup.h"
#include "clang/AST/DependenceFlags.h"
+#include "clang/AST/OperationKinds.h"
#include "clang/AST/StmtIterator.h"
#include "clang/Basic/CapturedStmt.h"
#include "clang/Basic/IdentifierTable.h"
#include "clang/Basic/LLVM.h"
+#include "clang/Basic/Lambda.h"
+#include "clang/Basic/LangOptions.h"
+#include "clang/Basic/OperatorKinds.h"
#include "clang/Basic/SourceLocation.h"
+#include "clang/Basic/Specifiers.h"
+#include "clang/Basic/TypeTraits.h"
+#include "llvm/ADT/APFloat.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/BitmaskEnum.h"
#include "llvm/ADT/PointerIntPair.h"
@@ -33,6 +41,7 @@
#include <cassert>
#include <cstddef>
#include <iterator>
+#include <optional>
#include <string>
namespace llvm {
@@ -58,6 +67,13 @@ class SourceManager;
class StringLiteral;
class Token;
class VarDecl;
+enum class CharacterLiteralKind;
+enum class ConstantResultStorageKind;
+enum class CXXConstructionKind;
+enum class CXXNewInitializationStyle;
+enum class PredefinedIdentKind;
+enum class SourceLocIdentKind;
+enum class StringLiteralKind;
//===----------------------------------------------------------------------===//
// AST classes for statements.
@@ -99,6 +115,7 @@ protected:
friend class Stmt;
/// The statement class.
+ LLVM_PREFERRED_TYPE(StmtClass)
unsigned sClass : 8;
};
enum { NumStmtBits = 8 };
@@ -108,6 +125,7 @@ protected:
friend class ASTStmtWriter;
friend class NullStmt;
+ LLVM_PREFERRED_TYPE(StmtBitfields)
unsigned : NumStmtBits;
/// True if the null statement was preceded by an empty macro, e.g:
@@ -115,6 +133,7 @@ protected:
/// #define CALL(x)
/// CALL(0);
/// @endcode
+ LLVM_PREFERRED_TYPE(bool)
unsigned HasLeadingEmptyMacro : 1;
/// The location of the semi-colon.
@@ -125,17 +144,21 @@ protected:
friend class ASTStmtReader;
friend class CompoundStmt;
+ LLVM_PREFERRED_TYPE(StmtBitfields)
unsigned : NumStmtBits;
- unsigned NumStmts : 32 - NumStmtBits;
+ /// True if the compound statement has one or more pragmas that set some
+ /// floating-point features.
+ LLVM_PREFERRED_TYPE(bool)
+ unsigned HasFPFeatures : 1;
- /// The location of the opening "{".
- SourceLocation LBraceLoc;
+ unsigned NumStmts;
};
class LabelStmtBitfields {
friend class LabelStmt;
+ LLVM_PREFERRED_TYPE(StmtBitfields)
unsigned : NumStmtBits;
SourceLocation IdentLoc;
@@ -145,6 +168,7 @@ protected:
friend class ASTStmtReader;
friend class AttributedStmt;
+ LLVM_PREFERRED_TYPE(StmtBitfields)
unsigned : NumStmtBits;
/// Number of attributes.
@@ -158,18 +182,23 @@ protected:
friend class ASTStmtReader;
friend class IfStmt;
+ LLVM_PREFERRED_TYPE(StmtBitfields)
unsigned : NumStmtBits;
- /// True if this if statement is a constexpr if.
- unsigned IsConstexpr : 1;
+ /// Whether this is a constexpr if, or a consteval if, or neither.
+ LLVM_PREFERRED_TYPE(IfStatementKind)
+ unsigned Kind : 3;
/// True if this if statement has storage for an else statement.
+ LLVM_PREFERRED_TYPE(bool)
unsigned HasElse : 1;
/// True if this if statement has storage for a variable declaration.
+ LLVM_PREFERRED_TYPE(bool)
unsigned HasVar : 1;
/// True if this if statement has storage for an init statement.
+ LLVM_PREFERRED_TYPE(bool)
unsigned HasInit : 1;
/// The location of the "if".
@@ -179,17 +208,21 @@ protected:
class SwitchStmtBitfields {
friend class SwitchStmt;
+ LLVM_PREFERRED_TYPE(StmtBitfields)
unsigned : NumStmtBits;
/// True if the SwitchStmt has storage for an init statement.
+ LLVM_PREFERRED_TYPE(bool)
unsigned HasInit : 1;
/// True if the SwitchStmt has storage for a condition variable.
+ LLVM_PREFERRED_TYPE(bool)
unsigned HasVar : 1;
/// If the SwitchStmt is a switch on an enum value, records whether all
/// the enum values were covered by CaseStmts. The coverage information
/// value is meant to be a hint for possible clients.
+ LLVM_PREFERRED_TYPE(bool)
unsigned AllEnumCasesCovered : 1;
/// The location of the "switch".
@@ -200,9 +233,11 @@ protected:
friend class ASTStmtReader;
friend class WhileStmt;
+ LLVM_PREFERRED_TYPE(StmtBitfields)
unsigned : NumStmtBits;
/// True if the WhileStmt has storage for a condition variable.
+ LLVM_PREFERRED_TYPE(bool)
unsigned HasVar : 1;
/// The location of the "while".
@@ -212,6 +247,7 @@ protected:
class DoStmtBitfields {
friend class DoStmt;
+ LLVM_PREFERRED_TYPE(StmtBitfields)
unsigned : NumStmtBits;
/// The location of the "do".
@@ -221,6 +257,7 @@ protected:
class ForStmtBitfields {
friend class ForStmt;
+ LLVM_PREFERRED_TYPE(StmtBitfields)
unsigned : NumStmtBits;
/// The location of the "for".
@@ -231,6 +268,7 @@ protected:
friend class GotoStmt;
friend class IndirectGotoStmt;
+ LLVM_PREFERRED_TYPE(StmtBitfields)
unsigned : NumStmtBits;
/// The location of the "goto".
@@ -240,6 +278,7 @@ protected:
class ContinueStmtBitfields {
friend class ContinueStmt;
+ LLVM_PREFERRED_TYPE(StmtBitfields)
unsigned : NumStmtBits;
/// The location of the "continue".
@@ -249,6 +288,7 @@ protected:
class BreakStmtBitfields {
friend class BreakStmt;
+ LLVM_PREFERRED_TYPE(StmtBitfields)
unsigned : NumStmtBits;
/// The location of the "break".
@@ -258,9 +298,11 @@ protected:
class ReturnStmtBitfields {
friend class ReturnStmt;
+ LLVM_PREFERRED_TYPE(StmtBitfields)
unsigned : NumStmtBits;
/// True if this ReturnStmt has storage for an NRVO candidate.
+ LLVM_PREFERRED_TYPE(bool)
unsigned HasNRVOCandidate : 1;
/// The location of the "return".
@@ -271,10 +313,12 @@ protected:
friend class SwitchCase;
friend class CaseStmt;
+ LLVM_PREFERRED_TYPE(StmtBitfields)
unsigned : NumStmtBits;
/// Used by CaseStmt to store whether it is a case statement
/// of the form case LHS ... RHS (a GNU extension).
+ LLVM_PREFERRED_TYPE(bool)
unsigned CaseStmtIsGNURange : 1;
/// The location of the "case" or "default" keyword.
@@ -307,11 +351,15 @@ protected:
friend class PseudoObjectExpr; // ctor
friend class ShuffleVectorExpr; // ctor
+ LLVM_PREFERRED_TYPE(StmtBitfields)
unsigned : NumStmtBits;
+ LLVM_PREFERRED_TYPE(ExprValueKind)
unsigned ValueKind : 2;
+ LLVM_PREFERRED_TYPE(ExprObjectKind)
unsigned ObjectKind : 3;
- unsigned /*ExprDependence*/ Dependent : llvm::BitWidth<ExprDependence>;
+ LLVM_PREFERRED_TYPE(ExprDependence)
+ unsigned Dependent : llvm::BitWidth<ExprDependence>;
};
enum { NumExprBits = NumStmtBits + 5 + llvm::BitWidth<ExprDependence> };
@@ -320,28 +368,35 @@ protected:
friend class ASTStmtWriter;
friend class ConstantExpr;
+ LLVM_PREFERRED_TYPE(ExprBitfields)
unsigned : NumExprBits;
/// The kind of result that is tail-allocated.
+ LLVM_PREFERRED_TYPE(ConstantResultStorageKind)
unsigned ResultKind : 2;
- /// The kind of Result as defined by APValue::Kind.
+ /// The kind of Result as defined by APValue::ValueKind.
+ LLVM_PREFERRED_TYPE(APValue::ValueKind)
unsigned APValueKind : 4;
- /// When ResultKind == RSK_Int64, true if the tail-allocated integer is
- /// unsigned.
+ /// When ResultKind == ConstantResultStorageKind::Int64, true if the
+ /// tail-allocated integer is unsigned.
+ LLVM_PREFERRED_TYPE(bool)
unsigned IsUnsigned : 1;
- /// When ResultKind == RSK_Int64. the BitWidth of the tail-allocated
- /// integer. 7 bits because it is the minimal number of bits to represent a
- /// value from 0 to 64 (the size of the tail-allocated integer).
+ /// When ResultKind == ConstantResultStorageKind::Int64. the BitWidth of the
+ /// tail-allocated integer. 7 bits because it is the minimal number of bits
+ /// to represent a value from 0 to 64 (the size of the tail-allocated
+ /// integer).
unsigned BitWidth : 7;
- /// When ResultKind == RSK_APValue, true if the ASTContext will cleanup the
- /// tail-allocated APValue.
+ /// When ResultKind == ConstantResultStorageKind::APValue, true if the
+ /// ASTContext will cleanup the tail-allocated APValue.
+ LLVM_PREFERRED_TYPE(bool)
unsigned HasCleanup : 1;
/// True if this ConstantExpr was created for immediate invocation.
+ LLVM_PREFERRED_TYPE(bool)
unsigned IsImmediateInvocation : 1;
};
@@ -349,16 +404,22 @@ protected:
friend class ASTStmtReader;
friend class PredefinedExpr;
+ LLVM_PREFERRED_TYPE(ExprBitfields)
unsigned : NumExprBits;
- /// The kind of this PredefinedExpr. One of the enumeration values
- /// in PredefinedExpr::IdentKind.
+ LLVM_PREFERRED_TYPE(PredefinedIdentKind)
unsigned Kind : 4;
/// True if this PredefinedExpr has a trailing "StringLiteral *"
/// for the predefined identifier.
+ LLVM_PREFERRED_TYPE(bool)
unsigned HasFunctionName : 1;
+ /// True if this PredefinedExpr should be treated as a StringLiteral (for
+ /// MSVC compatibility).
+ LLVM_PREFERRED_TYPE(bool)
+ unsigned IsTransparent : 1;
+
/// The location of this PredefinedExpr.
SourceLocation Loc;
};
@@ -367,14 +428,25 @@ protected:
friend class ASTStmtReader; // deserialization
friend class DeclRefExpr;
+ LLVM_PREFERRED_TYPE(ExprBitfields)
unsigned : NumExprBits;
+ LLVM_PREFERRED_TYPE(bool)
unsigned HasQualifier : 1;
+ LLVM_PREFERRED_TYPE(bool)
unsigned HasTemplateKWAndArgsInfo : 1;
+ LLVM_PREFERRED_TYPE(bool)
unsigned HasFoundDecl : 1;
+ LLVM_PREFERRED_TYPE(bool)
unsigned HadMultipleCandidates : 1;
+ LLVM_PREFERRED_TYPE(bool)
unsigned RefersToEnclosingVariableOrCapture : 1;
+ LLVM_PREFERRED_TYPE(bool)
+ unsigned CapturedByCopyInLambdaWithExplicitObjectParameter : 1;
+ LLVM_PREFERRED_TYPE(NonOdrUseReason)
unsigned NonOdrUseReason : 2;
+ LLVM_PREFERRED_TYPE(bool)
+ unsigned IsImmediateEscalating : 1;
/// The location of the declaration name itself.
SourceLocation Loc;
@@ -384,9 +456,15 @@ protected:
class FloatingLiteralBitfields {
friend class FloatingLiteral;
+ LLVM_PREFERRED_TYPE(ExprBitfields)
unsigned : NumExprBits;
- unsigned Semantics : 3; // Provides semantics for APFloat construction
+ static_assert(
+ llvm::APFloat::S_MaxSemantics < 16,
+ "Too many Semantics enum values to fit in bitfield of size 4");
+ LLVM_PREFERRED_TYPE(llvm::APFloat::Semantics)
+ unsigned Semantics : 4; // Provides semantics for APFloat construction
+ LLVM_PREFERRED_TYPE(bool)
unsigned IsExact : 1;
};
@@ -394,10 +472,12 @@ protected:
friend class ASTStmtReader;
friend class StringLiteral;
+ LLVM_PREFERRED_TYPE(ExprBitfields)
unsigned : NumExprBits;
/// The kind of this string literal.
/// One of the enumeration values of StringLiteral::StringKind.
+ LLVM_PREFERRED_TYPE(StringLiteralKind)
unsigned Kind : 3;
/// The width of a single character in bytes. Only values of 1, 2,
@@ -405,6 +485,7 @@ protected:
/// the target + string kind to the appropriate CharByteWidth.
unsigned CharByteWidth : 3;
+ LLVM_PREFERRED_TYPE(bool)
unsigned IsPascal : 1;
/// The number of concatenated token this string is made of.
@@ -415,22 +496,28 @@ protected:
class CharacterLiteralBitfields {
friend class CharacterLiteral;
+ LLVM_PREFERRED_TYPE(ExprBitfields)
unsigned : NumExprBits;
+ LLVM_PREFERRED_TYPE(CharacterLiteralKind)
unsigned Kind : 3;
};
class UnaryOperatorBitfields {
friend class UnaryOperator;
+ LLVM_PREFERRED_TYPE(ExprBitfields)
unsigned : NumExprBits;
+ LLVM_PREFERRED_TYPE(UnaryOperatorKind)
unsigned Opc : 5;
+ LLVM_PREFERRED_TYPE(bool)
unsigned CanOverflow : 1;
//
/// This is only meaningful for operations on floating point
/// types when additional values need to be in trailing storage.
/// It is 0 otherwise.
+ LLVM_PREFERRED_TYPE(bool)
unsigned HasFPFeatures : 1;
SourceLocation Loc;
@@ -439,9 +526,12 @@ protected:
class UnaryExprOrTypeTraitExprBitfields {
friend class UnaryExprOrTypeTraitExpr;
+ LLVM_PREFERRED_TYPE(ExprBitfields)
unsigned : NumExprBits;
+ LLVM_PREFERRED_TYPE(UnaryExprOrTypeTrait)
unsigned Kind : 3;
+ LLVM_PREFERRED_TYPE(bool)
unsigned IsType : 1; // true if operand is a type, false if an expression.
};
@@ -449,6 +539,7 @@ protected:
friend class ArraySubscriptExpr;
friend class MatrixSubscriptExpr;
+ LLVM_PREFERRED_TYPE(ExprBitfields)
unsigned : NumExprBits;
SourceLocation RBracketLoc;
@@ -457,14 +548,17 @@ protected:
class CallExprBitfields {
friend class CallExpr;
+ LLVM_PREFERRED_TYPE(ExprBitfields)
unsigned : NumExprBits;
unsigned NumPreArgs : 1;
/// True if the callee of the call expression was found using ADL.
+ LLVM_PREFERRED_TYPE(bool)
unsigned UsesADL : 1;
/// True if the call expression has some floating-point features.
+ LLVM_PREFERRED_TYPE(bool)
unsigned HasFPFeatures : 1;
/// Padding used to align OffsetToTrailingObjects to a byte multiple.
@@ -481,15 +575,18 @@ protected:
friend class ASTStmtReader;
friend class MemberExpr;
+ LLVM_PREFERRED_TYPE(ExprBitfields)
unsigned : NumExprBits;
/// IsArrow - True if this is "X->F", false if this is "X.F".
+ LLVM_PREFERRED_TYPE(bool)
unsigned IsArrow : 1;
/// True if this member expression used a nested-name-specifier to
/// refer to the member, e.g., "x->Base::f", or found its member via
/// a using declaration. When true, a MemberExprNameQualifier
/// structure is allocated immediately after the MemberExpr.
+ LLVM_PREFERRED_TYPE(bool)
unsigned HasQualifierOrFoundDecl : 1;
/// True if this member expression specified a template keyword
@@ -497,15 +594,18 @@ protected:
/// x->template f, x->template f<int>.
/// When true, an ASTTemplateKWAndArgsInfo structure and its
/// TemplateArguments (if any) are present.
+ LLVM_PREFERRED_TYPE(bool)
unsigned HasTemplateKWAndArgsInfo : 1;
/// True if this member expression refers to a method that
/// was resolved from an overloaded set having size greater than 1.
+ LLVM_PREFERRED_TYPE(bool)
unsigned HadMultipleCandidates : 1;
/// Value of type NonOdrUseReason indicating why this MemberExpr does
/// not constitute an odr-use of the named declaration. Meaningful only
/// when naming a static member.
+ LLVM_PREFERRED_TYPE(NonOdrUseReason)
unsigned NonOdrUseReason : 2;
/// This is the location of the -> or . in the expression.
@@ -516,12 +616,16 @@ protected:
friend class CastExpr;
friend class ImplicitCastExpr;
+ LLVM_PREFERRED_TYPE(ExprBitfields)
unsigned : NumExprBits;
+ LLVM_PREFERRED_TYPE(CastKind)
unsigned Kind : 7;
+ LLVM_PREFERRED_TYPE(bool)
unsigned PartOfExplicitCast : 1; // Only set for ImplicitCastExpr.
/// True if the call expression has some floating-point features.
+ LLVM_PREFERRED_TYPE(bool)
unsigned HasFPFeatures : 1;
/// The number of CXXBaseSpecifiers in the cast. 14 bits would be enough
@@ -532,13 +636,16 @@ protected:
class BinaryOperatorBitfields {
friend class BinaryOperator;
+ LLVM_PREFERRED_TYPE(ExprBitfields)
unsigned : NumExprBits;
+ LLVM_PREFERRED_TYPE(BinaryOperatorKind)
unsigned Opc : 6;
/// This is only meaningful for operations on floating point
/// types when additional values need to be in trailing storage.
/// It is 0 otherwise.
+ LLVM_PREFERRED_TYPE(bool)
unsigned HasFPFeatures : 1;
SourceLocation OpLoc;
@@ -547,10 +654,12 @@ protected:
class InitListExprBitfields {
friend class InitListExpr;
+ LLVM_PREFERRED_TYPE(ExprBitfields)
unsigned : NumExprBits;
/// Whether this initializer list originally had a GNU array-range
/// designator in it. This is a temporary marker used by CodeGen.
+ LLVM_PREFERRED_TYPE(bool)
unsigned HadArrayRangeDesignator : 1;
};
@@ -558,6 +667,7 @@ protected:
friend class ASTStmtReader;
friend class ParenListExpr;
+ LLVM_PREFERRED_TYPE(ExprBitfields)
unsigned : NumExprBits;
/// The number of expressions in the paren list.
@@ -568,6 +678,7 @@ protected:
friend class ASTStmtReader;
friend class GenericSelectionExpr;
+ LLVM_PREFERRED_TYPE(ExprBitfields)
unsigned : NumExprBits;
/// The location of the "_Generic".
@@ -578,29 +689,31 @@ protected:
friend class ASTStmtReader; // deserialization
friend class PseudoObjectExpr;
+ LLVM_PREFERRED_TYPE(ExprBitfields)
unsigned : NumExprBits;
- // These don't need to be particularly wide, because they're
- // strictly limited by the forms of expressions we permit.
- unsigned NumSubExprs : 8;
- unsigned ResultIndex : 32 - 8 - NumExprBits;
+ unsigned NumSubExprs : 16;
+ unsigned ResultIndex : 16;
};
class SourceLocExprBitfields {
friend class ASTStmtReader;
friend class SourceLocExpr;
+ LLVM_PREFERRED_TYPE(ExprBitfields)
unsigned : NumExprBits;
/// The kind of source location builtin represented by the SourceLocExpr.
- /// Ex. __builtin_LINE, __builtin_FUNCTION, ect.
- unsigned Kind : 2;
+ /// Ex. __builtin_LINE, __builtin_FUNCTION, etc.
+ LLVM_PREFERRED_TYPE(SourceLocIdentKind)
+ unsigned Kind : 3;
};
class StmtExprBitfields {
friend class ASTStmtReader;
friend class StmtExpr;
+ LLVM_PREFERRED_TYPE(ExprBitfields)
unsigned : NumExprBits;
/// The number of levels of template parameters enclosing this statement
@@ -615,10 +728,12 @@ protected:
friend class ASTStmtReader;
friend class CXXOperatorCallExpr;
+ LLVM_PREFERRED_TYPE(CallExprBitfields)
unsigned : NumCallExprBits;
/// The kind of this overloaded operator. One of the enumerator
/// value of OverloadedOperatorKind.
+ LLVM_PREFERRED_TYPE(OverloadedOperatorKind)
unsigned OperatorKind : 6;
};
@@ -626,17 +741,21 @@ protected:
friend class ASTStmtReader;
friend class CXXRewrittenBinaryOperator;
+ LLVM_PREFERRED_TYPE(CallExprBitfields)
unsigned : NumCallExprBits;
+ LLVM_PREFERRED_TYPE(bool)
unsigned IsReversed : 1;
};
class CXXBoolLiteralExprBitfields {
friend class CXXBoolLiteralExpr;
+ LLVM_PREFERRED_TYPE(ExprBitfields)
unsigned : NumExprBits;
/// The value of the boolean literal.
+ LLVM_PREFERRED_TYPE(bool)
unsigned Value : 1;
/// The location of the boolean literal.
@@ -646,6 +765,7 @@ protected:
class CXXNullPtrLiteralExprBitfields {
friend class CXXNullPtrLiteralExpr;
+ LLVM_PREFERRED_TYPE(ExprBitfields)
unsigned : NumExprBits;
/// The location of the null pointer literal.
@@ -655,9 +775,11 @@ protected:
class CXXThisExprBitfields {
friend class CXXThisExpr;
+ LLVM_PREFERRED_TYPE(ExprBitfields)
unsigned : NumExprBits;
/// Whether this is an implicit "this".
+ LLVM_PREFERRED_TYPE(bool)
unsigned IsImplicit : 1;
/// The location of the "this".
@@ -668,9 +790,11 @@ protected:
friend class ASTStmtReader;
friend class CXXThrowExpr;
+ LLVM_PREFERRED_TYPE(ExprBitfields)
unsigned : NumExprBits;
/// Whether the thrown variable (if any) is in scope.
+ LLVM_PREFERRED_TYPE(bool)
unsigned IsThrownVariableInScope : 1;
/// The location of the "throw".
@@ -681,8 +805,13 @@ protected:
friend class ASTStmtReader;
friend class CXXDefaultArgExpr;
+ LLVM_PREFERRED_TYPE(ExprBitfields)
unsigned : NumExprBits;
+ /// Whether this CXXDefaultArgExpr rewrote its argument and stores a copy.
+ LLVM_PREFERRED_TYPE(bool)
+ unsigned HasRewrittenInit : 1;
+
/// The location where the default argument expression was used.
SourceLocation Loc;
};
@@ -691,8 +820,14 @@ protected:
friend class ASTStmtReader;
friend class CXXDefaultInitExpr;
+ LLVM_PREFERRED_TYPE(ExprBitfields)
unsigned : NumExprBits;
+ /// Whether this CXXDefaultInitExprBitfields rewrote its argument and stores
+ /// a copy.
+ LLVM_PREFERRED_TYPE(bool)
+ unsigned HasRewrittenInit : 1;
+
/// The location where the default initializer expression was used.
SourceLocation Loc;
};
@@ -701,6 +836,7 @@ protected:
friend class ASTStmtReader;
friend class CXXScalarValueInitExpr;
+ LLVM_PREFERRED_TYPE(ExprBitfields)
unsigned : NumExprBits;
SourceLocation RParenLoc;
@@ -711,28 +847,37 @@ protected:
friend class ASTStmtWriter;
friend class CXXNewExpr;
+ LLVM_PREFERRED_TYPE(ExprBitfields)
unsigned : NumExprBits;
/// Was the usage ::new, i.e. is the global new to be used?
+ LLVM_PREFERRED_TYPE(bool)
unsigned IsGlobalNew : 1;
/// Do we allocate an array? If so, the first trailing "Stmt *" is the
/// size expression.
+ LLVM_PREFERRED_TYPE(bool)
unsigned IsArray : 1;
/// Should the alignment be passed to the allocation function?
+ LLVM_PREFERRED_TYPE(bool)
unsigned ShouldPassAlignment : 1;
/// If this is an array allocation, does the usual deallocation
/// function for the allocated type want to know the allocated size?
+ LLVM_PREFERRED_TYPE(bool)
unsigned UsualArrayDeleteWantsSize : 1;
- /// What kind of initializer do we have? Could be none, parens, or braces.
- /// In storage, we distinguish between "none, and no initializer expr", and
- /// "none, but an implicit initializer expr".
+ // Is initializer expr present?
+ LLVM_PREFERRED_TYPE(bool)
+ unsigned HasInitializer : 1;
+
+ /// What kind of initializer syntax used? Could be none, parens, or braces.
+ LLVM_PREFERRED_TYPE(CXXNewInitializationStyle)
unsigned StoredInitializationStyle : 2;
/// True if the allocated type was expressed as a parenthesized type-id.
+ LLVM_PREFERRED_TYPE(bool)
unsigned IsParenTypeId : 1;
/// The number of placement new arguments.
@@ -743,21 +888,26 @@ protected:
friend class ASTStmtReader;
friend class CXXDeleteExpr;
+ LLVM_PREFERRED_TYPE(ExprBitfields)
unsigned : NumExprBits;
/// Is this a forced global delete, i.e. "::delete"?
+ LLVM_PREFERRED_TYPE(bool)
unsigned GlobalDelete : 1;
/// Is this the array form of delete, i.e. "delete[]"?
+ LLVM_PREFERRED_TYPE(bool)
unsigned ArrayForm : 1;
/// ArrayFormAsWritten can be different from ArrayForm if 'delete' is
/// applied to pointer-to-array type (ArrayFormAsWritten will be false
/// while ArrayForm will be true).
+ LLVM_PREFERRED_TYPE(bool)
unsigned ArrayFormAsWritten : 1;
/// Does the usual deallocation function for the element type require
/// a size_t argument?
+ LLVM_PREFERRED_TYPE(bool)
unsigned UsualArrayDeleteWantsSize : 1;
/// Location of the expression.
@@ -769,13 +919,16 @@ protected:
friend class ASTStmtWriter;
friend class TypeTraitExpr;
+ LLVM_PREFERRED_TYPE(ExprBitfields)
unsigned : NumExprBits;
/// The kind of type trait, which is a value of a TypeTrait enumerator.
+ LLVM_PREFERRED_TYPE(TypeTrait)
unsigned Kind : 8;
/// If this expression is not value-dependent, this indicates whether
/// the trait evaluated true or false.
+ LLVM_PREFERRED_TYPE(bool)
unsigned Value : 1;
/// The number of arguments to this type trait. According to [implimits]
@@ -789,10 +942,12 @@ protected:
friend class ASTStmtWriter;
friend class DependentScopeDeclRefExpr;
+ LLVM_PREFERRED_TYPE(ExprBitfields)
unsigned : NumExprBits;
/// Whether the name includes info for explicit template
/// keyword and arguments.
+ LLVM_PREFERRED_TYPE(bool)
unsigned HasTemplateKWAndArgsInfo : 1;
};
@@ -800,14 +955,23 @@ protected:
friend class ASTStmtReader;
friend class CXXConstructExpr;
+ LLVM_PREFERRED_TYPE(ExprBitfields)
unsigned : NumExprBits;
+ LLVM_PREFERRED_TYPE(bool)
unsigned Elidable : 1;
+ LLVM_PREFERRED_TYPE(bool)
unsigned HadMultipleCandidates : 1;
+ LLVM_PREFERRED_TYPE(bool)
unsigned ListInitialization : 1;
+ LLVM_PREFERRED_TYPE(bool)
unsigned StdInitListInitialization : 1;
+ LLVM_PREFERRED_TYPE(bool)
unsigned ZeroInitialization : 1;
+ LLVM_PREFERRED_TYPE(CXXConstructionKind)
unsigned ConstructionKind : 3;
+ LLVM_PREFERRED_TYPE(bool)
+ unsigned IsImmediateEscalating : 1;
SourceLocation Loc;
};
@@ -816,9 +980,11 @@ protected:
friend class ASTStmtReader; // deserialization
friend class ExprWithCleanups;
+ LLVM_PREFERRED_TYPE(ExprBitfields)
unsigned : NumExprBits;
// When false, it must not have side effects.
+ LLVM_PREFERRED_TYPE(bool)
unsigned CleanupsHaveSideEffects : 1;
unsigned NumObjects : 32 - 1 - NumExprBits;
@@ -828,6 +994,7 @@ protected:
friend class ASTStmtReader;
friend class CXXUnresolvedConstructExpr;
+ LLVM_PREFERRED_TYPE(ExprBitfields)
unsigned : NumExprBits;
/// The number of arguments used to construct the type.
@@ -838,18 +1005,22 @@ protected:
friend class ASTStmtReader;
friend class CXXDependentScopeMemberExpr;
+ LLVM_PREFERRED_TYPE(ExprBitfields)
unsigned : NumExprBits;
/// Whether this member expression used the '->' operator or
/// the '.' operator.
+ LLVM_PREFERRED_TYPE(bool)
unsigned IsArrow : 1;
/// Whether this member expression has info for explicit template
/// keyword and arguments.
+ LLVM_PREFERRED_TYPE(bool)
unsigned HasTemplateKWAndArgsInfo : 1;
/// See getFirstQualifierFoundInScope() and the comment listing
/// the trailing objects.
+ LLVM_PREFERRED_TYPE(bool)
unsigned HasFirstQualifierFoundInScope : 1;
/// The location of the '->' or '.' operator.
@@ -860,10 +1031,12 @@ protected:
friend class ASTStmtReader;
friend class OverloadExpr;
+ LLVM_PREFERRED_TYPE(ExprBitfields)
unsigned : NumExprBits;
/// Whether the name includes info for explicit template
/// keyword and arguments.
+ LLVM_PREFERRED_TYPE(bool)
unsigned HasTemplateKWAndArgsInfo : 1;
/// Padding used by the derived classes to store various bits. If you
@@ -880,14 +1053,17 @@ protected:
friend class ASTStmtReader;
friend class UnresolvedLookupExpr;
+ LLVM_PREFERRED_TYPE(OverloadExprBitfields)
unsigned : NumOverloadExprBits;
/// True if these lookup results should be extended by
/// argument-dependent lookup if this is the operand of a function call.
+ LLVM_PREFERRED_TYPE(bool)
unsigned RequiresADL : 1;
/// True if these lookup results are overloaded. This is pretty trivially
/// rederivable if we urgently need to kill this field.
+ LLVM_PREFERRED_TYPE(bool)
unsigned Overloaded : 1;
};
static_assert(sizeof(UnresolvedLookupExprBitfields) <= 4,
@@ -898,13 +1074,16 @@ protected:
friend class ASTStmtReader;
friend class UnresolvedMemberExpr;
+ LLVM_PREFERRED_TYPE(OverloadExprBitfields)
unsigned : NumOverloadExprBits;
/// Whether this member expression used the '->' operator or
/// the '.' operator.
+ LLVM_PREFERRED_TYPE(bool)
unsigned IsArrow : 1;
/// Whether the lookup results contain an unresolved using declaration.
+ LLVM_PREFERRED_TYPE(bool)
unsigned HasUnresolvedUsing : 1;
};
static_assert(sizeof(UnresolvedMemberExprBitfields) <= 4,
@@ -915,8 +1094,10 @@ protected:
friend class ASTStmtReader;
friend class CXXNoexceptExpr;
+ LLVM_PREFERRED_TYPE(ExprBitfields)
unsigned : NumExprBits;
+ LLVM_PREFERRED_TYPE(bool)
unsigned Value : 1;
};
@@ -924,6 +1105,7 @@ protected:
friend class ASTStmtReader;
friend class SubstNonTypeTemplateParmExpr;
+ LLVM_PREFERRED_TYPE(ExprBitfields)
unsigned : NumExprBits;
/// The location of the non-type template parameter reference.
@@ -935,17 +1117,21 @@ protected:
friend class ASTStmtWriter;
friend class LambdaExpr;
+ LLVM_PREFERRED_TYPE(ExprBitfields)
unsigned : NumExprBits;
/// The default capture kind, which is a value of type
/// LambdaCaptureDefault.
+ LLVM_PREFERRED_TYPE(LambdaCaptureDefault)
unsigned CaptureDefault : 2;
/// Whether this lambda had an explicit parameter list vs. an
/// implicit (and empty) parameter list.
+ LLVM_PREFERRED_TYPE(bool)
unsigned ExplicitParams : 1;
/// Whether this lambda had the result type explicitly specified.
+ LLVM_PREFERRED_TYPE(bool)
unsigned ExplicitResultType : 1;
/// The number of captures.
@@ -957,19 +1143,23 @@ protected:
friend class ASTStmtWriter;
friend class RequiresExpr;
+ LLVM_PREFERRED_TYPE(ExprBitfields)
unsigned : NumExprBits;
+ LLVM_PREFERRED_TYPE(bool)
unsigned IsSatisfied : 1;
SourceLocation RequiresKWLoc;
};
- //===--- C++ Coroutines TS bitfields classes ---===//
+ //===--- C++ Coroutines bitfields classes ---===//
class CoawaitExprBitfields {
friend class CoawaitExpr;
+ LLVM_PREFERRED_TYPE(ExprBitfields)
unsigned : NumExprBits;
+ LLVM_PREFERRED_TYPE(bool)
unsigned IsImplicit : 1;
};
@@ -978,8 +1168,10 @@ protected:
class ObjCIndirectCopyRestoreExprBitfields {
friend class ObjCIndirectCopyRestoreExpr;
+ LLVM_PREFERRED_TYPE(ExprBitfields)
unsigned : NumExprBits;
+ LLVM_PREFERRED_TYPE(bool)
unsigned ShouldCopy : 1;
};
@@ -989,10 +1181,12 @@ protected:
friend class ASTStmtReader;
friend class OpaqueValueExpr;
+ LLVM_PREFERRED_TYPE(ExprBitfields)
unsigned : NumExprBits;
/// The OVE is a unique semantic reference to its source expression if this
/// bit is set to true.
+ LLVM_PREFERRED_TYPE(bool)
unsigned IsUnique : 1;
SourceLocation Loc;
@@ -1067,7 +1261,7 @@ protected:
LambdaExprBitfields LambdaExprBits;
RequiresExprBitfields RequiresExprBits;
- // C++ Coroutines TS expressions
+ // C++ Coroutines expressions
CoawaitExprBitfields CoawaitBits;
// Obj-C Expressions
@@ -1215,6 +1409,11 @@ public:
const PrintingPolicy &Policy, unsigned Indentation = 0,
StringRef NewlineSymbol = "\n",
const ASTContext *Context = nullptr) const;
+ void printPrettyControlled(raw_ostream &OS, PrinterHelper *Helper,
+ const PrintingPolicy &Policy,
+ unsigned Indentation = 0,
+ StringRef NewlineSymbol = "\n",
+ const ASTContext *Context = nullptr) const;
/// Pretty-prints in JSON format.
void printJson(raw_ostream &Out, PrinterHelper *Helper,
@@ -1238,7 +1437,7 @@ public:
}
/// Child Iterators: All subclasses must implement 'children'
- /// to permit easy iteration over the substatements/subexpessions of an
+ /// to permit easy iteration over the substatements/subexpressions of an
/// AST node. This permits easy iteration over all nodes in the AST.
using child_iterator = StmtIterator;
using const_child_iterator = ConstStmtIterator;
@@ -1271,8 +1470,13 @@ public:
/// parameters are identified by index/level rather than their
/// declaration pointers) or the exact representation of the statement as
/// written in the source.
+ /// \param ProfileLambdaExpr whether or not to profile lambda expressions.
+ /// When false, the lambda expressions are never considered to be equal to
+ /// other lambda expressions. When true, the lambda expressions with the same
+ /// implementation will be considered to be the same. ProfileLambdaExpr should
+ /// only be true when we try to merge two declarations within modules.
void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context,
- bool Canonical) const;
+ bool Canonical, bool ProfileLambdaExpr = false) const;
/// Calculate a unique representation for a statement that is
/// stable across compiler invocations.
@@ -1395,36 +1599,63 @@ public:
};
/// CompoundStmt - This represents a group of statements like { stmt stmt }.
-class CompoundStmt final : public Stmt,
- private llvm::TrailingObjects<CompoundStmt, Stmt *> {
+class CompoundStmt final
+ : public Stmt,
+ private llvm::TrailingObjects<CompoundStmt, Stmt *, FPOptionsOverride> {
friend class ASTStmtReader;
friend TrailingObjects;
- /// The location of the closing "}". LBraceLoc is stored in CompoundStmtBits.
+ /// The location of the opening "{".
+ SourceLocation LBraceLoc;
+
+ /// The location of the closing "}".
SourceLocation RBraceLoc;
- CompoundStmt(ArrayRef<Stmt *> Stmts, SourceLocation LB, SourceLocation RB);
+ CompoundStmt(ArrayRef<Stmt *> Stmts, FPOptionsOverride FPFeatures,
+ SourceLocation LB, SourceLocation RB);
explicit CompoundStmt(EmptyShell Empty) : Stmt(CompoundStmtClass, Empty) {}
void setStmts(ArrayRef<Stmt *> Stmts);
+ /// Set FPOptionsOverride in trailing storage. Used only by Serialization.
+ void setStoredFPFeatures(FPOptionsOverride F) {
+ assert(hasStoredFPFeatures());
+ *getTrailingObjects<FPOptionsOverride>() = F;
+ }
+
+ size_t numTrailingObjects(OverloadToken<Stmt *>) const {
+ return CompoundStmtBits.NumStmts;
+ }
+
public:
static CompoundStmt *Create(const ASTContext &C, ArrayRef<Stmt *> Stmts,
- SourceLocation LB, SourceLocation RB);
+ FPOptionsOverride FPFeatures, SourceLocation LB,
+ SourceLocation RB);
// Build an empty compound statement with a location.
- explicit CompoundStmt(SourceLocation Loc)
- : Stmt(CompoundStmtClass), RBraceLoc(Loc) {
+ explicit CompoundStmt(SourceLocation Loc) : CompoundStmt(Loc, Loc) {}
+
+ CompoundStmt(SourceLocation Loc, SourceLocation EndLoc)
+ : Stmt(CompoundStmtClass), LBraceLoc(Loc), RBraceLoc(EndLoc) {
CompoundStmtBits.NumStmts = 0;
- CompoundStmtBits.LBraceLoc = Loc;
+ CompoundStmtBits.HasFPFeatures = 0;
}
// Build an empty compound statement.
- static CompoundStmt *CreateEmpty(const ASTContext &C, unsigned NumStmts);
+ static CompoundStmt *CreateEmpty(const ASTContext &C, unsigned NumStmts,
+ bool HasFPFeatures);
bool body_empty() const { return CompoundStmtBits.NumStmts == 0; }
unsigned size() const { return CompoundStmtBits.NumStmts; }
+ bool hasStoredFPFeatures() const { return CompoundStmtBits.HasFPFeatures; }
+
+ /// Get FPOptionsOverride from trailing storage.
+ FPOptionsOverride getStoredFPFeatures() const {
+ assert(hasStoredFPFeatures());
+ return *getTrailingObjects<FPOptionsOverride>();
+ }
+
using body_iterator = Stmt **;
using body_range = llvm::iterator_range<body_iterator>;
@@ -1499,10 +1730,10 @@ public:
return const_cast<CompoundStmt *>(this)->getStmtExprResult();
}
- SourceLocation getBeginLoc() const { return CompoundStmtBits.LBraceLoc; }
+ SourceLocation getBeginLoc() const { return LBraceLoc; }
SourceLocation getEndLoc() const { return RBraceLoc; }
- SourceLocation getLBracLoc() const { return CompoundStmtBits.LBraceLoc; }
+ SourceLocation getLBracLoc() const { return LBraceLoc; }
SourceLocation getRBracLoc() const { return RBraceLoc; }
static bool classof(const Stmt *T) {
@@ -1879,7 +2110,7 @@ public:
SourceLocation getAttrLoc() const { return AttributedStmtBits.AttrLoc; }
ArrayRef<const Attr *> getAttrs() const {
- return llvm::makeArrayRef(getAttrArrayPtr(), AttributedStmtBits.NumAttrs);
+ return llvm::ArrayRef(getAttrArrayPtr(), AttributedStmtBits.NumAttrs);
}
Stmt *getSubStmt() { return SubStmt; }
@@ -1950,8 +2181,8 @@ class IfStmt final
unsigned elseOffset() const { return condOffset() + ElseOffsetFromCond; }
/// Build an if/then/else statement.
- IfStmt(const ASTContext &Ctx, SourceLocation IL, bool IsConstexpr, Stmt *Init,
- VarDecl *Var, Expr *Cond, SourceLocation LParenLoc,
+ IfStmt(const ASTContext &Ctx, SourceLocation IL, IfStatementKind Kind,
+ Stmt *Init, VarDecl *Var, Expr *Cond, SourceLocation LParenLoc,
SourceLocation RParenLoc, Stmt *Then, SourceLocation EL, Stmt *Else);
/// Build an empty if/then/else statement.
@@ -1960,9 +2191,9 @@ class IfStmt final
public:
/// Create an IfStmt.
static IfStmt *Create(const ASTContext &Ctx, SourceLocation IL,
- bool IsConstexpr, Stmt *Init, VarDecl *Var, Expr *Cond,
- SourceLocation LPL, SourceLocation RPL, Stmt *Then,
- SourceLocation EL = SourceLocation(),
+ IfStatementKind Kind, Stmt *Init, VarDecl *Var,
+ Expr *Cond, SourceLocation LPL, SourceLocation RPL,
+ Stmt *Then, SourceLocation EL = SourceLocation(),
Stmt *Else = nullptr);
/// Create an empty IfStmt optionally with storage for an else statement,
@@ -2047,6 +2278,11 @@ public:
: nullptr;
}
+ void setConditionVariableDeclStmt(DeclStmt *CondVar) {
+ assert(hasVarStorage());
+ getTrailingObjects<Stmt *>()[varOffset()] = CondVar;
+ }
+
Stmt *getInit() {
return hasInitStorage() ? getTrailingObjects<Stmt *>()[initOffset()]
: nullptr;
@@ -2077,13 +2313,35 @@ public:
*getTrailingObjects<SourceLocation>() = ElseLoc;
}
- bool isConstexpr() const { return IfStmtBits.IsConstexpr; }
- void setConstexpr(bool C) { IfStmtBits.IsConstexpr = C; }
+ bool isConsteval() const {
+ return getStatementKind() == IfStatementKind::ConstevalNonNegated ||
+ getStatementKind() == IfStatementKind::ConstevalNegated;
+ }
+
+ bool isNonNegatedConsteval() const {
+ return getStatementKind() == IfStatementKind::ConstevalNonNegated;
+ }
+
+ bool isNegatedConsteval() const {
+ return getStatementKind() == IfStatementKind::ConstevalNegated;
+ }
+
+ bool isConstexpr() const {
+ return getStatementKind() == IfStatementKind::Constexpr;
+ }
+
+ void setStatementKind(IfStatementKind Kind) {
+ IfStmtBits.Kind = static_cast<unsigned>(Kind);
+ }
+
+ IfStatementKind getStatementKind() const {
+ return static_cast<IfStatementKind>(IfStmtBits.Kind);
+ }
/// If this is an 'if constexpr', determine which substatement will be taken.
- /// Otherwise, or if the condition is value-dependent, returns None.
- Optional<const Stmt*> getNondiscardedCase(const ASTContext &Ctx) const;
- Optional<Stmt *> getNondiscardedCase(const ASTContext &Ctx);
+ /// Otherwise, or if the condition is value-dependent, returns std::nullopt.
+ std::optional<const Stmt *> getNondiscardedCase(const ASTContext &Ctx) const;
+ std::optional<Stmt *> getNondiscardedCase(const ASTContext &Ctx);
bool isObjCAvailabilityCheck() const;
@@ -2101,13 +2359,19 @@ public:
// Iterators over subexpressions. The iterators will include iterating
// over the initialization expression referenced by the condition variable.
child_range children() {
- return child_range(getTrailingObjects<Stmt *>(),
+ // We always store a condition, but there is none for consteval if
+ // statements, so skip it.
+ return child_range(getTrailingObjects<Stmt *>() +
+ (isConsteval() ? thenOffset() : 0),
getTrailingObjects<Stmt *>() +
numTrailingObjects(OverloadToken<Stmt *>()));
}
const_child_range children() const {
- return const_child_range(getTrailingObjects<Stmt *>(),
+ // We always store a condition, but there is none for consteval if
+ // statements, so skip it.
+ return const_child_range(getTrailingObjects<Stmt *>() +
+ (isConsteval() ? thenOffset() : 0),
getTrailingObjects<Stmt *>() +
numTrailingObjects(OverloadToken<Stmt *>()));
}
@@ -2251,6 +2515,11 @@ public:
: nullptr;
}
+ void setConditionVariableDeclStmt(DeclStmt *CondVar) {
+ assert(hasVarStorage());
+ getTrailingObjects<Stmt *>()[varOffset()] = CondVar;
+ }
+
SwitchCase *getSwitchCaseList() { return FirstCase; }
const SwitchCase *getSwitchCaseList() const { return FirstCase; }
void setSwitchCaseList(SwitchCase *SC) { FirstCase = SC; }
@@ -2414,6 +2683,11 @@ public:
: nullptr;
}
+ void setConditionVariableDeclStmt(DeclStmt *CondVar) {
+ assert(hasVarStorage());
+ getTrailingObjects<Stmt *>()[varOffset()] = CondVar;
+ }
+
SourceLocation getWhileLoc() const { return WhileStmtBits.WhileLoc; }
void setWhileLoc(SourceLocation L) { WhileStmtBits.WhileLoc = L; }
@@ -2503,6 +2777,8 @@ public:
/// the init/cond/inc parts of the ForStmt will be null if they were not
/// specified in the source.
class ForStmt : public Stmt {
+ friend class ASTStmtReader;
+
enum { INIT, CONDVAR, COND, INC, BODY, END_EXPR };
Stmt* SubExprs[END_EXPR]; // SubExprs[INIT] is an expression or declstmt.
SourceLocation LParenLoc, RParenLoc;
@@ -2530,10 +2806,18 @@ public:
/// If this ForStmt has a condition variable, return the faux DeclStmt
/// associated with the creation of that condition variable.
+ DeclStmt *getConditionVariableDeclStmt() {
+ return reinterpret_cast<DeclStmt*>(SubExprs[CONDVAR]);
+ }
+
const DeclStmt *getConditionVariableDeclStmt() const {
return reinterpret_cast<DeclStmt*>(SubExprs[CONDVAR]);
}
+ void setConditionVariableDeclStmt(DeclStmt *CondVar) {
+ SubExprs[CONDVAR] = CondVar;
+ }
+
Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); }
Expr *getInc() { return reinterpret_cast<Expr*>(SubExprs[INC]); }
Stmt *getBody() { return SubExprs[BODY]; }
@@ -3262,16 +3546,16 @@ public:
//===--- Other ---===//
ArrayRef<StringRef> getAllConstraints() const {
- return llvm::makeArrayRef(Constraints, NumInputs + NumOutputs);
+ return llvm::ArrayRef(Constraints, NumInputs + NumOutputs);
}
ArrayRef<StringRef> getClobbers() const {
- return llvm::makeArrayRef(Clobbers, NumClobbers);
+ return llvm::ArrayRef(Clobbers, NumClobbers);
}
ArrayRef<Expr*> getAllExprs() const {
- return llvm::makeArrayRef(reinterpret_cast<Expr**>(Exprs),
- NumInputs + NumOutputs);
+ return llvm::ArrayRef(reinterpret_cast<Expr **>(Exprs),
+ NumInputs + NumOutputs);
}
StringRef getClobber(unsigned i) const { return getClobbers()[i]; }
@@ -3485,8 +3769,11 @@ public:
llvm::PointerIntPair<VarDecl *, 2, VariableCaptureKind> VarAndKind;
SourceLocation Loc;
+ Capture() = default;
+
public:
friend class ASTStmtReader;
+ friend class CapturedStmt;
/// Create a new capture.
///
diff --git a/contrib/llvm-project/clang/include/clang/AST/StmtCXX.h b/contrib/llvm-project/clang/include/clang/AST/StmtCXX.h
index 4d1f3e8ef255..8b4ef24ed376 100644
--- a/contrib/llvm-project/clang/include/clang/AST/StmtCXX.h
+++ b/contrib/llvm-project/clang/include/clang/AST/StmtCXX.h
@@ -75,7 +75,8 @@ class CXXTryStmt final : public Stmt,
unsigned NumHandlers;
size_t numTrailingObjects(OverloadToken<Stmt *>) const { return NumHandlers; }
- CXXTryStmt(SourceLocation tryLoc, Stmt *tryBlock, ArrayRef<Stmt*> handlers);
+ CXXTryStmt(SourceLocation tryLoc, CompoundStmt *tryBlock,
+ ArrayRef<Stmt *> handlers);
CXXTryStmt(EmptyShell Empty, unsigned numHandlers)
: Stmt(CXXTryStmtClass), NumHandlers(numHandlers) { }
@@ -84,7 +85,7 @@ class CXXTryStmt final : public Stmt,
public:
static CXXTryStmt *Create(const ASTContext &C, SourceLocation tryLoc,
- Stmt *tryBlock, ArrayRef<Stmt*> handlers);
+ CompoundStmt *tryBlock, ArrayRef<Stmt *> handlers);
static CXXTryStmt *Create(const ASTContext &C, EmptyShell Empty,
unsigned numHandlers);
@@ -326,8 +327,8 @@ class CoroutineBodyStmt final
OnFallthrough, ///< Handler for control flow falling off the body.
Allocate, ///< Coroutine frame memory allocation.
Deallocate, ///< Coroutine frame memory deallocation.
- ReturnValue, ///< Return value for thunk function: p.get_return_object().
ResultDecl, ///< Declaration holding the result of get_return_object.
+ ReturnValue, ///< Return value for thunk function: p.get_return_object().
ReturnStmt, ///< Return statement for the thunk function.
ReturnStmtOnAllocFailure, ///< Return statement if allocation failed.
FirstParamMove ///< First offset for move construction of parameter copies.
@@ -353,8 +354,8 @@ public:
Stmt *OnFallthrough = nullptr;
Expr *Allocate = nullptr;
Expr *Deallocate = nullptr;
- Expr *ReturnValue = nullptr;
Stmt *ResultDecl = nullptr;
+ Expr *ReturnValue = nullptr;
Stmt *ReturnStmt = nullptr;
Stmt *ReturnStmtOnAllocFailure = nullptr;
ArrayRef<Stmt *> ParamMoves;
@@ -374,9 +375,10 @@ public:
}
/// Retrieve the body of the coroutine as written. This will be either
- /// a CompoundStmt or a TryStmt.
- Stmt *getBody() const {
- return getStoredStmts()[SubStmt::Body];
+ /// a CompoundStmt. If the coroutine is in function-try-block, we will
+ /// wrap the CXXTryStmt into a CompoundStmt to keep consistency.
+ CompoundStmt *getBody() const {
+ return cast<CompoundStmt>(getStoredStmts()[SubStmt::Body]);
}
Stmt *getPromiseDeclStmt() const {
@@ -406,10 +408,14 @@ public:
Expr *getDeallocate() const {
return cast_or_null<Expr>(getStoredStmts()[SubStmt::Deallocate]);
}
+ Stmt *getResultDecl() const { return getStoredStmts()[SubStmt::ResultDecl]; }
Expr *getReturnValueInit() const {
return cast<Expr>(getStoredStmts()[SubStmt::ReturnValue]);
}
- Stmt *getResultDecl() const { return getStoredStmts()[SubStmt::ResultDecl]; }
+ Expr *getReturnValue() const {
+ auto *RS = dyn_cast_or_null<clang::ReturnStmt>(getReturnStmt());
+ return RS ? RS->getRetValue() : nullptr;
+ }
Stmt *getReturnStmt() const { return getStoredStmts()[SubStmt::ReturnStmt]; }
Stmt *getReturnStmtOnAllocFailure() const {
return getStoredStmts()[SubStmt::ReturnStmtOnAllocFailure];
@@ -437,6 +443,17 @@ public:
NumParams);
}
+ child_range childrenExclBody() {
+ return child_range(getStoredStmts() + SubStmt::Body + 1,
+ getStoredStmts() + SubStmt::FirstParamMove + NumParams);
+ }
+
+ const_child_range childrenExclBody() const {
+ return const_child_range(getStoredStmts() + SubStmt::Body + 1,
+ getStoredStmts() + SubStmt::FirstParamMove +
+ NumParams);
+ }
+
static bool classof(const Stmt *T) {
return T->getStmtClass() == CoroutineBodyStmtClass;
}
@@ -495,16 +512,10 @@ public:
}
child_range children() {
- if (!getOperand())
- return child_range(SubStmts + SubStmt::PromiseCall,
- SubStmts + SubStmt::Count);
return child_range(SubStmts, SubStmts + SubStmt::Count);
}
const_child_range children() const {
- if (!getOperand())
- return const_child_range(SubStmts + SubStmt::PromiseCall,
- SubStmts + SubStmt::Count);
return const_child_range(SubStmts, SubStmts + SubStmt::Count);
}
diff --git a/contrib/llvm-project/clang/include/clang/AST/StmtObjC.h b/contrib/llvm-project/clang/include/clang/AST/StmtObjC.h
index 948ef2421cb9..c46ff4634c82 100644
--- a/contrib/llvm-project/clang/include/clang/AST/StmtObjC.h
+++ b/contrib/llvm-project/clang/include/clang/AST/StmtObjC.h
@@ -162,8 +162,14 @@ public:
};
/// Represents Objective-C's \@try ... \@catch ... \@finally statement.
-class ObjCAtTryStmt : public Stmt {
-private:
+class ObjCAtTryStmt final
+ : public Stmt,
+ private llvm::TrailingObjects<ObjCAtTryStmt, Stmt *> {
+ friend TrailingObjects;
+ size_t numTrailingObjects(OverloadToken<Stmt *>) const {
+ return 1 + NumCatchStmts + HasFinally;
+ }
+
// The location of the @ in the \@try.
SourceLocation AtTryLoc;
@@ -178,10 +184,8 @@ private:
/// The order of the statements in memory follows the order in the source,
/// with the \@try body first, followed by the \@catch statements (if any)
/// and, finally, the \@finally (if it exists).
- Stmt **getStmts() { return reinterpret_cast<Stmt **> (this + 1); }
- const Stmt* const *getStmts() const {
- return reinterpret_cast<const Stmt * const*> (this + 1);
- }
+ Stmt **getStmts() { return getTrailingObjects<Stmt *>(); }
+ Stmt *const *getStmts() const { return getTrailingObjects<Stmt *>(); }
ObjCAtTryStmt(SourceLocation atTryLoc, Stmt *atTryStmt,
Stmt **CatchStmts, unsigned NumCatchStmts,
@@ -257,13 +261,34 @@ public:
}
child_range children() {
- return child_range(getStmts(),
- getStmts() + 1 + NumCatchStmts + HasFinally);
+ return child_range(
+ getStmts(), getStmts() + numTrailingObjects(OverloadToken<Stmt *>()));
}
const_child_range children() const {
return const_child_range(const_cast<ObjCAtTryStmt *>(this)->children());
}
+
+ using catch_stmt_iterator = CastIterator<ObjCAtCatchStmt>;
+ using const_catch_stmt_iterator = ConstCastIterator<ObjCAtCatchStmt>;
+ using catch_range = llvm::iterator_range<catch_stmt_iterator>;
+ using catch_const_range = llvm::iterator_range<const_catch_stmt_iterator>;
+
+ catch_stmt_iterator catch_stmts_begin() { return getStmts() + 1; }
+ catch_stmt_iterator catch_stmts_end() {
+ return catch_stmts_begin() + NumCatchStmts;
+ }
+ catch_range catch_stmts() {
+ return catch_range(catch_stmts_begin(), catch_stmts_end());
+ }
+
+ const_catch_stmt_iterator catch_stmts_begin() const { return getStmts() + 1; }
+ const_catch_stmt_iterator catch_stmts_end() const {
+ return catch_stmts_begin() + NumCatchStmts;
+ }
+ catch_const_range catch_stmts() const {
+ return catch_const_range(catch_stmts_begin(), catch_stmts_end());
+ }
};
/// Represents Objective-C's \@synchronized statement.
diff --git a/contrib/llvm-project/clang/include/clang/AST/StmtOpenMP.h b/contrib/llvm-project/clang/include/clang/AST/StmtOpenMP.h
index 9c85df741f48..621643391535 100644
--- a/contrib/llvm-project/clang/include/clang/AST/StmtOpenMP.h
+++ b/contrib/llvm-project/clang/include/clang/AST/StmtOpenMP.h
@@ -277,10 +277,19 @@ class OMPExecutableDirective : public Stmt {
/// Get the clauses storage.
MutableArrayRef<OMPClause *> getClauses() {
if (!Data)
- return llvm::None;
+ return std::nullopt;
return Data->getClauses();
}
+ /// Was this directive mapped from an another directive?
+ /// e.g. 1) omp loop bind(parallel) is mapped to OMPD_for
+ /// 2) omp loop bind(teams) is mapped to OMPD_distribute
+ /// 3) omp loop bind(thread) is mapped to OMPD_simd
+ /// It was necessary to note it down in the Directive because of
+ /// clang::TreeTransform::TransformOMPExecutableDirective() pass in
+ /// the frontend.
+ OpenMPDirectiveKind PrevMappedDirective = llvm::omp::OMPD_unknown;
+
protected:
/// Data, associated with the directive.
OMPChildren *Data = nullptr;
@@ -345,6 +354,10 @@ protected:
return Inst;
}
+ void setMappedDirective(OpenMPDirectiveKind MappedDirective) {
+ PrevMappedDirective = MappedDirective;
+ }
+
public:
/// Iterates over expressions/statements used in the construct.
class used_clauses_child_iterator
@@ -399,8 +412,9 @@ public:
static llvm::iterator_range<used_clauses_child_iterator>
used_clauses_children(ArrayRef<OMPClause *> Clauses) {
- return {used_clauses_child_iterator(Clauses),
- used_clauses_child_iterator(llvm::makeArrayRef(Clauses.end(), 0))};
+ return {
+ used_clauses_child_iterator(Clauses),
+ used_clauses_child_iterator(llvm::ArrayRef(Clauses.end(), (size_t)0))};
}
/// Iterates over a filtered subrange of clauses applied to a
@@ -445,7 +459,7 @@ public:
getClausesOfKind(ArrayRef<OMPClause *> Clauses) {
return {specific_clause_iterator<SpecificClause>(Clauses),
specific_clause_iterator<SpecificClause>(
- llvm::makeArrayRef(Clauses.end(), 0))};
+ llvm::ArrayRef(Clauses.end(), (size_t)0))};
}
template <typename SpecificClause>
@@ -571,7 +585,7 @@ public:
ArrayRef<OMPClause *> clauses() const {
if (!Data)
- return llvm::None;
+ return std::nullopt;
return Data->getClauses();
}
@@ -597,6 +611,8 @@ public:
"Expected directive with the associated statement.");
return Data->getRawStmt();
}
+
+ OpenMPDirectiveKind getMappedDirective() const { return PrevMappedDirective; }
};
/// This represents '#pragma omp parallel' directive.
@@ -889,22 +905,23 @@ public:
/// Calls the specified callback function for all the loops in \p CurStmt,
/// from the outermost to the innermost.
- static bool doForAllLoops(Stmt *CurStmt, bool TryImperfectlyNestedLoops,
- unsigned NumLoops,
- llvm::function_ref<bool(unsigned, Stmt *)> Callback,
- llvm::function_ref<void(OMPLoopBasedDirective *)>
- OnTransformationCallback);
+ static bool
+ doForAllLoops(Stmt *CurStmt, bool TryImperfectlyNestedLoops,
+ unsigned NumLoops,
+ llvm::function_ref<bool(unsigned, Stmt *)> Callback,
+ llvm::function_ref<void(OMPLoopTransformationDirective *)>
+ OnTransformationCallback);
static bool
doForAllLoops(const Stmt *CurStmt, bool TryImperfectlyNestedLoops,
unsigned NumLoops,
llvm::function_ref<bool(unsigned, const Stmt *)> Callback,
- llvm::function_ref<void(const OMPLoopBasedDirective *)>
+ llvm::function_ref<void(const OMPLoopTransformationDirective *)>
OnTransformationCallback) {
auto &&NewCallback = [Callback](unsigned Cnt, Stmt *CurStmt) {
return Callback(Cnt, CurStmt);
};
auto &&NewTransformCb =
- [OnTransformationCallback](OMPLoopBasedDirective *A) {
+ [OnTransformationCallback](OMPLoopTransformationDirective *A) {
OnTransformationCallback(A);
};
return doForAllLoops(const_cast<Stmt *>(CurStmt), TryImperfectlyNestedLoops,
@@ -917,7 +934,7 @@ public:
doForAllLoops(Stmt *CurStmt, bool TryImperfectlyNestedLoops,
unsigned NumLoops,
llvm::function_ref<bool(unsigned, Stmt *)> Callback) {
- auto &&TransformCb = [](OMPLoopBasedDirective *) {};
+ auto &&TransformCb = [](OMPLoopTransformationDirective *) {};
return doForAllLoops(CurStmt, TryImperfectlyNestedLoops, NumLoops, Callback,
TransformCb);
}
@@ -954,6 +971,47 @@ public:
}
};
+/// The base class for all loop transformation directives.
+class OMPLoopTransformationDirective : public OMPLoopBasedDirective {
+ friend class ASTStmtReader;
+
+ /// Number of loops generated by this loop transformation.
+ unsigned NumGeneratedLoops = 0;
+
+protected:
+ explicit OMPLoopTransformationDirective(StmtClass SC,
+ OpenMPDirectiveKind Kind,
+ SourceLocation StartLoc,
+ SourceLocation EndLoc,
+ unsigned NumAssociatedLoops)
+ : OMPLoopBasedDirective(SC, Kind, StartLoc, EndLoc, NumAssociatedLoops) {}
+
+ /// Set the number of loops generated by this loop transformation.
+ void setNumGeneratedLoops(unsigned Num) { NumGeneratedLoops = Num; }
+
+public:
+ /// Return the number of associated (consumed) loops.
+ unsigned getNumAssociatedLoops() const { return getLoopsNumber(); }
+
+ /// Return the number of loops generated by this loop transformation.
+ unsigned getNumGeneratedLoops() const { return NumGeneratedLoops; }
+
+ /// Get the de-sugared statements after the loop transformation.
+ ///
+ /// Might be nullptr if either the directive generates no loops and is handled
+ /// directly in CodeGen, or resolving a template-dependence context is
+ /// required.
+ Stmt *getTransformedStmt() const;
+
+ /// Return preinits statement.
+ Stmt *getPreInits() const;
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == OMPTileDirectiveClass ||
+ T->getStmtClass() == OMPUnrollDirectiveClass;
+ }
+};
+
/// This is a common base class for loop directives ('omp simd', 'omp
/// for', 'omp for simd' etc.). It is responsible for the loop code generation.
///
@@ -1024,7 +1082,7 @@ class OMPLoopDirective : public OMPLoopBasedDirective {
MutableArrayRef<Expr *> getCounters() {
auto **Storage = reinterpret_cast<Expr **>(
&Data->getChildren()[getArraysOffset(getDirectiveKind())]);
- return llvm::makeMutableArrayRef(Storage, getLoopsNumber());
+ return llvm::MutableArrayRef(Storage, getLoopsNumber());
}
/// Get the private counters storage.
@@ -1032,7 +1090,7 @@ class OMPLoopDirective : public OMPLoopBasedDirective {
auto **Storage = reinterpret_cast<Expr **>(
&Data->getChildren()[getArraysOffset(getDirectiveKind()) +
getLoopsNumber()]);
- return llvm::makeMutableArrayRef(Storage, getLoopsNumber());
+ return llvm::MutableArrayRef(Storage, getLoopsNumber());
}
/// Get the updates storage.
@@ -1040,7 +1098,7 @@ class OMPLoopDirective : public OMPLoopBasedDirective {
auto **Storage = reinterpret_cast<Expr **>(
&Data->getChildren()[getArraysOffset(getDirectiveKind()) +
2 * getLoopsNumber()]);
- return llvm::makeMutableArrayRef(Storage, getLoopsNumber());
+ return llvm::MutableArrayRef(Storage, getLoopsNumber());
}
/// Get the updates storage.
@@ -1048,7 +1106,7 @@ class OMPLoopDirective : public OMPLoopBasedDirective {
auto **Storage = reinterpret_cast<Expr **>(
&Data->getChildren()[getArraysOffset(getDirectiveKind()) +
3 * getLoopsNumber()]);
- return llvm::makeMutableArrayRef(Storage, getLoopsNumber());
+ return llvm::MutableArrayRef(Storage, getLoopsNumber());
}
/// Get the final counter updates storage.
@@ -1056,7 +1114,7 @@ class OMPLoopDirective : public OMPLoopBasedDirective {
auto **Storage = reinterpret_cast<Expr **>(
&Data->getChildren()[getArraysOffset(getDirectiveKind()) +
4 * getLoopsNumber()]);
- return llvm::makeMutableArrayRef(Storage, getLoopsNumber());
+ return llvm::MutableArrayRef(Storage, getLoopsNumber());
}
/// Get the dependent counters storage.
@@ -1064,7 +1122,7 @@ class OMPLoopDirective : public OMPLoopBasedDirective {
auto **Storage = reinterpret_cast<Expr **>(
&Data->getChildren()[getArraysOffset(getDirectiveKind()) +
5 * getLoopsNumber()]);
- return llvm::makeMutableArrayRef(Storage, getLoopsNumber());
+ return llvm::MutableArrayRef(Storage, getLoopsNumber());
}
/// Get the dependent inits storage.
@@ -1072,7 +1130,7 @@ class OMPLoopDirective : public OMPLoopBasedDirective {
auto **Storage = reinterpret_cast<Expr **>(
&Data->getChildren()[getArraysOffset(getDirectiveKind()) +
6 * getLoopsNumber()]);
- return llvm::makeMutableArrayRef(Storage, getLoopsNumber());
+ return llvm::MutableArrayRef(Storage, getLoopsNumber());
}
/// Get the finals conditions storage.
@@ -1080,7 +1138,7 @@ class OMPLoopDirective : public OMPLoopBasedDirective {
auto **Storage = reinterpret_cast<Expr **>(
&Data->getChildren()[getArraysOffset(getDirectiveKind()) +
7 * getLoopsNumber()]);
- return llvm::makeMutableArrayRef(Storage, getLoopsNumber());
+ return llvm::MutableArrayRef(Storage, getLoopsNumber());
}
protected:
@@ -1102,7 +1160,7 @@ protected:
if (isOpenMPLoopBoundSharingDirective(Kind))
return CombinedDistributeEnd;
if (isOpenMPWorksharingDirective(Kind) || isOpenMPTaskLoopDirective(Kind) ||
- isOpenMPDistributeDirective(Kind))
+ isOpenMPGenericLoopDirective(Kind) || isOpenMPDistributeDirective(Kind))
return WorksharingEnd;
return DefaultEnd;
}
@@ -1134,6 +1192,7 @@ protected:
}
void setIsLastIterVariable(Expr *IL) {
assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
+ isOpenMPGenericLoopDirective(getDirectiveKind()) ||
isOpenMPTaskLoopDirective(getDirectiveKind()) ||
isOpenMPDistributeDirective(getDirectiveKind())) &&
"expected worksharing loop directive");
@@ -1141,6 +1200,7 @@ protected:
}
void setLowerBoundVariable(Expr *LB) {
assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
+ isOpenMPGenericLoopDirective(getDirectiveKind()) ||
isOpenMPTaskLoopDirective(getDirectiveKind()) ||
isOpenMPDistributeDirective(getDirectiveKind())) &&
"expected worksharing loop directive");
@@ -1148,6 +1208,7 @@ protected:
}
void setUpperBoundVariable(Expr *UB) {
assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
+ isOpenMPGenericLoopDirective(getDirectiveKind()) ||
isOpenMPTaskLoopDirective(getDirectiveKind()) ||
isOpenMPDistributeDirective(getDirectiveKind())) &&
"expected worksharing loop directive");
@@ -1155,6 +1216,7 @@ protected:
}
void setStrideVariable(Expr *ST) {
assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
+ isOpenMPGenericLoopDirective(getDirectiveKind()) ||
isOpenMPTaskLoopDirective(getDirectiveKind()) ||
isOpenMPDistributeDirective(getDirectiveKind())) &&
"expected worksharing loop directive");
@@ -1162,6 +1224,7 @@ protected:
}
void setEnsureUpperBound(Expr *EUB) {
assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
+ isOpenMPGenericLoopDirective(getDirectiveKind()) ||
isOpenMPTaskLoopDirective(getDirectiveKind()) ||
isOpenMPDistributeDirective(getDirectiveKind())) &&
"expected worksharing loop directive");
@@ -1169,6 +1232,7 @@ protected:
}
void setNextLowerBound(Expr *NLB) {
assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
+ isOpenMPGenericLoopDirective(getDirectiveKind()) ||
isOpenMPTaskLoopDirective(getDirectiveKind()) ||
isOpenMPDistributeDirective(getDirectiveKind())) &&
"expected worksharing loop directive");
@@ -1176,6 +1240,7 @@ protected:
}
void setNextUpperBound(Expr *NUB) {
assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
+ isOpenMPGenericLoopDirective(getDirectiveKind()) ||
isOpenMPTaskLoopDirective(getDirectiveKind()) ||
isOpenMPDistributeDirective(getDirectiveKind())) &&
"expected worksharing loop directive");
@@ -1183,6 +1248,7 @@ protected:
}
void setNumIterations(Expr *NI) {
assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
+ isOpenMPGenericLoopDirective(getDirectiveKind()) ||
isOpenMPTaskLoopDirective(getDirectiveKind()) ||
isOpenMPDistributeDirective(getDirectiveKind())) &&
"expected worksharing loop directive");
@@ -1285,6 +1351,7 @@ public:
Stmt *getPreInits() { return Data->getChildren()[PreInitsOffset]; }
Expr *getIsLastIterVariable() const {
assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
+ isOpenMPGenericLoopDirective(getDirectiveKind()) ||
isOpenMPTaskLoopDirective(getDirectiveKind()) ||
isOpenMPDistributeDirective(getDirectiveKind())) &&
"expected worksharing loop directive");
@@ -1292,6 +1359,7 @@ public:
}
Expr *getLowerBoundVariable() const {
assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
+ isOpenMPGenericLoopDirective(getDirectiveKind()) ||
isOpenMPTaskLoopDirective(getDirectiveKind()) ||
isOpenMPDistributeDirective(getDirectiveKind())) &&
"expected worksharing loop directive");
@@ -1299,6 +1367,7 @@ public:
}
Expr *getUpperBoundVariable() const {
assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
+ isOpenMPGenericLoopDirective(getDirectiveKind()) ||
isOpenMPTaskLoopDirective(getDirectiveKind()) ||
isOpenMPDistributeDirective(getDirectiveKind())) &&
"expected worksharing loop directive");
@@ -1306,6 +1375,7 @@ public:
}
Expr *getStrideVariable() const {
assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
+ isOpenMPGenericLoopDirective(getDirectiveKind()) ||
isOpenMPTaskLoopDirective(getDirectiveKind()) ||
isOpenMPDistributeDirective(getDirectiveKind())) &&
"expected worksharing loop directive");
@@ -1313,6 +1383,7 @@ public:
}
Expr *getEnsureUpperBound() const {
assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
+ isOpenMPGenericLoopDirective(getDirectiveKind()) ||
isOpenMPTaskLoopDirective(getDirectiveKind()) ||
isOpenMPDistributeDirective(getDirectiveKind())) &&
"expected worksharing loop directive");
@@ -1320,6 +1391,7 @@ public:
}
Expr *getNextLowerBound() const {
assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
+ isOpenMPGenericLoopDirective(getDirectiveKind()) ||
isOpenMPTaskLoopDirective(getDirectiveKind()) ||
isOpenMPDistributeDirective(getDirectiveKind())) &&
"expected worksharing loop directive");
@@ -1327,6 +1399,7 @@ public:
}
Expr *getNextUpperBound() const {
assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
+ isOpenMPGenericLoopDirective(getDirectiveKind()) ||
isOpenMPTaskLoopDirective(getDirectiveKind()) ||
isOpenMPDistributeDirective(getDirectiveKind())) &&
"expected worksharing loop directive");
@@ -1334,6 +1407,7 @@ public:
}
Expr *getNumIterations() const {
assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
+ isOpenMPGenericLoopDirective(getDirectiveKind()) ||
isOpenMPTaskLoopDirective(getDirectiveKind()) ||
isOpenMPDistributeDirective(getDirectiveKind())) &&
"expected worksharing loop directive");
@@ -1465,8 +1539,17 @@ public:
T->getStmtClass() == OMPParallelForSimdDirectiveClass ||
T->getStmtClass() == OMPTaskLoopDirectiveClass ||
T->getStmtClass() == OMPTaskLoopSimdDirectiveClass ||
+ T->getStmtClass() == OMPMaskedTaskLoopDirectiveClass ||
+ T->getStmtClass() == OMPMaskedTaskLoopSimdDirectiveClass ||
T->getStmtClass() == OMPMasterTaskLoopDirectiveClass ||
T->getStmtClass() == OMPMasterTaskLoopSimdDirectiveClass ||
+ T->getStmtClass() == OMPGenericLoopDirectiveClass ||
+ T->getStmtClass() == OMPTeamsGenericLoopDirectiveClass ||
+ T->getStmtClass() == OMPTargetTeamsGenericLoopDirectiveClass ||
+ T->getStmtClass() == OMPParallelGenericLoopDirectiveClass ||
+ T->getStmtClass() == OMPTargetParallelGenericLoopDirectiveClass ||
+ T->getStmtClass() == OMPParallelMaskedTaskLoopDirectiveClass ||
+ T->getStmtClass() == OMPParallelMaskedTaskLoopSimdDirectiveClass ||
T->getStmtClass() == OMPParallelMasterTaskLoopDirectiveClass ||
T->getStmtClass() == OMPParallelMasterTaskLoopSimdDirectiveClass ||
T->getStmtClass() == OMPDistributeDirectiveClass ||
@@ -1536,7 +1619,8 @@ public:
SourceLocation EndLoc, unsigned CollapsedNum,
ArrayRef<OMPClause *> Clauses,
Stmt *AssociatedStmt,
- const HelperExprs &Exprs);
+ const HelperExprs &Exprs,
+ OpenMPDirectiveKind ParamPrevMappedDirective);
/// Creates an empty directive with the place
/// for \a NumClauses clauses.
@@ -1614,7 +1698,8 @@ public:
SourceLocation EndLoc, unsigned CollapsedNum,
ArrayRef<OMPClause *> Clauses,
Stmt *AssociatedStmt, const HelperExprs &Exprs,
- Expr *TaskRedRef, bool HasCancel);
+ Expr *TaskRedRef, bool HasCancel,
+ OpenMPDirectiveKind ParamPrevMappedDirective);
/// Creates an empty directive with the place
/// for \a NumClauses clauses.
@@ -1846,6 +1931,57 @@ public:
}
};
+/// This represents '#pragma omp scope' directive.
+/// \code
+/// #pragma omp scope private(a,b) nowait
+/// \endcode
+/// In this example directive '#pragma omp scope' has clauses 'private' with
+/// the variables 'a' and 'b' and nowait.
+///
+class OMPScopeDirective final : public OMPExecutableDirective {
+ friend class ASTStmtReader;
+ friend class OMPExecutableDirective;
+
+ /// Build directive with the given start and end location.
+ ///
+ /// \param StartLoc Starting location of the directive kind.
+ /// \param EndLoc Ending location of the directive.
+ ///
+ OMPScopeDirective(SourceLocation StartLoc, SourceLocation EndLoc)
+ : OMPExecutableDirective(OMPScopeDirectiveClass, llvm::omp::OMPD_scope,
+ StartLoc, EndLoc) {}
+
+ /// Build an empty directive.
+ ///
+ explicit OMPScopeDirective()
+ : OMPExecutableDirective(OMPScopeDirectiveClass, llvm::omp::OMPD_scope,
+ SourceLocation(), SourceLocation()) {}
+
+public:
+ /// Creates directive.
+ ///
+ /// \param C AST context.
+ /// \param StartLoc Starting location of the directive kind.
+ /// \param EndLoc Ending Location of the directive.
+ /// \param AssociatedStmt Statement, associated with the directive.
+ ///
+ static OMPScopeDirective *Create(const ASTContext &C, SourceLocation StartLoc,
+ SourceLocation EndLoc,
+ ArrayRef<OMPClause *> Clauses,
+ Stmt *AssociatedStmt);
+
+ /// Creates an empty directive.
+ ///
+ /// \param C AST context.
+ ///
+ static OMPScopeDirective *CreateEmpty(const ASTContext &C,
+ unsigned NumClauses, EmptyShell);
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == OMPScopeDirectiveClass;
+ }
+};
+
/// This represents '#pragma omp single' directive.
///
/// \code
@@ -2241,6 +2377,69 @@ public:
}
};
+/// This represents '#pragma omp parallel masked' directive.
+///
+/// \code
+/// #pragma omp parallel masked filter(tid)
+/// \endcode
+/// In this example directive '#pragma omp parallel masked' has a clause
+/// 'filter' with the variable tid
+///
+class OMPParallelMaskedDirective final : public OMPExecutableDirective {
+ friend class ASTStmtReader;
+ friend class OMPExecutableDirective;
+
+ OMPParallelMaskedDirective(SourceLocation StartLoc, SourceLocation EndLoc)
+ : OMPExecutableDirective(OMPParallelMaskedDirectiveClass,
+ llvm::omp::OMPD_parallel_masked, StartLoc,
+ EndLoc) {}
+
+ explicit OMPParallelMaskedDirective()
+ : OMPExecutableDirective(OMPParallelMaskedDirectiveClass,
+ llvm::omp::OMPD_parallel_masked,
+ SourceLocation(), SourceLocation()) {}
+
+ /// Sets special task reduction descriptor.
+ void setTaskReductionRefExpr(Expr *E) { Data->getChildren()[0] = E; }
+
+public:
+ /// Creates directive with a list of \a Clauses.
+ ///
+ /// \param C AST context.
+ /// \param StartLoc Starting location of the directive kind.
+ /// \param EndLoc Ending Location of the directive.
+ /// \param Clauses List of clauses.
+ /// \param AssociatedStmt Statement, associated with the directive.
+ /// \param TaskRedRef Task reduction special reference expression to handle
+ /// taskgroup descriptor.
+ ///
+ static OMPParallelMaskedDirective *
+ Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
+ ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, Expr *TaskRedRef);
+
+ /// Creates an empty directive with the place for \a NumClauses
+ /// clauses.
+ ///
+ /// \param C AST context.
+ /// \param NumClauses Number of clauses.
+ ///
+ static OMPParallelMaskedDirective *
+ CreateEmpty(const ASTContext &C, unsigned NumClauses, EmptyShell);
+
+ /// Returns special task reduction reference expression.
+ Expr *getTaskReductionRefExpr() {
+ return cast_or_null<Expr>(Data->getChildren()[0]);
+ }
+ const Expr *getTaskReductionRefExpr() const {
+ return const_cast<OMPParallelMaskedDirective *>(this)
+ ->getTaskReductionRefExpr();
+ }
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == OMPParallelMaskedDirectiveClass;
+ }
+};
+
/// This represents '#pragma omp parallel sections' directive.
///
/// \code
@@ -2510,15 +2709,20 @@ public:
/// \param C AST context.
/// \param StartLoc Starting location of the directive kind.
/// \param EndLoc Ending Location of the directive.
+ /// \param Clauses List of clauses.
///
- static OMPTaskwaitDirective *
- Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc);
+ static OMPTaskwaitDirective *Create(const ASTContext &C,
+ SourceLocation StartLoc,
+ SourceLocation EndLoc,
+ ArrayRef<OMPClause *> Clauses);
/// Creates an empty directive.
///
/// \param C AST context.
+ /// \param NumClauses Number of clauses.
///
- static OMPTaskwaitDirective *CreateEmpty(const ASTContext &C, EmptyShell);
+ static OMPTaskwaitDirective *CreateEmpty(const ASTContext &C,
+ unsigned NumClauses, EmptyShell);
static bool classof(const Stmt *T) {
return T->getStmtClass() == OMPTaskwaitDirectiveClass;
@@ -2738,7 +2942,7 @@ public:
///
/// \param C AST context.
/// \param NumClauses Number of clauses.
- /// \param IsStandalone true, if the the standalone directive is created.
+ /// \param IsStandalone true, if the standalone directive is created.
///
static OMPOrderedDirective *CreateEmpty(const ASTContext &C,
unsigned NumClauses,
@@ -2759,25 +2963,31 @@ public:
class OMPAtomicDirective : public OMPExecutableDirective {
friend class ASTStmtReader;
friend class OMPExecutableDirective;
- /// Used for 'atomic update' or 'atomic capture' constructs. They may
- /// have atomic expressions of forms
- /// \code
- /// x = x binop expr;
- /// x = expr binop x;
- /// \endcode
- /// This field is true for the first form of the expression and false for the
- /// second. Required for correct codegen of non-associative operations (like
- /// << or >>).
- bool IsXLHSInRHSPart = false;
- /// Used for 'atomic update' or 'atomic capture' constructs. They may
- /// have atomic expressions of forms
- /// \code
- /// v = x; <update x>;
- /// <update x>; v = x;
- /// \endcode
- /// This field is true for the first(postfix) form of the expression and false
- /// otherwise.
- bool IsPostfixUpdate = false;
+
+ struct FlagTy {
+ /// Used for 'atomic update' or 'atomic capture' constructs. They may
+ /// have atomic expressions of forms:
+ /// \code
+ /// x = x binop expr;
+ /// x = expr binop x;
+ /// \endcode
+ /// This field is 1 for the first form of the expression and 0 for the
+ /// second. Required for correct codegen of non-associative operations (like
+ /// << or >>).
+ uint8_t IsXLHSInRHSPart : 1;
+ /// Used for 'atomic update' or 'atomic capture' constructs. They may
+ /// have atomic expressions of forms:
+ /// \code
+ /// v = x; <update x>;
+ /// <update x>; v = x;
+ /// \endcode
+ /// This field is 1 for the first(postfix) form of the expression and 0
+ /// otherwise.
+ uint8_t IsPostfixUpdate : 1;
+ /// 1 if 'v' is updated only when the condition is false (compare capture
+ /// only).
+ uint8_t IsFailOnly : 1;
+ } Flags;
/// Build directive with the given start and end location.
///
@@ -2794,18 +3004,62 @@ class OMPAtomicDirective : public OMPExecutableDirective {
: OMPExecutableDirective(OMPAtomicDirectiveClass, llvm::omp::OMPD_atomic,
SourceLocation(), SourceLocation()) {}
+ enum DataPositionTy : size_t {
+ POS_X = 0,
+ POS_V,
+ POS_E,
+ POS_UpdateExpr,
+ POS_D,
+ POS_Cond,
+ POS_R,
+ };
+
/// Set 'x' part of the associated expression/statement.
- void setX(Expr *X) { Data->getChildren()[0] = X; }
+ void setX(Expr *X) { Data->getChildren()[DataPositionTy::POS_X] = X; }
/// Set helper expression of the form
/// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
/// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
- void setUpdateExpr(Expr *UE) { Data->getChildren()[1] = UE; }
+ void setUpdateExpr(Expr *UE) {
+ Data->getChildren()[DataPositionTy::POS_UpdateExpr] = UE;
+ }
/// Set 'v' part of the associated expression/statement.
- void setV(Expr *V) { Data->getChildren()[2] = V; }
+ void setV(Expr *V) { Data->getChildren()[DataPositionTy::POS_V] = V; }
+ /// Set 'r' part of the associated expression/statement.
+ void setR(Expr *R) { Data->getChildren()[DataPositionTy::POS_R] = R; }
/// Set 'expr' part of the associated expression/statement.
- void setExpr(Expr *E) { Data->getChildren()[3] = E; }
+ void setExpr(Expr *E) { Data->getChildren()[DataPositionTy::POS_E] = E; }
+ /// Set 'd' part of the associated expression/statement.
+ void setD(Expr *D) { Data->getChildren()[DataPositionTy::POS_D] = D; }
+ /// Set conditional expression in `atomic compare`.
+ void setCond(Expr *C) { Data->getChildren()[DataPositionTy::POS_Cond] = C; }
public:
+ struct Expressions {
+ /// 'x' part of the associated expression/statement.
+ Expr *X = nullptr;
+ /// 'v' part of the associated expression/statement.
+ Expr *V = nullptr;
+ // 'r' part of the associated expression/statement.
+ Expr *R = nullptr;
+ /// 'expr' part of the associated expression/statement.
+ Expr *E = nullptr;
+ /// UE Helper expression of the form:
+ /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
+ /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
+ Expr *UE = nullptr;
+ /// 'd' part of the associated expression/statement.
+ Expr *D = nullptr;
+ /// Conditional expression in `atomic compare` construct.
+ Expr *Cond = nullptr;
+ /// True if UE has the first form and false if the second.
+ bool IsXLHSInRHSPart;
+ /// True if original value of 'x' must be stored in 'v', not an updated one.
+ bool IsPostfixUpdate;
+ /// True if 'v' is updated only when the condition is false (compare capture
+ /// only).
+ bool IsFailOnly;
+ };
+
/// Creates directive with a list of \a Clauses and 'x', 'v' and 'expr'
/// parts of the atomic construct (see Section 2.12.6, atomic Construct, for
/// detailed description of 'x', 'v' and 'expr').
@@ -2815,20 +3069,12 @@ public:
/// \param EndLoc Ending Location of the directive.
/// \param Clauses List of clauses.
/// \param AssociatedStmt Statement, associated with the directive.
- /// \param X 'x' part of the associated expression/statement.
- /// \param V 'v' part of the associated expression/statement.
- /// \param E 'expr' part of the associated expression/statement.
- /// \param UE Helper expression of the form
- /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
- /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
- /// \param IsXLHSInRHSPart true if \a UE has the first form and false if the
- /// second.
- /// \param IsPostfixUpdate true if original value of 'x' must be stored in
- /// 'v', not an updated one.
- static OMPAtomicDirective *
- Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
- ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, Expr *X, Expr *V,
- Expr *E, Expr *UE, bool IsXLHSInRHSPart, bool IsPostfixUpdate);
+ /// \param Exprs Associated expressions or statements.
+ static OMPAtomicDirective *Create(const ASTContext &C,
+ SourceLocation StartLoc,
+ SourceLocation EndLoc,
+ ArrayRef<OMPClause *> Clauses,
+ Stmt *AssociatedStmt, Expressions Exprs);
/// Creates an empty directive with the place for \a NumClauses
/// clauses.
@@ -2840,33 +3086,67 @@ public:
unsigned NumClauses, EmptyShell);
/// Get 'x' part of the associated expression/statement.
- Expr *getX() { return cast_or_null<Expr>(Data->getChildren()[0]); }
+ Expr *getX() {
+ return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_X]);
+ }
const Expr *getX() const {
- return cast_or_null<Expr>(Data->getChildren()[0]);
+ return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_X]);
}
/// Get helper expression of the form
/// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
/// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
- Expr *getUpdateExpr() { return cast_or_null<Expr>(Data->getChildren()[1]); }
+ Expr *getUpdateExpr() {
+ return cast_or_null<Expr>(
+ Data->getChildren()[DataPositionTy::POS_UpdateExpr]);
+ }
const Expr *getUpdateExpr() const {
- return cast_or_null<Expr>(Data->getChildren()[1]);
+ return cast_or_null<Expr>(
+ Data->getChildren()[DataPositionTy::POS_UpdateExpr]);
}
/// Return true if helper update expression has form
/// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' and false if it has form
/// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
- bool isXLHSInRHSPart() const { return IsXLHSInRHSPart; }
+ bool isXLHSInRHSPart() const { return Flags.IsXLHSInRHSPart; }
/// Return true if 'v' expression must be updated to original value of
/// 'x', false if 'v' must be updated to the new value of 'x'.
- bool isPostfixUpdate() const { return IsPostfixUpdate; }
+ bool isPostfixUpdate() const { return Flags.IsPostfixUpdate; }
+ /// Return true if 'v' is updated only when the condition is evaluated false
+ /// (compare capture only).
+ bool isFailOnly() const { return Flags.IsFailOnly; }
/// Get 'v' part of the associated expression/statement.
- Expr *getV() { return cast_or_null<Expr>(Data->getChildren()[2]); }
+ Expr *getV() {
+ return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_V]);
+ }
const Expr *getV() const {
- return cast_or_null<Expr>(Data->getChildren()[2]);
+ return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_V]);
+ }
+ /// Get 'r' part of the associated expression/statement.
+ Expr *getR() {
+ return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_R]);
+ }
+ const Expr *getR() const {
+ return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_R]);
}
/// Get 'expr' part of the associated expression/statement.
- Expr *getExpr() { return cast_or_null<Expr>(Data->getChildren()[3]); }
+ Expr *getExpr() {
+ return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_E]);
+ }
const Expr *getExpr() const {
- return cast_or_null<Expr>(Data->getChildren()[3]);
+ return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_E]);
+ }
+ /// Get 'd' part of the associated expression/statement.
+ Expr *getD() {
+ return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_D]);
+ }
+ Expr *getD() const {
+ return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_D]);
+ }
+ /// Get the 'cond' part of the source atomic expression.
+ Expr *getCondExpr() {
+ return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_Cond]);
+ }
+ Expr *getCondExpr() const {
+ return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_Cond]);
}
static bool classof(const Stmt *T) {
@@ -3651,6 +3931,82 @@ public:
}
};
+/// This represents '#pragma omp masked taskloop' directive.
+///
+/// \code
+/// #pragma omp masked taskloop private(a,b) grainsize(val) num_tasks(num)
+/// \endcode
+/// In this example directive '#pragma omp masked taskloop' has clauses
+/// 'private' with the variables 'a' and 'b', 'grainsize' with expression 'val'
+/// and 'num_tasks' with expression 'num'.
+///
+class OMPMaskedTaskLoopDirective final : public OMPLoopDirective {
+ friend class ASTStmtReader;
+ friend class OMPExecutableDirective;
+ /// true if the construct has inner cancel directive.
+ bool HasCancel = false;
+
+ /// Build directive with the given start and end location.
+ ///
+ /// \param StartLoc Starting location of the directive kind.
+ /// \param EndLoc Ending location of the directive.
+ /// \param CollapsedNum Number of collapsed nested loops.
+ ///
+ OMPMaskedTaskLoopDirective(SourceLocation StartLoc, SourceLocation EndLoc,
+ unsigned CollapsedNum)
+ : OMPLoopDirective(OMPMaskedTaskLoopDirectiveClass,
+ llvm::omp::OMPD_masked_taskloop, StartLoc, EndLoc,
+ CollapsedNum) {}
+
+ /// Build an empty directive.
+ ///
+ /// \param CollapsedNum Number of collapsed nested loops.
+ ///
+ explicit OMPMaskedTaskLoopDirective(unsigned CollapsedNum)
+ : OMPLoopDirective(OMPMaskedTaskLoopDirectiveClass,
+ llvm::omp::OMPD_masked_taskloop, SourceLocation(),
+ SourceLocation(), CollapsedNum) {}
+
+ /// Set cancel state.
+ void setHasCancel(bool Has) { HasCancel = Has; }
+
+public:
+ /// Creates directive with a list of \a Clauses.
+ ///
+ /// \param C AST context.
+ /// \param StartLoc Starting location of the directive kind.
+ /// \param EndLoc Ending Location of the directive.
+ /// \param CollapsedNum Number of collapsed loops.
+ /// \param Clauses List of clauses.
+ /// \param AssociatedStmt Statement, associated with the directive.
+ /// \param Exprs Helper expressions for CodeGen.
+ /// \param HasCancel true if this directive has inner cancel directive.
+ ///
+ static OMPMaskedTaskLoopDirective *
+ Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
+ unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
+ Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel);
+
+ /// Creates an empty directive with the place
+ /// for \a NumClauses clauses.
+ ///
+ /// \param C AST context.
+ /// \param CollapsedNum Number of collapsed nested loops.
+ /// \param NumClauses Number of clauses.
+ ///
+ static OMPMaskedTaskLoopDirective *CreateEmpty(const ASTContext &C,
+ unsigned NumClauses,
+ unsigned CollapsedNum,
+ EmptyShell);
+
+ /// Return true if current directive has inner cancel directive.
+ bool hasCancel() const { return HasCancel; }
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == OMPMaskedTaskLoopDirectiveClass;
+ }
+};
+
/// This represents '#pragma omp master taskloop simd' directive.
///
/// \code
@@ -3716,6 +4072,71 @@ public:
}
};
+/// This represents '#pragma omp masked taskloop simd' directive.
+///
+/// \code
+/// #pragma omp masked taskloop simd private(a,b) grainsize(val) num_tasks(num)
+/// \endcode
+/// In this example directive '#pragma omp masked taskloop simd' has clauses
+/// 'private' with the variables 'a' and 'b', 'grainsize' with expression 'val'
+/// and 'num_tasks' with expression 'num'.
+///
+class OMPMaskedTaskLoopSimdDirective final : public OMPLoopDirective {
+ friend class ASTStmtReader;
+ friend class OMPExecutableDirective;
+ /// Build directive with the given start and end location.
+ ///
+ /// \param StartLoc Starting location of the directive kind.
+ /// \param EndLoc Ending location of the directive.
+ /// \param CollapsedNum Number of collapsed nested loops.
+ ///
+ OMPMaskedTaskLoopSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc,
+ unsigned CollapsedNum)
+ : OMPLoopDirective(OMPMaskedTaskLoopSimdDirectiveClass,
+ llvm::omp::OMPD_masked_taskloop_simd, StartLoc, EndLoc,
+ CollapsedNum) {}
+
+ /// Build an empty directive.
+ ///
+ /// \param CollapsedNum Number of collapsed nested loops.
+ ///
+ explicit OMPMaskedTaskLoopSimdDirective(unsigned CollapsedNum)
+ : OMPLoopDirective(OMPMaskedTaskLoopSimdDirectiveClass,
+ llvm::omp::OMPD_masked_taskloop_simd, SourceLocation(),
+ SourceLocation(), CollapsedNum) {}
+
+public:
+ /// Creates directive with a list of \p Clauses.
+ ///
+ /// \param C AST context.
+ /// \param StartLoc Starting location of the directive kind.
+ /// \param EndLoc Ending Location of the directive.
+ /// \param CollapsedNum Number of collapsed loops.
+ /// \param Clauses List of clauses.
+ /// \param AssociatedStmt Statement, associated with the directive.
+ /// \param Exprs Helper expressions for CodeGen.
+ ///
+ static OMPMaskedTaskLoopSimdDirective *
+ Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
+ unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
+ Stmt *AssociatedStmt, const HelperExprs &Exprs);
+
+ /// Creates an empty directive with the place for \p NumClauses clauses.
+ ///
+ /// \param C AST context.
+ /// \param CollapsedNum Number of collapsed nested loops.
+ /// \param NumClauses Number of clauses.
+ ///
+ static OMPMaskedTaskLoopSimdDirective *CreateEmpty(const ASTContext &C,
+ unsigned NumClauses,
+ unsigned CollapsedNum,
+ EmptyShell);
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == OMPMaskedTaskLoopSimdDirectiveClass;
+ }
+};
+
/// This represents '#pragma omp parallel master taskloop' directive.
///
/// \code
@@ -3794,6 +4215,84 @@ public:
}
};
+/// This represents '#pragma omp parallel masked taskloop' directive.
+///
+/// \code
+/// #pragma omp parallel masked taskloop private(a,b) grainsize(val)
+/// num_tasks(num)
+/// \endcode
+/// In this example directive '#pragma omp parallel masked taskloop' has clauses
+/// 'private' with the variables 'a' and 'b', 'grainsize' with expression 'val'
+/// and 'num_tasks' with expression 'num'.
+///
+class OMPParallelMaskedTaskLoopDirective final : public OMPLoopDirective {
+ friend class ASTStmtReader;
+ friend class OMPExecutableDirective;
+ /// true if the construct has inner cancel directive.
+ bool HasCancel = false;
+
+ /// Build directive with the given start and end location.
+ ///
+ /// \param StartLoc Starting location of the directive kind.
+ /// \param EndLoc Ending location of the directive.
+ /// \param CollapsedNum Number of collapsed nested loops.
+ ///
+ OMPParallelMaskedTaskLoopDirective(SourceLocation StartLoc,
+ SourceLocation EndLoc,
+ unsigned CollapsedNum)
+ : OMPLoopDirective(OMPParallelMaskedTaskLoopDirectiveClass,
+ llvm::omp::OMPD_parallel_masked_taskloop, StartLoc,
+ EndLoc, CollapsedNum) {}
+
+ /// Build an empty directive.
+ ///
+ /// \param CollapsedNum Number of collapsed nested loops.
+ ///
+ explicit OMPParallelMaskedTaskLoopDirective(unsigned CollapsedNum)
+ : OMPLoopDirective(OMPParallelMaskedTaskLoopDirectiveClass,
+ llvm::omp::OMPD_parallel_masked_taskloop,
+ SourceLocation(), SourceLocation(), CollapsedNum) {}
+
+ /// Set cancel state.
+ void setHasCancel(bool Has) { HasCancel = Has; }
+
+public:
+ /// Creates directive with a list of \a Clauses.
+ ///
+ /// \param C AST context.
+ /// \param StartLoc Starting location of the directive kind.
+ /// \param EndLoc Ending Location of the directive.
+ /// \param CollapsedNum Number of collapsed loops.
+ /// \param Clauses List of clauses.
+ /// \param AssociatedStmt Statement, associated with the directive.
+ /// \param Exprs Helper expressions for CodeGen.
+ /// \param HasCancel true if this directive has inner cancel directive.
+ ///
+ static OMPParallelMaskedTaskLoopDirective *
+ Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
+ unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
+ Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel);
+
+ /// Creates an empty directive with the place
+ /// for \a NumClauses clauses.
+ ///
+ /// \param C AST context.
+ /// \param CollapsedNum Number of collapsed nested loops.
+ /// \param NumClauses Number of clauses.
+ ///
+ static OMPParallelMaskedTaskLoopDirective *CreateEmpty(const ASTContext &C,
+ unsigned NumClauses,
+ unsigned CollapsedNum,
+ EmptyShell);
+
+ /// Return true if current directive has inner cancel directive.
+ bool hasCancel() const { return HasCancel; }
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == OMPParallelMaskedTaskLoopDirectiveClass;
+ }
+};
+
/// This represents '#pragma omp parallel master taskloop simd' directive.
///
/// \code
@@ -3861,6 +4360,73 @@ public:
}
};
+/// This represents '#pragma omp parallel masked taskloop simd' directive.
+///
+/// \code
+/// #pragma omp parallel masked taskloop simd private(a,b) grainsize(val)
+/// num_tasks(num)
+/// \endcode
+/// In this example directive '#pragma omp parallel masked taskloop simd' has
+/// clauses 'private' with the variables 'a' and 'b', 'grainsize' with
+/// expression 'val' and 'num_tasks' with expression 'num'.
+///
+class OMPParallelMaskedTaskLoopSimdDirective final : public OMPLoopDirective {
+ friend class ASTStmtReader;
+ friend class OMPExecutableDirective;
+ /// Build directive with the given start and end location.
+ ///
+ /// \param StartLoc Starting location of the directive kind.
+ /// \param EndLoc Ending location of the directive.
+ /// \param CollapsedNum Number of collapsed nested loops.
+ ///
+ OMPParallelMaskedTaskLoopSimdDirective(SourceLocation StartLoc,
+ SourceLocation EndLoc,
+ unsigned CollapsedNum)
+ : OMPLoopDirective(OMPParallelMaskedTaskLoopSimdDirectiveClass,
+ llvm::omp::OMPD_parallel_masked_taskloop_simd,
+ StartLoc, EndLoc, CollapsedNum) {}
+
+ /// Build an empty directive.
+ ///
+ /// \param CollapsedNum Number of collapsed nested loops.
+ ///
+ explicit OMPParallelMaskedTaskLoopSimdDirective(unsigned CollapsedNum)
+ : OMPLoopDirective(OMPParallelMaskedTaskLoopSimdDirectiveClass,
+ llvm::omp::OMPD_parallel_masked_taskloop_simd,
+ SourceLocation(), SourceLocation(), CollapsedNum) {}
+
+public:
+ /// Creates directive with a list of \p Clauses.
+ ///
+ /// \param C AST context.
+ /// \param StartLoc Starting location of the directive kind.
+ /// \param EndLoc Ending Location of the directive.
+ /// \param CollapsedNum Number of collapsed loops.
+ /// \param Clauses List of clauses.
+ /// \param AssociatedStmt Statement, associated with the directive.
+ /// \param Exprs Helper expressions for CodeGen.
+ ///
+ static OMPParallelMaskedTaskLoopSimdDirective *
+ Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
+ unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
+ Stmt *AssociatedStmt, const HelperExprs &Exprs);
+
+ /// Creates an empty directive with the place
+ /// for \a NumClauses clauses.
+ ///
+ /// \param C AST context.
+ /// \param CollapsedNum Number of collapsed nested loops.
+ /// \param NumClauses Number of clauses.
+ ///
+ static OMPParallelMaskedTaskLoopSimdDirective *
+ CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum,
+ EmptyShell);
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == OMPParallelMaskedTaskLoopSimdDirectiveClass;
+ }
+};
+
/// This represents '#pragma omp distribute' directive.
///
/// \code
@@ -3908,7 +4474,8 @@ public:
static OMPDistributeDirective *
Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
- Stmt *AssociatedStmt, const HelperExprs &Exprs);
+ Stmt *AssociatedStmt, const HelperExprs &Exprs,
+ OpenMPDirectiveKind ParamPrevMappedDirective);
/// Creates an empty directive with the place
/// for \a NumClauses clauses.
@@ -4992,7 +5559,7 @@ public:
};
/// This represents the '#pragma omp tile' loop transformation directive.
-class OMPTileDirective final : public OMPLoopBasedDirective {
+class OMPTileDirective final : public OMPLoopTransformationDirective {
friend class ASTStmtReader;
friend class OMPExecutableDirective;
@@ -5004,8 +5571,11 @@ class OMPTileDirective final : public OMPLoopBasedDirective {
explicit OMPTileDirective(SourceLocation StartLoc, SourceLocation EndLoc,
unsigned NumLoops)
- : OMPLoopBasedDirective(OMPTileDirectiveClass, llvm::omp::OMPD_tile,
- StartLoc, EndLoc, NumLoops) {}
+ : OMPLoopTransformationDirective(OMPTileDirectiveClass,
+ llvm::omp::OMPD_tile, StartLoc, EndLoc,
+ NumLoops) {
+ setNumGeneratedLoops(3 * NumLoops);
+ }
void setPreInits(Stmt *PreInits) {
Data->getChildren()[PreInitsOffset] = PreInits;
@@ -5042,8 +5612,6 @@ public:
static OMPTileDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses,
unsigned NumLoops);
- unsigned getNumAssociatedLoops() const { return getLoopsNumber(); }
-
/// Gets/sets the associated loops after tiling.
///
/// This is in de-sugared format stored as a CompoundStmt.
@@ -5073,7 +5641,7 @@ public:
/// #pragma omp unroll
/// for (int i = 0; i < 64; ++i)
/// \endcode
-class OMPUnrollDirective final : public OMPLoopBasedDirective {
+class OMPUnrollDirective final : public OMPLoopTransformationDirective {
friend class ASTStmtReader;
friend class OMPExecutableDirective;
@@ -5084,8 +5652,9 @@ class OMPUnrollDirective final : public OMPLoopBasedDirective {
};
explicit OMPUnrollDirective(SourceLocation StartLoc, SourceLocation EndLoc)
- : OMPLoopBasedDirective(OMPUnrollDirectiveClass, llvm::omp::OMPD_unroll,
- StartLoc, EndLoc, 1) {}
+ : OMPLoopTransformationDirective(OMPUnrollDirectiveClass,
+ llvm::omp::OMPD_unroll, StartLoc, EndLoc,
+ 1) {}
/// Set the pre-init statements.
void setPreInits(Stmt *PreInits) {
@@ -5111,7 +5680,7 @@ public:
static OMPUnrollDirective *
Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt,
- Stmt *TransformedStmt, Stmt *PreInits);
+ unsigned NumGeneratedLoops, Stmt *TransformedStmt, Stmt *PreInits);
/// Build an empty '#pragma omp unroll' AST node for deserialization.
///
@@ -5360,6 +5929,412 @@ public:
}
};
+/// This represents '#pragma omp metadirective' directive.
+///
+/// \code
+/// #pragma omp metadirective when(user={condition(N>10)}: parallel for)
+/// \endcode
+/// In this example directive '#pragma omp metadirective' has clauses 'when'
+/// with a dynamic user condition to check if a variable 'N > 10'
+///
+class OMPMetaDirective final : public OMPExecutableDirective {
+ friend class ASTStmtReader;
+ friend class OMPExecutableDirective;
+ Stmt *IfStmt;
+
+ OMPMetaDirective(SourceLocation StartLoc, SourceLocation EndLoc)
+ : OMPExecutableDirective(OMPMetaDirectiveClass,
+ llvm::omp::OMPD_metadirective, StartLoc,
+ EndLoc) {}
+ explicit OMPMetaDirective()
+ : OMPExecutableDirective(OMPMetaDirectiveClass,
+ llvm::omp::OMPD_metadirective, SourceLocation(),
+ SourceLocation()) {}
+
+ void setIfStmt(Stmt *S) { IfStmt = S; }
+
+public:
+ static OMPMetaDirective *Create(const ASTContext &C, SourceLocation StartLoc,
+ SourceLocation EndLoc,
+ ArrayRef<OMPClause *> Clauses,
+ Stmt *AssociatedStmt, Stmt *IfStmt);
+ static OMPMetaDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses,
+ EmptyShell);
+ Stmt *getIfStmt() const { return IfStmt; }
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == OMPMetaDirectiveClass;
+ }
+};
+
+/// This represents '#pragma omp loop' directive.
+///
+/// \code
+/// #pragma omp loop private(a,b) binding(parallel) order(concurrent)
+/// \endcode
+/// In this example directive '#pragma omp loop' has
+/// clauses 'private' with the variables 'a' and 'b', 'binding' with
+/// modifier 'parallel' and 'order(concurrent).
+///
+class OMPGenericLoopDirective final : public OMPLoopDirective {
+ friend class ASTStmtReader;
+ friend class OMPExecutableDirective;
+ /// Build directive with the given start and end location.
+ ///
+ /// \param StartLoc Starting location of the directive kind.
+ /// \param EndLoc Ending location of the directive.
+ /// \param CollapsedNum Number of collapsed nested loops.
+ ///
+ OMPGenericLoopDirective(SourceLocation StartLoc, SourceLocation EndLoc,
+ unsigned CollapsedNum)
+ : OMPLoopDirective(OMPGenericLoopDirectiveClass, llvm::omp::OMPD_loop,
+ StartLoc, EndLoc, CollapsedNum) {}
+
+ /// Build an empty directive.
+ ///
+ /// \param CollapsedNum Number of collapsed nested loops.
+ ///
+ explicit OMPGenericLoopDirective(unsigned CollapsedNum)
+ : OMPLoopDirective(OMPGenericLoopDirectiveClass, llvm::omp::OMPD_loop,
+ SourceLocation(), SourceLocation(), CollapsedNum) {}
+
+public:
+ /// Creates directive with a list of \p Clauses.
+ ///
+ /// \param C AST context.
+ /// \param StartLoc Starting location of the directive kind.
+ /// \param EndLoc Ending Location of the directive.
+ /// \param CollapsedNum Number of collapsed loops.
+ /// \param Clauses List of clauses.
+ /// \param AssociatedStmt Statement, associated with the directive.
+ /// \param Exprs Helper expressions for CodeGen.
+ ///
+ static OMPGenericLoopDirective *
+ Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
+ unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
+ Stmt *AssociatedStmt, const HelperExprs &Exprs);
+
+ /// Creates an empty directive with a place for \a NumClauses clauses.
+ ///
+ /// \param C AST context.
+ /// \param NumClauses Number of clauses.
+ /// \param CollapsedNum Number of collapsed nested loops.
+ ///
+ static OMPGenericLoopDirective *CreateEmpty(const ASTContext &C,
+ unsigned NumClauses,
+ unsigned CollapsedNum,
+ EmptyShell);
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == OMPGenericLoopDirectiveClass;
+ }
+};
+
+/// This represents '#pragma omp teams loop' directive.
+///
+/// \code
+/// #pragma omp teams loop private(a,b) order(concurrent)
+/// \endcode
+/// In this example directive '#pragma omp teams loop' has
+/// clauses 'private' with the variables 'a' and 'b', and order(concurrent).
+///
+class OMPTeamsGenericLoopDirective final : public OMPLoopDirective {
+ friend class ASTStmtReader;
+ friend class OMPExecutableDirective;
+ /// Build directive with the given start and end location.
+ ///
+ /// \param StartLoc Starting location of the directive kind.
+ /// \param EndLoc Ending location of the directive.
+ /// \param CollapsedNum Number of collapsed nested loops.
+ ///
+ OMPTeamsGenericLoopDirective(SourceLocation StartLoc, SourceLocation EndLoc,
+ unsigned CollapsedNum)
+ : OMPLoopDirective(OMPTeamsGenericLoopDirectiveClass,
+ llvm::omp::OMPD_teams_loop, StartLoc, EndLoc,
+ CollapsedNum) {}
+
+ /// Build an empty directive.
+ ///
+ /// \param CollapsedNum Number of collapsed nested loops.
+ ///
+ explicit OMPTeamsGenericLoopDirective(unsigned CollapsedNum)
+ : OMPLoopDirective(OMPTeamsGenericLoopDirectiveClass,
+ llvm::omp::OMPD_teams_loop, SourceLocation(),
+ SourceLocation(), CollapsedNum) {}
+
+public:
+ /// Creates directive with a list of \p Clauses.
+ ///
+ /// \param C AST context.
+ /// \param StartLoc Starting location of the directive kind.
+ /// \param EndLoc Ending Location of the directive.
+ /// \param CollapsedNum Number of collapsed loops.
+ /// \param Clauses List of clauses.
+ /// \param AssociatedStmt Statement, associated with the directive.
+ /// \param Exprs Helper expressions for CodeGen.
+ ///
+ static OMPTeamsGenericLoopDirective *
+ Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
+ unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
+ Stmt *AssociatedStmt, const HelperExprs &Exprs);
+
+ /// Creates an empty directive with the place
+ /// for \a NumClauses clauses.
+ ///
+ /// \param C AST context.
+ /// \param CollapsedNum Number of collapsed nested loops.
+ /// \param NumClauses Number of clauses.
+ ///
+ static OMPTeamsGenericLoopDirective *CreateEmpty(const ASTContext &C,
+ unsigned NumClauses,
+ unsigned CollapsedNum,
+ EmptyShell);
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == OMPTeamsGenericLoopDirectiveClass;
+ }
+};
+
+/// This represents '#pragma omp target teams loop' directive.
+///
+/// \code
+/// #pragma omp target teams loop private(a,b) order(concurrent)
+/// \endcode
+/// In this example directive '#pragma omp target teams loop' has
+/// clauses 'private' with the variables 'a' and 'b', and order(concurrent).
+///
+class OMPTargetTeamsGenericLoopDirective final : public OMPLoopDirective {
+ friend class ASTStmtReader;
+ friend class OMPExecutableDirective;
+ /// Build directive with the given start and end location.
+ ///
+ /// \param StartLoc Starting location of the directive kind.
+ /// \param EndLoc Ending location of the directive.
+ /// \param CollapsedNum Number of collapsed nested loops.
+ ///
+ OMPTargetTeamsGenericLoopDirective(SourceLocation StartLoc,
+ SourceLocation EndLoc,
+ unsigned CollapsedNum)
+ : OMPLoopDirective(OMPTargetTeamsGenericLoopDirectiveClass,
+ llvm::omp::OMPD_target_teams_loop, StartLoc, EndLoc,
+ CollapsedNum) {}
+
+ /// Build an empty directive.
+ ///
+ /// \param CollapsedNum Number of collapsed nested loops.
+ ///
+ explicit OMPTargetTeamsGenericLoopDirective(unsigned CollapsedNum)
+ : OMPLoopDirective(OMPTargetTeamsGenericLoopDirectiveClass,
+ llvm::omp::OMPD_target_teams_loop, SourceLocation(),
+ SourceLocation(), CollapsedNum) {}
+
+public:
+ /// Creates directive with a list of \p Clauses.
+ ///
+ /// \param C AST context.
+ /// \param StartLoc Starting location of the directive kind.
+ /// \param EndLoc Ending Location of the directive.
+ /// \param CollapsedNum Number of collapsed loops.
+ /// \param Clauses List of clauses.
+ /// \param AssociatedStmt Statement, associated with the directive.
+ /// \param Exprs Helper expressions for CodeGen.
+ ///
+ static OMPTargetTeamsGenericLoopDirective *
+ Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
+ unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
+ Stmt *AssociatedStmt, const HelperExprs &Exprs);
+
+ /// Creates an empty directive with the place
+ /// for \a NumClauses clauses.
+ ///
+ /// \param C AST context.
+ /// \param CollapsedNum Number of collapsed nested loops.
+ /// \param NumClauses Number of clauses.
+ ///
+ static OMPTargetTeamsGenericLoopDirective *CreateEmpty(const ASTContext &C,
+ unsigned NumClauses,
+ unsigned CollapsedNum,
+ EmptyShell);
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == OMPTargetTeamsGenericLoopDirectiveClass;
+ }
+};
+
+/// This represents '#pragma omp parallel loop' directive.
+///
+/// \code
+/// #pragma omp parallel loop private(a,b) order(concurrent)
+/// \endcode
+/// In this example directive '#pragma omp parallel loop' has
+/// clauses 'private' with the variables 'a' and 'b', and order(concurrent).
+///
+class OMPParallelGenericLoopDirective final : public OMPLoopDirective {
+ friend class ASTStmtReader;
+ friend class OMPExecutableDirective;
+ /// Build directive with the given start and end location.
+ ///
+ /// \param StartLoc Starting location of the directive kind.
+ /// \param EndLoc Ending location of the directive.
+ /// \param CollapsedNum Number of collapsed nested loops.
+ ///
+ OMPParallelGenericLoopDirective(SourceLocation StartLoc,
+ SourceLocation EndLoc, unsigned CollapsedNum)
+ : OMPLoopDirective(OMPParallelGenericLoopDirectiveClass,
+ llvm::omp::OMPD_parallel_loop, StartLoc, EndLoc,
+ CollapsedNum) {}
+
+ /// Build an empty directive.
+ ///
+ /// \param CollapsedNum Number of collapsed nested loops.
+ ///
+ explicit OMPParallelGenericLoopDirective(unsigned CollapsedNum)
+ : OMPLoopDirective(OMPParallelGenericLoopDirectiveClass,
+ llvm::omp::OMPD_parallel_loop, SourceLocation(),
+ SourceLocation(), CollapsedNum) {}
+
+public:
+ /// Creates directive with a list of \p Clauses.
+ ///
+ /// \param C AST context.
+ /// \param StartLoc Starting location of the directive kind.
+ /// \param EndLoc Ending Location of the directive.
+ /// \param CollapsedNum Number of collapsed loops.
+ /// \param Clauses List of clauses.
+ /// \param AssociatedStmt Statement, associated with the directive.
+ /// \param Exprs Helper expressions for CodeGen.
+ ///
+ static OMPParallelGenericLoopDirective *
+ Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
+ unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
+ Stmt *AssociatedStmt, const HelperExprs &Exprs);
+
+ /// Creates an empty directive with the place
+ /// for \a NumClauses clauses.
+ ///
+ /// \param C AST context.
+ /// \param CollapsedNum Number of collapsed nested loops.
+ /// \param NumClauses Number of clauses.
+ ///
+ static OMPParallelGenericLoopDirective *CreateEmpty(const ASTContext &C,
+ unsigned NumClauses,
+ unsigned CollapsedNum,
+ EmptyShell);
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == OMPParallelGenericLoopDirectiveClass;
+ }
+};
+
+/// This represents '#pragma omp target parallel loop' directive.
+///
+/// \code
+/// #pragma omp target parallel loop private(a,b) order(concurrent)
+/// \endcode
+/// In this example directive '#pragma omp target parallel loop' has
+/// clauses 'private' with the variables 'a' and 'b', and order(concurrent).
+///
+class OMPTargetParallelGenericLoopDirective final : public OMPLoopDirective {
+ friend class ASTStmtReader;
+ friend class OMPExecutableDirective;
+ /// Build directive with the given start and end location.
+ ///
+ /// \param StartLoc Starting location of the directive kind.
+ /// \param EndLoc Ending location of the directive.
+ /// \param CollapsedNum Number of collapsed nested loops.
+ ///
+ OMPTargetParallelGenericLoopDirective(SourceLocation StartLoc,
+ SourceLocation EndLoc,
+ unsigned CollapsedNum)
+ : OMPLoopDirective(OMPTargetParallelGenericLoopDirectiveClass,
+ llvm::omp::OMPD_target_parallel_loop, StartLoc, EndLoc,
+ CollapsedNum) {}
+
+ /// Build an empty directive.
+ ///
+ /// \param CollapsedNum Number of collapsed nested loops.
+ ///
+ explicit OMPTargetParallelGenericLoopDirective(unsigned CollapsedNum)
+ : OMPLoopDirective(OMPTargetParallelGenericLoopDirectiveClass,
+ llvm::omp::OMPD_target_parallel_loop, SourceLocation(),
+ SourceLocation(), CollapsedNum) {}
+
+public:
+ /// Creates directive with a list of \p Clauses.
+ ///
+ /// \param C AST context.
+ /// \param StartLoc Starting location of the directive kind.
+ /// \param EndLoc Ending Location of the directive.
+ /// \param CollapsedNum Number of collapsed loops.
+ /// \param Clauses List of clauses.
+ /// \param AssociatedStmt Statement, associated with the directive.
+ /// \param Exprs Helper expressions for CodeGen.
+ ///
+ static OMPTargetParallelGenericLoopDirective *
+ Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
+ unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
+ Stmt *AssociatedStmt, const HelperExprs &Exprs);
+
+ /// Creates an empty directive with the place
+ /// for \a NumClauses clauses.
+ ///
+ /// \param C AST context.
+ /// \param CollapsedNum Number of collapsed nested loops.
+ /// \param NumClauses Number of clauses.
+ ///
+ static OMPTargetParallelGenericLoopDirective *
+ CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum,
+ EmptyShell);
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == OMPTargetParallelGenericLoopDirectiveClass;
+ }
+};
+
+/// This represents '#pragma omp error' directive.
+///
+/// \code
+/// #pragma omp error
+/// \endcode
+class OMPErrorDirective final : public OMPExecutableDirective {
+ friend class ASTStmtReader;
+ friend class OMPExecutableDirective;
+ /// Build directive with the given start and end location.
+ ///
+ /// \param StartLoc Starting location of the directive kind.
+ /// \param EndLoc Ending location of the directive.
+ ///
+ OMPErrorDirective(SourceLocation StartLoc, SourceLocation EndLoc)
+ : OMPExecutableDirective(OMPErrorDirectiveClass, llvm::omp::OMPD_error,
+ StartLoc, EndLoc) {}
+ /// Build an empty directive.
+ ///
+ explicit OMPErrorDirective()
+ : OMPExecutableDirective(OMPErrorDirectiveClass, llvm::omp::OMPD_error,
+ SourceLocation(), SourceLocation()) {}
+
+public:
+ ///
+ /// \param C AST context.
+ /// \param StartLoc Starting location of the directive kind.
+ /// \param EndLoc Ending Location of the directive.
+ /// \param Clauses List of clauses.
+ ///
+ static OMPErrorDirective *Create(const ASTContext &C, SourceLocation StartLoc,
+ SourceLocation EndLoc,
+ ArrayRef<OMPClause *> Clauses);
+
+ /// Creates an empty directive.
+ ///
+ /// \param C AST context.
+ ///
+ static OMPErrorDirective *CreateEmpty(const ASTContext &C,
+ unsigned NumClauses, EmptyShell);
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == OMPErrorDirectiveClass;
+ }
+};
} // end namespace clang
#endif
diff --git a/contrib/llvm-project/clang/include/clang/AST/TemplateArgumentVisitor.h b/contrib/llvm-project/clang/include/clang/AST/TemplateArgumentVisitor.h
index 190aa97adf45..cf0d32201580 100644
--- a/contrib/llvm-project/clang/include/clang/AST/TemplateArgumentVisitor.h
+++ b/contrib/llvm-project/clang/include/clang/AST/TemplateArgumentVisitor.h
@@ -37,6 +37,7 @@ public:
DISPATCH(Declaration);
DISPATCH(NullPtr);
DISPATCH(Integral);
+ DISPATCH(StructuralValue);
DISPATCH(Template);
DISPATCH(TemplateExpansion);
DISPATCH(Expression);
@@ -59,6 +60,7 @@ public:
VISIT_METHOD(Declaration);
VISIT_METHOD(NullPtr);
VISIT_METHOD(Integral);
+ VISIT_METHOD(StructuralValue);
VISIT_METHOD(Template);
VISIT_METHOD(TemplateExpansion);
VISIT_METHOD(Expression);
diff --git a/contrib/llvm-project/clang/include/clang/AST/TemplateBase.h b/contrib/llvm-project/clang/include/clang/AST/TemplateBase.h
index fa27a12cfbb9..fea2c8ccfee6 100644
--- a/contrib/llvm-project/clang/include/clang/AST/TemplateBase.h
+++ b/contrib/llvm-project/clang/include/clang/AST/TemplateBase.h
@@ -23,14 +23,13 @@
#include "llvm/ADT/APInt.h"
#include "llvm/ADT/APSInt.h"
#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/None.h"
-#include "llvm/ADT/Optional.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/TrailingObjects.h"
#include <cassert>
#include <cstddef>
#include <cstdint>
+#include <optional>
namespace llvm {
@@ -51,8 +50,8 @@ template <> struct PointerLikeTypeTraits<clang::Expr *> {
namespace clang {
+class APValue;
class ASTContext;
-class DiagnosticBuilder;
class Expr;
struct PrintingPolicy;
class TypeSourceInfo;
@@ -82,6 +81,13 @@ public:
/// that was provided for an integral non-type template parameter.
Integral,
+ /// The template argument is a non-type template argument that can't be
+ /// represented by the special-case Declaration, NullPtr, or Integral
+ /// forms. These values are only ever produced by constant evaluation,
+ /// so cannot be dependent.
+ /// TODO: merge Declaration, NullPtr and Integral into this?
+ StructuralValue,
+
/// The template argument is a template name that was provided for a
/// template template parameter.
Template,
@@ -105,16 +111,23 @@ private:
/// The kind of template argument we're storing.
struct DA {
- unsigned Kind;
+ LLVM_PREFERRED_TYPE(ArgKind)
+ unsigned Kind : 31;
+ LLVM_PREFERRED_TYPE(bool)
+ unsigned IsDefaulted : 1;
void *QT;
ValueDecl *D;
};
struct I {
- unsigned Kind;
+ LLVM_PREFERRED_TYPE(ArgKind)
+ unsigned Kind : 31;
+ LLVM_PREFERRED_TYPE(bool)
+ unsigned IsDefaulted : 1;
// We store a decomposed APSInt with the data allocated by ASTContext if
// BitWidth > 64. The memory may be shared between multiple
// TemplateArgument instances.
unsigned BitWidth : 31;
+ LLVM_PREFERRED_TYPE(bool)
unsigned IsUnsigned : 1;
union {
/// Used to store the <= 64 bits integer value.
@@ -125,51 +138,77 @@ private:
};
void *Type;
};
+ struct V {
+ LLVM_PREFERRED_TYPE(ArgKind)
+ unsigned Kind : 31;
+ LLVM_PREFERRED_TYPE(bool)
+ unsigned IsDefaulted : 1;
+ APValue *Value;
+ void *Type;
+ };
struct A {
- unsigned Kind;
+ LLVM_PREFERRED_TYPE(ArgKind)
+ unsigned Kind : 31;
+ LLVM_PREFERRED_TYPE(bool)
+ unsigned IsDefaulted : 1;
unsigned NumArgs;
const TemplateArgument *Args;
};
struct TA {
- unsigned Kind;
+ LLVM_PREFERRED_TYPE(ArgKind)
+ unsigned Kind : 31;
+ LLVM_PREFERRED_TYPE(bool)
+ unsigned IsDefaulted : 1;
unsigned NumExpansions;
void *Name;
};
struct TV {
- unsigned Kind;
+ LLVM_PREFERRED_TYPE(ArgKind)
+ unsigned Kind : 31;
+ LLVM_PREFERRED_TYPE(bool)
+ unsigned IsDefaulted : 1;
uintptr_t V;
};
union {
struct DA DeclArg;
struct I Integer;
+ struct V Value;
struct A Args;
struct TA TemplateArg;
struct TV TypeOrValue;
};
+ void initFromType(QualType T, bool IsNullPtr, bool IsDefaulted);
+ void initFromDeclaration(ValueDecl *D, QualType QT, bool IsDefaulted);
+ void initFromIntegral(const ASTContext &Ctx, const llvm::APSInt &Value,
+ QualType Type, bool IsDefaulted);
+ void initFromStructural(const ASTContext &Ctx, QualType Type,
+ const APValue &V, bool IsDefaulted);
+
public:
/// Construct an empty, invalid template argument.
- constexpr TemplateArgument() : TypeOrValue({Null, 0}) {}
+ constexpr TemplateArgument() : TypeOrValue({Null, 0, /* IsDefaulted */ 0}) {}
/// Construct a template type argument.
- TemplateArgument(QualType T, bool isNullPtr = false) {
- TypeOrValue.Kind = isNullPtr ? NullPtr : Type;
- TypeOrValue.V = reinterpret_cast<uintptr_t>(T.getAsOpaquePtr());
+ TemplateArgument(QualType T, bool isNullPtr = false,
+ bool IsDefaulted = false) {
+ initFromType(T, isNullPtr, IsDefaulted);
}
- /// Construct a template argument that refers to a
- /// declaration, which is either an external declaration or a
- /// template declaration.
- TemplateArgument(ValueDecl *D, QualType QT) {
- assert(D && "Expected decl");
- DeclArg.Kind = Declaration;
- DeclArg.QT = QT.getAsOpaquePtr();
- DeclArg.D = D;
+ /// Construct a template argument that refers to a (non-dependent)
+ /// declaration.
+ TemplateArgument(ValueDecl *D, QualType QT, bool IsDefaulted = false) {
+ initFromDeclaration(D, QT, IsDefaulted);
}
/// Construct an integral constant template argument. The memory to
/// store the value is allocated with Ctx.
- TemplateArgument(ASTContext &Ctx, const llvm::APSInt &Value, QualType Type);
+ TemplateArgument(const ASTContext &Ctx, const llvm::APSInt &Value,
+ QualType Type, bool IsDefaulted = false);
+
+ /// Construct a template argument from an arbitrary constant value.
+ TemplateArgument(const ASTContext &Ctx, QualType Type, const APValue &Value,
+ bool IsDefaulted = false);
/// Construct an integral constant template argument with the same
/// value as Other but a different type.
@@ -186,8 +225,12 @@ public:
/// is taken.
///
/// \param Name The template name.
- TemplateArgument(TemplateName Name) {
+ ///
+ /// \param IsDefaulted If 'true', implies that this TemplateArgument
+ /// corresponds to a default template parameter
+ TemplateArgument(TemplateName Name, bool IsDefaulted = false) {
TemplateArg.Kind = Template;
+ TemplateArg.IsDefaulted = IsDefaulted;
TemplateArg.Name = Name.getAsVoidPointer();
TemplateArg.NumExpansions = 0;
}
@@ -203,8 +246,13 @@ public:
///
/// \param NumExpansions The number of expansions that will be generated by
/// instantiating
- TemplateArgument(TemplateName Name, Optional<unsigned> NumExpansions) {
+ ///
+ /// \param IsDefaulted If 'true', implies that this TemplateArgument
+ /// corresponds to a default template parameter
+ TemplateArgument(TemplateName Name, std::optional<unsigned> NumExpansions,
+ bool IsDefaulted = false) {
TemplateArg.Kind = TemplateExpansion;
+ TemplateArg.IsDefaulted = IsDefaulted;
TemplateArg.Name = Name.getAsVoidPointer();
if (NumExpansions)
TemplateArg.NumExpansions = *NumExpansions + 1;
@@ -217,8 +265,9 @@ public:
/// This form of template argument only occurs in template argument
/// lists used for dependent types and for expression; it will not
/// occur in a non-dependent, canonical template argument list.
- TemplateArgument(Expr *E) {
+ TemplateArgument(Expr *E, bool IsDefaulted = false) {
TypeOrValue.Kind = Expression;
+ TypeOrValue.IsDefaulted = IsDefaulted;
TypeOrValue.V = reinterpret_cast<uintptr_t>(E);
}
@@ -228,13 +277,14 @@ public:
/// outlives the TemplateArgument itself.
explicit TemplateArgument(ArrayRef<TemplateArgument> Args) {
this->Args.Kind = Pack;
+ this->Args.IsDefaulted = false;
this->Args.Args = Args.data();
this->Args.NumArgs = Args.size();
}
- TemplateArgument(TemplateName, bool) = delete;
-
- static TemplateArgument getEmptyPack() { return TemplateArgument(None); }
+ static TemplateArgument getEmptyPack() {
+ return TemplateArgument(std::nullopt);
+ }
/// Create a new template argument pack by copying the given set of
/// template arguments.
@@ -268,7 +318,7 @@ public:
/// Retrieve the type for a type template argument.
QualType getAsType() const {
assert(getKind() == Type && "Unexpected kind");
- return QualType::getFromOpaquePtr(reinterpret_cast<void*>(TypeOrValue.V));
+ return QualType::getFromOpaquePtr(reinterpret_cast<void *>(TypeOrValue.V));
}
/// Retrieve the declaration for a declaration non-type
@@ -286,7 +336,7 @@ public:
/// Retrieve the type for null non-type template argument.
QualType getNullPtrType() const {
assert(getKind() == NullPtr && "Unexpected kind");
- return QualType::getFromOpaquePtr(reinterpret_cast<void*>(TypeOrValue.V));
+ return QualType::getFromOpaquePtr(reinterpret_cast<void *>(TypeOrValue.V));
}
/// Retrieve the template name for a template name argument.
@@ -306,7 +356,7 @@ public:
/// Retrieve the number of expansions that a template template argument
/// expansion will produce, if known.
- Optional<unsigned> getNumTemplateExpansions() const;
+ std::optional<unsigned> getNumTemplateExpansions() const;
/// Retrieve the template argument as an integral value.
// FIXME: Provide a way to read the integral data without copying the value.
@@ -319,7 +369,7 @@ public:
return APSInt(APInt(Integer.BitWidth, Integer.VAL), Integer.IsUnsigned);
unsigned NumWords = APInt::getNumWords(Integer.BitWidth);
- return APSInt(APInt(Integer.BitWidth, makeArrayRef(Integer.pVal, NumWords)),
+ return APSInt(APInt(Integer.BitWidth, ArrayRef(Integer.pVal, NumWords)),
Integer.IsUnsigned);
}
@@ -334,6 +384,22 @@ public:
Integer.Type = T.getAsOpaquePtr();
}
+ /// Set to 'true' if this TemplateArgument corresponds to a
+ /// default template parameter.
+ void setIsDefaulted(bool v) { TypeOrValue.IsDefaulted = v; }
+
+ /// If returns 'true', this TemplateArgument corresponds to a
+ /// default template parameter.
+ bool getIsDefaulted() const { return (bool)TypeOrValue.IsDefaulted; }
+
+ /// Get the value of a StructuralValue.
+ const APValue &getAsStructuralValue() const { return *Value.Value; }
+
+ /// Get the type of a StructuralValue.
+ QualType getStructuralValueType() const {
+ return QualType::getFromOpaquePtr(Value.Type);
+ }
+
/// If this is a non-type template argument, get its type. Otherwise,
/// returns a null QualType.
QualType getNonTypeTemplateArgumentType() const;
@@ -364,7 +430,7 @@ public:
/// Iterator range referencing all of the elements of a template
/// argument pack.
ArrayRef<TemplateArgument> pack_elements() const {
- return llvm::makeArrayRef(pack_begin(), pack_end());
+ return llvm::ArrayRef(pack_begin(), pack_end());
}
/// The number of template arguments in the given template argument
@@ -377,7 +443,7 @@ public:
/// Return the array of arguments in this template argument pack.
ArrayRef<TemplateArgument> getPackAsArray() const {
assert(getKind() == Pack);
- return llvm::makeArrayRef(Args.Args, Args.NumArgs);
+ return llvm::ArrayRef(Args.Args, Args.NumArgs);
}
/// Determines whether two template arguments are superficially the
@@ -479,6 +545,7 @@ public:
assert(Argument.getKind() == TemplateArgument::NullPtr ||
Argument.getKind() == TemplateArgument::Integral ||
Argument.getKind() == TemplateArgument::Declaration ||
+ Argument.getKind() == TemplateArgument::StructuralValue ||
Argument.getKind() == TemplateArgument::Expression);
}
@@ -504,13 +571,9 @@ public:
/// - Fetches the full source range of the argument.
SourceRange getSourceRange() const LLVM_READONLY;
- const TemplateArgument &getArgument() const {
- return Argument;
- }
+ const TemplateArgument &getArgument() const { return Argument; }
- TemplateArgumentLocInfo getLocInfo() const {
- return LocInfo;
- }
+ TemplateArgumentLocInfo getLocInfo() const { return LocInfo; }
TypeSourceInfo *getTypeSourceInfo() const {
if (Argument.getKind() != TemplateArgument::Type)
@@ -538,6 +601,11 @@ public:
return LocInfo.getAsExpr();
}
+ Expr *getSourceStructuralValueExpression() const {
+ assert(Argument.getKind() == TemplateArgument::StructuralValue);
+ return LocInfo.getAsExpr();
+ }
+
NestedNameSpecifierLoc getTemplateQualifierLoc() const {
if (Argument.getKind() != TemplateArgument::Template &&
Argument.getKind() != TemplateArgument::TemplateExpansion)
@@ -569,8 +637,7 @@ class TemplateArgumentListInfo {
public:
TemplateArgumentListInfo() = default;
- TemplateArgumentListInfo(SourceLocation LAngleLoc,
- SourceLocation RAngleLoc)
+ TemplateArgumentListInfo(SourceLocation LAngleLoc, SourceLocation RAngleLoc)
: LAngleLoc(LAngleLoc), RAngleLoc(RAngleLoc) {}
// This can leak if used in an AST node, use ASTTemplateArgumentListInfo
@@ -589,21 +656,15 @@ public:
return Arguments.data();
}
- llvm::ArrayRef<TemplateArgumentLoc> arguments() const {
- return Arguments;
- }
+ llvm::ArrayRef<TemplateArgumentLoc> arguments() const { return Arguments; }
const TemplateArgumentLoc &operator[](unsigned I) const {
return Arguments[I];
}
- TemplateArgumentLoc &operator[](unsigned I) {
- return Arguments[I];
- }
+ TemplateArgumentLoc &operator[](unsigned I) { return Arguments[I]; }
- void addArgument(const TemplateArgumentLoc &Loc) {
- Arguments.push_back(Loc);
- }
+ void addArgument(const TemplateArgumentLoc &Loc) { Arguments.push_back(Loc); }
};
/// Represents an explicit template argument list in C++, e.g.,
@@ -619,6 +680,9 @@ private:
ASTTemplateArgumentListInfo(const TemplateArgumentListInfo &List);
+ // FIXME: Is it ever necessary to copy to another context?
+ ASTTemplateArgumentListInfo(const ASTTemplateArgumentListInfo *List);
+
public:
/// The source location of the left angle bracket ('<').
SourceLocation LAngleLoc;
@@ -639,7 +703,7 @@ public:
unsigned getNumTemplateArgs() const { return NumTemplateArgs; }
llvm::ArrayRef<TemplateArgumentLoc> arguments() const {
- return llvm::makeArrayRef(getTemplateArgs(), getNumTemplateArgs());
+ return llvm::ArrayRef(getTemplateArgs(), getNumTemplateArgs());
}
const TemplateArgumentLoc &operator[](unsigned I) const {
@@ -648,6 +712,10 @@ public:
static const ASTTemplateArgumentListInfo *
Create(const ASTContext &C, const TemplateArgumentListInfo &List);
+
+ // FIXME: Is it ever necessary to copy to another context?
+ static const ASTTemplateArgumentListInfo *
+ Create(const ASTContext &C, const ASTTemplateArgumentListInfo *List);
};
/// Represents an explicit template argument list in C++, e.g.,
@@ -692,33 +760,6 @@ struct alignas(void *) ASTTemplateKWAndArgsInfo {
const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB,
const TemplateArgument &Arg);
-inline TemplateSpecializationType::iterator
- TemplateSpecializationType::end() const {
- return getArgs() + getNumArgs();
-}
-
-inline DependentTemplateSpecializationType::iterator
- DependentTemplateSpecializationType::end() const {
- return getArgs() + getNumArgs();
-}
-
-inline const TemplateArgument &
- TemplateSpecializationType::getArg(unsigned Idx) const {
- assert(Idx < getNumArgs() && "Template argument out of range");
- return getArgs()[Idx];
-}
-
-inline const TemplateArgument &
- DependentTemplateSpecializationType::getArg(unsigned Idx) const {
- assert(Idx < getNumArgs() && "Template argument out of range");
- return getArgs()[Idx];
-}
-
-inline const TemplateArgument &AutoType::getArg(unsigned Idx) const {
- assert(Idx < getNumArgs() && "Template argument out of range");
- return getArgs()[Idx];
-}
-
} // namespace clang
#endif // LLVM_CLANG_AST_TEMPLATEBASE_H
diff --git a/contrib/llvm-project/clang/include/clang/AST/TemplateName.h b/contrib/llvm-project/clang/include/clang/AST/TemplateName.h
index 010b813dc525..b7732e54ba10 100644
--- a/contrib/llvm-project/clang/include/clang/AST/TemplateName.h
+++ b/contrib/llvm-project/clang/include/clang/AST/TemplateName.h
@@ -21,19 +21,19 @@
#include "llvm/ADT/PointerUnion.h"
#include "llvm/Support/PointerLikeTypeTraits.h"
#include <cassert>
+#include <optional>
namespace clang {
class ASTContext;
+class Decl;
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;
@@ -41,6 +41,7 @@ class SubstTemplateTemplateParmStorage;
class TemplateArgument;
class TemplateDecl;
class TemplateTemplateParmDecl;
+class UsingShadowDecl;
/// Implementation class used to describe either a set of overloaded
/// template names or an already-substituted template template parameter pack.
@@ -54,12 +55,15 @@ protected:
};
struct BitsTag {
- /// A Kind.
+ LLVM_PREFERRED_TYPE(Kind)
unsigned Kind : 2;
- /// The number of stored templates or template arguments,
- /// depending on which subclass we have.
- unsigned Size : 30;
+ // The template parameter index.
+ unsigned Index : 15;
+
+ /// The pack index, or the number of stored templates
+ /// or template arguments, depending on which subclass we have.
+ unsigned Data : 15;
};
union {
@@ -67,14 +71,13 @@ protected:
void *PointerAlignment;
};
- UncommonTemplateNameStorage(Kind kind, unsigned size) {
- Bits.Kind = kind;
- Bits.Size = size;
+ UncommonTemplateNameStorage(Kind Kind, unsigned Index, unsigned Data) {
+ Bits.Kind = Kind;
+ Bits.Index = Index;
+ Bits.Data = Data;
}
public:
- unsigned size() const { return Bits.Size; }
-
OverloadedTemplateStorage *getAsOverloadedStorage() {
return Bits.Kind == Overloaded
? reinterpret_cast<OverloadedTemplateStorage *>(this)
@@ -106,7 +109,7 @@ class OverloadedTemplateStorage : public UncommonTemplateNameStorage {
friend class ASTContext;
OverloadedTemplateStorage(unsigned size)
- : UncommonTemplateNameStorage(Overloaded, size) {}
+ : UncommonTemplateNameStorage(Overloaded, 0, size) {}
NamedDecl **getStorage() {
return reinterpret_cast<NamedDecl **>(this + 1);
@@ -116,13 +119,15 @@ class OverloadedTemplateStorage : public UncommonTemplateNameStorage {
}
public:
+ unsigned size() const { return Bits.Data; }
+
using iterator = NamedDecl *const *;
iterator begin() const { return getStorage(); }
- iterator end() const { return getStorage() + size(); }
+ iterator end() const { return getStorage() + Bits.Data; }
llvm::ArrayRef<NamedDecl*> decls() const {
- return llvm::makeArrayRef(begin(), end());
+ return llvm::ArrayRef(begin(), end());
}
};
@@ -132,23 +137,29 @@ public:
/// This kind of template names occurs when the parameter pack has been
/// provided with a template template argument pack in a context where its
/// enclosing pack expansion could not be fully expanded.
-class SubstTemplateTemplateParmPackStorage
- : public UncommonTemplateNameStorage, public llvm::FoldingSetNode
-{
- TemplateTemplateParmDecl *Parameter;
+class SubstTemplateTemplateParmPackStorage : public UncommonTemplateNameStorage,
+ public llvm::FoldingSetNode {
const TemplateArgument *Arguments;
+ llvm::PointerIntPair<Decl *, 1, bool> AssociatedDeclAndFinal;
public:
- SubstTemplateTemplateParmPackStorage(TemplateTemplateParmDecl *Parameter,
- unsigned Size,
- const TemplateArgument *Arguments)
- : UncommonTemplateNameStorage(SubstTemplateTemplateParmPack, Size),
- Parameter(Parameter), Arguments(Arguments) {}
+ SubstTemplateTemplateParmPackStorage(ArrayRef<TemplateArgument> ArgPack,
+ Decl *AssociatedDecl, unsigned Index,
+ bool Final);
+
+ /// A template-like entity which owns the whole pattern being substituted.
+ /// This will own a set of template parameters.
+ Decl *getAssociatedDecl() const;
+
+ /// Returns the index of the replaced parameter in the associated declaration.
+ /// This should match the result of `getParameterPack()->getIndex()`.
+ unsigned getIndex() const { return Bits.Index; }
+
+ // When true the substitution will be 'Final' (subst node won't be placed).
+ bool getFinal() const;
/// Retrieve the template template parameter pack being substituted.
- TemplateTemplateParmDecl *getParameterPack() const {
- return Parameter;
- }
+ TemplateTemplateParmDecl *getParameterPack() const;
/// Retrieve the template template argument pack with which this
/// parameter was substituted.
@@ -156,10 +167,9 @@ public:
void Profile(llvm::FoldingSetNodeID &ID, ASTContext &Context);
- static void Profile(llvm::FoldingSetNodeID &ID,
- ASTContext &Context,
- TemplateTemplateParmDecl *Parameter,
- const TemplateArgument &ArgPack);
+ static void Profile(llvm::FoldingSetNodeID &ID, ASTContext &Context,
+ const TemplateArgument &ArgPack, Decl *AssociatedDecl,
+ unsigned Index, bool Final);
};
/// Represents a C++ template name within the type system.
@@ -190,8 +200,12 @@ public:
/// specifier in the typedef. "apply" is a nested template, and can
/// only be understood in the context of
class TemplateName {
+ // NameDecl is either a TemplateDecl or a UsingShadowDecl depending on the
+ // NameKind.
+ // !! There is no free low bits in 32-bit builds to discriminate more than 4
+ // pointer types in PointerUnion.
using StorageType =
- llvm::PointerUnion<TemplateDecl *, UncommonTemplateNameStorage *,
+ llvm::PointerUnion<Decl *, UncommonTemplateNameStorage *,
QualifiedTemplateName *, DependentTemplateName *>;
StorageType Storage;
@@ -226,7 +240,11 @@ public:
/// A template template parameter pack that has been substituted for
/// a template template argument pack, but has not yet been expanded into
/// individual arguments.
- SubstTemplateTemplateParmPack
+ SubstTemplateTemplateParmPack,
+
+ /// A template name that refers to a template declaration found through a
+ /// specific using shadow declaration.
+ UsingTemplate,
};
TemplateName() = default;
@@ -237,6 +255,7 @@ public:
explicit TemplateName(SubstTemplateTemplateParmPackStorage *Storage);
explicit TemplateName(QualifiedTemplateName *Qual);
explicit TemplateName(DependentTemplateName *Dep);
+ explicit TemplateName(UsingShadowDecl *Using);
/// Determine whether this template name is NULL.
bool isNull() const;
@@ -289,6 +308,10 @@ public:
/// structure, if any.
DependentTemplateName *getAsDependentTemplateName() const;
+ /// Retrieve the using shadow declaration through which the underlying
+ /// template declaration is introduced, if any.
+ UsingShadowDecl *getAsUsingShadowDecl() const;
+
TemplateName getUnderlying() const;
/// Get the template name to substitute when this template name is used as a
@@ -309,16 +332,17 @@ public:
/// unexpanded parameter pack (for C++0x variadic templates).
bool containsUnexpandedParameterPack() const;
+ enum class Qualified { None, AsWritten, Fully };
/// Print the template name.
///
/// \param OS the output stream to which the template name will be
/// printed.
///
- /// \param SuppressNNS if true, don't print the
- /// nested-name-specifier that precedes the template name (if it has
- /// one).
+ /// \param Qual print the (Qualified::None) simple name,
+ /// (Qualified::AsWritten) any written (possibly partial) qualifier, or
+ /// (Qualified::Fully) the fully qualified name.
void print(raw_ostream &OS, const PrintingPolicy &Policy,
- bool SuppressNNS = false) const;
+ Qualified Qual = Qualified::AsWritten) const;
/// Debugging aid that dumps the template name.
void dump(raw_ostream &OS) const;
@@ -327,9 +351,7 @@ public:
/// error.
void dump() const;
- void Profile(llvm::FoldingSetNodeID &ID) {
- ID.AddPointer(Storage.getOpaqueValue());
- }
+ void Profile(llvm::FoldingSetNodeID &ID);
/// Retrieve the template name as a void pointer.
void *getAsVoidPointer() const { return Storage.getOpaqueValue(); }
@@ -351,23 +373,41 @@ class SubstTemplateTemplateParmStorage
: public UncommonTemplateNameStorage, public llvm::FoldingSetNode {
friend class ASTContext;
- TemplateTemplateParmDecl *Parameter;
TemplateName Replacement;
-
- SubstTemplateTemplateParmStorage(TemplateTemplateParmDecl *parameter,
- TemplateName replacement)
- : UncommonTemplateNameStorage(SubstTemplateTemplateParm, 0),
- Parameter(parameter), Replacement(replacement) {}
+ Decl *AssociatedDecl;
+
+ SubstTemplateTemplateParmStorage(TemplateName Replacement,
+ Decl *AssociatedDecl, unsigned Index,
+ std::optional<unsigned> PackIndex)
+ : UncommonTemplateNameStorage(SubstTemplateTemplateParm, Index,
+ PackIndex ? *PackIndex + 1 : 0),
+ Replacement(Replacement), AssociatedDecl(AssociatedDecl) {
+ assert(AssociatedDecl != nullptr);
+ }
public:
- TemplateTemplateParmDecl *getParameter() const { return Parameter; }
+ /// A template-like entity which owns the whole pattern being substituted.
+ /// This will own a set of template parameters.
+ Decl *getAssociatedDecl() const { return AssociatedDecl; }
+
+ /// Returns the index of the replaced parameter in the associated declaration.
+ /// This should match the result of `getParameter()->getIndex()`.
+ unsigned getIndex() const { return Bits.Index; }
+
+ std::optional<unsigned> getPackIndex() const {
+ if (Bits.Data == 0)
+ return std::nullopt;
+ return Bits.Data - 1;
+ }
+
+ TemplateTemplateParmDecl *getParameter() const;
TemplateName getReplacement() const { return Replacement; }
void Profile(llvm::FoldingSetNodeID &ID);
- static void Profile(llvm::FoldingSetNodeID &ID,
- TemplateTemplateParmDecl *parameter,
- TemplateName replacement);
+ static void Profile(llvm::FoldingSetNodeID &ID, TemplateName Replacement,
+ Decl *AssociatedDecl, unsigned Index,
+ std::optional<unsigned> PackIndex);
};
inline TemplateName TemplateName::getUnderlying() const {
@@ -400,13 +440,19 @@ class QualifiedTemplateName : public llvm::FoldingSetNode {
/// this name with DependentTemplateName).
llvm::PointerIntPair<NestedNameSpecifier *, 1> Qualifier;
- /// The template declaration or set of overloaded function templates
- /// that this qualified name refers to.
- TemplateDecl *Template;
+ /// The underlying template name, it is either
+ /// 1) a Template -- a template declaration that this qualified name refers
+ /// to.
+ /// 2) or a UsingTemplate -- a template declaration introduced by a
+ /// using-shadow declaration.
+ TemplateName UnderlyingTemplate;
QualifiedTemplateName(NestedNameSpecifier *NNS, bool TemplateKeyword,
- TemplateDecl *Template)
- : Qualifier(NNS, TemplateKeyword? 1 : 0), Template(Template) {}
+ TemplateName Template)
+ : Qualifier(NNS, TemplateKeyword ? 1 : 0), UnderlyingTemplate(Template) {
+ assert(UnderlyingTemplate.getKind() == TemplateName::Template ||
+ UnderlyingTemplate.getKind() == TemplateName::UsingTemplate);
+ }
public:
/// Return the nested name specifier that qualifies this name.
@@ -416,23 +462,18 @@ public:
/// keyword.
bool hasTemplateKeyword() const { return Qualifier.getInt(); }
- /// The template declaration that this qualified name refers
- /// to.
- TemplateDecl *getDecl() const { return Template; }
-
- /// The template declaration to which this qualified name
- /// refers.
- TemplateDecl *getTemplateDecl() const { return Template; }
+ /// Return the underlying template name.
+ TemplateName getUnderlyingTemplate() const { return UnderlyingTemplate; }
void Profile(llvm::FoldingSetNodeID &ID) {
- Profile(ID, getQualifier(), hasTemplateKeyword(), getTemplateDecl());
+ Profile(ID, getQualifier(), hasTemplateKeyword(), UnderlyingTemplate);
}
static void Profile(llvm::FoldingSetNodeID &ID, NestedNameSpecifier *NNS,
- bool TemplateKeyword, TemplateDecl *Template) {
+ bool TemplateKeyword, TemplateName TN) {
ID.AddPointer(NNS);
ID.AddBoolean(TemplateKeyword);
- ID.AddPointer(Template);
+ ID.AddPointer(TN.getAsVoidPointer());
}
};
diff --git a/contrib/llvm-project/clang/include/clang/AST/TextNodeDumper.h b/contrib/llvm-project/clang/include/clang/AST/TextNodeDumper.h
index 0eb0031de11f..732749ad305e 100644
--- a/contrib/llvm-project/clang/include/clang/AST/TextNodeDumper.h
+++ b/contrib/llvm-project/clang/include/clang/AST/TextNodeDumper.h
@@ -189,6 +189,8 @@ public:
void Visit(const GenericSelectionExpr::ConstAssociation &A);
+ void Visit(const ConceptReference *);
+
void Visit(const concepts::Requirement *R);
void Visit(const APValue &Value, QualType Ty);
@@ -202,6 +204,9 @@ public:
void dumpName(const NamedDecl *ND);
void dumpAccessSpecifier(AccessSpecifier AS);
void dumpCleanupObject(const ExprWithCleanups::CleanupObject &C);
+ void dumpTemplateSpecializationKind(TemplateSpecializationKind TSK);
+ void dumpNestedNameSpecifier(const NestedNameSpecifier *NNS);
+ void dumpConceptReference(const ConceptReference *R);
void dumpDeclRef(const Decl *D, StringRef Label = {});
@@ -246,12 +251,17 @@ public:
void VisitLabelStmt(const LabelStmt *Node);
void VisitGotoStmt(const GotoStmt *Node);
void VisitCaseStmt(const CaseStmt *Node);
+ void VisitReturnStmt(const ReturnStmt *Node);
+ void VisitCoawaitExpr(const CoawaitExpr *Node);
+ void VisitCoreturnStmt(const CoreturnStmt *Node);
+ void VisitCompoundStmt(const CompoundStmt *Node);
void VisitConstantExpr(const ConstantExpr *Node);
void VisitCallExpr(const CallExpr *Node);
void VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *Node);
void VisitCastExpr(const CastExpr *Node);
void VisitImplicitCastExpr(const ImplicitCastExpr *Node);
void VisitDeclRefExpr(const DeclRefExpr *Node);
+ void VisitDependentScopeDeclRefExpr(const DependentScopeDeclRefExpr *Node);
void VisitSYCLUniqueStableNameExpr(const SYCLUniqueStableNameExpr *Node);
void VisitPredefinedExpr(const PredefinedExpr *Node);
void VisitCharacterLiteral(const CharacterLiteral *Node);
@@ -311,11 +321,17 @@ public:
void VisitFunctionType(const FunctionType *T);
void VisitFunctionProtoType(const FunctionProtoType *T);
void VisitUnresolvedUsingType(const UnresolvedUsingType *T);
+ void VisitUsingType(const UsingType *T);
void VisitTypedefType(const TypedefType *T);
void VisitUnaryTransformType(const UnaryTransformType *T);
void VisitTagType(const TagType *T);
void VisitTemplateTypeParmType(const TemplateTypeParmType *T);
+ void VisitSubstTemplateTypeParmType(const SubstTemplateTypeParmType *T);
+ void
+ VisitSubstTemplateTypeParmPackType(const SubstTemplateTypeParmPackType *T);
void VisitAutoType(const AutoType *T);
+ void VisitDeducedTemplateSpecializationType(
+ const DeducedTemplateSpecializationType *T);
void VisitTemplateSpecializationType(const TemplateSpecializationType *T);
void VisitInjectedClassNameType(const InjectedClassNameType *T);
void VisitObjCInterfaceType(const ObjCInterfaceType *T);
@@ -376,6 +392,7 @@ public:
void VisitConceptDecl(const ConceptDecl *D);
void
VisitLifetimeExtendedTemporaryDecl(const LifetimeExtendedTemporaryDecl *D);
+ void VisitHLSLBufferDecl(const HLSLBufferDecl *D);
};
} // namespace clang
diff --git a/contrib/llvm-project/clang/include/clang/AST/Type.h b/contrib/llvm-project/clang/include/clang/AST/Type.h
index 9f46d5337897..6384cf9420b8 100644
--- a/contrib/llvm-project/clang/include/clang/AST/Type.h
+++ b/contrib/llvm-project/clang/include/clang/AST/Type.h
@@ -34,10 +34,9 @@
#include "llvm/ADT/APSInt.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/FoldingSet.h"
-#include "llvm/ADT/None.h"
-#include "llvm/ADT/Optional.h"
#include "llvm/ADT/PointerIntPair.h"
#include "llvm/ADT/PointerUnion.h"
+#include "llvm/ADT/STLForwardCompat.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Twine.h"
#include "llvm/ADT/iterator_range.h"
@@ -51,12 +50,14 @@
#include <cstddef>
#include <cstdint>
#include <cstring>
+#include <optional>
#include <string>
#include <type_traits>
#include <utility>
namespace clang {
+class BTFTypeTagAttr;
class ExtQuals;
class QualType;
class ConceptDecl;
@@ -129,6 +130,7 @@ class TemplateArgumentLoc;
class TemplateTypeParmDecl;
class TypedefNameDecl;
class UnresolvedUsingTypenameDecl;
+class UsingShadowDecl;
using CanQualType = CanQual<Type>;
@@ -263,16 +265,31 @@ public:
bool hasOnlyConst() const { return Mask == Const; }
void removeConst() { Mask &= ~Const; }
void addConst() { Mask |= Const; }
+ Qualifiers withConst() const {
+ Qualifiers Qs = *this;
+ Qs.addConst();
+ return Qs;
+ }
bool hasVolatile() const { return Mask & Volatile; }
bool hasOnlyVolatile() const { return Mask == Volatile; }
void removeVolatile() { Mask &= ~Volatile; }
void addVolatile() { Mask |= Volatile; }
+ Qualifiers withVolatile() const {
+ Qualifiers Qs = *this;
+ Qs.addVolatile();
+ return Qs;
+ }
bool hasRestrict() const { return Mask & Restrict; }
bool hasOnlyRestrict() const { return Mask == Restrict; }
void removeRestrict() { Mask &= ~Restrict; }
void addRestrict() { Mask |= Restrict; }
+ Qualifiers withRestrict() const {
+ Qualifiers Qs = *this;
+ Qs.addRestrict();
+ return Qs;
+ }
bool hasCVRQualifiers() const { return getCVRQualifiers(); }
unsigned getCVRQualifiers() const { return Mask & CVRMask; }
@@ -495,7 +512,12 @@ public:
(A == LangAS::Default &&
(B == LangAS::sycl_private || B == LangAS::sycl_local ||
B == LangAS::sycl_global || B == LangAS::sycl_global_device ||
- B == LangAS::sycl_global_host));
+ B == LangAS::sycl_global_host)) ||
+ // In HIP device compilation, any cuda address space is allowed
+ // to implicitly cast into the default address space.
+ (A == LangAS::Default &&
+ (B == LangAS::cuda_constant || B == LangAS::cuda_device ||
+ B == LangAS::cuda_shared));
}
/// Returns true if the address space in these qualifiers is equal to or
@@ -602,6 +624,47 @@ private:
static const uint32_t AddressSpaceShift = 9;
};
+class QualifiersAndAtomic {
+ Qualifiers Quals;
+ bool HasAtomic;
+
+public:
+ QualifiersAndAtomic() : HasAtomic(false) {}
+ QualifiersAndAtomic(Qualifiers Quals, bool HasAtomic)
+ : Quals(Quals), HasAtomic(HasAtomic) {}
+
+ operator Qualifiers() const { return Quals; }
+
+ bool hasVolatile() const { return Quals.hasVolatile(); }
+ bool hasConst() const { return Quals.hasConst(); }
+ bool hasRestrict() const { return Quals.hasRestrict(); }
+ bool hasAtomic() const { return HasAtomic; }
+
+ void addVolatile() { Quals.addVolatile(); }
+ void addConst() { Quals.addConst(); }
+ void addRestrict() { Quals.addRestrict(); }
+ void addAtomic() { HasAtomic = true; }
+
+ void removeVolatile() { Quals.removeVolatile(); }
+ void removeConst() { Quals.removeConst(); }
+ void removeRestrict() { Quals.removeRestrict(); }
+ void removeAtomic() { HasAtomic = false; }
+
+ QualifiersAndAtomic withVolatile() {
+ return {Quals.withVolatile(), HasAtomic};
+ }
+ QualifiersAndAtomic withConst() { return {Quals.withConst(), HasAtomic}; }
+ QualifiersAndAtomic withRestrict() {
+ return {Quals.withRestrict(), HasAtomic};
+ }
+ QualifiersAndAtomic withAtomic() { return {Quals, true}; }
+
+ QualifiersAndAtomic &operator+=(Qualifiers RHS) {
+ Quals += RHS;
+ return *this;
+ }
+};
+
/// A std::pair-like structure for storing a qualified type split
/// into its local qualifiers and its locally-unqualified type.
struct SplitQualType {
@@ -651,6 +714,12 @@ enum class ObjCSubstitutionContext {
Superclass,
};
+/// The kind of 'typeof' expression we're after.
+enum class TypeOfKind : uint8_t {
+ Qualified,
+ Unqualified,
+};
+
/// A (possibly-)qualified type.
///
/// For efficiency, we don't store CV-qualified types as nodes on their
@@ -695,6 +764,8 @@ public:
unsigned getLocalFastQualifiers() const { return Value.getInt(); }
void setLocalFastQualifiers(unsigned Quals) { Value.setInt(Quals); }
+ bool UseExcessPrecision(const ASTContext &Ctx);
+
/// Retrieves a pointer to the underlying (unqualified) type.
///
/// This function requires that the type not be NULL. If the type might be
@@ -734,6 +805,9 @@ public:
return Value.getPointer().isNull();
}
+ // Determines if a type can form `T&`.
+ bool isReferenceable() const;
+
/// Determine whether this particular QualType instance has the
/// "const" qualifier set, without looking through typedefs that may have
/// added "const" at a different level.
@@ -744,6 +818,26 @@ public:
/// Determine whether this type is const-qualified.
bool isConstQualified() const;
+ enum class NonConstantStorageReason {
+ MutableField,
+ NonConstNonReferenceType,
+ NonTrivialCtor,
+ NonTrivialDtor,
+ };
+ /// Determine whether instances of this type can be placed in immutable
+ /// storage.
+ /// If ExcludeCtor is true, the duration when the object's constructor runs
+ /// will not be considered. The caller will need to verify that the object is
+ /// not written to during its construction. ExcludeDtor works similarly.
+ std::optional<NonConstantStorageReason>
+ isNonConstantStorage(const ASTContext &Ctx, bool ExcludeCtor,
+ bool ExcludeDtor);
+
+ bool isConstantStorage(const ASTContext &Ctx, bool ExcludeCtor,
+ bool ExcludeDtor) {
+ return !isNonConstantStorage(Ctx, ExcludeCtor, ExcludeDtor);
+ }
+
/// Determine whether this particular QualType instance has the
/// "restrict" qualifier set, without looking through typedefs that may have
/// added "restrict" at a different level.
@@ -823,6 +917,14 @@ public:
/// Return true if this is a trivially copyable type (C++0x [basic.types]p9)
bool isTriviallyCopyableType(const ASTContext &Context) const;
+ /// Return true if this is a trivially copyable type
+ bool isTriviallyCopyConstructibleType(const ASTContext &Context) const;
+
+ /// Return true if this is a trivially relocatable type.
+ bool isTriviallyRelocatableType(const ASTContext &Context) const;
+
+ /// Return true if this is a trivially equality comparable type.
+ bool isTriviallyEqualityComparableType(const ASTContext &Context) const;
/// Returns true if it is a class and it might be dynamic.
bool mayBeDynamicClass() const;
@@ -830,6 +932,15 @@ public:
/// Returns true if it is not a class or if the class might not be dynamic.
bool mayBeNotDynamicClass() const;
+ /// Returns true if it is a WebAssembly Reference Type.
+ bool isWebAssemblyReferenceType() const;
+
+ /// Returns true if it is a WebAssembly Externref Type.
+ bool isWebAssemblyExternrefType() const;
+
+ /// Returns true if it is a WebAssembly Funcref Type.
+ bool isWebAssemblyFuncrefType() const;
+
// Don't promise in the API that anything besides 'const' can be
// easily added.
@@ -870,7 +981,6 @@ public:
void removeLocalConst();
void removeLocalVolatile();
void removeLocalRestrict();
- void removeLocalCVRQualifiers(unsigned Mask);
void removeLocalFastQualifiers() { Value.setInt(0); }
void removeLocalFastQualifiers(unsigned Mask) {
@@ -924,6 +1034,10 @@ public:
/// The resulting type might still be qualified if it's sugar for an array
/// type. To strip qualifiers even from within a sugared array type, use
/// ASTContext::getUnqualifiedArrayType.
+ ///
+ /// Note: In C, the _Atomic qualifier is special (see C23 6.2.5p32 for
+ /// details), and it is not stripped by this function. Use
+ /// getAtomicUnqualifiedType() to strip qualifiers including _Atomic.
inline QualType getUnqualifiedType() const;
/// Retrieve the unqualified variant of the given type, removing as little
@@ -1305,6 +1419,8 @@ private:
static bool hasNonTrivialToPrimitiveCopyCUnion(const RecordDecl *RD);
};
+raw_ostream &operator<<(raw_ostream &OS, QualType QT);
+
} // namespace clang
namespace llvm {
@@ -1370,7 +1486,8 @@ class ExtQualsTypeCommonBase {
/// in three low bits on the QualType pointer; a fourth bit records whether
/// the pointer is an ExtQuals node. The extended qualifiers (address spaces,
/// Objective-C GC attributes) are much more rare.
-class ExtQuals : public ExtQualsTypeCommonBase, public llvm::FoldingSetNode {
+class alignas(TypeAlignment) ExtQuals : public ExtQualsTypeCommonBase,
+ public llvm::FoldingSetNode {
// NOTE: changing the fast qualifiers should be straightforward as
// long as you don't make 'const' non-fast.
// 1. Qualifiers:
@@ -1456,6 +1573,10 @@ enum class AutoTypeKeyword {
GNUAutoType
};
+enum class ArraySizeModifier;
+enum class ElaboratedTypeKeyword;
+enum class VectorKind;
+
/// The base class of the type hierarchy.
///
/// A central concept with types is that each type always has a canonical
@@ -1482,7 +1603,7 @@ enum class AutoTypeKeyword {
///
/// Types, once created, are immutable.
///
-class alignas(8) Type : public ExtQualsTypeCommonBase {
+class alignas(TypeAlignment) Type : public ExtQualsTypeCommonBase {
public:
enum TypeClass {
#define TYPE(Class, Base) Class,
@@ -1498,22 +1619,28 @@ private:
template <class T> friend class TypePropertyCache;
/// TypeClass bitfield - Enum that specifies what subclass this belongs to.
+ LLVM_PREFERRED_TYPE(TypeClass)
unsigned TC : 8;
/// Store information on the type dependency.
+ LLVM_PREFERRED_TYPE(TypeDependence)
unsigned Dependence : llvm::BitWidth<TypeDependence>;
/// True if the cache (i.e. the bitfields here starting with
/// 'Cache') is valid.
+ LLVM_PREFERRED_TYPE(bool)
mutable unsigned CacheValid : 1;
/// Linkage of this type.
+ LLVM_PREFERRED_TYPE(Linkage)
mutable unsigned CachedLinkage : 3;
/// Whether this type involves and local or unnamed types.
+ LLVM_PREFERRED_TYPE(bool)
mutable unsigned CachedLocalOrUnnamed : 1;
/// Whether this type comes from an AST file.
+ LLVM_PREFERRED_TYPE(bool)
mutable unsigned FromAST : 1;
bool isCacheValid() const {
@@ -1539,34 +1666,41 @@ protected:
class ArrayTypeBitfields {
friend class ArrayType;
+ LLVM_PREFERRED_TYPE(TypeBitfields)
unsigned : NumTypeBits;
/// CVR qualifiers from declarations like
/// 'int X[static restrict 4]'. For function parameters only.
+ LLVM_PREFERRED_TYPE(Qualifiers)
unsigned IndexTypeQuals : 3;
/// Storage class qualifiers from declarations like
/// 'int X[static restrict 4]'. For function parameters only.
- /// Actually an ArrayType::ArraySizeModifier.
+ LLVM_PREFERRED_TYPE(ArraySizeModifier)
unsigned SizeModifier : 3;
};
+ enum { NumArrayTypeBits = NumTypeBits + 6 };
class ConstantArrayTypeBitfields {
friend class ConstantArrayType;
- unsigned : NumTypeBits + 3 + 3;
+ LLVM_PREFERRED_TYPE(ArrayTypeBitfields)
+ unsigned : NumArrayTypeBits;
/// Whether we have a stored size expression.
+ LLVM_PREFERRED_TYPE(bool)
unsigned HasStoredSizeExpr : 1;
};
class BuiltinTypeBitfields {
friend class BuiltinType;
+ LLVM_PREFERRED_TYPE(TypeBitfields)
unsigned : NumTypeBits;
/// The kind (BuiltinType::Kind) of builtin type this is.
- unsigned Kind : 8;
+ static constexpr unsigned NumOfBuiltinTypeBits = 9;
+ unsigned Kind : NumOfBuiltinTypeBits;
};
/// FunctionTypeBitfields store various bits belonging to FunctionProtoType.
@@ -1576,15 +1710,18 @@ protected:
friend class FunctionProtoType;
friend class FunctionType;
+ LLVM_PREFERRED_TYPE(TypeBitfields)
unsigned : NumTypeBits;
/// Extra information which affects how the function is called, like
/// regparm and the calling convention.
+ LLVM_PREFERRED_TYPE(CallingConv)
unsigned ExtInfo : 13;
/// The ref-qualifier associated with a \c FunctionProtoType.
///
/// This is a value of type \c RefQualifierKind.
+ LLVM_PREFERRED_TYPE(RefQualifierKind)
unsigned RefQualifier : 2;
/// Used only by FunctionProtoType, put here to pack with the
@@ -1593,8 +1730,10 @@ protected:
///
/// C++ 8.3.5p4: The return type, the parameter type list and the
/// cv-qualifier-seq, [...], are part of the function type.
+ LLVM_PREFERRED_TYPE(Qualifiers)
unsigned FastTypeQuals : Qualifiers::FastWidth;
/// Whether this function has extended Qualifiers.
+ LLVM_PREFERRED_TYPE(bool)
unsigned HasExtQuals : 1;
/// The number of parameters this function has, not counting '...'.
@@ -1604,21 +1743,30 @@ protected:
unsigned NumParams : 16;
/// The type of exception specification this function has.
+ LLVM_PREFERRED_TYPE(ExceptionSpecificationType)
unsigned ExceptionSpecType : 4;
/// Whether this function has extended parameter information.
+ LLVM_PREFERRED_TYPE(bool)
unsigned HasExtParameterInfos : 1;
+ /// Whether this function has extra bitfields for the prototype.
+ LLVM_PREFERRED_TYPE(bool)
+ unsigned HasExtraBitfields : 1;
+
/// Whether the function is variadic.
+ LLVM_PREFERRED_TYPE(bool)
unsigned Variadic : 1;
/// Whether this function has a trailing return type.
+ LLVM_PREFERRED_TYPE(bool)
unsigned HasTrailingReturn : 1;
};
class ObjCObjectTypeBitfields {
friend class ObjCObjectType;
+ LLVM_PREFERRED_TYPE(TypeBitfields)
unsigned : NumTypeBits;
/// The number of type arguments stored directly on this object type.
@@ -1628,12 +1776,14 @@ protected:
unsigned NumProtocols : 6;
/// Whether this is a "kindof" type.
+ LLVM_PREFERRED_TYPE(bool)
unsigned IsKindOf : 1;
};
class ReferenceTypeBitfields {
friend class ReferenceType;
+ LLVM_PREFERRED_TYPE(TypeBitfields)
unsigned : NumTypeBits;
/// True if the type was originally spelled with an lvalue sigil.
@@ -1647,31 +1797,36 @@ protected:
/// ref &&a; // lvalue, inner ref
/// rvref &a; // lvalue, inner ref, spelled lvalue
/// rvref &&a; // rvalue, inner ref
+ LLVM_PREFERRED_TYPE(bool)
unsigned SpelledAsLValue : 1;
/// True if the inner type is a reference type. This only happens
/// in non-canonical forms.
+ LLVM_PREFERRED_TYPE(bool)
unsigned InnerRef : 1;
};
class TypeWithKeywordBitfields {
friend class TypeWithKeyword;
+ LLVM_PREFERRED_TYPE(TypeBitfields)
unsigned : NumTypeBits;
/// An ElaboratedTypeKeyword. 8 bits for efficient access.
+ LLVM_PREFERRED_TYPE(ElaboratedTypeKeyword)
unsigned Keyword : 8;
};
- enum { NumTypeWithKeywordBits = 8 };
+ enum { NumTypeWithKeywordBits = NumTypeBits + 8 };
class ElaboratedTypeBitfields {
friend class ElaboratedType;
- unsigned : NumTypeBits;
+ LLVM_PREFERRED_TYPE(TypeWithKeywordBitfields)
unsigned : NumTypeWithKeywordBits;
/// Whether the ElaboratedType has a trailing OwnedTagDecl.
+ LLVM_PREFERRED_TYPE(bool)
unsigned HasOwnedTagDecl : 1;
};
@@ -1679,11 +1834,13 @@ protected:
friend class VectorType;
friend class DependentVectorType;
+ LLVM_PREFERRED_TYPE(TypeBitfields)
unsigned : NumTypeBits;
/// The kind of vector, either a generic vector type or some
/// target-specific vector type such as for AltiVec or Neon.
- unsigned VecKind : 3;
+ LLVM_PREFERRED_TYPE(VectorKind)
+ unsigned VecKind : 4;
/// The number of elements in the vector.
uint32_t NumElements;
};
@@ -1691,19 +1848,22 @@ protected:
class AttributedTypeBitfields {
friend class AttributedType;
+ LLVM_PREFERRED_TYPE(TypeBitfields)
unsigned : NumTypeBits;
- /// An AttributedType::Kind
+ LLVM_PREFERRED_TYPE(attr::Kind)
unsigned AttrKind : 32 - NumTypeBits;
};
class AutoTypeBitfields {
friend class AutoType;
+ LLVM_PREFERRED_TYPE(TypeBitfields)
unsigned : NumTypeBits;
/// Was this placeholder type spelled as 'auto', 'decltype(auto)',
/// or '__auto_type'? AutoTypeKeyword value.
+ LLVM_PREFERRED_TYPE(AutoTypeKeyword)
unsigned Keyword : 2;
/// The number of template arguments in the type-constraints, which is
@@ -1716,27 +1876,82 @@ protected:
unsigned NumArgs;
};
+ class TypeOfBitfields {
+ friend class TypeOfType;
+ friend class TypeOfExprType;
+
+ LLVM_PREFERRED_TYPE(TypeBitfields)
+ unsigned : NumTypeBits;
+ LLVM_PREFERRED_TYPE(bool)
+ unsigned IsUnqual : 1; // If true: typeof_unqual, else: typeof
+ };
+
+ class UsingBitfields {
+ friend class UsingType;
+
+ LLVM_PREFERRED_TYPE(TypeBitfields)
+ unsigned : NumTypeBits;
+
+ /// True if the underlying type is different from the declared one.
+ LLVM_PREFERRED_TYPE(bool)
+ unsigned hasTypeDifferentFromDecl : 1;
+ };
+
+ class TypedefBitfields {
+ friend class TypedefType;
+
+ LLVM_PREFERRED_TYPE(TypeBitfields)
+ unsigned : NumTypeBits;
+
+ /// True if the underlying type is different from the declared one.
+ LLVM_PREFERRED_TYPE(bool)
+ unsigned hasTypeDifferentFromDecl : 1;
+ };
+
+ class SubstTemplateTypeParmTypeBitfields {
+ friend class SubstTemplateTypeParmType;
+
+ LLVM_PREFERRED_TYPE(TypeBitfields)
+ unsigned : NumTypeBits;
+
+ LLVM_PREFERRED_TYPE(bool)
+ unsigned HasNonCanonicalUnderlyingType : 1;
+
+ // The index of the template parameter this substitution represents.
+ unsigned Index : 15;
+
+ /// Represents the index within a pack if this represents a substitution
+ /// from a pack expansion. This index starts at the end of the pack and
+ /// increments towards the beginning.
+ /// Positive non-zero number represents the index + 1.
+ /// Zero means this is not substituted from an expansion.
+ unsigned PackIndex : 16;
+ };
+
class SubstTemplateTypeParmPackTypeBitfields {
friend class SubstTemplateTypeParmPackType;
+ LLVM_PREFERRED_TYPE(TypeBitfields)
unsigned : NumTypeBits;
+ // The index of the template parameter this substitution represents.
+ unsigned Index : 16;
+
/// The number of template arguments in \c Arguments, which is
/// expected to be able to hold at least 1024 according to [implimits].
/// However as this limit is somewhat easy to hit with template
/// metaprogramming we'd prefer to keep it as large as possible.
- /// At the moment it has been left as a non-bitfield since this type
- /// safely fits in 64 bits as an unsigned, so there is no reason to
- /// introduce the performance impact of a bitfield.
- unsigned NumArgs;
+ unsigned NumArgs : 16;
};
class TemplateSpecializationTypeBitfields {
friend class TemplateSpecializationType;
+ LLVM_PREFERRED_TYPE(TypeBitfields)
unsigned : NumTypeBits;
/// Whether this template specialization type is a substituted type alias.
+ LLVM_PREFERRED_TYPE(bool)
unsigned TypeAlias : 1;
/// The number of template arguments named in this class template
@@ -1752,7 +1967,7 @@ protected:
class DependentTemplateSpecializationTypeBitfields {
friend class DependentTemplateSpecializationType;
- unsigned : NumTypeBits;
+ LLVM_PREFERRED_TYPE(TypeWithKeywordBitfields)
unsigned : NumTypeWithKeywordBits;
/// The number of template arguments named in this class template
@@ -1768,6 +1983,7 @@ protected:
class PackExpansionTypeBitfields {
friend class PackExpansionType;
+ LLVM_PREFERRED_TYPE(TypeBitfields)
unsigned : NumTypeBits;
/// The number of expansions that this pack expansion will
@@ -1790,6 +2006,9 @@ protected:
ConstantArrayTypeBitfields ConstantArrayTypeBits;
AttributedTypeBitfields AttributedTypeBits;
AutoTypeBitfields AutoTypeBits;
+ TypeOfBitfields TypeOfBits;
+ TypedefBitfields TypedefBits;
+ UsingBitfields UsingBits;
BuiltinTypeBitfields BuiltinTypeBits;
FunctionTypeBitfields FunctionTypeBits;
ObjCObjectTypeBitfields ObjCObjectTypeBits;
@@ -1797,6 +2016,7 @@ protected:
TypeWithKeywordBitfields TypeWithKeywordBits;
ElaboratedTypeBitfields ElaboratedTypeBits;
VectorTypeBitfields VectorTypeBits;
+ SubstTemplateTypeParmTypeBitfields SubstTemplateTypeParmTypeBits;
SubstTemplateTypeParmPackTypeBitfields SubstTemplateTypeParmPackTypeBits;
TemplateSpecializationTypeBitfields TemplateSpecializationTypeBits;
DependentTemplateSpecializationTypeBitfields
@@ -1818,15 +2038,16 @@ protected:
Type(TypeClass tc, QualType canon, TypeDependence Dependence)
: ExtQualsTypeCommonBase(this,
canon.isNull() ? QualType(this_(), 0) : canon) {
- static_assert(sizeof(*this) <= 8 + sizeof(ExtQualsTypeCommonBase),
+ static_assert(sizeof(*this) <=
+ alignof(decltype(*this)) + sizeof(ExtQualsTypeCommonBase),
"changing bitfields changed sizeof(Type)!");
- static_assert(alignof(decltype(*this)) % sizeof(void *) == 0,
+ static_assert(alignof(decltype(*this)) % TypeAlignment == 0,
"Insufficient alignment!");
TypeBits.TC = tc;
TypeBits.Dependence = static_cast<unsigned>(Dependence);
TypeBits.CacheValid = false;
TypeBits.CachedLocalOrUnnamed = false;
- TypeBits.CachedLinkage = NoLinkage;
+ TypeBits.CachedLinkage = llvm::to_underlying(Linkage::Invalid);
TypeBits.FromAST = false;
}
@@ -1894,16 +2115,43 @@ public:
bool isSizelessType() const;
bool isSizelessBuiltinType() const;
+ /// Returns true for all scalable vector types.
+ bool isSizelessVectorType() const;
+
+ /// Returns true for SVE scalable vector types.
+ bool isSVESizelessBuiltinType() const;
+
+ /// Returns true for RVV scalable vector types.
+ bool isRVVSizelessBuiltinType() const;
+
+ /// Check if this is a WebAssembly Externref Type.
+ bool isWebAssemblyExternrefType() const;
+
+ /// Returns true if this is a WebAssembly table type: either an array of
+ /// reference types, or a pointer to a reference type (which can only be
+ /// created by array to pointer decay).
+ bool isWebAssemblyTableType() const;
+
/// Determines if this is a sizeless type supported by the
/// 'arm_sve_vector_bits' type attribute, which can be applied to a single
/// SVE vector or predicate, excluding tuple types such as svint32x4_t.
- bool isVLSTBuiltinType() const;
+ bool isSveVLSBuiltinType() const;
/// Returns the representative type for the element of an SVE builtin type.
/// This is used to represent fixed-length SVE vectors created with the
/// 'arm_sve_vector_bits' type attribute as VectorType.
QualType getSveEltType(const ASTContext &Ctx) const;
+ /// Determines if this is a sizeless type supported by the
+ /// 'riscv_rvv_vector_bits' type attribute, which can be applied to a single
+ /// RVV vector or mask.
+ bool isRVVVLSBuiltinType() const;
+
+ /// Returns the representative type for the element of an RVV builtin type.
+ /// This is used to represent fixed-length RVV vectors created with the
+ /// 'riscv_rvv_vector_bits' type attribute as VectorType.
+ QualType getRVVEltType(const ASTContext &Ctx) const;
+
/// Types are partitioned into 3 broad categories (C99 6.2.5p1):
/// object types, function types, and incomplete types.
@@ -1998,6 +2246,7 @@ public:
bool isFloat16Type() const; // C11 extension ISO/IEC TS 18661
bool isBFloat16Type() const;
bool isFloat128Type() const;
+ bool isIbm128Type() const;
bool isRealType() const; // C99 6.2.5p17 (real floating + integer)
bool isArithmeticType() const; // C99 6.2.5p18 (integer + floating)
bool isVoidType() const; // C99 6.2.5p19
@@ -2039,6 +2288,7 @@ public:
bool isComplexIntegerType() const; // GCC _Complex integer type.
bool isVectorType() const; // GCC vector type.
bool isExtVectorType() const; // Extended vector type.
+ bool isExtVectorBoolType() const; // Extended vector type with bool element.
bool isMatrixType() const; // Matrix type.
bool isConstantMatrixType() const; // Constant matrix type.
bool isDependentAddressSpaceType() const; // value-dependent address space qualifier
@@ -2093,7 +2343,8 @@ public:
bool isObjCARCBridgableType() const;
bool isCARCBridgableType() const;
bool isTemplateTypeParmType() const; // C++ template type parameter
- bool isNullPtrType() const; // C++11 std::nullptr_t
+ bool isNullPtrType() const; // C++11 std::nullptr_t or
+ // C23 nullptr_t
bool isNothrowT() const; // C++ std::nothrow_t
bool isAlignValT() const; // C++17 std::align_val_t
bool isStdByteType() const; // C++17 std::byte
@@ -2122,7 +2373,7 @@ public:
bool isOCLExtOpaqueType() const; // Any OpenCL extension type
bool isPipeType() const; // OpenCL pipe type
- bool isExtIntType() const; // Extended Int Type
+ bool isBitIntType() const; // Bit-precise integer type
bool isOpenCLSpecificType() const; // Any OpenCL specific type
/// Determines if this type, which must satisfy
@@ -2337,9 +2588,6 @@ public:
/// removing any typedefs, typeofs, etc., as well as any qualifiers.
const Type *getUnqualifiedDesugaredType() const;
- /// More type predicates useful for type checking/promotion
- bool isPromotableIntegerType() const; // C99 6.3.1.1p2
-
/// Return true if this is an integer type that is
/// signed, according to C99 6.2.5p4 [char, signed char, short, int, long..],
/// or an enum decl which has a signed representation.
@@ -2415,7 +2663,7 @@ public:
/// Note that nullability is only captured as sugar within the type
/// system, not as part of the canonical type, so nullability will
/// be lost by canonicalization and desugaring.
- Optional<NullabilityKind> getNullability(const ASTContext &context) const;
+ std::optional<NullabilityKind> getNullability() const;
/// Determine whether the given type can have a nullability
/// specifier applied to it, i.e., if it is any kind of pointer type.
@@ -2439,7 +2687,7 @@ public:
/// the type parameters of the given declaration context in any type described
/// within that context, or an empty optional to indicate that no
/// substitution is required.
- Optional<ArrayRef<QualType>>
+ std::optional<ArrayRef<QualType>>
getObjCSubstitutions(const DeclContext *dc) const;
/// Determines if this is an ObjC interface type that may accept type
@@ -2460,6 +2708,7 @@ public:
/// This will check for a TypedefType by removing any existing sugar
/// until it reaches a TypedefType or a non-sugared type.
template <> const TypedefType *Type::getAs() const;
+template <> const UsingType *Type::getAs() const;
/// This will check for a TemplateSpecializationType by removing any
/// existing sugar until it reaches a TemplateSpecializationType or a
@@ -2502,6 +2751,9 @@ public:
// RVV Types
#define RVV_TYPE(Name, Id, SingletonId) Id,
#include "clang/Basic/RISCVVTypes.def"
+// WebAssembly reference types
+#define WASM_TYPE(Name, Id, SingletonId) Id,
+#include "clang/Basic/WebAssemblyReferenceTypes.def"
// All other builtin types
#define BUILTIN_TYPE(Id, SingletonId) Id,
#define LAST_BUILTIN_TYPE(Id) LastKind = Id
@@ -2515,6 +2767,10 @@ private:
: Type(Builtin, QualType(),
K == Dependent ? TypeDependence::DependentInstantiation
: TypeDependence::None) {
+ static_assert(Kind::LastKind <
+ (1 << BuiltinTypeBitfields::NumOfBuiltinTypeBits) &&
+ "Defined builtin type exceeds the allocated space for serial "
+ "numbering");
BuiltinTypeBits.Kind = K;
}
@@ -2545,9 +2801,13 @@ public:
}
bool isFloatingPoint() const {
- return getKind() >= Half && getKind() <= Float128;
+ return getKind() >= Half && getKind() <= Ibm128;
}
+ bool isSVEBool() const { return getKind() == Kind::SveBool; }
+
+ bool isSVECount() const { return getKind() == Kind::SveCount; }
+
/// Determines whether the given kind corresponds to a placeholder type.
static bool isPlaceholderTypeKind(Kind K) {
return K >= Overload;
@@ -2873,17 +3133,14 @@ public:
}
};
+/// Capture whether this is a normal array (e.g. int X[4])
+/// an array with a static size (e.g. int X[static 4]), or an array
+/// with a star size (e.g. int X[*]).
+/// 'static' is only allowed on function parameters.
+enum class ArraySizeModifier { Normal, Static, Star };
+
/// Represents an array type, per C99 6.7.5.2 - Array Declarators.
class ArrayType : public Type, public llvm::FoldingSetNode {
-public:
- /// Capture whether this is a normal array (e.g. int X[4])
- /// an array with a static size (e.g. int X[static 4]), or an array
- /// with a star size (e.g. int X[*]).
- /// 'static' is only allowed on function parameters.
- enum ArraySizeModifier {
- Normal, Static, Star
- };
-
private:
/// The element type of the array.
QualType ElementType;
@@ -2958,6 +3215,8 @@ public:
QualType ElementType,
const llvm::APInt &NumElements);
+ unsigned getNumAddressingBits(const ASTContext &Context) const;
+
/// Determine the maximum number of active bits that an array's size
/// can require, which limits the maximum size of the array.
static unsigned getMaxSizeBits(const ASTContext &Context);
@@ -3005,7 +3264,7 @@ public:
static void Profile(llvm::FoldingSetNodeID &ID, QualType ET,
ArraySizeModifier SizeMod, unsigned TypeQuals) {
ID.AddPointer(ET.getAsOpaquePtr());
- ID.AddInteger(SizeMod);
+ ID.AddInteger(llvm::to_underlying(SizeMod));
ID.AddInteger(TypeQuals);
}
};
@@ -3081,8 +3340,6 @@ public:
class DependentSizedArrayType : public ArrayType {
friend class ASTContext; // ASTContext creates these.
- const ASTContext &Context;
-
/// An assignment expression that will instantiate to the
/// size of the array.
///
@@ -3093,8 +3350,8 @@ class DependentSizedArrayType : public ArrayType {
/// The range spanned by the left and right array brackets.
SourceRange Brackets;
- DependentSizedArrayType(const ASTContext &Context, QualType et, QualType can,
- Expr *e, ArraySizeModifier sm, unsigned tq,
+ DependentSizedArrayType(QualType et, QualType can, Expr *e,
+ ArraySizeModifier sm, unsigned tq,
SourceRange brackets);
public:
@@ -3117,7 +3374,7 @@ public:
return T->getTypeClass() == DependentSizedArray;
}
- void Profile(llvm::FoldingSetNodeID &ID) {
+ void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context) {
Profile(ID, Context, getElementType(),
getSizeModifier(), getIndexTypeCVRQualifiers(), getSizeExpr());
}
@@ -3141,14 +3398,12 @@ public:
class DependentAddressSpaceType : public Type, public llvm::FoldingSetNode {
friend class ASTContext;
- const ASTContext &Context;
Expr *AddrSpaceExpr;
QualType PointeeType;
SourceLocation loc;
- DependentAddressSpaceType(const ASTContext &Context, QualType PointeeType,
- QualType can, Expr *AddrSpaceExpr,
- SourceLocation loc);
+ DependentAddressSpaceType(QualType PointeeType, QualType can,
+ Expr *AddrSpaceExpr, SourceLocation loc);
public:
Expr *getAddrSpaceExpr() const { return AddrSpaceExpr; }
@@ -3162,7 +3417,7 @@ public:
return T->getTypeClass() == DependentAddressSpace;
}
- void Profile(llvm::FoldingSetNodeID &ID) {
+ void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context) {
Profile(ID, Context, getPointeeType(), getAddrSpaceExpr());
}
@@ -3183,7 +3438,6 @@ public:
class DependentSizedExtVectorType : public Type, public llvm::FoldingSetNode {
friend class ASTContext;
- const ASTContext &Context;
Expr *SizeExpr;
/// The element type of the array.
@@ -3191,8 +3445,8 @@ class DependentSizedExtVectorType : public Type, public llvm::FoldingSetNode {
SourceLocation loc;
- DependentSizedExtVectorType(const ASTContext &Context, QualType ElementType,
- QualType can, Expr *SizeExpr, SourceLocation loc);
+ DependentSizedExtVectorType(QualType ElementType, QualType can,
+ Expr *SizeExpr, SourceLocation loc);
public:
Expr *getSizeExpr() const { return SizeExpr; }
@@ -3206,7 +3460,7 @@ public:
return T->getTypeClass() == DependentSizedExtVector;
}
- void Profile(llvm::FoldingSetNodeID &ID) {
+ void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context) {
Profile(ID, Context, getElementType(), getSizeExpr());
}
@@ -3214,40 +3468,44 @@ public:
QualType ElementType, Expr *SizeExpr);
};
+enum class VectorKind {
+ /// not a target-specific vector type
+ Generic,
-/// Represents a GCC generic vector type. This type is created using
-/// __attribute__((vector_size(n)), where "n" specifies the vector size in
-/// bytes; or from an Altivec __vector or vector declaration.
-/// Since the constructor takes the number of vector elements, the
-/// client is responsible for converting the size into the number of elements.
-class VectorType : public Type, public llvm::FoldingSetNode {
-public:
- enum VectorKind {
- /// not a target-specific vector type
- GenericVector,
+ /// is AltiVec vector
+ AltiVecVector,
- /// is AltiVec vector
- AltiVecVector,
+ /// is AltiVec 'vector Pixel'
+ AltiVecPixel,
- /// is AltiVec 'vector Pixel'
- AltiVecPixel,
+ /// is AltiVec 'vector bool ...'
+ AltiVecBool,
- /// is AltiVec 'vector bool ...'
- AltiVecBool,
+ /// is ARM Neon vector
+ Neon,
- /// is ARM Neon vector
- NeonVector,
+ /// is ARM Neon polynomial vector
+ NeonPoly,
- /// is ARM Neon polynomial vector
- NeonPolyVector,
+ /// is AArch64 SVE fixed-length data vector
+ SveFixedLengthData,
- /// is AArch64 SVE fixed-length data vector
- SveFixedLengthDataVector,
+ /// is AArch64 SVE fixed-length predicate vector
+ SveFixedLengthPredicate,
- /// is AArch64 SVE fixed-length predicate vector
- SveFixedLengthPredicateVector
- };
+ /// is RISC-V RVV fixed-length data vector
+ RVVFixedLengthData,
+
+ /// is RISC-V RVV fixed-length mask vector
+ RVVFixedLengthMask,
+};
+/// Represents a GCC generic vector type. This type is created using
+/// __attribute__((vector_size(n)), where "n" specifies the vector size in
+/// bytes; or from an Altivec __vector or vector declaration.
+/// Since the constructor takes the number of vector elements, the
+/// client is responsible for converting the size into the number of elements.
+class VectorType : public Type, public llvm::FoldingSetNode {
protected:
friend class ASTContext; // ASTContext creates these.
@@ -3282,7 +3540,7 @@ public:
ID.AddPointer(ElementType.getAsOpaquePtr());
ID.AddInteger(NumElements);
ID.AddInteger(TypeClass);
- ID.AddInteger(VecKind);
+ ID.AddInteger(llvm::to_underlying(VecKind));
}
static bool classof(const Type *T) {
@@ -3302,21 +3560,19 @@ public:
class DependentVectorType : public Type, public llvm::FoldingSetNode {
friend class ASTContext;
- const ASTContext &Context;
QualType ElementType;
Expr *SizeExpr;
SourceLocation Loc;
- DependentVectorType(const ASTContext &Context, QualType ElementType,
- QualType CanonType, Expr *SizeExpr,
- SourceLocation Loc, VectorType::VectorKind vecKind);
+ DependentVectorType(QualType ElementType, QualType CanonType, Expr *SizeExpr,
+ SourceLocation Loc, VectorKind vecKind);
public:
Expr *getSizeExpr() const { return SizeExpr; }
QualType getElementType() const { return ElementType; }
SourceLocation getAttributeLoc() const { return Loc; }
- VectorType::VectorKind getVectorKind() const {
- return VectorType::VectorKind(VectorTypeBits.VecKind);
+ VectorKind getVectorKind() const {
+ return VectorKind(VectorTypeBits.VecKind);
}
bool isSugared() const { return false; }
@@ -3326,13 +3582,13 @@ public:
return T->getTypeClass() == DependentVector;
}
- void Profile(llvm::FoldingSetNodeID &ID) {
+ void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context) {
Profile(ID, Context, getElementType(), getSizeExpr(), getVectorKind());
}
static void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context,
QualType ElementType, const Expr *SizeExpr,
- VectorType::VectorKind VecKind);
+ VectorKind VecKind);
};
/// ExtVectorType - Extended vector type. This type is created using
@@ -3345,7 +3601,8 @@ class ExtVectorType : public VectorType {
friend class ASTContext; // ASTContext creates these.
ExtVectorType(QualType vecType, unsigned nElements, QualType canonType)
- : VectorType(ExtVector, vecType, nElements, canonType, GenericVector) {}
+ : VectorType(ExtVector, vecType, nElements, canonType,
+ VectorKind::Generic) {}
public:
static int getPointAccessorIdx(char c) {
@@ -3427,7 +3684,7 @@ public:
QualType getElementType() const { return ElementType; }
/// Valid elements types are the following:
- /// * an integer type (as in C2x 6.2.5p19), but excluding enumerated types
+ /// * an integer type (as in C23 6.2.5p22), but excluding enumerated types
/// and _Bool
/// * the standard floating types float or double
/// * a half-precision floating point type, if one is supported on the target
@@ -3450,10 +3707,6 @@ class ConstantMatrixType final : public MatrixType {
protected:
friend class ASTContext;
- /// The element type of the matrix.
- // FIXME: Appears to be unused? There is also MatrixType::ElementType...
- QualType ElementType;
-
/// Number of rows and columns.
unsigned NumRows;
unsigned NumColumns;
@@ -3512,30 +3765,24 @@ public:
class DependentSizedMatrixType final : public MatrixType {
friend class ASTContext;
- const ASTContext &Context;
Expr *RowExpr;
Expr *ColumnExpr;
SourceLocation loc;
- DependentSizedMatrixType(const ASTContext &Context, QualType ElementType,
- QualType CanonicalType, Expr *RowExpr,
- Expr *ColumnExpr, SourceLocation loc);
+ DependentSizedMatrixType(QualType ElementType, QualType CanonicalType,
+ Expr *RowExpr, Expr *ColumnExpr, SourceLocation loc);
public:
- QualType getElementType() const { return ElementType; }
Expr *getRowExpr() const { return RowExpr; }
Expr *getColumnExpr() const { return ColumnExpr; }
SourceLocation getAttributeLoc() const { return loc; }
- bool isSugared() const { return false; }
- QualType desugar() const { return QualType(this, 0); }
-
static bool classof(const Type *T) {
return T->getTypeClass() == DependentSizedMatrix;
}
- void Profile(llvm::FoldingSetNodeID &ID) {
+ void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context) {
Profile(ID, Context, getElementType(), getRowExpr(), getColumnExpr());
}
@@ -3787,13 +4034,64 @@ public:
/// A simple holder for various uncommon bits which do not fit in
/// FunctionTypeBitfields. Aligned to alignof(void *) to maintain the
- /// alignment of subsequent objects in TrailingObjects. You must update
- /// hasExtraBitfields in FunctionProtoType after adding extra data here.
+ /// alignment of subsequent objects in TrailingObjects.
struct alignas(void *) FunctionTypeExtraBitfields {
/// The number of types in the exception specification.
/// A whole unsigned is not needed here and according to
/// [implimits] 8 bits would be enough here.
- unsigned NumExceptionType;
+ unsigned NumExceptionType : 10;
+
+ LLVM_PREFERRED_TYPE(bool)
+ unsigned HasArmTypeAttributes : 1;
+
+ FunctionTypeExtraBitfields()
+ : NumExceptionType(0), HasArmTypeAttributes(false) {}
+ };
+
+ /// The AArch64 SME ACLE (Arm C/C++ Language Extensions) define a number
+ /// of function type attributes that can be set on function types, including
+ /// function pointers.
+ enum AArch64SMETypeAttributes : unsigned {
+ SME_NormalFunction = 0,
+ SME_PStateSMEnabledMask = 1 << 0,
+ SME_PStateSMCompatibleMask = 1 << 1,
+
+ // Describes the value of the state using ArmStateValue.
+ SME_ZAShift = 2,
+ SME_ZAMask = 0b111 << SME_ZAShift,
+ SME_ZT0Shift = 5,
+ SME_ZT0Mask = 0b111 << SME_ZT0Shift,
+
+ SME_AttributeMask =
+ 0b111'111'11 // We can't support more than 8 bits because of
+ // the bitmask in FunctionTypeExtraBitfields.
+ };
+
+ enum ArmStateValue : unsigned {
+ ARM_None = 0,
+ ARM_Preserves = 1,
+ ARM_In = 2,
+ ARM_Out = 3,
+ ARM_InOut = 4,
+ };
+
+ static ArmStateValue getArmZAState(unsigned AttrBits) {
+ return (ArmStateValue)((AttrBits & SME_ZAMask) >> SME_ZAShift);
+ }
+
+ static ArmStateValue getArmZT0State(unsigned AttrBits) {
+ return (ArmStateValue)((AttrBits & SME_ZT0Mask) >> SME_ZT0Shift);
+ }
+
+ /// A holder for Arm type attributes as described in the Arm C/C++
+ /// Language extensions which are not particularly common to all
+ /// types and therefore accounted separately from FunctionTypeBitfields.
+ struct alignas(void *) FunctionTypeArmAttributes {
+ /// Any AArch64 SME ACLE type attributes that need to be propagated
+ /// on declarations and function pointers.
+ unsigned AArch64SMEAttributes : 8;
+
+ FunctionTypeArmAttributes() : AArch64SMEAttributes(SME_NormalFunction) {}
};
protected:
@@ -3804,7 +4102,10 @@ protected:
}
Qualifiers getFastTypeQuals() const {
- return Qualifiers::fromFastMask(FunctionTypeBits.FastTypeQuals);
+ if (isFunctionProtoType())
+ return Qualifiers::fromFastMask(FunctionTypeBits.FastTypeQuals);
+
+ return Qualifiers();
}
public:
@@ -3889,7 +4190,8 @@ class FunctionProtoType final
public llvm::FoldingSetNode,
private llvm::TrailingObjects<
FunctionProtoType, QualType, SourceLocation,
- FunctionType::FunctionTypeExtraBitfields, FunctionType::ExceptionType,
+ FunctionType::FunctionTypeExtraBitfields,
+ FunctionType::FunctionTypeArmAttributes, FunctionType::ExceptionType,
Expr *, FunctionDecl *, FunctionType::ExtParameterInfo, Qualifiers> {
friend class ASTContext; // ASTContext creates these.
friend TrailingObjects;
@@ -3962,6 +4264,8 @@ public:
ExceptionSpecInfo() = default;
ExceptionSpecInfo(ExceptionSpecificationType EST) : Type(EST) {}
+
+ void instantiate();
};
/// Extra information about a function prototype. ExtProtoInfo is not
@@ -3969,24 +4273,44 @@ public:
/// the various bits of extra information about a function prototype.
struct ExtProtoInfo {
FunctionType::ExtInfo ExtInfo;
- bool Variadic : 1;
- bool HasTrailingReturn : 1;
+ unsigned Variadic : 1;
+ unsigned HasTrailingReturn : 1;
+ unsigned AArch64SMEAttributes : 8;
Qualifiers TypeQuals;
RefQualifierKind RefQualifier = RQ_None;
ExceptionSpecInfo ExceptionSpec;
const ExtParameterInfo *ExtParameterInfos = nullptr;
SourceLocation EllipsisLoc;
- ExtProtoInfo() : Variadic(false), HasTrailingReturn(false) {}
+ ExtProtoInfo()
+ : Variadic(false), HasTrailingReturn(false),
+ AArch64SMEAttributes(SME_NormalFunction) {}
ExtProtoInfo(CallingConv CC)
- : ExtInfo(CC), Variadic(false), HasTrailingReturn(false) {}
+ : ExtInfo(CC), Variadic(false), HasTrailingReturn(false),
+ AArch64SMEAttributes(SME_NormalFunction) {}
ExtProtoInfo withExceptionSpec(const ExceptionSpecInfo &ESI) {
ExtProtoInfo Result(*this);
Result.ExceptionSpec = ESI;
return Result;
}
+
+ bool requiresFunctionProtoTypeExtraBitfields() const {
+ return ExceptionSpec.Type == EST_Dynamic ||
+ requiresFunctionProtoTypeArmAttributes();
+ }
+
+ bool requiresFunctionProtoTypeArmAttributes() const {
+ return AArch64SMEAttributes != SME_NormalFunction;
+ }
+
+ void setArmSMEAttribute(AArch64SMETypeAttributes Kind, bool Enable = true) {
+ if (Enable)
+ AArch64SMEAttributes |= Kind;
+ else
+ AArch64SMEAttributes &= ~Kind;
+ }
};
private:
@@ -3998,6 +4322,10 @@ private:
return isVariadic();
}
+ unsigned numTrailingObjects(OverloadToken<FunctionTypeArmAttributes>) const {
+ return hasArmTypeAttributes();
+ }
+
unsigned numTrailingObjects(OverloadToken<FunctionTypeExtraBitfields>) const {
return hasExtraBitfields();
}
@@ -4078,15 +4406,18 @@ private:
}
/// Whether the trailing FunctionTypeExtraBitfields is present.
- static bool hasExtraBitfields(ExceptionSpecificationType EST) {
- // If the exception spec type is EST_Dynamic then we have > 0 exception
- // types and the exact number is stored in FunctionTypeExtraBitfields.
- return EST == EST_Dynamic;
+ bool hasExtraBitfields() const {
+ assert((getExceptionSpecType() != EST_Dynamic ||
+ FunctionTypeBits.HasExtraBitfields) &&
+ "ExtraBitfields are required for given ExceptionSpecType");
+ return FunctionTypeBits.HasExtraBitfields;
+
}
- /// Whether the trailing FunctionTypeExtraBitfields is present.
- bool hasExtraBitfields() const {
- return hasExtraBitfields(getExceptionSpecType());
+ bool hasArmTypeAttributes() const {
+ return FunctionTypeBits.HasExtraBitfields &&
+ getTrailingObjects<FunctionTypeExtraBitfields>()
+ ->HasArmTypeAttributes;
}
bool hasExtQualifiers() const {
@@ -4102,7 +4433,7 @@ public:
}
ArrayRef<QualType> getParamTypes() const {
- return llvm::makeArrayRef(param_type_begin(), param_type_end());
+ return llvm::ArrayRef(param_type_begin(), param_type_end());
}
ExtProtoInfo getExtProtoInfo() const {
@@ -4115,6 +4446,7 @@ public:
EPI.TypeQuals = getMethodQuals();
EPI.RefQualifier = getRefQualifier();
EPI.ExtParameterInfos = getExtParameterInfosOrNull();
+ EPI.AArch64SMEAttributes = getAArch64SMEAttributes();
return EPI;
}
@@ -4247,10 +4579,9 @@ public:
}
using param_type_iterator = const QualType *;
- using param_type_range = llvm::iterator_range<param_type_iterator>;
- param_type_range param_types() const {
- return param_type_range(param_type_begin(), param_type_end());
+ ArrayRef<QualType> param_types() const {
+ return llvm::ArrayRef(param_type_begin(), param_type_end());
}
param_type_iterator param_type_begin() const {
@@ -4264,7 +4595,7 @@ public:
using exception_iterator = const QualType *;
ArrayRef<QualType> exceptions() const {
- return llvm::makeArrayRef(exception_begin(), exception_end());
+ return llvm::ArrayRef(exception_begin(), exception_end());
}
exception_iterator exception_begin() const {
@@ -4297,6 +4628,15 @@ public:
return getTrailingObjects<ExtParameterInfo>();
}
+ /// Return a bitmask describing the SME attributes on the function type, see
+ /// AArch64SMETypeAttributes for their values.
+ unsigned getAArch64SMEAttributes() const {
+ if (!hasArmTypeAttributes())
+ return SME_NormalFunction;
+ return getTrailingObjects<FunctionTypeArmAttributes>()
+ ->AArch64SMEAttributes;
+ }
+
ExtParameterInfo getExtParameterInfo(unsigned I) const {
assert(I < getNumParams() && "parameter index out of range");
if (hasExtParameterInfos())
@@ -4370,11 +4710,45 @@ public:
}
};
-class TypedefType : public Type {
- TypedefNameDecl *Decl;
+class UsingType final : public Type,
+ public llvm::FoldingSetNode,
+ private llvm::TrailingObjects<UsingType, QualType> {
+ UsingShadowDecl *Found;
+ friend class ASTContext; // ASTContext creates these.
+ friend TrailingObjects;
-private:
+ UsingType(const UsingShadowDecl *Found, QualType Underlying, QualType Canon);
+
+public:
+ UsingShadowDecl *getFoundDecl() const { return Found; }
+ QualType getUnderlyingType() const;
+
+ bool isSugared() const { return true; }
+
+ // This always has the 'same' type as declared, but not necessarily identical.
+ QualType desugar() const { return getUnderlyingType(); }
+
+ // Internal helper, for debugging purposes.
+ bool typeMatchesDecl() const { return !UsingBits.hasTypeDifferentFromDecl; }
+
+ void Profile(llvm::FoldingSetNodeID &ID) {
+ Profile(ID, Found, typeMatchesDecl() ? QualType() : getUnderlyingType());
+ }
+ static void Profile(llvm::FoldingSetNodeID &ID, const UsingShadowDecl *Found,
+ QualType Underlying) {
+ ID.AddPointer(Found);
+ if (!Underlying.isNull())
+ Underlying.Profile(ID);
+ }
+ static bool classof(const Type *T) { return T->getTypeClass() == Using; }
+};
+
+class TypedefType final : public Type,
+ public llvm::FoldingSetNode,
+ private llvm::TrailingObjects<TypedefType, QualType> {
+ TypedefNameDecl *Decl;
friend class ASTContext; // ASTContext creates these.
+ friend TrailingObjects;
TypedefType(TypeClass tc, const TypedefNameDecl *D, QualType underlying,
QualType can);
@@ -4383,8 +4757,23 @@ public:
TypedefNameDecl *getDecl() const { return Decl; }
bool isSugared() const { return true; }
+
+ // This always has the 'same' type as declared, but not necessarily identical.
QualType desugar() const;
+ // Internal helper, for debugging purposes.
+ bool typeMatchesDecl() const { return !TypedefBits.hasTypeDifferentFromDecl; }
+
+ void Profile(llvm::FoldingSetNodeID &ID) {
+ Profile(ID, Decl, typeMatchesDecl() ? QualType() : desugar());
+ }
+ static void Profile(llvm::FoldingSetNodeID &ID, const TypedefNameDecl *Decl,
+ QualType Underlying) {
+ ID.AddPointer(Decl);
+ if (!Underlying.isNull())
+ Underlying.Profile(ID);
+ }
+
static bool classof(const Type *T) { return T->getTypeClass() == Typedef; }
};
@@ -4420,18 +4809,25 @@ public:
}
};
-/// Represents a `typeof` (or __typeof__) expression (a GCC extension).
+/// Represents a `typeof` (or __typeof__) expression (a C23 feature and GCC
+/// extension) or a `typeof_unqual` expression (a C23 feature).
class TypeOfExprType : public Type {
Expr *TOExpr;
protected:
friend class ASTContext; // ASTContext creates these.
- TypeOfExprType(Expr *E, QualType can = QualType());
+ TypeOfExprType(Expr *E, TypeOfKind Kind, QualType Can = QualType());
public:
Expr *getUnderlyingExpr() const { return TOExpr; }
+ /// Returns the kind of 'typeof' type this is.
+ TypeOfKind getKind() const {
+ return TypeOfBits.IsUnqual ? TypeOfKind::Unqualified
+ : TypeOfKind::Qualified;
+ }
+
/// Remove a single level of sugar.
QualType desugar() const;
@@ -4447,42 +4843,54 @@ public:
/// This class is used internally by the ASTContext to manage
/// canonical, dependent types, only. Clients will only see instances
/// of this class via TypeOfExprType nodes.
-class DependentTypeOfExprType
- : public TypeOfExprType, public llvm::FoldingSetNode {
- const ASTContext &Context;
-
+class DependentTypeOfExprType : public TypeOfExprType,
+ public llvm::FoldingSetNode {
public:
- DependentTypeOfExprType(const ASTContext &Context, Expr *E)
- : TypeOfExprType(E), Context(Context) {}
+ DependentTypeOfExprType(Expr *E, TypeOfKind Kind) : TypeOfExprType(E, Kind) {}
- void Profile(llvm::FoldingSetNodeID &ID) {
- Profile(ID, Context, getUnderlyingExpr());
+ void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context) {
+ Profile(ID, Context, getUnderlyingExpr(),
+ getKind() == TypeOfKind::Unqualified);
}
static void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context,
- Expr *E);
+ Expr *E, bool IsUnqual);
};
-/// Represents `typeof(type)`, a GCC extension.
+/// Represents `typeof(type)`, a C23 feature and GCC extension, or
+/// `typeof_unqual(type), a C23 feature.
class TypeOfType : public Type {
friend class ASTContext; // ASTContext creates these.
QualType TOType;
- TypeOfType(QualType T, QualType can)
- : Type(TypeOf, can, T->getDependence()), TOType(T) {
- assert(!isa<TypedefType>(can) && "Invalid canonical type");
+ TypeOfType(QualType T, QualType Can, TypeOfKind Kind)
+ : Type(TypeOf,
+ Kind == TypeOfKind::Unqualified ? Can.getAtomicUnqualifiedType()
+ : Can,
+ T->getDependence()),
+ TOType(T) {
+ TypeOfBits.IsUnqual = Kind == TypeOfKind::Unqualified;
}
public:
- QualType getUnderlyingType() const { return TOType; }
+ QualType getUnmodifiedType() const { return TOType; }
/// Remove a single level of sugar.
- QualType desugar() const { return getUnderlyingType(); }
+ QualType desugar() const {
+ QualType QT = getUnmodifiedType();
+ return TypeOfBits.IsUnqual ? QT.getAtomicUnqualifiedType() : QT;
+ }
/// Returns whether this type directly provides sugar.
bool isSugared() const { return true; }
+ /// Returns the kind of 'typeof' type this is.
+ TypeOfKind getKind() const {
+ return TypeOfBits.IsUnqual ? TypeOfKind::Unqualified
+ : TypeOfKind::Qualified;
+ }
+
static bool classof(const Type *T) { return T->getTypeClass() == TypeOf; }
};
@@ -4516,12 +4924,10 @@ public:
/// canonical, dependent types, only. Clients will only see instances
/// of this class via DecltypeType nodes.
class DependentDecltypeType : public DecltypeType, public llvm::FoldingSetNode {
- const ASTContext &Context;
-
public:
- DependentDecltypeType(const ASTContext &Context, Expr *E);
+ DependentDecltypeType(Expr *E, QualType UnderlyingTpe);
- void Profile(llvm::FoldingSetNodeID &ID) {
+ void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context) {
Profile(ID, Context, getUnderlyingExpr());
}
@@ -4533,7 +4939,8 @@ public:
class UnaryTransformType : public Type {
public:
enum UTTKind {
- EnumUnderlyingType
+#define TRANSFORM_TYPE_TRAIT_DEF(Enum, _) Enum,
+#include "clang/Basic/TransformTypeTraits.def"
};
private:
@@ -4714,9 +5121,11 @@ public:
bool isMSTypeSpec() const;
+ bool isWebAssemblyFuncrefSpec() const;
+
bool isCallingConv() const;
- llvm::Optional<NullabilityKind> getImmediateNullability() const;
+ std::optional<NullabilityKind> getImmediateNullability() const;
/// Retrieve the attribute kind corresponding to the given
/// nullability kind.
@@ -4746,7 +5155,7 @@ public:
/// to the underlying modified type.
///
/// \returns the top-level nullability, if present.
- static Optional<NullabilityKind> stripOuterNullability(QualType &T);
+ static std::optional<NullabilityKind> stripOuterNullability(QualType &T);
void Profile(llvm::FoldingSetNodeID &ID) {
Profile(ID, getAttrKind(), ModifiedType, EquivalentType);
@@ -4764,6 +5173,40 @@ public:
}
};
+class BTFTagAttributedType : public Type, public llvm::FoldingSetNode {
+private:
+ friend class ASTContext; // ASTContext creates these
+
+ QualType WrappedType;
+ const BTFTypeTagAttr *BTFAttr;
+
+ BTFTagAttributedType(QualType Canon, QualType Wrapped,
+ const BTFTypeTagAttr *BTFAttr)
+ : Type(BTFTagAttributed, Canon, Wrapped->getDependence()),
+ WrappedType(Wrapped), BTFAttr(BTFAttr) {}
+
+public:
+ QualType getWrappedType() const { return WrappedType; }
+ const BTFTypeTagAttr *getAttr() const { return BTFAttr; }
+
+ bool isSugared() const { return true; }
+ QualType desugar() const { return getWrappedType(); }
+
+ void Profile(llvm::FoldingSetNodeID &ID) {
+ Profile(ID, WrappedType, BTFAttr);
+ }
+
+ static void Profile(llvm::FoldingSetNodeID &ID, QualType Wrapped,
+ const BTFTypeTagAttr *BTFAttr) {
+ ID.AddPointer(Wrapped.getAsOpaquePtr());
+ ID.AddPointer(BTFAttr);
+ }
+
+ static bool classof(const Type *T) {
+ return T->getTypeClass() == BTFTagAttributed;
+ }
+};
+
class TemplateTypeParmType : public Type, public llvm::FoldingSetNode {
friend class ASTContext; // ASTContext creates these
@@ -4843,40 +5286,60 @@ public:
/// been replaced with these. They are used solely to record that a
/// type was originally written as a template type parameter;
/// therefore they are never canonical.
-class SubstTemplateTypeParmType : public Type, public llvm::FoldingSetNode {
+class SubstTemplateTypeParmType final
+ : public Type,
+ public llvm::FoldingSetNode,
+ private llvm::TrailingObjects<SubstTemplateTypeParmType, QualType> {
friend class ASTContext;
+ friend class llvm::TrailingObjects<SubstTemplateTypeParmType, QualType>;
- // The original type parameter.
- const TemplateTypeParmType *Replaced;
+ Decl *AssociatedDecl;
- SubstTemplateTypeParmType(const TemplateTypeParmType *Param, QualType Canon)
- : Type(SubstTemplateTypeParm, Canon, Canon->getDependence()),
- Replaced(Param) {}
+ SubstTemplateTypeParmType(QualType Replacement, Decl *AssociatedDecl,
+ unsigned Index, std::optional<unsigned> PackIndex);
public:
- /// Gets the template parameter that was substituted for.
- const TemplateTypeParmType *getReplacedParameter() const {
- return Replaced;
- }
-
/// Gets the type that was substituted for the template
/// parameter.
QualType getReplacementType() const {
- return getCanonicalTypeInternal();
+ return SubstTemplateTypeParmTypeBits.HasNonCanonicalUnderlyingType
+ ? *getTrailingObjects<QualType>()
+ : getCanonicalTypeInternal();
+ }
+
+ /// A template-like entity which owns the whole pattern being substituted.
+ /// This will usually own a set of template parameters, or in some
+ /// cases might even be a template parameter itself.
+ Decl *getAssociatedDecl() const { return AssociatedDecl; }
+
+ /// Gets the template parameter declaration that was substituted for.
+ const TemplateTypeParmDecl *getReplacedParameter() const;
+
+ /// Returns the index of the replaced parameter in the associated declaration.
+ /// This should match the result of `getReplacedParameter()->getIndex()`.
+ unsigned getIndex() const { return SubstTemplateTypeParmTypeBits.Index; }
+
+ std::optional<unsigned> getPackIndex() const {
+ if (SubstTemplateTypeParmTypeBits.PackIndex == 0)
+ return std::nullopt;
+ return SubstTemplateTypeParmTypeBits.PackIndex - 1;
}
bool isSugared() const { return true; }
QualType desugar() const { return getReplacementType(); }
void Profile(llvm::FoldingSetNodeID &ID) {
- Profile(ID, getReplacedParameter(), getReplacementType());
+ Profile(ID, getReplacementType(), getAssociatedDecl(), getIndex(),
+ getPackIndex());
}
- static void Profile(llvm::FoldingSetNodeID &ID,
- const TemplateTypeParmType *Replaced,
- QualType Replacement) {
- ID.AddPointer(Replaced);
- ID.AddPointer(Replacement.getAsOpaquePtr());
+ static void Profile(llvm::FoldingSetNodeID &ID, QualType Replacement,
+ const Decl *AssociatedDecl, unsigned Index,
+ std::optional<unsigned> PackIndex) {
+ Replacement.Profile(ID);
+ ID.AddPointer(AssociatedDecl);
+ ID.AddInteger(Index);
+ ID.AddInteger(PackIndex ? *PackIndex - 1 : 0);
}
static bool classof(const Type *T) {
@@ -4899,24 +5362,33 @@ public:
class SubstTemplateTypeParmPackType : public Type, public llvm::FoldingSetNode {
friend class ASTContext;
- /// The original type parameter.
- const TemplateTypeParmType *Replaced;
-
/// A pointer to the set of template arguments that this
/// parameter pack is instantiated with.
const TemplateArgument *Arguments;
- SubstTemplateTypeParmPackType(const TemplateTypeParmType *Param,
- QualType Canon,
+ llvm::PointerIntPair<Decl *, 1, bool> AssociatedDeclAndFinal;
+
+ SubstTemplateTypeParmPackType(QualType Canon, Decl *AssociatedDecl,
+ unsigned Index, bool Final,
const TemplateArgument &ArgPack);
public:
- IdentifierInfo *getIdentifier() const { return Replaced->getIdentifier(); }
+ IdentifierInfo *getIdentifier() const;
- /// Gets the template parameter that was substituted for.
- const TemplateTypeParmType *getReplacedParameter() const {
- return Replaced;
- }
+ /// A template-like entity which owns the whole pattern being substituted.
+ /// This will usually own a set of template parameters, or in some
+ /// cases might even be a template parameter itself.
+ Decl *getAssociatedDecl() const;
+
+ /// Gets the template parameter declaration that was substituted for.
+ const TemplateTypeParmDecl *getReplacedParameter() const;
+
+ /// Returns the index of the replaced parameter in the associated declaration.
+ /// This should match the result of `getReplacedParameter()->getIndex()`.
+ unsigned getIndex() const { return SubstTemplateTypeParmPackTypeBits.Index; }
+
+ // When true the substitution will be 'Final' (subst node won't be placed).
+ bool getFinal() const;
unsigned getNumArgs() const {
return SubstTemplateTypeParmPackTypeBits.NumArgs;
@@ -4928,8 +5400,8 @@ public:
TemplateArgument getArgumentPack() const;
void Profile(llvm::FoldingSetNodeID &ID);
- static void Profile(llvm::FoldingSetNodeID &ID,
- const TemplateTypeParmType *Replaced,
+ static void Profile(llvm::FoldingSetNodeID &ID, const Decl *AssociatedDecl,
+ unsigned Index, bool Final,
const TemplateArgument &ArgPack);
static bool classof(const Type *T) {
@@ -4946,29 +5418,29 @@ public:
/// type-dependent, there is no deduced type and the type is canonical. In
/// the latter case, it is also a dependent type.
class DeducedType : public Type {
+ QualType DeducedAsType;
+
protected:
DeducedType(TypeClass TC, QualType DeducedAsType,
- TypeDependence ExtraDependence)
- : Type(TC,
- // FIXME: Retain the sugared deduced type?
- DeducedAsType.isNull() ? QualType(this, 0)
- : DeducedAsType.getCanonicalType(),
+ TypeDependence ExtraDependence, QualType Canon)
+ : Type(TC, Canon,
ExtraDependence | (DeducedAsType.isNull()
? TypeDependence::None
: DeducedAsType->getDependence() &
- ~TypeDependence::VariablyModified)) {}
+ ~TypeDependence::VariablyModified)),
+ DeducedAsType(DeducedAsType) {}
public:
- bool isSugared() const { return !isCanonicalUnqualified(); }
- QualType desugar() const { return getCanonicalTypeInternal(); }
-
- /// Get the type deduced for this placeholder type, or null if it's
- /// either not been deduced or was deduced to a dependent type.
- QualType getDeducedType() const {
- return !isCanonicalUnqualified() ? getCanonicalTypeInternal() : QualType();
+ bool isSugared() const { return !DeducedAsType.isNull(); }
+ QualType desugar() const {
+ return isSugared() ? DeducedAsType : QualType(this, 0);
}
+
+ /// Get the type deduced for this placeholder type, or null if it
+ /// has not been deduced.
+ QualType getDeducedType() const { return DeducedAsType; }
bool isDeduced() const {
- return !isCanonicalUnqualified() || isDependentType();
+ return !DeducedAsType.isNull() || isDependentType();
}
static bool classof(const Type *T) {
@@ -4979,38 +5451,19 @@ public:
/// Represents a C++11 auto or C++14 decltype(auto) type, possibly constrained
/// by a type-constraint.
-class alignas(8) AutoType : public DeducedType, public llvm::FoldingSetNode {
+class AutoType : public DeducedType, public llvm::FoldingSetNode {
friend class ASTContext; // ASTContext creates these
ConceptDecl *TypeConstraintConcept;
AutoType(QualType DeducedAsType, AutoTypeKeyword Keyword,
- TypeDependence ExtraDependence, ConceptDecl *CD,
+ TypeDependence ExtraDependence, QualType Canon, ConceptDecl *CD,
ArrayRef<TemplateArgument> TypeConstraintArgs);
- const TemplateArgument *getArgBuffer() const {
- return reinterpret_cast<const TemplateArgument*>(this+1);
- }
-
- TemplateArgument *getArgBuffer() {
- return reinterpret_cast<TemplateArgument*>(this+1);
- }
-
public:
- /// Retrieve the template arguments.
- const TemplateArgument *getArgs() const {
- return getArgBuffer();
- }
-
- /// Retrieve the number of template arguments.
- unsigned getNumArgs() const {
- return AutoTypeBits.NumArgs;
- }
-
- const TemplateArgument &getArg(unsigned Idx) const; // in TemplateBase.h
-
ArrayRef<TemplateArgument> getTypeConstraintArguments() const {
- return {getArgs(), getNumArgs()};
+ return {reinterpret_cast<const TemplateArgument *>(this + 1),
+ AutoTypeBits.NumArgs};
}
ConceptDecl *getTypeConstraintConcept() const {
@@ -5025,15 +5478,15 @@ public:
return getKeyword() == AutoTypeKeyword::DecltypeAuto;
}
- AutoTypeKeyword getKeyword() const {
- return (AutoTypeKeyword)AutoTypeBits.Keyword;
+ bool isGNUAutoType() const {
+ return getKeyword() == AutoTypeKeyword::GNUAutoType;
}
- void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context) {
- Profile(ID, Context, getDeducedType(), getKeyword(), isDependentType(),
- getTypeConstraintConcept(), getTypeConstraintArguments());
+ AutoTypeKeyword getKeyword() const {
+ return (AutoTypeKeyword)AutoTypeBits.Keyword;
}
+ void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context);
static void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context,
QualType Deduced, AutoTypeKeyword Keyword,
bool IsDependent, ConceptDecl *CD,
@@ -5059,7 +5512,9 @@ class DeducedTemplateSpecializationType : public DeducedType,
toTypeDependence(Template.getDependence()) |
(IsDeducedAsDependent
? TypeDependence::DependentInstantiation
- : TypeDependence::None)),
+ : TypeDependence::None),
+ DeducedAsType.isNull() ? QualType(this, 0)
+ : DeducedAsType.getCanonicalType()),
Template(Template) {}
public:
@@ -5073,8 +5528,10 @@ public:
static void Profile(llvm::FoldingSetNodeID &ID, TemplateName Template,
QualType Deduced, bool IsDependent) {
Template.Profile(ID);
- ID.AddPointer(Deduced.getAsOpaquePtr());
- ID.AddBoolean(IsDependent);
+ QualType CanonicalType =
+ Deduced.isNull() ? Deduced : Deduced.getCanonicalType();
+ ID.AddPointer(CanonicalType.getAsOpaquePtr());
+ ID.AddBoolean(IsDependent || Template.isDependent());
}
static bool classof(const Type *T) {
@@ -5102,9 +5559,7 @@ public:
/// TemplateArguments, followed by a QualType representing the
/// non-canonical aliased type when the template is a type alias
/// template.
-class alignas(8) TemplateSpecializationType
- : public Type,
- public llvm::FoldingSetNode {
+class TemplateSpecializationType : public Type, public llvm::FoldingSetNode {
friend class ASTContext; // ASTContext creates these
/// The name of the template being specialized. This is
@@ -5167,35 +5622,14 @@ public:
/// Get the aliased type, if this is a specialization of a type alias
/// template.
- QualType getAliasedType() const {
- assert(isTypeAlias() && "not a type alias template specialization");
- return *reinterpret_cast<const QualType*>(end());
- }
-
- using iterator = const TemplateArgument *;
-
- iterator begin() const { return getArgs(); }
- iterator end() const; // defined inline in TemplateBase.h
+ QualType getAliasedType() const;
/// Retrieve the name of the template that we are specializing.
TemplateName getTemplateName() const { return Template; }
- /// Retrieve the template arguments.
- const TemplateArgument *getArgs() const {
- return reinterpret_cast<const TemplateArgument *>(this + 1);
- }
-
- /// Retrieve the number of template arguments.
- unsigned getNumArgs() const {
- return TemplateSpecializationTypeBits.NumArgs;
- }
-
- /// Retrieve a specific template argument as a type.
- /// \pre \c isArgType(Arg)
- const TemplateArgument &getArg(unsigned Idx) const; // in TemplateBase.h
-
ArrayRef<TemplateArgument> template_arguments() const {
- return {getArgs(), getNumArgs()};
+ return {reinterpret_cast<const TemplateArgument *>(this + 1),
+ TemplateSpecializationTypeBits.NumArgs};
}
bool isSugared() const {
@@ -5206,12 +5640,7 @@ public:
return isTypeAlias() ? getAliasedType() : getCanonicalTypeInternal();
}
- void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Ctx) {
- Profile(ID, Template, template_arguments(), Ctx);
- if (isTypeAlias())
- getAliasedType().Profile(ID);
- }
-
+ void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Ctx);
static void Profile(llvm::FoldingSetNodeID &ID, TemplateName T,
ArrayRef<TemplateArgument> Args,
const ASTContext &Context);
@@ -5238,6 +5667,13 @@ void printTemplateArgumentList(raw_ostream &OS,
const PrintingPolicy &Policy,
const TemplateParameterList *TPL = nullptr);
+/// Make a best-effort determination of whether the type T can be produced by
+/// substituting Args into the default argument of Param.
+bool isSubstitutedDefaultArgument(ASTContext &Ctx, TemplateArgument Arg,
+ const NamedDecl *Param,
+ ArrayRef<TemplateArgument> Args,
+ unsigned Depth);
+
/// The injected class name of a C++ class template or class
/// template partial specialization. Used to record that a type was
/// spelled with a bare identifier rather than as a template-id; the
@@ -5306,48 +5742,48 @@ public:
}
};
-/// The kind of a tag type.
-enum TagTypeKind {
- /// The "struct" keyword.
- TTK_Struct,
-
- /// The "__interface" keyword.
- TTK_Interface,
-
- /// The "union" keyword.
- TTK_Union,
-
- /// The "class" keyword.
- TTK_Class,
-
- /// The "enum" keyword.
- TTK_Enum
-};
-
/// The elaboration keyword that precedes a qualified type name or
/// introduces an elaborated-type-specifier.
-enum ElaboratedTypeKeyword {
+enum class ElaboratedTypeKeyword {
/// The "struct" keyword introduces the elaborated-type-specifier.
- ETK_Struct,
+ Struct,
/// The "__interface" keyword introduces the elaborated-type-specifier.
- ETK_Interface,
+ Interface,
/// The "union" keyword introduces the elaborated-type-specifier.
- ETK_Union,
+ Union,
/// The "class" keyword introduces the elaborated-type-specifier.
- ETK_Class,
+ Class,
/// The "enum" keyword introduces the elaborated-type-specifier.
- ETK_Enum,
+ Enum,
/// The "typename" keyword precedes the qualified type name, e.g.,
/// \c typename T::type.
- ETK_Typename,
+ Typename,
/// No keyword precedes the qualified type name.
- ETK_None
+ None
+};
+
+/// The kind of a tag type.
+enum class TagTypeKind {
+ /// The "struct" keyword.
+ Struct,
+
+ /// The "__interface" keyword.
+ Interface,
+
+ /// The "union" keyword.
+ Union,
+
+ /// The "class" keyword.
+ Class,
+
+ /// The "enum" keyword.
+ Enum
};
/// A helper class for Type nodes having an ElaboratedTypeKeyword.
@@ -5359,7 +5795,7 @@ protected:
TypeWithKeyword(ElaboratedTypeKeyword Keyword, TypeClass tc,
QualType Canonical, TypeDependence Dependence)
: Type(tc, Canonical, Dependence) {
- TypeWithKeywordBits.Keyword = Keyword;
+ TypeWithKeywordBits.Keyword = llvm::to_underlying(Keyword);
}
public:
@@ -5436,9 +5872,6 @@ class ElaboratedType final
ElaboratedTypeBits.HasOwnedTagDecl = true;
*getTrailingObjects<TagDecl *>() = OwnedTagDecl;
}
- assert(!(Keyword == ETK_None && NNS == nullptr) &&
- "ElaboratedType cannot have elaborated type keyword "
- "and name qualifier both null.");
}
public:
@@ -5468,7 +5901,7 @@ public:
static void Profile(llvm::FoldingSetNodeID &ID, ElaboratedTypeKeyword Keyword,
NestedNameSpecifier *NNS, QualType NamedType,
TagDecl *OwnedTagDecl) {
- ID.AddInteger(Keyword);
+ ID.AddInteger(llvm::to_underlying(Keyword));
ID.AddPointer(NNS);
NamedType.Profile(ID);
ID.AddPointer(OwnedTagDecl);
@@ -5527,7 +5960,7 @@ public:
static void Profile(llvm::FoldingSetNodeID &ID, ElaboratedTypeKeyword Keyword,
NestedNameSpecifier *NNS, const IdentifierInfo *Name) {
- ID.AddInteger(Keyword);
+ ID.AddInteger(llvm::to_underlying(Keyword));
ID.AddPointer(NNS);
ID.AddPointer(Name);
}
@@ -5540,9 +5973,8 @@ public:
/// Represents a template specialization type whose template cannot be
/// resolved, e.g.
/// A<T>::template B<T>
-class alignas(8) DependentTemplateSpecializationType
- : public TypeWithKeyword,
- public llvm::FoldingSetNode {
+class DependentTemplateSpecializationType : public TypeWithKeyword,
+ public llvm::FoldingSetNode {
friend class ASTContext; // ASTContext creates these
/// The nested name specifier containing the qualifier.
@@ -5557,44 +5989,20 @@ class alignas(8) DependentTemplateSpecializationType
ArrayRef<TemplateArgument> Args,
QualType Canon);
- const TemplateArgument *getArgBuffer() const {
- return reinterpret_cast<const TemplateArgument*>(this+1);
- }
-
- TemplateArgument *getArgBuffer() {
- return reinterpret_cast<TemplateArgument*>(this+1);
- }
-
public:
NestedNameSpecifier *getQualifier() const { return NNS; }
const IdentifierInfo *getIdentifier() const { return Name; }
- /// Retrieve the template arguments.
- const TemplateArgument *getArgs() const {
- return getArgBuffer();
- }
-
- /// Retrieve the number of template arguments.
- unsigned getNumArgs() const {
- return DependentTemplateSpecializationTypeBits.NumArgs;
- }
-
- const TemplateArgument &getArg(unsigned Idx) const; // in TemplateBase.h
-
ArrayRef<TemplateArgument> template_arguments() const {
- return {getArgs(), getNumArgs()};
+ return {reinterpret_cast<const TemplateArgument *>(this + 1),
+ DependentTemplateSpecializationTypeBits.NumArgs};
}
- using iterator = const TemplateArgument *;
-
- iterator begin() const { return getArgs(); }
- iterator end() const; // inline in TemplateBase.h
-
bool isSugared() const { return false; }
QualType desugar() const { return QualType(this, 0); }
void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context) {
- Profile(ID, Context, getKeyword(), NNS, Name, {getArgs(), getNumArgs()});
+ Profile(ID, Context, getKeyword(), NNS, Name, template_arguments());
}
static void Profile(llvm::FoldingSetNodeID &ID,
@@ -5638,7 +6046,7 @@ class PackExpansionType : public Type, public llvm::FoldingSetNode {
QualType Pattern;
PackExpansionType(QualType Pattern, QualType Canon,
- Optional<unsigned> NumExpansions)
+ std::optional<unsigned> NumExpansions)
: Type(PackExpansion, Canon,
(Pattern->getDependence() | TypeDependence::Dependent |
TypeDependence::Instantiation) &
@@ -5656,10 +6064,10 @@ public:
/// Retrieve the number of expansions that this pack expansion will
/// generate, if known.
- Optional<unsigned> getNumExpansions() const {
+ std::optional<unsigned> getNumExpansions() const {
if (PackExpansionTypeBits.NumExpansions)
return PackExpansionTypeBits.NumExpansions - 1;
- return None;
+ return std::nullopt;
}
bool isSugared() const { return false; }
@@ -5670,9 +6078,9 @@ public:
}
static void Profile(llvm::FoldingSetNodeID &ID, QualType Pattern,
- Optional<unsigned> NumExpansions) {
+ std::optional<unsigned> NumExpansions) {
ID.AddPointer(Pattern.getAsOpaquePtr());
- ID.AddBoolean(NumExpansions.hasValue());
+ ID.AddBoolean(NumExpansions.has_value());
if (NumExpansions)
ID.AddInteger(*NumExpansions);
}
@@ -5927,8 +6335,7 @@ public:
/// Retrieve the type arguments of this object type as they were
/// written.
ArrayRef<QualType> getTypeArgsAsWritten() const {
- return llvm::makeArrayRef(getTypeArgStorage(),
- ObjCObjectTypeBits.NumTypeArgs);
+ return llvm::ArrayRef(getTypeArgStorage(), ObjCObjectTypeBits.NumTypeArgs);
}
/// Whether this is a "__kindof" type as written.
@@ -6018,10 +6425,9 @@ inline ObjCProtocolDecl **ObjCTypeParamType::getProtocolStorageImpl() {
class ObjCInterfaceType : public ObjCObjectType {
friend class ASTContext; // ASTContext creates these.
friend class ASTReader;
- friend class ObjCInterfaceDecl;
template <class T> friend class serialization::AbstractTypeReader;
- mutable ObjCInterfaceDecl *Decl;
+ ObjCInterfaceDecl *Decl;
ObjCInterfaceType(const ObjCInterfaceDecl *D)
: ObjCObjectType(Nonce_ObjCInterface),
@@ -6029,7 +6435,7 @@ class ObjCInterfaceType : public ObjCObjectType {
public:
/// Get the declaration of this interface.
- ObjCInterfaceDecl *getDecl() const { return Decl; }
+ ObjCInterfaceDecl *getDecl() const;
bool isSugared() const { return false; }
QualType desugar() const { return QualType(this, 0); }
@@ -6306,13 +6712,14 @@ public:
};
/// A fixed int type of a specified bitwidth.
-class ExtIntType final : public Type, public llvm::FoldingSetNode {
+class BitIntType final : public Type, public llvm::FoldingSetNode {
friend class ASTContext;
+ LLVM_PREFERRED_TYPE(bool)
unsigned IsUnsigned : 1;
unsigned NumBits : 24;
protected:
- ExtIntType(bool isUnsigned, unsigned NumBits);
+ BitIntType(bool isUnsigned, unsigned NumBits);
public:
bool isUnsigned() const { return IsUnsigned; }
@@ -6322,7 +6729,7 @@ public:
bool isSugared() const { return false; }
QualType desugar() const { return QualType(this, 0); }
- void Profile(llvm::FoldingSetNodeID &ID) {
+ void Profile(llvm::FoldingSetNodeID &ID) const {
Profile(ID, isUnsigned(), getNumBits());
}
@@ -6332,17 +6739,15 @@ public:
ID.AddInteger(NumBits);
}
- static bool classof(const Type *T) { return T->getTypeClass() == ExtInt; }
+ static bool classof(const Type *T) { return T->getTypeClass() == BitInt; }
};
-class DependentExtIntType final : public Type, public llvm::FoldingSetNode {
+class DependentBitIntType final : public Type, public llvm::FoldingSetNode {
friend class ASTContext;
- const ASTContext &Context;
llvm::PointerIntPair<Expr*, 1, bool> ExprAndUnsigned;
protected:
- DependentExtIntType(const ASTContext &Context, bool IsUnsigned,
- Expr *NumBits);
+ DependentBitIntType(bool IsUnsigned, Expr *NumBits);
public:
bool isUnsigned() const;
@@ -6352,14 +6757,14 @@ public:
bool isSugared() const { return false; }
QualType desugar() const { return QualType(this, 0); }
- void Profile(llvm::FoldingSetNodeID &ID) {
+ void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context) {
Profile(ID, Context, isUnsigned(), getNumBitsExpr());
}
static void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context,
bool IsUnsigned, Expr *NumBitsExpr);
static bool classof(const Type *T) {
- return T->getTypeClass() == DependentExtInt;
+ return T->getTypeClass() == DependentBitInt;
}
};
@@ -6402,7 +6807,7 @@ class alignas(8) TypeSourceInfo {
QualType Ty;
- TypeSourceInfo(QualType ty) : Ty(ty) {}
+ TypeSourceInfo(QualType ty, size_t DataSize); // implemented in TypeLoc.h
public:
/// Return the type wrapped by this type source info.
@@ -6432,6 +6837,19 @@ inline const Type *QualType::getTypePtrOrNull() const {
return (isNull() ? nullptr : getCommonPtr()->BaseType);
}
+inline bool QualType::isReferenceable() const {
+ // C++ [defns.referenceable]
+ // type that is either an object type, a function type that does not have
+ // cv-qualifiers or a ref-qualifier, or a reference type.
+ const Type &Self = **this;
+ if (Self.isObjectType() || Self.isReferenceType())
+ return true;
+ if (const auto *F = Self.getAs<FunctionProtoType>())
+ return F->getMethodQuals().empty() && F->getRefQualifier() == RQ_None;
+
+ return false;
+}
+
inline SplitQualType QualType::split() const {
if (!hasLocalNonFastQualifiers())
return SplitQualType(getTypePtrUnsafe(),
@@ -6530,15 +6948,6 @@ inline void QualType::removeLocalVolatile() {
removeLocalFastQualifiers(Qualifiers::Volatile);
}
-inline void QualType::removeLocalCVRQualifiers(unsigned Mask) {
- assert(!(Mask & ~Qualifiers::CVRMask) && "mask has non-CVR bits");
- static_assert((int)Qualifiers::CVRMask == (int)Qualifiers::FastMask,
- "Fast bits differ from CVR bits!");
-
- // Fast path: we don't need to touch the slow qualifiers.
- removeLocalFastQualifiers(Mask);
-}
-
/// Check if this type has any address space qualifier.
inline bool QualType::hasAddressSpace() const {
return getQualifiers().hasAddressSpace();
@@ -6782,6 +7191,12 @@ inline bool Type::isExtVectorType() const {
return isa<ExtVectorType>(CanonicalType);
}
+inline bool Type::isExtVectorBoolType() const {
+ if (!isExtVectorType())
+ return false;
+ return cast<ExtVectorType>(CanonicalType)->getElementType()->isBooleanType();
+}
+
inline bool Type::isMatrixType() const {
return isa<MatrixType>(CanonicalType);
}
@@ -6890,8 +7305,8 @@ inline bool Type::isPipeType() const {
return isa<PipeType>(CanonicalType);
}
-inline bool Type::isExtIntType() const {
- return isa<ExtIntType>(CanonicalType);
+inline bool Type::isBitIntType() const {
+ return isa<BitIntType>(CanonicalType);
}
#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
@@ -6976,6 +7391,10 @@ inline bool Type::isFloat128Type() const {
return isSpecificBuiltinType(BuiltinType::Float128);
}
+inline bool Type::isIbm128Type() const {
+ return isSpecificBuiltinType(BuiltinType::Ibm128);
+}
+
inline bool Type::isNullPtrType() const {
return isSpecificBuiltinType(BuiltinType::NullPtr);
}
@@ -6993,7 +7412,7 @@ inline bool Type::isIntegerType() const {
return IsEnumDeclComplete(ET->getDecl()) &&
!IsEnumDeclScoped(ET->getDecl());
}
- return isExtIntType();
+ return isBitIntType();
}
inline bool Type::isFixedPointType() const {
@@ -7051,7 +7470,7 @@ inline bool Type::isScalarType() const {
isa<MemberPointerType>(CanonicalType) ||
isa<ComplexType>(CanonicalType) ||
isa<ObjCObjectPointerType>(CanonicalType) ||
- isExtIntType();
+ isBitIntType();
}
inline bool Type::isIntegralOrEnumerationType() const {
@@ -7064,7 +7483,7 @@ inline bool Type::isIntegralOrEnumerationType() const {
if (const auto *ET = dyn_cast<EnumType>(CanonicalType))
return IsEnumDeclComplete(ET->getDecl());
- return isExtIntType();
+ return isBitIntType();
}
inline bool Type::isBooleanType() const {
@@ -7126,7 +7545,7 @@ inline const Type *Type::getPointeeOrArrayElementType() const {
/// spaces into a diagnostic with <<.
inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &PD,
LangAS AS) {
- PD.AddTaggedVal(static_cast<std::underlying_type_t<LangAS>>(AS),
+ PD.AddTaggedVal(llvm::to_underlying(AS),
DiagnosticsEngine::ArgumentKind::ak_addrspace);
return PD;
}
@@ -7144,7 +7563,7 @@ inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &PD,
/// into a diagnostic with <<.
inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &PD,
QualType T) {
- PD.AddTaggedVal(reinterpret_cast<intptr_t>(T.getAsOpaquePtr()),
+ PD.AddTaggedVal(reinterpret_cast<uint64_t>(T.getAsOpaquePtr()),
DiagnosticsEngine::ak_qualtype);
return PD;
}
@@ -7191,6 +7610,8 @@ template <typename T> const T *Type::getAsAdjusted() const {
while (Ty) {
if (const auto *A = dyn_cast<AttributedType>(Ty))
Ty = A->getModifiedType().getTypePtr();
+ else if (const auto *A = dyn_cast<BTFTagAttributedType>(Ty))
+ Ty = A->getWrappedType().getTypePtr();
else if (const auto *E = dyn_cast<ElaboratedType>(Ty))
Ty = E->desugar().getTypePtr();
else if (const auto *P = dyn_cast<ParenType>(Ty))
diff --git a/contrib/llvm-project/clang/include/clang/AST/TypeLoc.h b/contrib/llvm-project/clang/include/clang/AST/TypeLoc.h
index 65e95d52c303..471deb14aba5 100644
--- a/contrib/llvm-project/clang/include/clang/AST/TypeLoc.h
+++ b/contrib/llvm-project/clang/include/clang/AST/TypeLoc.h
@@ -14,6 +14,7 @@
#ifndef LLVM_CLANG_AST_TYPELOC_H
#define LLVM_CLANG_AST_TYPELOC_H
+#include "clang/AST/ASTConcept.h"
#include "clang/AST/DeclarationName.h"
#include "clang/AST/NestedNameSpecifier.h"
#include "clang/AST/TemplateBase.h"
@@ -240,6 +241,11 @@ private:
static SourceRange getLocalSourceRangeImpl(TypeLoc TL);
};
+inline TypeSourceInfo::TypeSourceInfo(QualType ty, size_t DataSize) : Ty(ty) {
+ // Init data attached to the object. See getTypeLoc.
+ memset(static_cast<void *>(this + 1), 0, DataSize);
+}
+
/// Return the TypeLoc for a type source info.
inline TypeLoc TypeSourceInfo::getTypeLoc() const {
// TODO: is this alignment already sufficient?
@@ -430,7 +436,7 @@ protected:
unsigned size = sizeof(LocalData);
unsigned extraAlign = asDerived()->getExtraLocalDataAlignment();
size = llvm::alignTo(size, extraAlign);
- return reinterpret_cast<char*>(Base::Data) + size;
+ return reinterpret_cast<char *>(Base::Data) + size;
}
void *getNonLocalData() const {
@@ -581,10 +587,9 @@ public:
bool needsExtraLocalData() const {
BuiltinType::Kind bk = getTypePtr()->getKind();
- return (bk >= BuiltinType::UShort && bk <= BuiltinType::UInt128)
- || (bk >= BuiltinType::Short && bk <= BuiltinType::Float128)
- || bk == BuiltinType::UChar
- || bk == BuiltinType::SChar;
+ return (bk >= BuiltinType::UShort && bk <= BuiltinType::UInt128) ||
+ (bk >= BuiltinType::Short && bk <= BuiltinType::Ibm128) ||
+ bk == BuiltinType::UChar || bk == BuiltinType::SChar;
}
unsigned getExtraLocalDataSize() const {
@@ -666,6 +671,16 @@ public:
}
};
+/// Wrapper for source info for types used via transparent aliases.
+class UsingTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
+ UsingTypeLoc, UsingType> {
+public:
+ QualType getUnderlyingType() const {
+ return getTypePtr()->getUnderlyingType();
+ }
+ UsingShadowDecl *getFoundDecl() const { return getTypePtr()->getFoundDecl(); }
+};
+
/// Wrapper for source info for typedefs.
class TypedefTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
TypedefTypeLoc,
@@ -805,7 +820,7 @@ public:
}
ArrayRef<SourceLocation> getProtocolLocs() const {
- return llvm::makeArrayRef(getProtocolLocArray(), getNumProtocols());
+ return llvm::ArrayRef(getProtocolLocArray(), getNumProtocols());
}
void initializeLocal(ASTContext &Context, SourceLocation Loc);
@@ -892,6 +907,29 @@ public:
}
};
+struct BTFTagAttributedLocInfo {}; // Nothing.
+
+/// Type source information for an btf_tag attributed type.
+class BTFTagAttributedTypeLoc
+ : public ConcreteTypeLoc<UnqualTypeLoc, BTFTagAttributedTypeLoc,
+ BTFTagAttributedType, BTFTagAttributedLocInfo> {
+public:
+ TypeLoc getWrappedLoc() const { return getInnerTypeLoc(); }
+
+ /// The btf_type_tag attribute.
+ const BTFTypeTagAttr *getAttr() const { return getTypePtr()->getAttr(); }
+
+ template <typename T> T *getAttrAs() {
+ return dyn_cast_or_null<T>(getAttr());
+ }
+
+ SourceRange getLocalSourceRange() const;
+
+ void initializeLocal(ASTContext &Context, SourceLocation loc) {}
+
+ QualType getInnerType() const { return getTypePtr()->getWrappedType(); }
+};
+
struct ObjCObjectTypeLocInfo {
SourceLocation TypeArgsLAngleLoc;
SourceLocation TypeArgsRAngleLoc;
@@ -988,7 +1026,7 @@ public:
ArrayRef<SourceLocation> getProtocolLocs() const {
- return llvm::makeArrayRef(getProtocolLocArray(), getNumProtocols());
+ return llvm::ArrayRef(getProtocolLocArray(), getNumProtocols());
}
bool hasBaseTypeAsWritten() const {
@@ -1415,7 +1453,7 @@ public:
}
ArrayRef<ParmVarDecl *> getParams() const {
- return llvm::makeArrayRef(getParmArray(), getNumParams());
+ return llvm::ArrayRef(getParmArray(), getNumParams());
}
// ParmVarDecls* are stored after Info, one for each parameter.
@@ -1602,7 +1640,7 @@ public:
}
unsigned getNumArgs() const {
- return getTypePtr()->getNumArgs();
+ return getTypePtr()->template_arguments().size();
}
void setArgLocInfo(unsigned i, TemplateArgumentLocInfo AI) {
@@ -1614,7 +1652,8 @@ public:
}
TemplateArgumentLoc getArgLoc(unsigned i) const {
- return TemplateArgumentLoc(getTypePtr()->getArg(i), getArgLocInfo(i));
+ return TemplateArgumentLoc(getTypePtr()->template_arguments()[i],
+ getArgLocInfo(i));
}
SourceLocation getTemplateNameLoc() const {
@@ -1649,12 +1688,12 @@ public:
setTemplateNameLoc(Loc);
setLAngleLoc(Loc);
setRAngleLoc(Loc);
- initializeArgLocs(Context, getNumArgs(), getTypePtr()->getArgs(),
+ initializeArgLocs(Context, getTypePtr()->template_arguments(),
getArgInfos(), Loc);
}
- static void initializeArgLocs(ASTContext &Context, unsigned NumArgs,
- const TemplateArgument *Args,
+ static void initializeArgLocs(ASTContext &Context,
+ ArrayRef<TemplateArgument> Args,
TemplateArgumentLocInfo *ArgInfos,
SourceLocation Loc);
@@ -1902,7 +1941,7 @@ struct TypeOfExprTypeLocInfo : public TypeofLocInfo {
};
struct TypeOfTypeLocInfo : public TypeofLocInfo {
- TypeSourceInfo* UnderlyingTInfo;
+ TypeSourceInfo *UnmodifiedTInfo;
};
template <class Derived, class TypeClass, class LocalData = TypeofLocInfo>
@@ -1970,27 +2009,50 @@ public:
class TypeOfTypeLoc
: public TypeofLikeTypeLoc<TypeOfTypeLoc, TypeOfType, TypeOfTypeLocInfo> {
public:
- QualType getUnderlyingType() const {
- return this->getTypePtr()->getUnderlyingType();
+ QualType getUnmodifiedType() const {
+ return this->getTypePtr()->getUnmodifiedType();
}
- TypeSourceInfo* getUnderlyingTInfo() const {
- return this->getLocalData()->UnderlyingTInfo;
+ TypeSourceInfo *getUnmodifiedTInfo() const {
+ return this->getLocalData()->UnmodifiedTInfo;
}
- void setUnderlyingTInfo(TypeSourceInfo* TI) const {
- this->getLocalData()->UnderlyingTInfo = TI;
+ void setUnmodifiedTInfo(TypeSourceInfo *TI) const {
+ this->getLocalData()->UnmodifiedTInfo = TI;
}
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 {
@@ -2043,12 +2105,10 @@ class DeducedTypeLoc
DeducedType> {};
struct AutoTypeLocInfo : TypeSpecLocInfo {
- NestedNameSpecifierLoc NestedNameSpec;
- SourceLocation TemplateKWLoc;
- SourceLocation ConceptNameLoc;
- NamedDecl *FoundDecl;
- SourceLocation LAngleLoc;
- SourceLocation RAngleLoc;
+ // For decltype(auto).
+ SourceLocation RParenLoc;
+
+ ConceptReference *CR = nullptr;
};
class AutoTypeLoc
@@ -2061,96 +2121,95 @@ 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();
}
- const NestedNameSpecifierLoc &getNestedNameSpecifierLoc() const {
- return getLocalData()->NestedNameSpec;
- }
+ void setConceptReference(ConceptReference *CR) { getLocalData()->CR = CR; }
- void setNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS) {
- getLocalData()->NestedNameSpec = NNS;
- }
+ ConceptReference *getConceptReference() const { return getLocalData()->CR; }
- SourceLocation getTemplateKWLoc() const {
- return getLocalData()->TemplateKWLoc;
+ // FIXME: Several of the following functions can be removed. Instead the
+ // caller can directly work with the ConceptReference.
+ const NestedNameSpecifierLoc getNestedNameSpecifierLoc() const {
+ if (const auto *CR = getConceptReference())
+ return CR->getNestedNameSpecifierLoc();
+ return NestedNameSpecifierLoc();
}
- void setTemplateKWLoc(SourceLocation Loc) {
- getLocalData()->TemplateKWLoc = Loc;
+ SourceLocation getTemplateKWLoc() const {
+ if (const auto *CR = getConceptReference())
+ return CR->getTemplateKWLoc();
+ return SourceLocation();
}
SourceLocation getConceptNameLoc() const {
- return getLocalData()->ConceptNameLoc;
- }
-
- void setConceptNameLoc(SourceLocation Loc) {
- getLocalData()->ConceptNameLoc = Loc;
+ if (const auto *CR = getConceptReference())
+ return CR->getConceptNameLoc();
+ return SourceLocation();
}
NamedDecl *getFoundDecl() const {
- return getLocalData()->FoundDecl;
- }
-
- void setFoundDecl(NamedDecl *D) {
- getLocalData()->FoundDecl = D;
+ if (const auto *CR = getConceptReference())
+ return CR->getFoundDecl();
+ return nullptr;
}
ConceptDecl *getNamedConcept() const {
- return getTypePtr()->getTypeConstraintConcept();
+ if (const auto *CR = getConceptReference())
+ return CR->getNamedConcept();
+ return nullptr;
}
- DeclarationNameInfo getConceptNameInfo() const;
+ DeclarationNameInfo getConceptNameInfo() const {
+ return getConceptReference()->getConceptNameInfo();
+ }
bool hasExplicitTemplateArgs() const {
- return getLocalData()->LAngleLoc.isValid();
+ return (getConceptReference() &&
+ getConceptReference()->getTemplateArgsAsWritten() &&
+ getConceptReference()
+ ->getTemplateArgsAsWritten()
+ ->getLAngleLoc()
+ .isValid());
}
SourceLocation getLAngleLoc() const {
- return this->getLocalData()->LAngleLoc;
- }
-
- void setLAngleLoc(SourceLocation Loc) {
- this->getLocalData()->LAngleLoc = Loc;
+ if (const auto *CR = getConceptReference())
+ if (const auto *TAAW = CR->getTemplateArgsAsWritten())
+ return TAAW->getLAngleLoc();
+ return SourceLocation();
}
SourceLocation getRAngleLoc() const {
- return this->getLocalData()->RAngleLoc;
- }
-
- void setRAngleLoc(SourceLocation Loc) {
- this->getLocalData()->RAngleLoc = Loc;
+ if (const auto *CR = getConceptReference())
+ if (const auto *TAAW = CR->getTemplateArgsAsWritten())
+ return TAAW->getRAngleLoc();
+ return SourceLocation();
}
unsigned getNumArgs() const {
- return getTypePtr()->getNumArgs();
- }
-
- void setArgLocInfo(unsigned i, TemplateArgumentLocInfo AI) {
- getArgInfos()[i] = AI;
- }
-
- TemplateArgumentLocInfo getArgLocInfo(unsigned i) const {
- return getArgInfos()[i];
+ return getTypePtr()->getTypeConstraintArguments().size();
}
TemplateArgumentLoc getArgLoc(unsigned i) const {
- return TemplateArgumentLoc(getTypePtr()->getTypeConstraintArguments()[i],
- getArgLocInfo(i));
+ const auto *CR = getConceptReference();
+ assert(CR && "No ConceptReference");
+ return CR->getTemplateArgsAsWritten()->getTemplateArgs()[i];
}
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) {
@@ -2160,19 +2219,6 @@ public:
}
void initializeLocal(ASTContext &Context, SourceLocation Loc);
-
- unsigned getExtraLocalDataSize() const {
- return getNumArgs() * sizeof(TemplateArgumentLocInfo);
- }
-
- unsigned getExtraLocalDataAlignment() const {
- return alignof(TemplateArgumentLocInfo);
- }
-
-private:
- TemplateArgumentLocInfo *getArgInfos() const {
- return static_cast<TemplateArgumentLocInfo*>(getExtraLocalData());
- }
};
class DeducedTemplateSpecializationTypeLoc
@@ -2202,22 +2248,31 @@ class ElaboratedTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
ElaboratedLocInfo> {
public:
SourceLocation getElaboratedKeywordLoc() const {
- return this->getLocalData()->ElaboratedKWLoc;
+ return !isEmpty() ? getLocalData()->ElaboratedKWLoc : SourceLocation();
}
void setElaboratedKeywordLoc(SourceLocation Loc) {
- this->getLocalData()->ElaboratedKWLoc = Loc;
+ if (isEmpty()) {
+ assert(Loc.isInvalid());
+ return;
+ }
+ getLocalData()->ElaboratedKWLoc = Loc;
}
NestedNameSpecifierLoc getQualifierLoc() const {
- return NestedNameSpecifierLoc(getTypePtr()->getQualifier(),
- getLocalData()->QualifierData);
+ return !isEmpty() ? NestedNameSpecifierLoc(getTypePtr()->getQualifier(),
+ getLocalData()->QualifierData)
+ : NestedNameSpecifierLoc();
}
void setQualifierLoc(NestedNameSpecifierLoc QualifierLoc) {
- assert(QualifierLoc.getNestedNameSpecifier()
- == getTypePtr()->getQualifier() &&
+ assert(QualifierLoc.getNestedNameSpecifier() ==
+ getTypePtr()->getQualifier() &&
"Inconsistent nested-name-specifier pointer");
+ if (isEmpty()) {
+ assert(!QualifierLoc.hasQualifier());
+ return;
+ }
getLocalData()->QualifierData = QualifierLoc.getOpaqueData();
}
@@ -2234,12 +2289,24 @@ public:
void initializeLocal(ASTContext &Context, SourceLocation Loc);
- TypeLoc getNamedTypeLoc() const {
- return getInnerTypeLoc();
+ TypeLoc getNamedTypeLoc() const { return getInnerTypeLoc(); }
+
+ QualType getInnerType() const { return getTypePtr()->getNamedType(); }
+
+ bool isEmpty() const {
+ return getTypePtr()->getKeyword() == ElaboratedTypeKeyword::None &&
+ !getTypePtr()->getQualifier();
}
- QualType getInnerType() const {
- return getTypePtr()->getNamedType();
+ unsigned getLocalDataAlignment() const {
+ // FIXME: We want to return 1 here in the empty case, but
+ // there are bugs in how alignment is handled in TypeLocs
+ // that prevent this from working.
+ return ConcreteTypeLoc::getLocalDataAlignment();
+ }
+
+ unsigned getLocalDataSize() const {
+ return !isEmpty() ? ConcreteTypeLoc::getLocalDataSize() : 0;
}
void copy(ElaboratedTypeLoc Loc) {
@@ -2382,7 +2449,7 @@ public:
}
unsigned getNumArgs() const {
- return getTypePtr()->getNumArgs();
+ return getTypePtr()->template_arguments().size();
}
void setArgLocInfo(unsigned i, TemplateArgumentLocInfo AI) {
@@ -2394,7 +2461,8 @@ public:
}
TemplateArgumentLoc getArgLoc(unsigned i) const {
- return TemplateArgumentLoc(getTypePtr()->getArg(i), getArgLocInfo(i));
+ return TemplateArgumentLoc(getTypePtr()->template_arguments()[i],
+ getArgLocInfo(i));
}
SourceRange getLocalSourceRange() const {
@@ -2551,6 +2619,8 @@ inline T TypeLoc::getAsAdjusted() const {
Cur = PTL.getInnerLoc();
else if (auto ATL = Cur.getAs<AttributedTypeLoc>())
Cur = ATL.getModifiedLoc();
+ else if (auto ATL = Cur.getAs<BTFTagAttributedTypeLoc>())
+ Cur = ATL.getWrappedLoc();
else if (auto ETL = Cur.getAs<ElaboratedTypeLoc>())
Cur = ETL.getNamedTypeLoc();
else if (auto ATL = Cur.getAs<AdjustedTypeLoc>())
@@ -2562,12 +2632,28 @@ inline T TypeLoc::getAsAdjusted() const {
}
return Cur.getAs<T>();
}
-class ExtIntTypeLoc final
- : public InheritingConcreteTypeLoc<TypeSpecTypeLoc, ExtIntTypeLoc,
- ExtIntType> {};
-class DependentExtIntTypeLoc final
- : public InheritingConcreteTypeLoc<TypeSpecTypeLoc, DependentExtIntTypeLoc,
- DependentExtIntType> {};
+class BitIntTypeLoc final
+ : public InheritingConcreteTypeLoc<TypeSpecTypeLoc, BitIntTypeLoc,
+ BitIntType> {};
+class DependentBitIntTypeLoc final
+ : public InheritingConcreteTypeLoc<TypeSpecTypeLoc, DependentBitIntTypeLoc,
+ DependentBitIntType> {};
+
+class ObjCProtocolLoc {
+ ObjCProtocolDecl *Protocol = nullptr;
+ SourceLocation Loc = SourceLocation();
+
+public:
+ ObjCProtocolLoc(ObjCProtocolDecl *protocol, SourceLocation loc)
+ : Protocol(protocol), Loc(loc) {}
+ ObjCProtocolDecl *getProtocol() const { return Protocol; }
+ SourceLocation getLocation() const { return Loc; }
+
+ /// The source range is just the protocol name.
+ SourceRange getSourceRange() const LLVM_READONLY {
+ return SourceRange(Loc, Loc);
+ }
+};
} // namespace clang
diff --git a/contrib/llvm-project/clang/include/clang/AST/TypeOrdering.h b/contrib/llvm-project/clang/include/clang/AST/TypeOrdering.h
index 6630105136f5..8037f98cc965 100644
--- a/contrib/llvm-project/clang/include/clang/AST/TypeOrdering.h
+++ b/contrib/llvm-project/clang/include/clang/AST/TypeOrdering.h
@@ -34,7 +34,6 @@ struct QualTypeOrdering {
}
namespace llvm {
- template<class> struct DenseMapInfo;
template<> struct DenseMapInfo<clang::QualType> {
static inline clang::QualType getEmptyKey() { return clang::QualType(); }
diff --git a/contrib/llvm-project/clang/include/clang/AST/TypeProperties.td b/contrib/llvm-project/clang/include/clang/AST/TypeProperties.td
index 438d5af5a2e2..682c869b0c58 100644
--- a/contrib/llvm-project/clang/include/clang/AST/TypeProperties.td
+++ b/contrib/llvm-project/clang/include/clang/AST/TypeProperties.td
@@ -11,7 +11,7 @@ include "clang/Basic/TypeNodes.td"
let Class = ComplexType in {
def : Property<"elementType", QualType> {
- let Read = [{ node->getElementType() }];
+ let Read = [{ node->getElementType() }];
}
def : Creator<[{ return ctx.getComplexType(elementType); }]>;
@@ -323,6 +323,9 @@ let Class = FunctionProtoType in {
? node->getExtParameterInfos()
: llvm::ArrayRef<FunctionProtoType::ExtParameterInfo>() }];
}
+ def : Property<"AArch64SMEAttributes", UInt32> {
+ let Read = [{ node->getAArch64SMEAttributes() }];
+ }
def : Creator<[{
auto extInfo = FunctionType::ExtInfo(noReturn, hasRegParm, regParm,
@@ -338,6 +341,7 @@ let Class = FunctionProtoType in {
epi.ExceptionSpec = exceptionSpecifier;
epi.ExtParameterInfos =
extParameterInfo.empty() ? nullptr : extParameterInfo.data();
+ epi.AArch64SMEAttributes = AArch64SMEAttributes;
return ctx.getFunctionType(returnType, parameters, epi);
}]>;
}
@@ -358,7 +362,20 @@ let Class = UnresolvedUsingType in {
}
def : Creator<[{
- return ctx.getTypeDeclType(cast<UnresolvedUsingTypenameDecl>(declaration));
+ return ctx.getUnresolvedUsingType(cast<UnresolvedUsingTypenameDecl>(declaration));
+ }]>;
+}
+
+let Class = UsingType in {
+ def : Property<"foundDeclaration", UsingShadowDeclRef> {
+ let Read = [{ node->getFoundDecl() }];
+ }
+ def : Property<"underlyingType", QualType> {
+ let Read = [{ node->getUnderlyingType() }];
+ }
+
+ def : Creator<[{
+ return ctx.getUsingType(foundDeclaration, underlyingType);
}]>;
}
@@ -366,16 +383,12 @@ let Class = TypedefType in {
def : Property<"declaration", DeclRef> {
let Read = [{ node->getDecl() }];
}
- def : Property<"canonicalType", Optional<QualType>> {
- let Read = [{ makeOptionalFromNullable(node->getCanonicalTypeInternal()) }];
+ def : Property<"underlyingType", QualType> {
+ let Read = [{ node->desugar() }];
}
def : Creator<[{
- QualType finalCanonicalType =
- canonicalType ? ctx.getCanonicalType(*canonicalType)
- : QualType();
- return ctx.getTypedefType(cast<TypedefNameDecl>(declaration),
- finalCanonicalType);
+ return ctx.getTypedefType(cast<TypedefNameDecl>(declaration), underlyingType);
}]>;
}
@@ -384,18 +397,26 @@ let Class = TypeOfExprType in {
let Read = [{ node->getUnderlyingExpr() }];
}
+ def : Property<"kind", TypeOfKind> {
+ let Read = [{ node->getKind() }];
+ }
+
def : Creator<[{
- return ctx.getTypeOfExprType(expression);
+ return ctx.getTypeOfExprType(expression, kind);
}]>;
}
let Class = TypeOfType in {
- def : Property<"underlyingType", QualType> {
- let Read = [{ node->getUnderlyingType() }];
+ def : Property<"unmodifiedType", QualType> {
+ let Read = [{ node->getUnmodifiedType() }];
+ }
+
+ def : Property<"kind", TypeOfKind> {
+ let Read = [{ node->getKind() }];
}
def : Creator<[{
- return ctx.getTypeOfType(underlyingType);
+ return ctx.getTypeOfType(unmodifiedType, kind);
}]>;
}
@@ -574,7 +595,7 @@ let Class = ParenType in {
def : Creator<[{
return ctx.getParenType(innerType);
- }]>;
+ }]>;
}
let Class = MacroQualifiedType in {
@@ -606,6 +627,19 @@ let Class = AttributedType in {
}]>;
}
+let Class = BTFTagAttributedType in {
+ def : Property<"attr", BTFTypeTagAttr> {
+ let Read = [{ node->getAttr() }];
+ }
+ def : Property<"wrappedType", QualType> {
+ let Read = [{ node->getWrappedType() }];
+ }
+
+ def : Creator<[{
+ return ctx.getBTFTagAttributedType(attr, wrappedType);
+ }]>;
+}
+
let Class = DependentAddressSpaceType in {
def : Property<"pointeeType", QualType> {
let Read = [{ node->getPointeeType() }];
@@ -636,16 +670,16 @@ let Class = TemplateSpecializationType in {
def : Property<"underlyingType", Optional<QualType>> {
let Read = [{
node->isTypeAlias()
- ? llvm::Optional<QualType>(node->getAliasedType())
+ ? std::optional<QualType>(node->getAliasedType())
: node->isCanonicalUnqualified()
- ? llvm::None
- : llvm::Optional<QualType>(node->getCanonicalTypeInternal())
+ ? std::nullopt
+ : std::optional<QualType>(node->getCanonicalTypeInternal())
}];
}
def : Creator<[{
QualType result;
- if (!underlyingType.hasValue()) {
+ if (!underlyingType) {
result = ctx.getCanonicalTemplateSpecializationType(templateName,
templateArguments);
} else {
@@ -702,18 +736,23 @@ let Class = TemplateTypeParmType in {
}
let Class = SubstTemplateTypeParmType in {
- def : Property<"replacedParameter", QualType> {
- let Read = [{ QualType(node->getReplacedParameter(), 0) }];
- }
def : Property<"replacementType", QualType> {
let Read = [{ node->getReplacementType() }];
}
+ def : Property<"associatedDecl", DeclRef> {
+ let Read = [{ node->getAssociatedDecl() }];
+ }
+ def : Property<"Index", UInt32> {
+ let Read = [{ node->getIndex() }];
+ }
+ def : Property<"PackIndex", Optional<UInt32>> {
+ let Read = [{ node->getPackIndex() }];
+ }
+ // The call to getCanonicalType here existed in ASTReader.cpp, too.
def : Creator<[{
- // The call to getCanonicalType here existed in ASTReader.cpp, too.
return ctx.getSubstTemplateTypeParmType(
- cast<TemplateTypeParmType>(replacedParameter),
- ctx.getCanonicalType(replacementType));
+ replacementType, associatedDecl, Index, PackIndex);
}]>;
}
@@ -732,8 +771,14 @@ let Class = PackExpansionType in {
}
let Class = SubstTemplateTypeParmPackType in {
- def : Property<"replacedParameter", QualType> {
- let Read = [{ QualType(node->getReplacedParameter(), 0) }];
+ def : Property<"associatedDecl", DeclRef> {
+ let Read = [{ node->getAssociatedDecl() }];
+ }
+ def : Property<"Index", UInt32> {
+ let Read = [{ node->getIndex() }];
+ }
+ def : Property<"Final", Bool> {
+ let Read = [{ node->getFinal() }];
}
def : Property<"replacementPack", TemplateArgument> {
let Read = [{ node->getArgumentPack() }];
@@ -741,8 +786,7 @@ let Class = SubstTemplateTypeParmPackType in {
def : Creator<[{
return ctx.getSubstTemplateTypeParmPackType(
- cast<TemplateTypeParmType>(replacedParameter),
- replacementPack);
+ associatedDecl, Index, Final, replacementPack);
}]>;
}
@@ -773,6 +817,10 @@ let Class = BuiltinType in {
case BuiltinType::ID: return ctx.SINGLETON_ID;
#include "clang/Basic/RISCVVTypes.def"
+#define WASM_TYPE(NAME, ID, SINGLETON_ID) \
+ case BuiltinType::ID: return ctx.SINGLETON_ID;
+#include "clang/Basic/WebAssemblyReferenceTypes.def"
+
#define BUILTIN_TYPE(ID, SINGLETON_ID) \
case BuiltinType::ID: return ctx.SINGLETON_ID;
#include "clang/AST/BuiltinTypes.def"
@@ -794,8 +842,8 @@ let Class = DependentNameType in {
def : Property<"underlyingType", Optional<QualType>> {
let Read = [{
node->isCanonicalUnqualified()
- ? llvm::None
- : llvm::Optional<QualType>(node->getCanonicalTypeInternal())
+ ? std::nullopt
+ : std::optional<QualType>(node->getCanonicalTypeInternal())
}];
}
@@ -849,7 +897,7 @@ let Class = ObjCInterfaceType in {
let Class = ObjCTypeParamType in {
def : Property<"declaration", ObjCTypeParamDeclRef> {
let Read = [{ node->getDecl() }];
- }
+ }
def : Property<"qualifiers", Array<ObjCProtocolDeclRef>> {
let Read = [{ node->getProtocols() }];
}
@@ -882,7 +930,7 @@ let Class = PipeType in {
}]>;
}
-let Class = ExtIntType in {
+let Class = BitIntType in {
def : Property<"isUnsigned", Bool> {
let Read = [{ node->isUnsigned() }];
}
@@ -891,11 +939,11 @@ let Class = ExtIntType in {
}
def : Creator<[{
- return ctx.getExtIntType(isUnsigned, numBits);
+ return ctx.getBitIntType(isUnsigned, numBits);
}]>;
}
-let Class = DependentExtIntType in {
+let Class = DependentBitIntType in {
def : Property<"isUnsigned", Bool> {
let Read = [{ node->isUnsigned() }];
}
@@ -903,6 +951,6 @@ let Class = DependentExtIntType in {
let Read = [{ node->getNumBitsExpr() }];
}
def : Creator<[{
- return ctx.getDependentExtIntType(isUnsigned, numBitsExpr);
+ return ctx.getDependentBitIntType(isUnsigned, numBitsExpr);
}]>;
}
diff --git a/contrib/llvm-project/clang/include/clang/AST/UnresolvedSet.h b/contrib/llvm-project/clang/include/clang/AST/UnresolvedSet.h
index c75aa0785a63..ee31be969b6e 100644
--- a/contrib/llvm-project/clang/include/clang/AST/UnresolvedSet.h
+++ b/contrib/llvm-project/clang/include/clang/AST/UnresolvedSet.h
@@ -114,14 +114,22 @@ public:
I.I->set(New, AS);
}
- void erase(unsigned I) { decls()[I] = decls().pop_back_val(); }
+ void erase(unsigned I) {
+ auto val = decls().pop_back_val();
+ if (I < size())
+ decls()[I] = val;
+ }
- void erase(iterator I) { *I.I = decls().pop_back_val(); }
+ void erase(iterator I) {
+ auto val = decls().pop_back_val();
+ if (I != end())
+ *I.I = val;
+ }
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/AST/VTableBuilder.h b/contrib/llvm-project/clang/include/clang/AST/VTableBuilder.h
index e451f3f861b7..fbf6c041a1ec 100644
--- a/contrib/llvm-project/clang/include/clang/AST/VTableBuilder.h
+++ b/contrib/llvm-project/clang/include/clang/AST/VTableBuilder.h
@@ -279,7 +279,7 @@ public:
AddressPointLocation getAddressPoint(BaseSubobject Base) const {
assert(AddressPoints.count(Base) && "Did not find address point!");
- return AddressPoints.find(Base)->second;
+ return AddressPoints.lookup(Base);
}
const AddressPointsMapTy &getAddressPoints() const {
@@ -563,8 +563,6 @@ private:
llvm::DenseMap<const CXXRecordDecl *, std::unique_ptr<VirtualBaseInfo>>
VBaseInfo;
- void enumerateVFPtrs(const CXXRecordDecl *ForClass, VPtrInfoVector &Result);
-
void computeVTableRelatedInformation(const CXXRecordDecl *RD) override;
void dumpMethodLocations(const CXXRecordDecl *RD,
diff --git a/contrib/llvm-project/clang/include/clang/ASTMatchers/ASTMatchFinder.h b/contrib/llvm-project/clang/include/clang/ASTMatchers/ASTMatchFinder.h
index 91024f9425e0..a387d9037b7d 100644
--- a/contrib/llvm-project/clang/include/clang/ASTMatchers/ASTMatchFinder.h
+++ b/contrib/llvm-project/clang/include/clang/ASTMatchers/ASTMatchFinder.h
@@ -44,6 +44,7 @@
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/Support/Timer.h"
+#include <optional>
namespace clang {
@@ -115,7 +116,7 @@ public:
/// the result nodes. This API is temporary to facilitate
/// third parties porting existing code to the default
/// behavior of clang-tidy.
- virtual llvm::Optional<TraversalKind> getCheckTraversalKind() const;
+ virtual std::optional<TraversalKind> getCheckTraversalKind() const;
};
/// Called when parsing is finished. Intended for testing only.
@@ -137,7 +138,7 @@ public:
/// Enables per-check timers.
///
/// It prints a report after match.
- llvm::Optional<Profiling> CheckProfiling;
+ std::optional<Profiling> CheckProfiling;
};
MatchFinder(MatchFinderOptions Options = MatchFinderOptions());
@@ -167,6 +168,7 @@ public:
MatchCallback *Action);
void addMatcher(const TemplateArgumentLocMatcher &NodeMatch,
MatchCallback *Action);
+ void addMatcher(const AttrMatcher &NodeMatch, MatchCallback *Action);
/// @}
/// Adds a matcher to execute when running over the AST.
@@ -219,6 +221,7 @@ public:
std::vector<std::pair<CXXCtorInitializerMatcher, MatchCallback *>> CtorInit;
std::vector<std::pair<TemplateArgumentLocMatcher, MatchCallback *>>
TemplateArgumentLoc;
+ std::vector<std::pair<AttrMatcher, MatchCallback *>> Attr;
/// All the callbacks in one container to simplify iteration.
llvm::SmallPtrSet<MatchCallback *, 16> AllCallbacks;
};
@@ -287,8 +290,8 @@ public:
Nodes.push_back(Result.Nodes);
}
- llvm::Optional<TraversalKind> getCheckTraversalKind() const override {
- return llvm::None;
+ std::optional<TraversalKind> getCheckTraversalKind() const override {
+ return std::nullopt;
}
SmallVector<BoundNodes, 1> Nodes;
diff --git a/contrib/llvm-project/clang/include/clang/ASTMatchers/ASTMatchers.h b/contrib/llvm-project/clang/include/clang/ASTMatchers/ASTMatchers.h
index 8e3ee6cb9e7e..dc1f49525a00 100644
--- a/contrib/llvm-project/clang/include/clang/ASTMatchers/ASTMatchers.h
+++ b/contrib/llvm-project/clang/include/clang/ASTMatchers/ASTMatchers.h
@@ -81,6 +81,7 @@
#include "clang/Basic/TypeTraits.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/Compiler.h"
@@ -90,6 +91,7 @@
#include <cstddef>
#include <iterator>
#include <limits>
+#include <optional>
#include <string>
#include <utility>
#include <vector>
@@ -148,6 +150,8 @@ using CXXBaseSpecifierMatcher = internal::Matcher<CXXBaseSpecifier>;
using CXXCtorInitializerMatcher = internal::Matcher<CXXCtorInitializer>;
using TemplateArgumentMatcher = internal::Matcher<TemplateArgument>;
using TemplateArgumentLocMatcher = internal::Matcher<TemplateArgumentLoc>;
+using LambdaCaptureMatcher = internal::Matcher<LambdaCapture>;
+using AttrMatcher = internal::Matcher<Attr>;
/// @}
/// Matches any node.
@@ -296,7 +300,7 @@ AST_POLYMORPHIC_MATCHER_REGEX(isExpansionInFileMatching,
return false;
}
auto FileEntry =
- SourceManager.getFileEntryForID(SourceManager.getFileID(ExpansionLoc));
+ SourceManager.getFileEntryRefForID(SourceManager.getFileID(ExpansionLoc));
if (!FileEntry) {
return false;
}
@@ -307,7 +311,7 @@ AST_POLYMORPHIC_MATCHER_REGEX(isExpansionInFileMatching,
/// Matches statements that are (transitively) expanded from the named macro.
/// Does not match if only part of the statement is expanded from that macro or
-/// if different parts of the the statement are expanded from different
+/// if different parts of the statement are expanded from different
/// appearances of the macro.
AST_POLYMORPHIC_MATCHER_P(isExpandedFromMacro,
AST_POLYMORPHIC_SUPPORTED_TYPES(Decl, Stmt, TypeLoc),
@@ -315,10 +319,10 @@ AST_POLYMORPHIC_MATCHER_P(isExpandedFromMacro,
// Verifies that the statement' beginning and ending are both expanded from
// the same instance of the given macro.
auto& Context = Finder->getASTContext();
- llvm::Optional<SourceLocation> B =
+ std::optional<SourceLocation> B =
internal::getExpansionLocOfMacro(MacroName, Node.getBeginLoc(), Context);
if (!B) return false;
- llvm::Optional<SourceLocation> E =
+ std::optional<SourceLocation> E =
internal::getExpansionLocOfMacro(MacroName, Node.getEndLoc(), Context);
if (!E) return false;
return *B == *E;
@@ -752,9 +756,11 @@ AST_MATCHER_P(ClassTemplateSpecializationDecl, hasSpecializedTemplate,
InnerMatcher.matches(*Decl, Finder, Builder));
}
-/// Matches a declaration that has been implicitly added
-/// by the compiler (eg. implicit default/copy constructors).
-AST_MATCHER(Decl, isImplicit) {
+/// Matches an entity that has been implicitly added by the compiler (e.g.
+/// implicit default/copy constructors).
+AST_POLYMORPHIC_MATCHER(isImplicit,
+ AST_POLYMORPHIC_SUPPORTED_TYPES(Decl, Attr,
+ LambdaCapture)) {
return Node.isImplicit();
}
@@ -1097,9 +1103,9 @@ AST_POLYMORPHIC_MATCHER_P(
/// template<typename T> struct A {};
/// A<X> a;
/// \endcode
-/// classTemplateSpecializationDecl(hasAnyTemplateArgument(
-/// refersToType(class(hasName("X")))))
-/// matches the specialization \c A<X>
+/// classTemplateSpecializationDecl(hasAnyTemplateArgument(refersToType(
+/// recordType(hasDeclaration(recordDecl(hasName("X")))))))
+/// matches the specialization of \c struct A generated by \c A<X>.
AST_MATCHER_P(TemplateArgument, refersToType,
internal::Matcher<QualType>, InnerMatcher) {
if (Node.getKind() != TemplateArgument::Type)
@@ -1328,6 +1334,16 @@ extern const internal::VariadicDynCastAllOfMatcher<Decl, CXXConversionDecl>
extern const internal::VariadicDynCastAllOfMatcher<Decl, CXXDeductionGuideDecl>
cxxDeductionGuideDecl;
+/// Matches concept declarations.
+///
+/// Example matches integral
+/// \code
+/// template<typename T>
+/// concept integral = std::is_integral_v<T>;
+/// \endcode
+extern const internal::VariadicDynCastAllOfMatcher<Decl, ConceptDecl>
+ conceptDecl;
+
/// Matches variable declarations.
///
/// Note: this does not match declarations of member variables, which are
@@ -1511,6 +1527,15 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXMemberCallExpr>
extern const internal::VariadicDynCastAllOfMatcher<Stmt, ObjCMessageExpr>
objcMessageExpr;
+/// Matches ObjectiveC String literal expressions.
+///
+/// Example matches @"abcd"
+/// \code
+/// NSString *s = @"abcd";
+/// \endcode
+extern const internal::VariadicDynCastAllOfMatcher<Stmt, ObjCStringLiteral>
+ objcStringLiteral;
+
/// Matches Objective-C interface declarations.
///
/// Example matches Foo
@@ -1956,6 +1981,45 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXDeleteExpr>
extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXNoexceptExpr>
cxxNoexceptExpr;
+/// Matches a loop initializing the elements of an array in a number of contexts:
+/// * in the implicit copy/move constructor for a class with an array member
+/// * when a lambda-expression captures an array by value
+/// * when a decomposition declaration decomposes an array
+///
+/// Given
+/// \code
+/// void testLambdaCapture() {
+/// int a[10];
+/// auto Lam1 = [a]() {
+/// return;
+/// };
+/// }
+/// \endcode
+/// arrayInitLoopExpr() matches the implicit loop that initializes each element of
+/// the implicit array field inside the lambda object, that represents the array `a`
+/// captured by value.
+extern const internal::VariadicDynCastAllOfMatcher<Stmt, ArrayInitLoopExpr>
+ arrayInitLoopExpr;
+
+/// The arrayInitIndexExpr consists of two subexpressions: a common expression
+/// (the source array) that is evaluated once up-front, and a per-element initializer
+/// that runs once for each array element. Within the per-element initializer,
+/// the current index may be obtained via an ArrayInitIndexExpr.
+///
+/// Given
+/// \code
+/// void testStructBinding() {
+/// int a[2] = {1, 2};
+/// auto [x, y] = a;
+/// }
+/// \endcode
+/// arrayInitIndexExpr() matches the array index that implicitly iterates
+/// over the array `a` to copy each element to the anonymous array
+/// that backs the structured binding `[x, y]` elements of which are
+/// referred to by their aliases `x` and `y`.
+extern const internal::VariadicDynCastAllOfMatcher<Stmt, ArrayInitIndexExpr>
+ arrayInitIndexExpr;
+
/// Matches array subscript expressions.
///
/// Given
@@ -1998,6 +2062,18 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXDefaultArgExpr>
extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXOperatorCallExpr>
cxxOperatorCallExpr;
+/// Matches C++17 fold expressions.
+///
+/// Example matches `(0 + ... + args)`:
+/// \code
+/// template <typename... Args>
+/// auto sum(Args... args) {
+/// return (0 + ... + args);
+/// }
+/// \endcode
+extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXFoldExpr>
+ cxxFoldExpr;
+
/// Matches rewritten binary operators
///
/// Example matches use of "<":
@@ -2436,6 +2512,17 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt, DependentCoawaitExpr>
extern const internal::VariadicDynCastAllOfMatcher<Stmt, CoyieldExpr>
coyieldExpr;
+/// Matches coroutine body statements.
+///
+/// coroutineBodyStmt() matches the coroutine below
+/// \code
+/// generator<int> gen() {
+/// co_return;
+/// }
+/// \endcode
+extern const internal::VariadicDynCastAllOfMatcher<Stmt, CoroutineBodyStmt>
+ coroutineBodyStmt;
+
/// Matches nullptr literal.
extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXNullPtrLiteralExpr>
cxxNullPtrLiteralExpr;
@@ -2444,6 +2531,10 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXNullPtrLiteralExpr>
extern const internal::VariadicDynCastAllOfMatcher<Stmt, ChooseExpr>
chooseExpr;
+/// Matches builtin function __builtin_convertvector.
+extern const internal::VariadicDynCastAllOfMatcher<Stmt, ConvertVectorExpr>
+ convertVectorExpr;
+
/// Matches GNU __null expression.
extern const internal::VariadicDynCastAllOfMatcher<Stmt, GNUNullExpr>
gnuNullExpr;
@@ -2519,7 +2610,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt, OpaqueValueExpr>
/// Matches a C++ static_assert declaration.
///
/// Example:
-/// staticAssertExpr()
+/// staticAssertDecl()
/// matches
/// static_assert(sizeof(S) == sizeof(int))
/// in
@@ -3489,8 +3580,8 @@ internal::Matcher<T> findAll(const internal::Matcher<T> &Matcher) {
/// Usable as: Any Matcher
extern const internal::ArgumentAdaptingMatcherFunc<
internal::HasParentMatcher,
- internal::TypeList<Decl, NestedNameSpecifierLoc, Stmt, TypeLoc>,
- internal::TypeList<Decl, NestedNameSpecifierLoc, Stmt, TypeLoc>>
+ internal::TypeList<Decl, NestedNameSpecifierLoc, Stmt, TypeLoc, Attr>,
+ internal::TypeList<Decl, NestedNameSpecifierLoc, Stmt, TypeLoc, Attr>>
hasParent;
/// Matches AST nodes that have an ancestor that matches the provided
@@ -3506,8 +3597,8 @@ extern const internal::ArgumentAdaptingMatcherFunc<
/// Usable as: Any Matcher
extern const internal::ArgumentAdaptingMatcherFunc<
internal::HasAncestorMatcher,
- internal::TypeList<Decl, NestedNameSpecifierLoc, Stmt, TypeLoc>,
- internal::TypeList<Decl, NestedNameSpecifierLoc, Stmt, TypeLoc>>
+ internal::TypeList<Decl, NestedNameSpecifierLoc, Stmt, TypeLoc, Attr>,
+ internal::TypeList<Decl, NestedNameSpecifierLoc, Stmt, TypeLoc, Attr>>
hasAncestor;
/// Matches if the provided matcher does not match.
@@ -3721,10 +3812,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()
///
@@ -3803,7 +3893,7 @@ AST_MATCHER_P(ObjCMessageExpr, numSelectorArgs, unsigned, N) {
return Node.getSelector().getNumArgs() == N;
}
-/// Matches if the call expression's callee expression matches.
+/// Matches if the call or fold expression's callee expression matches.
///
/// Given
/// \code
@@ -3815,19 +3905,39 @@ AST_MATCHER_P(ObjCMessageExpr, numSelectorArgs, unsigned, N) {
/// with callee(...)
/// matching this->x, x, y.x, f respectively
///
+/// Given
+/// \code
+/// template <typename... Args>
+/// auto sum(Args... args) {
+/// return (0 + ... + args);
+/// }
+///
+/// template <typename... Args>
+/// auto multiply(Args... args) {
+/// return (args * ... * 1);
+/// }
+/// \endcode
+/// cxxFoldExpr(callee(expr()))
+/// matches (args * ... * 1)
+/// with callee(...)
+/// matching *
+///
/// Note: Callee cannot take the more general internal::Matcher<Expr>
/// because this introduces ambiguous overloads with calls to Callee taking a
/// internal::Matcher<Decl>, as the matcher hierarchy is purely
/// implemented in terms of implicit casts.
-AST_MATCHER_P(CallExpr, callee, internal::Matcher<Stmt>,
- InnerMatcher) {
- const Expr *ExprNode = Node.getCallee();
+AST_POLYMORPHIC_MATCHER_P_OVERLOAD(callee,
+ AST_POLYMORPHIC_SUPPORTED_TYPES(CallExpr,
+ CXXFoldExpr),
+ internal::Matcher<Stmt>, InnerMatcher, 0) {
+ const auto *ExprNode = Node.getCallee();
return (ExprNode != nullptr &&
InnerMatcher.matches(*ExprNode, Finder, Builder));
}
-/// Matches if the call expression's callee's declaration matches the
-/// given matcher.
+/// Matches 1) if the call expression's callee's declaration matches the
+/// given matcher; or 2) if the Obj-C message expression's callee's method
+/// declaration matches the given matcher.
///
/// Example matches y.x() (matcher = callExpr(callee(
/// cxxMethodDecl(hasName("x")))))
@@ -3835,9 +3945,31 @@ AST_MATCHER_P(CallExpr, callee, internal::Matcher<Stmt>,
/// class Y { public: void x(); };
/// void z() { Y y; y.x(); }
/// \endcode
-AST_MATCHER_P_OVERLOAD(CallExpr, callee, internal::Matcher<Decl>, InnerMatcher,
- 1) {
- return callExpr(hasDeclaration(InnerMatcher)).matches(Node, Finder, Builder);
+///
+/// Example 2. Matches [I foo] with
+/// objcMessageExpr(callee(objcMethodDecl(hasName("foo"))))
+///
+/// \code
+/// @interface I: NSObject
+/// +(void)foo;
+/// @end
+/// ...
+/// [I foo]
+/// \endcode
+AST_POLYMORPHIC_MATCHER_P_OVERLOAD(
+ callee, AST_POLYMORPHIC_SUPPORTED_TYPES(ObjCMessageExpr, CallExpr),
+ internal::Matcher<Decl>, InnerMatcher, 1) {
+ if (isa<CallExpr>(&Node))
+ return callExpr(hasDeclaration(InnerMatcher))
+ .matches(Node, Finder, Builder);
+ else {
+ // The dynamic cast below is guaranteed to succeed as there are only 2
+ // supported return types.
+ const auto *MsgNode = cast<ObjCMessageExpr>(&Node);
+ const Decl *DeclNode = MsgNode->getMethodDecl();
+ return (DeclNode != nullptr &&
+ InnerMatcher.matches(*DeclNode, Finder, Builder));
+ }
}
/// Matches if the expression's or declaration's type matches a type
@@ -3919,14 +4051,14 @@ AST_POLYMORPHIC_MATCHER_P_OVERLOAD(
///
/// \code
/// auto x = int(3);
-/// \code
+/// \endcode
/// cxxTemporaryObjectExpr(hasTypeLoc(loc(asString("int"))))
/// matches int(3)
///
/// \code
/// struct Foo { Foo(int, int); };
/// auto x = Foo(1, 2);
-/// \code
+/// \endcode
/// cxxFunctionalCastExpr(hasTypeLoc(loc(asString("struct Foo"))))
/// matches Foo(1, 2)
///
@@ -4124,25 +4256,34 @@ AST_MATCHER_P(DeclRefExpr, to, internal::Matcher<Decl>,
InnerMatcher.matches(*DeclNode, Finder, Builder));
}
-/// Matches a \c DeclRefExpr that refers to a declaration through a
-/// specific using shadow declaration.
+/// Matches if a node refers to a declaration through a specific
+/// using shadow declaration.
///
-/// Given
+/// Examples:
/// \code
-/// namespace a { void f() {} }
+/// namespace a { int f(); }
/// using a::f;
-/// void g() {
-/// f(); // Matches this ..
-/// a::f(); // .. but not this.
-/// }
+/// int x = f();
/// \endcode
/// declRefExpr(throughUsingDecl(anything()))
-/// matches \c f()
-AST_MATCHER_P(DeclRefExpr, throughUsingDecl,
- internal::Matcher<UsingShadowDecl>, InnerMatcher) {
+/// matches \c f
+///
+/// \code
+/// namespace a { class X{}; }
+/// using a::X;
+/// X x;
+/// \endcode
+/// typeLoc(loc(usingType(throughUsingDecl(anything()))))
+/// matches \c X
+///
+/// Usable as: Matcher<DeclRefExpr>, Matcher<UsingType>
+AST_POLYMORPHIC_MATCHER_P(throughUsingDecl,
+ AST_POLYMORPHIC_SUPPORTED_TYPES(DeclRefExpr,
+ UsingType),
+ internal::Matcher<UsingShadowDecl>, Inner) {
const NamedDecl *FoundDecl = Node.getFoundDecl();
if (const UsingShadowDecl *UsingDecl = dyn_cast<UsingShadowDecl>(FoundDecl))
- return InnerMatcher.matches(*UsingDecl, Finder, Builder);
+ return Inner.matches(*UsingDecl, Finder, Builder);
return false;
}
@@ -4201,6 +4342,45 @@ AST_MATCHER_P(
InnerMatcher.matches(*Initializer, Finder, Builder));
}
+/// Matches a variable serving as the implicit variable for a lambda init-
+/// capture.
+///
+/// Example matches x (matcher = varDecl(isInitCapture()))
+/// \code
+/// auto f = [x=3]() { return x; };
+/// \endcode
+AST_MATCHER(VarDecl, isInitCapture) { return Node.isInitCapture(); }
+
+/// Matches each lambda capture in a lambda expression.
+///
+/// Given
+/// \code
+/// int main() {
+/// int x, y;
+/// float z;
+/// auto f = [=]() { return x + y + z; };
+/// }
+/// \endcode
+/// lambdaExpr(forEachLambdaCapture(
+/// lambdaCapture(capturesVar(varDecl(hasType(isInteger()))))))
+/// will trigger two matches, binding for 'x' and 'y' respectively.
+AST_MATCHER_P(LambdaExpr, forEachLambdaCapture,
+ internal::Matcher<LambdaCapture>, InnerMatcher) {
+ BoundNodesTreeBuilder Result;
+ bool Matched = false;
+ for (const auto &Capture : Node.captures()) {
+ if (Finder->isTraversalIgnoringImplicitNodes() && Capture.isImplicit())
+ continue;
+ BoundNodesTreeBuilder CaptureBuilder(*Builder);
+ if (InnerMatcher.matches(Capture, Finder, &CaptureBuilder)) {
+ Matched = true;
+ Result.addMatch(CaptureBuilder);
+ }
+ }
+ *Builder = std::move(Result);
+ return Matched;
+}
+
/// \brief Matches a static variable with local scope.
///
/// Example matches y (matcher = varDecl(isStaticLocal()))
@@ -4335,6 +4515,33 @@ AST_POLYMORPHIC_MATCHER_P(argumentCountIs,
return NumArgs == N;
}
+/// Checks that a call expression or a constructor call expression has at least
+/// the specified number of arguments (including absent default arguments).
+///
+/// Example matches f(0, 0) and g(0, 0, 0)
+/// (matcher = callExpr(argumentCountAtLeast(2)))
+/// \code
+/// void f(int x, int y);
+/// void g(int x, int y, int z);
+/// f(0, 0);
+/// g(0, 0, 0);
+/// \endcode
+AST_POLYMORPHIC_MATCHER_P(argumentCountAtLeast,
+ AST_POLYMORPHIC_SUPPORTED_TYPES(
+ CallExpr, CXXConstructExpr,
+ CXXUnresolvedConstructExpr, ObjCMessageExpr),
+ unsigned, N) {
+ unsigned NumArgs = Node.getNumArgs();
+ if (!Finder->isTraversalIgnoringImplicitNodes())
+ return NumArgs >= N;
+ while (NumArgs) {
+ if (!isa<CXXDefaultArgExpr>(Node.getArg(NumArgs - 1)))
+ break;
+ --NumArgs;
+ }
+ return NumArgs >= N;
+}
+
/// Matches the n'th argument of a call expression or a constructor
/// call expression.
///
@@ -4356,6 +4563,121 @@ AST_POLYMORPHIC_MATCHER_P2(hasArgument,
return InnerMatcher.matches(*Arg->IgnoreParenImpCasts(), Finder, Builder);
}
+/// Matches the operand that does not contain the parameter pack.
+///
+/// Example matches `(0 + ... + args)` and `(args * ... * 1)`
+/// (matcher = cxxFoldExpr(hasFoldInit(expr())))
+/// with hasFoldInit(...)
+/// matching `0` and `1` respectively
+/// \code
+/// template <typename... Args>
+/// auto sum(Args... args) {
+/// return (0 + ... + args);
+/// }
+///
+/// template <typename... Args>
+/// auto multiply(Args... args) {
+/// return (args * ... * 1);
+/// }
+/// \endcode
+AST_MATCHER_P(CXXFoldExpr, hasFoldInit, ast_matchers::internal::Matcher<Expr>,
+ InnerMacher) {
+ const auto *const Init = Node.getInit();
+ return Init && InnerMacher.matches(*Init, Finder, Builder);
+}
+
+/// Matches the operand that contains the parameter pack.
+///
+/// Example matches `(0 + ... + args)`
+/// (matcher = cxxFoldExpr(hasPattern(expr())))
+/// with hasPattern(...)
+/// matching `args`
+/// \code
+/// template <typename... Args>
+/// auto sum(Args... args) {
+/// return (0 + ... + args);
+/// }
+///
+/// template <typename... Args>
+/// auto multiply(Args... args) {
+/// return (args * ... * 1);
+/// }
+/// \endcode
+AST_MATCHER_P(CXXFoldExpr, hasPattern, ast_matchers::internal::Matcher<Expr>,
+ InnerMacher) {
+ const Expr *const Pattern = Node.getPattern();
+ return Pattern && InnerMacher.matches(*Pattern, Finder, Builder);
+}
+
+/// Matches right-folding fold expressions.
+///
+/// Example matches `(args * ... * 1)`
+/// (matcher = cxxFoldExpr(isRightFold()))
+/// \code
+/// template <typename... Args>
+/// auto sum(Args... args) {
+/// return (0 + ... + args);
+/// }
+///
+/// template <typename... Args>
+/// auto multiply(Args... args) {
+/// return (args * ... * 1);
+/// }
+/// \endcode
+AST_MATCHER(CXXFoldExpr, isRightFold) { return Node.isRightFold(); }
+
+/// Matches left-folding fold expressions.
+///
+/// Example matches `(0 + ... + args)`
+/// (matcher = cxxFoldExpr(isLeftFold()))
+/// \code
+/// template <typename... Args>
+/// auto sum(Args... args) {
+/// return (0 + ... + args);
+/// }
+///
+/// template <typename... Args>
+/// auto multiply(Args... args) {
+/// return (args * ... * 1);
+/// }
+/// \endcode
+AST_MATCHER(CXXFoldExpr, isLeftFold) { return Node.isLeftFold(); }
+
+/// Matches unary fold expressions, i.e. fold expressions without an
+/// initializer.
+///
+/// Example matches `(args * ...)`
+/// (matcher = cxxFoldExpr(isUnaryFold()))
+/// \code
+/// template <typename... Args>
+/// auto sum(Args... args) {
+/// return (0 + ... + args);
+/// }
+///
+/// template <typename... Args>
+/// auto multiply(Args... args) {
+/// return (args * ...);
+/// }
+/// \endcode
+AST_MATCHER(CXXFoldExpr, isUnaryFold) { return Node.getInit() == nullptr; }
+
+/// Matches binary fold expressions, i.e. fold expressions with an initializer.
+///
+/// Example matches `(0 + ... + args)`
+/// (matcher = cxxFoldExpr(isBinaryFold()))
+/// \code
+/// template <typename... Args>
+/// auto sum(Args... args) {
+/// return (0 + ... + args);
+/// }
+///
+/// template <typename... Args>
+/// auto multiply(Args... args) {
+/// return (args * ...);
+/// }
+/// \endcode
+AST_MATCHER(CXXFoldExpr, isBinaryFold) { return Node.getInit() != nullptr; }
+
/// Matches the n'th item of an initializer list expression.
///
/// Example matches y.
@@ -4586,50 +4908,81 @@ AST_POLYMORPHIC_MATCHER_P(hasAnyArgument,
return false;
}
-/// Matches any capture of a lambda expression.
+/// Matches lambda captures.
///
/// Given
/// \code
-/// void foo() {
+/// int main() {
/// int x;
/// auto f = [x](){};
+/// auto g = [x = 1](){};
/// }
/// \endcode
-/// lambdaExpr(hasAnyCapture(anything()))
-/// matches [x](){};
-AST_MATCHER_P_OVERLOAD(LambdaExpr, hasAnyCapture, internal::Matcher<VarDecl>,
- InnerMatcher, 0) {
+/// In the matcher `lambdaExpr(hasAnyCapture(lambdaCapture()))`,
+/// `lambdaCapture()` matches `x` and `x=1`.
+extern const internal::VariadicAllOfMatcher<LambdaCapture> lambdaCapture;
+
+/// Matches any capture in a lambda expression.
+///
+/// Given
+/// \code
+/// void foo() {
+/// int t = 5;
+/// auto f = [=](){ return t; };
+/// }
+/// \endcode
+/// lambdaExpr(hasAnyCapture(lambdaCapture())) and
+/// lambdaExpr(hasAnyCapture(lambdaCapture(refersToVarDecl(hasName("t")))))
+/// both match `[=](){ return t; }`.
+AST_MATCHER_P(LambdaExpr, hasAnyCapture, internal::Matcher<LambdaCapture>,
+ InnerMatcher) {
for (const LambdaCapture &Capture : Node.captures()) {
- if (Capture.capturesVariable()) {
- BoundNodesTreeBuilder Result(*Builder);
- if (InnerMatcher.matches(*Capture.getCapturedVar(), Finder, &Result)) {
- *Builder = std::move(Result);
- return true;
- }
+ clang::ast_matchers::internal::BoundNodesTreeBuilder Result(*Builder);
+ if (InnerMatcher.matches(Capture, Finder, &Result)) {
+ *Builder = std::move(Result);
+ return true;
}
}
return false;
}
-/// Matches any capture of 'this' in a lambda expression.
+/// Matches a `LambdaCapture` that refers to the specified `VarDecl`. The
+/// `VarDecl` can be a separate variable that is captured by value or
+/// reference, or a synthesized variable if the capture has an initializer.
///
/// Given
/// \code
-/// struct foo {
-/// void bar() {
-/// auto f = [this](){};
-/// }
+/// void foo() {
+/// int x;
+/// auto f = [x](){};
+/// auto g = [x = 1](){};
/// }
/// \endcode
-/// lambdaExpr(hasAnyCapture(cxxThisExpr()))
-/// matches [this](){};
-AST_MATCHER_P_OVERLOAD(LambdaExpr, hasAnyCapture,
- internal::Matcher<CXXThisExpr>, InnerMatcher, 1) {
- return llvm::any_of(Node.captures(), [](const LambdaCapture &LC) {
- return LC.capturesThis();
- });
+/// In the matcher
+/// lambdaExpr(hasAnyCapture(lambdaCapture(capturesVar(hasName("x")))),
+/// capturesVar(hasName("x")) matches `x` and `x = 1`.
+AST_MATCHER_P(LambdaCapture, capturesVar, internal::Matcher<ValueDecl>,
+ InnerMatcher) {
+ auto *capturedVar = Node.getCapturedVar();
+ return capturedVar && InnerMatcher.matches(*capturedVar, Finder, Builder);
}
+/// Matches a `LambdaCapture` that refers to 'this'.
+///
+/// Given
+/// \code
+/// class C {
+/// int cc;
+/// int f() {
+/// auto l = [this]() { return cc; };
+/// return l();
+/// }
+/// };
+/// \endcode
+/// lambdaExpr(hasAnyCapture(lambdaCapture(capturesThis())))
+/// matches `[this]() { return cc; }`.
+AST_MATCHER(LambdaCapture, capturesThis) { return Node.capturesThis(); }
+
/// Matches a constructor call expression which uses list initialization.
AST_MATCHER(CXXConstructExpr, isListInitialization) {
return Node.isListInitialization();
@@ -4798,7 +5151,7 @@ AST_POLYMORPHIC_MATCHER_P2(forEachArgumentWithParamType,
}
}
- int ParamIndex = 0;
+ unsigned ParamIndex = 0;
bool Matched = false;
unsigned NumArgs = Node.getNumArgs();
if (FProto && FProto->isVariadic())
@@ -4812,7 +5165,7 @@ AST_POLYMORPHIC_MATCHER_P2(forEachArgumentWithParamType,
// This test is cheaper compared to the big matcher in the next if.
// Therefore, please keep this order.
- if (FProto) {
+ if (FProto && FProto->getNumParams() > ParamIndex) {
QualType ParamType = FProto->getParamType(ParamIndex);
if (ParamMatcher.matches(ParamType, Finder, &ParamMatches)) {
Result.addMatch(ParamMatches);
@@ -4929,6 +5282,49 @@ AST_POLYMORPHIC_MATCHER_P(parameterCountIs,
return Node.getNumParams() == N;
}
+/// Matches classTemplateSpecialization, templateSpecializationType and
+/// functionDecl nodes where the template argument matches the inner matcher.
+/// This matcher may produce multiple matches.
+///
+/// Given
+/// \code
+/// template <typename T, unsigned N, unsigned M>
+/// struct Matrix {};
+///
+/// constexpr unsigned R = 2;
+/// Matrix<int, R * 2, R * 4> M;
+///
+/// template <typename T, typename U>
+/// void f(T&& t, U&& u) {}
+///
+/// bool B = false;
+/// f(R, B);
+/// \endcode
+/// templateSpecializationType(forEachTemplateArgument(isExpr(expr())))
+/// matches twice, with expr() matching 'R * 2' and 'R * 4'
+/// functionDecl(forEachTemplateArgument(refersToType(builtinType())))
+/// matches the specialization f<unsigned, bool> twice, for 'unsigned'
+/// and 'bool'
+AST_POLYMORPHIC_MATCHER_P(
+ forEachTemplateArgument,
+ AST_POLYMORPHIC_SUPPORTED_TYPES(ClassTemplateSpecializationDecl,
+ TemplateSpecializationType, FunctionDecl),
+ clang::ast_matchers::internal::Matcher<TemplateArgument>, InnerMatcher) {
+ ArrayRef<TemplateArgument> TemplateArgs =
+ clang::ast_matchers::internal::getTemplateSpecializationArgs(Node);
+ clang::ast_matchers::internal::BoundNodesTreeBuilder Result;
+ bool Matched = false;
+ for (const auto &Arg : TemplateArgs) {
+ clang::ast_matchers::internal::BoundNodesTreeBuilder ArgBuilder(*Builder);
+ if (InnerMatcher.matches(Arg, Finder, &ArgBuilder)) {
+ Matched = true;
+ Result.addMatch(ArgBuilder);
+ }
+ }
+ *Builder = std::move(Result);
+ return Matched;
+}
+
/// Matches \c FunctionDecls that have a noreturn attribute.
///
/// Given
@@ -5088,6 +5484,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.
///
@@ -5110,6 +5525,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:
@@ -5266,16 +5698,16 @@ AST_MATCHER_P(ArraySubscriptExpr, hasBase,
return false;
}
-/// Matches a 'for', 'while', 'do while' statement or a function
-/// definition that has a given body. Note that in case of functions
-/// this matcher only matches the definition itself and not the other
-/// declarations of the same function.
+/// Matches a 'for', 'while', 'while' statement or a function or coroutine
+/// definition that has a given body. Note that in case of functions or
+/// coroutines this matcher only matches the definition itself and not the
+/// other declarations of the same function or coroutine.
///
/// Given
/// \code
/// for (;;) {}
/// \endcode
-/// hasBody(compoundStmt())
+/// forStmt(hasBody(compoundStmt()))
/// matches 'for (;;) {}'
/// with compoundStmt()
/// matching '{}'
@@ -5285,18 +5717,16 @@ AST_MATCHER_P(ArraySubscriptExpr, hasBase,
/// void f();
/// void f() {}
/// \endcode
-/// hasBody(functionDecl())
+/// functionDecl(hasBody(compoundStmt()))
/// matches 'void f() {}'
/// with compoundStmt()
/// matching '{}'
/// but does not match 'void f();'
-
-AST_POLYMORPHIC_MATCHER_P(hasBody,
- AST_POLYMORPHIC_SUPPORTED_TYPES(DoStmt, ForStmt,
- WhileStmt,
- CXXForRangeStmt,
- FunctionDecl),
- internal::Matcher<Stmt>, InnerMatcher) {
+AST_POLYMORPHIC_MATCHER_P(
+ hasBody,
+ AST_POLYMORPHIC_SUPPORTED_TYPES(DoStmt, ForStmt, WhileStmt, CXXForRangeStmt,
+ FunctionDecl, CoroutineBodyStmt),
+ internal::Matcher<Stmt>, InnerMatcher) {
if (Finder->isTraversalIgnoringImplicitNodes() && isDefaultedHelper(&Node))
return false;
const Stmt *const Statement = internal::GetBodyMatcher<NodeType>::get(Node);
@@ -5425,19 +5855,29 @@ AST_POLYMORPHIC_MATCHER_P_OVERLOAD(equals,
.matchesNode(Node);
}
-/// Matches the operator Name of operator expressions (binary or
-/// unary).
+/// Matches the operator Name of operator expressions and fold expressions
+/// (binary or unary).
///
/// Example matches a || b (matcher = binaryOperator(hasOperatorName("||")))
/// \code
/// !(a || b)
/// \endcode
+///
+/// Example matches `(0 + ... + args)`
+/// (matcher = cxxFoldExpr(hasOperatorName("+")))
+/// \code
+/// template <typename... Args>
+/// auto sum(Args... args) {
+/// return (0 + ... + args);
+/// }
+/// \endcode
AST_POLYMORPHIC_MATCHER_P(
hasOperatorName,
AST_POLYMORPHIC_SUPPORTED_TYPES(BinaryOperator, CXXOperatorCallExpr,
- CXXRewrittenBinaryOperator, UnaryOperator),
+ CXXRewrittenBinaryOperator, CXXFoldExpr,
+ UnaryOperator),
std::string, Name) {
- if (Optional<StringRef> OpName = internal::getOpName(Node))
+ if (std::optional<StringRef> OpName = internal::getOpName(Node))
return *OpName == Name;
return false;
}
@@ -5505,11 +5945,12 @@ AST_POLYMORPHIC_MATCHER(
/// \code
/// a || b
/// \endcode
-AST_POLYMORPHIC_MATCHER_P(hasLHS,
- AST_POLYMORPHIC_SUPPORTED_TYPES(
- BinaryOperator, CXXOperatorCallExpr,
- CXXRewrittenBinaryOperator, ArraySubscriptExpr),
- internal::Matcher<Expr>, InnerMatcher) {
+AST_POLYMORPHIC_MATCHER_P(
+ hasLHS,
+ AST_POLYMORPHIC_SUPPORTED_TYPES(BinaryOperator, CXXOperatorCallExpr,
+ CXXRewrittenBinaryOperator,
+ ArraySubscriptExpr, CXXFoldExpr),
+ internal::Matcher<Expr>, InnerMatcher) {
const Expr *LeftHandSide = internal::getLHS(Node);
return (LeftHandSide != nullptr &&
InnerMatcher.matches(*LeftHandSide, Finder, Builder));
@@ -5521,29 +5962,31 @@ AST_POLYMORPHIC_MATCHER_P(hasLHS,
/// \code
/// a || b
/// \endcode
-AST_POLYMORPHIC_MATCHER_P(hasRHS,
- AST_POLYMORPHIC_SUPPORTED_TYPES(
- BinaryOperator, CXXOperatorCallExpr,
- CXXRewrittenBinaryOperator, ArraySubscriptExpr),
- internal::Matcher<Expr>, InnerMatcher) {
+AST_POLYMORPHIC_MATCHER_P(
+ hasRHS,
+ AST_POLYMORPHIC_SUPPORTED_TYPES(BinaryOperator, CXXOperatorCallExpr,
+ CXXRewrittenBinaryOperator,
+ ArraySubscriptExpr, CXXFoldExpr),
+ internal::Matcher<Expr>, InnerMatcher) {
const Expr *RightHandSide = internal::getRHS(Node);
return (RightHandSide != nullptr &&
InnerMatcher.matches(*RightHandSide, Finder, Builder));
}
/// Matches if either the left hand side or the right hand side of a
-/// binary operator matches.
+/// binary operator or fold expression matches.
AST_POLYMORPHIC_MATCHER_P(
hasEitherOperand,
AST_POLYMORPHIC_SUPPORTED_TYPES(BinaryOperator, CXXOperatorCallExpr,
- CXXRewrittenBinaryOperator),
+ CXXFoldExpr, CXXRewrittenBinaryOperator),
internal::Matcher<Expr>, InnerMatcher) {
return internal::VariadicDynCastAllOfMatcher<Stmt, NodeType>()(
anyOf(hasLHS(InnerMatcher), hasRHS(InnerMatcher)))
.matches(Node, Finder, Builder);
}
-/// Matches if both matchers match with opposite sides of the binary operator.
+/// Matches if both matchers match with opposite sides of the binary operator
+/// or fold expression.
///
/// Example matcher = binaryOperator(hasOperands(integerLiteral(equals(1),
/// integerLiteral(equals(2)))
@@ -5556,7 +5999,7 @@ AST_POLYMORPHIC_MATCHER_P(
AST_POLYMORPHIC_MATCHER_P2(
hasOperands,
AST_POLYMORPHIC_SUPPORTED_TYPES(BinaryOperator, CXXOperatorCallExpr,
- CXXRewrittenBinaryOperator),
+ CXXFoldExpr, CXXRewrittenBinaryOperator),
internal::Matcher<Expr>, Matcher1, internal::Matcher<Expr>, Matcher2) {
return internal::VariadicDynCastAllOfMatcher<Stmt, NodeType>()(
anyOf(allOf(hasLHS(Matcher1), hasRHS(Matcher2)),
@@ -5631,8 +6074,6 @@ AST_MATCHER_P(ExplicitCastExpr, hasDestinationType,
/// Matches implicit casts whose destination type matches a given
/// matcher.
-///
-/// FIXME: Unit test this matcher
AST_MATCHER_P(ImplicitCastExpr, hasImplicitDestinationType,
internal::Matcher<QualType>, InnerMatcher) {
return InnerMatcher.matches(Node.getType(), Finder, Builder);
@@ -5875,6 +6316,10 @@ AST_MATCHER(CXXMethodDecl, isVirtualAsWritten) {
return Node.isVirtualAsWritten();
}
+AST_MATCHER(CXXConstructorDecl, isInheritingConstructor) {
+ return Node.isInheritingConstructor();
+}
+
/// Matches if the given method or class declaration is final.
///
/// Given:
@@ -5906,9 +6351,7 @@ AST_POLYMORPHIC_MATCHER(isFinal,
/// };
/// \endcode
/// matches A::x
-AST_MATCHER(CXXMethodDecl, isPure) {
- return Node.isPure();
-}
+AST_MATCHER(CXXMethodDecl, isPure) { return Node.isPureVirtual(); }
/// Matches if the given method declaration is const.
///
@@ -6333,6 +6776,187 @@ AST_MATCHER_FUNCTION_P_OVERLOAD(internal::BindableMatcher<TypeLoc>, loc,
new internal::TypeLocTypeMatcher(InnerMatcher));
}
+/// Matches `QualifiedTypeLoc`s in the clang AST.
+///
+/// Given
+/// \code
+/// const int x = 0;
+/// \endcode
+/// qualifiedTypeLoc()
+/// matches `const int`.
+extern const internal::VariadicDynCastAllOfMatcher<TypeLoc, QualifiedTypeLoc>
+ qualifiedTypeLoc;
+
+/// Matches `QualifiedTypeLoc`s that have an unqualified `TypeLoc` matching
+/// `InnerMatcher`.
+///
+/// Given
+/// \code
+/// int* const x;
+/// const int y;
+/// \endcode
+/// qualifiedTypeLoc(hasUnqualifiedLoc(pointerTypeLoc()))
+/// matches the `TypeLoc` of the variable declaration of `x`, but not `y`.
+AST_MATCHER_P(QualifiedTypeLoc, hasUnqualifiedLoc, internal::Matcher<TypeLoc>,
+ InnerMatcher) {
+ return InnerMatcher.matches(Node.getUnqualifiedLoc(), Finder, Builder);
+}
+
+/// Matches a function declared with the specified return `TypeLoc`.
+///
+/// Given
+/// \code
+/// int f() { return 5; }
+/// void g() {}
+/// \endcode
+/// functionDecl(hasReturnTypeLoc(loc(asString("int"))))
+/// matches the declaration of `f`, but not `g`.
+AST_MATCHER_P(FunctionDecl, hasReturnTypeLoc, internal::Matcher<TypeLoc>,
+ ReturnMatcher) {
+ auto Loc = Node.getFunctionTypeLoc();
+ return Loc && ReturnMatcher.matches(Loc.getReturnLoc(), Finder, Builder);
+}
+
+/// Matches pointer `TypeLoc`s.
+///
+/// Given
+/// \code
+/// int* x;
+/// \endcode
+/// pointerTypeLoc()
+/// matches `int*`.
+extern const internal::VariadicDynCastAllOfMatcher<TypeLoc, PointerTypeLoc>
+ pointerTypeLoc;
+
+/// Matches pointer `TypeLoc`s that have a pointee `TypeLoc` matching
+/// `PointeeMatcher`.
+///
+/// Given
+/// \code
+/// int* x;
+/// \endcode
+/// pointerTypeLoc(hasPointeeLoc(loc(asString("int"))))
+/// matches `int*`.
+AST_MATCHER_P(PointerTypeLoc, hasPointeeLoc, internal::Matcher<TypeLoc>,
+ PointeeMatcher) {
+ return PointeeMatcher.matches(Node.getPointeeLoc(), Finder, Builder);
+}
+
+/// Matches reference `TypeLoc`s.
+///
+/// Given
+/// \code
+/// int x = 3;
+/// int& l = x;
+/// int&& r = 3;
+/// \endcode
+/// referenceTypeLoc()
+/// matches `int&` and `int&&`.
+extern const internal::VariadicDynCastAllOfMatcher<TypeLoc, ReferenceTypeLoc>
+ referenceTypeLoc;
+
+/// Matches reference `TypeLoc`s that have a referent `TypeLoc` matching
+/// `ReferentMatcher`.
+///
+/// Given
+/// \code
+/// int x = 3;
+/// int& xx = x;
+/// \endcode
+/// referenceTypeLoc(hasReferentLoc(loc(asString("int"))))
+/// matches `int&`.
+AST_MATCHER_P(ReferenceTypeLoc, hasReferentLoc, internal::Matcher<TypeLoc>,
+ ReferentMatcher) {
+ return ReferentMatcher.matches(Node.getPointeeLoc(), Finder, Builder);
+}
+
+/// Matches template specialization `TypeLoc`s.
+///
+/// Given
+/// \code
+/// template <typename T> class C {};
+/// C<char> var;
+/// \endcode
+/// varDecl(hasTypeLoc(templateSpecializationTypeLoc(typeLoc())))
+/// matches `C<char> var`.
+extern const internal::VariadicDynCastAllOfMatcher<
+ TypeLoc, TemplateSpecializationTypeLoc>
+ templateSpecializationTypeLoc;
+
+/// Matches template specialization `TypeLoc`s that have at least one
+/// `TemplateArgumentLoc` matching the given `InnerMatcher`.
+///
+/// Given
+/// \code
+/// template<typename T> class A {};
+/// A<int> a;
+/// \endcode
+/// varDecl(hasTypeLoc(templateSpecializationTypeLoc(hasAnyTemplateArgumentLoc(
+/// hasTypeLoc(loc(asString("int")))))))
+/// matches `A<int> a`.
+AST_MATCHER_P(TemplateSpecializationTypeLoc, hasAnyTemplateArgumentLoc,
+ internal::Matcher<TemplateArgumentLoc>, InnerMatcher) {
+ for (unsigned Index = 0, N = Node.getNumArgs(); Index < N; ++Index) {
+ clang::ast_matchers::internal::BoundNodesTreeBuilder Result(*Builder);
+ if (InnerMatcher.matches(Node.getArgLoc(Index), Finder, &Result)) {
+ *Builder = std::move(Result);
+ return true;
+ }
+ }
+ return false;
+}
+
+/// Matches template specialization `TypeLoc`s where the n'th
+/// `TemplateArgumentLoc` matches the given `InnerMatcher`.
+///
+/// Given
+/// \code
+/// template<typename T, typename U> class A {};
+/// A<double, int> b;
+/// A<int, double> c;
+/// \endcode
+/// varDecl(hasTypeLoc(templateSpecializationTypeLoc(hasTemplateArgumentLoc(0,
+/// hasTypeLoc(loc(asString("double")))))))
+/// matches `A<double, int> b`, but not `A<int, double> c`.
+AST_POLYMORPHIC_MATCHER_P2(
+ hasTemplateArgumentLoc,
+ AST_POLYMORPHIC_SUPPORTED_TYPES(DeclRefExpr, TemplateSpecializationTypeLoc),
+ unsigned, Index, internal::Matcher<TemplateArgumentLoc>, InnerMatcher) {
+ return internal::MatchTemplateArgLocAt(Node, Index, InnerMatcher, Finder,
+ Builder);
+}
+
+/// Matches C or C++ elaborated `TypeLoc`s.
+///
+/// Given
+/// \code
+/// struct s {};
+/// struct s ss;
+/// \endcode
+/// elaboratedTypeLoc()
+/// matches the `TypeLoc` of the variable declaration of `ss`.
+extern const internal::VariadicDynCastAllOfMatcher<TypeLoc, ElaboratedTypeLoc>
+ elaboratedTypeLoc;
+
+/// Matches elaborated `TypeLoc`s that have a named `TypeLoc` matching
+/// `InnerMatcher`.
+///
+/// Given
+/// \code
+/// template <typename T>
+/// class C {};
+/// class C<int> c;
+///
+/// class D {};
+/// class D d;
+/// \endcode
+/// elaboratedTypeLoc(hasNamedTypeLoc(templateSpecializationTypeLoc()));
+/// matches the `TypeLoc` of the variable declaration of `c`, but not `d`.
+AST_MATCHER_P(ElaboratedTypeLoc, hasNamedTypeLoc, internal::Matcher<TypeLoc>,
+ InnerMatcher) {
+ return InnerMatcher.matches(Node.getNamedTypeLoc(), Finder, Builder);
+}
+
/// Matches type \c bool.
///
/// Given
@@ -6471,10 +7095,25 @@ AST_POLYMORPHIC_MATCHER_P(hasSize,
/// T data[Size];
/// };
/// \endcode
-/// dependentSizedArrayType
+/// dependentSizedArrayType()
/// matches "T data[Size]"
extern const AstTypeMatcher<DependentSizedArrayType> dependentSizedArrayType;
+/// Matches C++ extended vector type where either the type or size is
+/// dependent.
+///
+/// Given
+/// \code
+/// template<typename T, int Size>
+/// class vector {
+/// typedef T __attribute__((ext_vector_type(Size))) type;
+/// };
+/// \endcode
+/// dependentSizedExtVectorType()
+/// matches "T __attribute__((ext_vector_type(Size)))"
+extern const AstTypeMatcher<DependentSizedExtVectorType>
+ dependentSizedExtVectorType;
+
/// Matches C arrays with unspecified size.
///
/// Given
@@ -6584,7 +7223,7 @@ extern const AstTypeMatcher<DecltypeType> decltypeType;
AST_TYPE_TRAVERSE_MATCHER(hasDeducedType, getDeducedType,
AST_POLYMORPHIC_SUPPORTED_TYPES(AutoType));
-/// Matches \c DecltypeType nodes to find out the underlying type.
+/// Matches \c DecltypeType or \c UsingType nodes to find the underlying type.
///
/// Given
/// \code
@@ -6594,9 +7233,10 @@ AST_TYPE_TRAVERSE_MATCHER(hasDeducedType, getDeducedType,
/// decltypeType(hasUnderlyingType(isInteger()))
/// matches the type of "a"
///
-/// Usable as: Matcher<DecltypeType>
+/// Usable as: Matcher<DecltypeType>, Matcher<UsingType>
AST_TYPE_TRAVERSE_MATCHER(hasUnderlyingType, getUnderlyingType,
- AST_POLYMORPHIC_SUPPORTED_TYPES(DecltypeType));
+ AST_POLYMORPHIC_SUPPORTED_TYPES(DecltypeType,
+ UsingType));
/// Matches \c FunctionType nodes.
///
@@ -6775,6 +7415,18 @@ AST_TYPELOC_TRAVERSE_MATCHER_DECL(
/// matches "typedef int X"
extern const AstTypeMatcher<TypedefType> typedefType;
+/// Matches qualified types when the qualifier is applied via a macro.
+///
+/// Given
+/// \code
+/// #define CDECL __attribute__((cdecl))
+/// typedef void (CDECL *X)();
+/// typedef void (__attribute__((cdecl)) *Y)();
+/// \endcode
+/// macroQualifiedType()
+/// matches the type of the typedef declaration of \c X but not \c Y.
+extern const AstTypeMatcher<MacroQualifiedType> macroQualifiedType;
+
/// Matches enum types.
///
/// Given
@@ -6924,6 +7576,18 @@ AST_MATCHER_P(ElaboratedType, namesType, internal::Matcher<QualType>,
return InnerMatcher.matches(Node.getNamedType(), Finder, Builder);
}
+/// Matches types specified through a using declaration.
+///
+/// Given
+/// \code
+/// namespace a { struct S {}; }
+/// using a::S;
+/// S s;
+/// \endcode
+///
+/// \c usingType() matches the type of the variable declaration of \c s.
+extern const AstTypeMatcher<UsingType> usingType;
+
/// Matches types that represent the result of substituting a type for a
/// template type parameter.
///
@@ -7133,6 +7797,24 @@ AST_MATCHER_P(NestedNameSpecifier, specifiesNamespace,
return InnerMatcher.matches(*Node.getAsNamespace(), Finder, Builder);
}
+/// Matches attributes.
+/// Attributes may be attached with a variety of different syntaxes (including
+/// keywords, C++11 attributes, GNU ``__attribute``` and MSVC `__declspec``,
+/// and ``#pragma``s). They may also be implicit.
+///
+/// Given
+/// \code
+/// struct [[nodiscard]] Foo{};
+/// void bar(int * __attribute__((nonnull)) );
+/// __declspec(noinline) void baz();
+///
+/// #pragma omp declare simd
+/// int min();
+/// \endcode
+/// attr()
+/// matches "nodiscard", "nonnull", "noinline", and the whole "#pragma" line.
+extern const internal::VariadicAllOfMatcher<Attr> attr;
+
/// Overloads for the \c equalsNode matcher.
/// FIXME: Implement for other node types.
/// @{
@@ -7339,7 +8021,7 @@ AST_MATCHER_P(FunctionDecl, hasExplicitSpecifier, internal::Matcher<Expr>,
return InnerMatcher.matches(*ES.getExpr(), Finder, Builder);
}
-/// Matches function and namespace declarations that are marked with
+/// Matches functions, variables and namespace declarations that are marked with
/// the inline keyword.
///
/// Given
@@ -7349,18 +8031,22 @@ AST_MATCHER_P(FunctionDecl, hasExplicitSpecifier, internal::Matcher<Expr>,
/// namespace n {
/// inline namespace m {}
/// }
+/// inline int Foo = 5;
/// \endcode
/// functionDecl(isInline()) will match ::f().
/// namespaceDecl(isInline()) will match n::m.
-AST_POLYMORPHIC_MATCHER(isInline,
- AST_POLYMORPHIC_SUPPORTED_TYPES(NamespaceDecl,
- FunctionDecl)) {
+/// varDecl(isInline()) will match Foo;
+AST_POLYMORPHIC_MATCHER(isInline, AST_POLYMORPHIC_SUPPORTED_TYPES(NamespaceDecl,
+ FunctionDecl,
+ VarDecl)) {
// This is required because the spelling of the function used to determine
// whether inline is specified or not differs between the polymorphic types.
if (const auto *FD = dyn_cast<FunctionDecl>(&Node))
return FD->isInlineSpecified();
- else if (const auto *NSD = dyn_cast<NamespaceDecl>(&Node))
+ if (const auto *NSD = dyn_cast<NamespaceDecl>(&Node))
return NSD->isInline();
+ if (const auto *VD = dyn_cast<VarDecl>(&Node))
+ return VD->isInline();
llvm_unreachable("Not a valid polymorphic type");
}
@@ -7400,6 +8086,30 @@ AST_MATCHER(NamespaceDecl, isAnonymous) {
/// cxxRecordDecl(hasName("vector"), isInStdNamespace()) will match only #1.
AST_MATCHER(Decl, isInStdNamespace) { return Node.isInStdNamespace(); }
+/// Matches declarations in an anonymous namespace.
+///
+/// Given
+/// \code
+/// class vector {};
+/// namespace foo {
+/// class vector {};
+/// namespace {
+/// class vector {}; // #1
+/// }
+/// }
+/// namespace {
+/// class vector {}; // #2
+/// namespace foo {
+/// class vector{}; // #3
+/// }
+/// }
+/// \endcode
+/// cxxRecordDecl(hasName("vector"), isInAnonymousNamespace()) will match
+/// #1, #2 and #3.
+AST_MATCHER(Decl, isInAnonymousNamespace) {
+ return Node.isInAnonymousNamespace();
+}
+
/// If the given case statement does not use the GNU case range
/// extension, matches the constant given in the statement.
///
@@ -7590,8 +8300,7 @@ AST_MATCHER_P(Stmt, forFunction, internal::Matcher<FunctionDecl>,
return true;
}
} else {
- for (const auto &Parent : Finder->getASTContext().getParents(CurNode))
- Stack.push_back(Parent);
+ llvm::append_range(Stack, Finder->getASTContext().getParents(CurNode));
}
}
return false;
@@ -7649,8 +8358,7 @@ AST_MATCHER_P(Stmt, forCallable, internal::Matcher<Decl>, InnerMatcher) {
return true;
}
} else {
- for (const auto &Parent : Finder->getASTContext().getParents(CurNode))
- Stack.push_back(Parent);
+ llvm::append_range(Stack, Finder->getASTContext().getParents(CurNode));
}
}
return false;
@@ -7924,12 +8632,13 @@ AST_MATCHER_P(OMPExecutableDirective, hasAnyClause,
/// \code
/// #pragma omp parallel default(none)
/// #pragma omp parallel default(shared)
+/// #pragma omp parallel default(private)
/// #pragma omp parallel default(firstprivate)
/// #pragma omp parallel
/// \endcode
///
-/// ``ompDefaultClause()`` matches ``default(none)``, ``default(shared)``, and
-/// ``default(firstprivate)``
+/// ``ompDefaultClause()`` matches ``default(none)``, ``default(shared)``,
+/// `` default(private)`` and ``default(firstprivate)``
extern const internal::VariadicDynCastAllOfMatcher<OMPClause, OMPDefaultClause>
ompDefaultClause;
@@ -7941,6 +8650,7 @@ extern const internal::VariadicDynCastAllOfMatcher<OMPClause, OMPDefaultClause>
/// #pragma omp parallel
/// #pragma omp parallel default(none)
/// #pragma omp parallel default(shared)
+/// #pragma omp parallel default(private)
/// #pragma omp parallel default(firstprivate)
/// \endcode
///
@@ -7957,6 +8667,7 @@ AST_MATCHER(OMPDefaultClause, isNoneKind) {
/// #pragma omp parallel
/// #pragma omp parallel default(none)
/// #pragma omp parallel default(shared)
+/// #pragma omp parallel default(private)
/// #pragma omp parallel default(firstprivate)
/// \endcode
///
@@ -7965,6 +8676,25 @@ AST_MATCHER(OMPDefaultClause, isSharedKind) {
return Node.getDefaultKind() == llvm::omp::OMP_DEFAULT_shared;
}
+/// Matches if the OpenMP ``default`` clause has ``private`` kind
+/// specified.
+///
+/// Given
+///
+/// \code
+/// #pragma omp parallel
+/// #pragma omp parallel default(none)
+/// #pragma omp parallel default(shared)
+/// #pragma omp parallel default(private)
+/// #pragma omp parallel default(firstprivate)
+/// \endcode
+///
+/// ``ompDefaultClause(isPrivateKind())`` matches only
+/// ``default(private)``.
+AST_MATCHER(OMPDefaultClause, isPrivateKind) {
+ return Node.getDefaultKind() == llvm::omp::OMP_DEFAULT_private;
+}
+
/// Matches if the OpenMP ``default`` clause has ``firstprivate`` kind
/// specified.
///
@@ -7974,6 +8704,7 @@ AST_MATCHER(OMPDefaultClause, isSharedKind) {
/// #pragma omp parallel
/// #pragma omp parallel default(none)
/// #pragma omp parallel default(shared)
+/// #pragma omp parallel default(private)
/// #pragma omp parallel default(firstprivate)
/// \endcode
///
diff --git a/contrib/llvm-project/clang/include/clang/ASTMatchers/ASTMatchersInternal.h b/contrib/llvm-project/clang/include/clang/ASTMatchers/ASTMatchersInternal.h
index 71f4f2d17ae3..47d912c73dd7 100644
--- a/contrib/llvm-project/clang/include/clang/ASTMatchers/ASTMatchersInternal.h
+++ b/contrib/llvm-project/clang/include/clang/ASTMatchers/ASTMatchersInternal.h
@@ -52,8 +52,6 @@
#include "llvm/ADT/APFloat.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/IntrusiveRefCntPtr.h"
-#include "llvm/ADT/None.h"
-#include "llvm/ADT/Optional.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
@@ -67,6 +65,7 @@
#include <cstdint>
#include <map>
#include <memory>
+#include <optional>
#include <string>
#include <tuple>
#include <type_traits>
@@ -122,7 +121,7 @@ template <typename T> struct TypeListContainsSuperOf<EmptyTypeList, T> {
template <typename ResultT, typename ArgT,
ResultT (*Func)(ArrayRef<const ArgT *>)>
struct VariadicFunction {
- ResultT operator()() const { return Func(None); }
+ ResultT operator()() const { return Func(std::nullopt); }
template <typename... ArgsT>
ResultT operator()(const ArgT &Arg1, const ArgsT &... Args) const {
@@ -132,10 +131,7 @@ struct VariadicFunction {
// We also allow calls with an already created array, in case the caller
// already had it.
ResultT operator()(ArrayRef<ArgT> Args) const {
- SmallVector<const ArgT*, 8> InnerArgs;
- for (const ArgT &Arg : Args)
- InnerArgs.push_back(&Arg);
- return Func(InnerArgs);
+ return Func(llvm::to_vector<8>(llvm::make_pointer_range(Args)));
}
private:
@@ -312,8 +308,7 @@ public:
template <typename ExcludePredicate>
bool removeBindings(const ExcludePredicate &Predicate) {
- Bindings.erase(std::remove_if(Bindings.begin(), Bindings.end(), Predicate),
- Bindings.end());
+ llvm::erase_if(Bindings, Predicate);
return !Bindings.empty();
}
@@ -355,8 +350,8 @@ public:
virtual bool dynMatches(const DynTypedNode &DynNode, ASTMatchFinder *Finder,
BoundNodesTreeBuilder *Builder) const = 0;
- virtual llvm::Optional<clang::TraversalKind> TraversalKind() const {
- return llvm::None;
+ virtual std::optional<clang::TraversalKind> TraversalKind() const {
+ return std::nullopt;
}
};
@@ -468,7 +463,7 @@ public:
/// restricts the node types for \p Kind.
DynTypedMatcher dynCastTo(const ASTNodeKind Kind) const;
- /// Return a matcher that that points to the same implementation, but sets the
+ /// Return a matcher that points to the same implementation, but sets the
/// traversal kind.
///
/// If the traversal kind is already set, then \c TK overrides it.
@@ -487,8 +482,8 @@ public:
/// Bind the specified \p ID to the matcher.
/// \return A new matcher with the \p ID bound to it if this matcher supports
- /// binding. Otherwise, returns an empty \c Optional<>.
- llvm::Optional<DynTypedMatcher> tryBind(StringRef ID) const;
+ /// binding. Otherwise, returns an empty \c std::optional<>.
+ std::optional<DynTypedMatcher> tryBind(StringRef ID) const;
/// Returns a unique \p ID for the matcher.
///
@@ -540,8 +535,8 @@ public:
/// Returns the \c TraversalKind respected by calls to `match()`, if any.
///
/// Most matchers will not have a traversal kind set, instead relying on the
- /// surrounding context. For those, \c llvm::None is returned.
- llvm::Optional<clang::TraversalKind> getTraversalKind() const {
+ /// surrounding context. For those, \c std::nullopt is returned.
+ std::optional<clang::TraversalKind> getTraversalKind() const {
return Implementation->TraversalKind();
}
@@ -601,17 +596,15 @@ public:
/// Convert \c this into a \c Matcher<T> by applying dyn_cast<> to the
/// argument.
/// \c To must be a base class of \c T.
- template <typename To> Matcher<To> dynCastTo() const LLVM_LVALUE_FUNCTION {
+ template <typename To> Matcher<To> dynCastTo() const & {
static_assert(std::is_base_of<To, T>::value, "Invalid dynCast call.");
return Matcher<To>(Implementation);
}
-#if LLVM_HAS_RVALUE_REFERENCE_THIS
template <typename To> Matcher<To> dynCastTo() && {
static_assert(std::is_base_of<To, T>::value, "Invalid dynCast call.");
return Matcher<To>(std::move(Implementation));
}
-#endif
/// Forwards the call to the underlying MatcherInterface<T> pointer.
bool matches(const T &Node,
@@ -629,13 +622,9 @@ public:
///
/// The returned matcher keeps the same restrictions as \c this and remembers
/// that it is meant to support nodes of type \c T.
- operator DynTypedMatcher() const LLVM_LVALUE_FUNCTION {
- return Implementation;
- }
+ operator DynTypedMatcher() const & { return Implementation; }
-#if LLVM_HAS_RVALUE_REFERENCE_THIS
operator DynTypedMatcher() && { return std::move(Implementation); }
-#endif
/// Allows the conversion of a \c Matcher<Type> to a \c
/// Matcher<QualType>.
@@ -659,7 +648,7 @@ public:
Builder);
}
- llvm::Optional<clang::TraversalKind> TraversalKind() const override {
+ std::optional<clang::TraversalKind> TraversalKind() const override {
return this->InnerMatcher.getTraversalKind();
}
};
@@ -757,7 +746,8 @@ public:
std::is_base_of<NestedNameSpecifier, T>::value ||
std::is_base_of<NestedNameSpecifierLoc, T>::value ||
std::is_base_of<TypeLoc, T>::value ||
- std::is_base_of<QualType, T>::value,
+ std::is_base_of<QualType, T>::value ||
+ std::is_base_of<Attr, T>::value,
"unsupported type for recursive matching");
return matchesChildOf(DynTypedNode::create(Node), getASTContext(), Matcher,
Builder, Bind);
@@ -771,7 +761,8 @@ public:
std::is_base_of<NestedNameSpecifier, T>::value ||
std::is_base_of<NestedNameSpecifierLoc, T>::value ||
std::is_base_of<TypeLoc, T>::value ||
- std::is_base_of<QualType, T>::value,
+ std::is_base_of<QualType, T>::value ||
+ std::is_base_of<Attr, T>::value,
"unsupported type for recursive matching");
return matchesDescendantOf(DynTypedNode::create(Node), getASTContext(),
Matcher, Builder, Bind);
@@ -785,7 +776,8 @@ public:
static_assert(std::is_base_of<Decl, T>::value ||
std::is_base_of<NestedNameSpecifierLoc, T>::value ||
std::is_base_of<Stmt, T>::value ||
- std::is_base_of<TypeLoc, T>::value,
+ std::is_base_of<TypeLoc, T>::value ||
+ std::is_base_of<Attr, T>::value,
"type not allowed for recursive matching");
return matchesAncestorOf(DynTypedNode::create(Node), getASTContext(),
Matcher, Builder, MatchMode);
@@ -954,7 +946,7 @@ class HasNameMatcher : public SingleNodeMatcherInterface<NamedDecl> {
bool matchesNode(const NamedDecl &Node) const override;
- private:
+private:
/// Unqualified match routine.
///
/// It is much faster than the full match, but it only works for unqualified
@@ -1025,31 +1017,29 @@ private:
BoundNodesTreeBuilder *Builder) const {
// DeducedType does not have declarations of its own, so
// match the deduced type instead.
- const Type *EffectiveType = &Node;
if (const auto *S = dyn_cast<DeducedType>(&Node)) {
- EffectiveType = S->getDeducedType().getTypePtrOrNull();
- if (!EffectiveType)
- return false;
+ QualType DT = S->getDeducedType();
+ return !DT.isNull() ? matchesSpecialized(*DT, Finder, Builder) : false;
}
// First, for any types that have a declaration, extract the declaration and
// match on it.
- if (const auto *S = dyn_cast<TagType>(EffectiveType)) {
+ if (const auto *S = dyn_cast<TagType>(&Node)) {
return matchesDecl(S->getDecl(), Finder, Builder);
}
- if (const auto *S = dyn_cast<InjectedClassNameType>(EffectiveType)) {
+ if (const auto *S = dyn_cast<InjectedClassNameType>(&Node)) {
return matchesDecl(S->getDecl(), Finder, Builder);
}
- if (const auto *S = dyn_cast<TemplateTypeParmType>(EffectiveType)) {
+ if (const auto *S = dyn_cast<TemplateTypeParmType>(&Node)) {
return matchesDecl(S->getDecl(), Finder, Builder);
}
- if (const auto *S = dyn_cast<TypedefType>(EffectiveType)) {
+ if (const auto *S = dyn_cast<TypedefType>(&Node)) {
return matchesDecl(S->getDecl(), Finder, Builder);
}
- if (const auto *S = dyn_cast<UnresolvedUsingType>(EffectiveType)) {
+ if (const auto *S = dyn_cast<UnresolvedUsingType>(&Node)) {
return matchesDecl(S->getDecl(), Finder, Builder);
}
- if (const auto *S = dyn_cast<ObjCObjectType>(EffectiveType)) {
+ if (const auto *S = dyn_cast<ObjCObjectType>(&Node)) {
return matchesDecl(S->getInterface(), Finder, Builder);
}
@@ -1061,14 +1051,14 @@ private:
// template<typename T> struct X { T t; } class A {}; X<A> a;
// The following matcher will match, which otherwise would not:
// fieldDecl(hasType(pointerType())).
- if (const auto *S = dyn_cast<SubstTemplateTypeParmType>(EffectiveType)) {
+ if (const auto *S = dyn_cast<SubstTemplateTypeParmType>(&Node)) {
return matchesSpecialized(S->getReplacementType(), Finder, Builder);
}
// For template specialization types, we want to match the template
// declaration, as long as the type is still dependent, and otherwise the
// declaration of the instantiated tag type.
- if (const auto *S = dyn_cast<TemplateSpecializationType>(EffectiveType)) {
+ if (const auto *S = dyn_cast<TemplateSpecializationType>(&Node)) {
if (!S->isTypeAlias() && S->isSugared()) {
// If the template is non-dependent, we want to match the instantiated
// tag type.
@@ -1087,7 +1077,13 @@ private:
// FIXME: We desugar elaborated types. This makes the assumption that users
// do never want to match on whether a type is elaborated - there are
// arguments for both sides; for now, continue desugaring.
- if (const auto *S = dyn_cast<ElaboratedType>(EffectiveType)) {
+ if (const auto *S = dyn_cast<ElaboratedType>(&Node)) {
+ return matchesSpecialized(S->desugar(), Finder, Builder);
+ }
+ // Similarly types found via using declarations.
+ // These are *usually* meaningless sugar, and this matches the historical
+ // behavior prior to the introduction of UsingType.
+ if (const auto *S = dyn_cast<UsingType>(&Node)) {
return matchesSpecialized(S->desugar(), Finder, Builder);
}
return false;
@@ -1175,7 +1171,8 @@ struct IsBaseType {
std::is_same<T, NestedNameSpecifier>::value ||
std::is_same<T, NestedNameSpecifierLoc>::value ||
std::is_same<T, CXXCtorInitializer>::value ||
- std::is_same<T, TemplateArgumentLoc>::value;
+ std::is_same<T, TemplateArgumentLoc>::value ||
+ std::is_same<T, Attr>::value;
};
template <typename T>
const bool IsBaseType<T>::value;
@@ -1185,7 +1182,7 @@ const bool IsBaseType<T>::value;
/// Useful for matchers like \c anything and \c unless.
using AllNodeBaseTypes =
TypeList<Decl, Stmt, NestedNameSpecifier, NestedNameSpecifierLoc, QualType,
- Type, TypeLoc, CXXCtorInitializer>;
+ Type, TypeLoc, CXXCtorInitializer, Attr>;
/// Helper meta-function to extract the argument out of a function of
/// type void(Arg).
@@ -1212,7 +1209,7 @@ template <class T, class Tuple> constexpr T *new_from_tuple(Tuple &&t) {
using AdaptativeDefaultFromTypes = AllNodeBaseTypes;
using AdaptativeDefaultToTypes =
TypeList<Decl, Stmt, NestedNameSpecifier, NestedNameSpecifierLoc, TypeLoc,
- QualType>;
+ QualType, Attr>;
/// All types that are supported by HasDeclarationMatcher above.
using HasDeclarationSupportedTypes =
@@ -1354,35 +1351,31 @@ public:
VariadicOperatorMatcher(DynTypedMatcher::VariadicOperator Op, Ps &&... Params)
: Op(Op), Params(std::forward<Ps>(Params)...) {}
- template <typename T> operator Matcher<T>() const LLVM_LVALUE_FUNCTION {
+ template <typename T> operator Matcher<T>() const & {
return DynTypedMatcher::constructVariadic(
Op, ASTNodeKind::getFromNodeKind<T>(),
getMatchers<T>(std::index_sequence_for<Ps...>()))
.template unconditionalConvertTo<T>();
}
-#if LLVM_HAS_RVALUE_REFERENCE_THIS
template <typename T> operator Matcher<T>() && {
return DynTypedMatcher::constructVariadic(
Op, ASTNodeKind::getFromNodeKind<T>(),
getMatchers<T>(std::index_sequence_for<Ps...>()))
.template unconditionalConvertTo<T>();
}
-#endif
+
private:
// Helper method to unpack the tuple into a vector.
template <typename T, std::size_t... Is>
- std::vector<DynTypedMatcher>
- getMatchers(std::index_sequence<Is...>) const LLVM_LVALUE_FUNCTION {
+ std::vector<DynTypedMatcher> getMatchers(std::index_sequence<Is...>) const & {
return {Matcher<T>(std::get<Is>(Params))...};
}
-#if LLVM_HAS_RVALUE_REFERENCE_THIS
template <typename T, std::size_t... Is>
std::vector<DynTypedMatcher> getMatchers(std::index_sequence<Is...>) && {
return {Matcher<T>(std::get<Is>(std::move(Params)))...};
}
-#endif
const DynTypedMatcher::VariadicOperator Op;
std::tuple<Ps...> Params;
@@ -1402,20 +1395,6 @@ struct VariadicOperatorMatcherFunc {
}
};
-template <typename F, typename Tuple, std::size_t... I>
-constexpr auto applyMatcherImpl(F &&f, Tuple &&args,
- std::index_sequence<I...>) {
- return std::forward<F>(f)(std::get<I>(std::forward<Tuple>(args))...);
-}
-
-template <typename F, typename Tuple>
-constexpr auto applyMatcher(F &&f, Tuple &&args) {
- return applyMatcherImpl(
- std::forward<F>(f), std::forward<Tuple>(args),
- std::make_index_sequence<
- std::tuple_size<typename std::decay<Tuple>::type>::value>());
-}
-
template <typename T, bool IsBaseOf, typename Head, typename Tail>
struct GetCladeImpl {
using Type = Head;
@@ -1434,12 +1413,11 @@ struct MapAnyOfMatcherImpl {
template <typename... InnerMatchers>
BindableMatcher<CladeType>
operator()(InnerMatchers &&... InnerMatcher) const {
- // TODO: Use std::apply from c++17
- return VariadicAllOfMatcher<CladeType>()(applyMatcher(
+ return VariadicAllOfMatcher<CladeType>()(std::apply(
internal::VariadicOperatorMatcherFunc<
0, std::numeric_limits<unsigned>::max()>{
internal::DynTypedMatcher::VO_AnyOf},
- applyMatcher(
+ std::apply(
[&](auto... Matcher) {
return std::make_tuple(Matcher(InnerMatcher...)...);
},
@@ -1472,15 +1450,13 @@ public:
using ReturnTypes = ToTypes;
- template <typename To> operator Matcher<To>() const LLVM_LVALUE_FUNCTION {
+ template <typename To> operator Matcher<To>() const & {
return Matcher<To>(new ArgumentAdapterT<To, T>(InnerMatcher));
}
-#if LLVM_HAS_RVALUE_REFERENCE_THIS
template <typename To> operator Matcher<To>() && {
return Matcher<To>(new ArgumentAdapterT<To, T>(std::move(InnerMatcher)));
}
-#endif
private:
Matcher<T> InnerMatcher;
@@ -1539,7 +1515,7 @@ public:
Builder);
}
- llvm::Optional<clang::TraversalKind> TraversalKind() const override {
+ std::optional<clang::TraversalKind> TraversalKind() const override {
if (auto NestedKind = this->InnerMatcher.getTraversalKind())
return NestedKind;
return Traversal;
@@ -1551,21 +1527,19 @@ public:
TraversalWrapper(TraversalKind TK, const MatcherType &InnerMatcher)
: TK(TK), InnerMatcher(InnerMatcher) {}
- template <typename T> operator Matcher<T>() const LLVM_LVALUE_FUNCTION {
+ template <typename T> operator Matcher<T>() const & {
return internal::DynTypedMatcher::constructRestrictedWrapper(
new internal::TraversalMatcher<T>(TK, InnerMatcher),
ASTNodeKind::getFromNodeKind<T>())
.template unconditionalConvertTo<T>();
}
-#if LLVM_HAS_RVALUE_REFERENCE_THIS
template <typename T> operator Matcher<T>() && {
return internal::DynTypedMatcher::constructRestrictedWrapper(
new internal::TraversalMatcher<T>(TK, std::move(InnerMatcher)),
ASTNodeKind::getFromNodeKind<T>())
.template unconditionalConvertTo<T>();
}
-#endif
private:
TraversalKind TK;
@@ -1592,20 +1566,18 @@ public:
using ReturnTypes = typename ExtractFunctionArgMeta<ReturnTypesF>::type;
- template <typename T> operator Matcher<T>() const LLVM_LVALUE_FUNCTION {
+ template <typename T> operator Matcher<T>() const & {
static_assert(TypeListContainsSuperOf<ReturnTypes, T>::value,
"right polymorphic conversion");
return Matcher<T>(new_from_tuple<MatcherT<T, ParamTypes...>>(Params));
}
-#if LLVM_HAS_RVALUE_REFERENCE_THIS
template <typename T> operator Matcher<T>() && {
static_assert(TypeListContainsSuperOf<ReturnTypes, T>::value,
"right polymorphic conversion");
return Matcher<T>(
new_from_tuple<MatcherT<T, ParamTypes...>>(std::move(Params)));
}
-#endif
private:
std::tuple<ParamTypes...> Params;
@@ -1969,7 +1941,7 @@ getTemplateSpecializationArgs(const ClassTemplateSpecializationDecl &D) {
inline ArrayRef<TemplateArgument>
getTemplateSpecializationArgs(const TemplateSpecializationType &T) {
- return llvm::makeArrayRef(T.getArgs(), T.getNumArgs());
+ return T.template_arguments();
}
inline ArrayRef<TemplateArgument>
@@ -1993,27 +1965,27 @@ template <typename Ty, typename Enable = void> struct GetBodyMatcher {
};
template <typename Ty>
-struct GetBodyMatcher<Ty, typename std::enable_if<
- std::is_base_of<FunctionDecl, Ty>::value>::type> {
+struct GetBodyMatcher<
+ Ty, std::enable_if_t<std::is_base_of<FunctionDecl, Ty>::value>> {
static const Stmt *get(const Ty &Node) {
return Node.doesThisDeclarationHaveABody() ? Node.getBody() : nullptr;
}
};
template <typename NodeType>
-inline Optional<BinaryOperatorKind>
+inline std::optional<BinaryOperatorKind>
equivalentBinaryOperator(const NodeType &Node) {
return Node.getOpcode();
}
template <>
-inline Optional<BinaryOperatorKind>
+inline std::optional<BinaryOperatorKind>
equivalentBinaryOperator<CXXOperatorCallExpr>(const CXXOperatorCallExpr &Node) {
if (Node.getNumArgs() != 2)
- return None;
+ return std::nullopt;
switch (Node.getOperator()) {
default:
- return None;
+ return std::nullopt;
case OO_ArrowStar:
return BO_PtrMemI;
case OO_Star:
@@ -2082,20 +2054,20 @@ equivalentBinaryOperator<CXXOperatorCallExpr>(const CXXOperatorCallExpr &Node) {
}
template <typename NodeType>
-inline Optional<UnaryOperatorKind>
+inline std::optional<UnaryOperatorKind>
equivalentUnaryOperator(const NodeType &Node) {
return Node.getOpcode();
}
template <>
-inline Optional<UnaryOperatorKind>
+inline std::optional<UnaryOperatorKind>
equivalentUnaryOperator<CXXOperatorCallExpr>(const CXXOperatorCallExpr &Node) {
if (Node.getNumArgs() != 1 && Node.getOperator() != OO_PlusPlus &&
Node.getOperator() != OO_MinusMinus)
- return None;
+ return std::nullopt;
switch (Node.getOperator()) {
default:
- return None;
+ return std::nullopt;
case OO_Plus:
return UO_Plus;
case OO_Minus:
@@ -2111,13 +2083,13 @@ equivalentUnaryOperator<CXXOperatorCallExpr>(const CXXOperatorCallExpr &Node) {
case OO_PlusPlus: {
const auto *FD = Node.getDirectCallee();
if (!FD)
- return None;
+ return std::nullopt;
return FD->getNumParams() > 0 ? UO_PostInc : UO_PreInc;
}
case OO_MinusMinus: {
const auto *FD = Node.getDirectCallee();
if (!FD)
- return None;
+ return std::nullopt;
return FD->getNumParams() > 0 ? UO_PostDec : UO_PreDec;
}
case OO_Coawait:
@@ -2200,29 +2172,32 @@ CompoundStmtMatcher<StmtExpr>::get(const StmtExpr &Node) {
/// location (in the chain of expansions) at which \p MacroName was
/// expanded. Since the macro may have been expanded inside a series of
/// expansions, that location may itself be a MacroID.
-llvm::Optional<SourceLocation>
-getExpansionLocOfMacro(StringRef MacroName, SourceLocation Loc,
- const ASTContext &Context);
+std::optional<SourceLocation> getExpansionLocOfMacro(StringRef MacroName,
+ SourceLocation Loc,
+ const ASTContext &Context);
-inline Optional<StringRef> getOpName(const UnaryOperator &Node) {
+inline std::optional<StringRef> getOpName(const UnaryOperator &Node) {
return Node.getOpcodeStr(Node.getOpcode());
}
-inline Optional<StringRef> getOpName(const BinaryOperator &Node) {
+inline std::optional<StringRef> getOpName(const BinaryOperator &Node) {
return Node.getOpcodeStr();
}
inline StringRef getOpName(const CXXRewrittenBinaryOperator &Node) {
return Node.getOpcodeStr();
}
-inline Optional<StringRef> getOpName(const CXXOperatorCallExpr &Node) {
+inline std::optional<StringRef> getOpName(const CXXOperatorCallExpr &Node) {
auto optBinaryOpcode = equivalentBinaryOperator(Node);
if (!optBinaryOpcode) {
auto optUnaryOpcode = equivalentUnaryOperator(Node);
if (!optUnaryOpcode)
- return None;
+ return std::nullopt;
return UnaryOperator::getOpcodeStr(*optUnaryOpcode);
}
return BinaryOperator::getOpcodeStr(*optBinaryOpcode);
}
+inline StringRef getOpName(const CXXFoldExpr &Node) {
+ return BinaryOperator::getOpcodeStr(Node.getOperator());
+}
/// Matches overloaded operators with a specific name.
///
@@ -2244,30 +2219,26 @@ public:
: SingleNodeMatcherInterface<T>(), Names(std::move(Names)) {}
bool matchesNode(const T &Node) const override {
- Optional<StringRef> OptOpName = getOpName(Node);
- if (!OptOpName)
- return false;
- return llvm::any_of(Names, [OpName = *OptOpName](const std::string &Name) {
- return Name == OpName;
- });
+ std::optional<StringRef> OptOpName = getOpName(Node);
+ return OptOpName && llvm::is_contained(Names, *OptOpName);
}
private:
- static Optional<StringRef> getOpName(const UnaryOperator &Node) {
+ static std::optional<StringRef> getOpName(const UnaryOperator &Node) {
return Node.getOpcodeStr(Node.getOpcode());
}
- static Optional<StringRef> getOpName(const BinaryOperator &Node) {
+ static std::optional<StringRef> getOpName(const BinaryOperator &Node) {
return Node.getOpcodeStr();
}
static StringRef getOpName(const CXXRewrittenBinaryOperator &Node) {
return Node.getOpcodeStr();
}
- static Optional<StringRef> getOpName(const CXXOperatorCallExpr &Node) {
+ static std::optional<StringRef> getOpName(const CXXOperatorCallExpr &Node) {
auto optBinaryOpcode = equivalentBinaryOperator(Node);
if (!optBinaryOpcode) {
auto optUnaryOpcode = equivalentUnaryOperator(Node);
if (!optUnaryOpcode)
- return None;
+ return std::nullopt;
return UnaryOperator::getOpcodeStr(*optUnaryOpcode);
}
return BinaryOperator::getOpcodeStr(*optBinaryOpcode);
@@ -2304,6 +2275,26 @@ std::shared_ptr<llvm::Regex> createAndVerifyRegex(StringRef Regex,
llvm::Regex::RegexFlags Flags,
StringRef MatcherID);
+inline bool
+MatchTemplateArgLocAt(const DeclRefExpr &Node, unsigned int Index,
+ internal::Matcher<TemplateArgumentLoc> InnerMatcher,
+ internal::ASTMatchFinder *Finder,
+ internal::BoundNodesTreeBuilder *Builder) {
+ llvm::ArrayRef<TemplateArgumentLoc> ArgLocs = Node.template_arguments();
+ return Index < ArgLocs.size() &&
+ InnerMatcher.matches(ArgLocs[Index], Finder, Builder);
+}
+
+inline bool
+MatchTemplateArgLocAt(const TemplateSpecializationTypeLoc &Node,
+ unsigned int Index,
+ internal::Matcher<TemplateArgumentLoc> InnerMatcher,
+ internal::ASTMatchFinder *Finder,
+ internal::BoundNodesTreeBuilder *Builder) {
+ return !Node.isNull() && Index < Node.getNumArgs() &&
+ InnerMatcher.matches(Node.getArgLoc(Index), Finder, Builder);
+}
+
} // namespace internal
} // namespace ast_matchers
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..960d59a747fc 100644
--- a/contrib/llvm-project/clang/include/clang/ASTMatchers/Dynamic/Diagnostics.h
+++ b/contrib/llvm-project/clang/include/clang/ASTMatchers/Dynamic/Diagnostics.h
@@ -28,9 +28,9 @@ namespace ast_matchers {
namespace dynamic {
struct SourceLocation {
- SourceLocation() : Line(), Column() {}
- unsigned Line;
- unsigned Column;
+ SourceLocation() = default;
+ unsigned Line = 0;
+ unsigned Column = 0;
};
struct SourceRange {
@@ -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..7adaef5054b5 100644
--- a/contrib/llvm-project/clang/include/clang/ASTMatchers/Dynamic/Parser.h
+++ b/contrib/llvm-project/clang/include/clang/ASTMatchers/Dynamic/Parser.h
@@ -39,9 +39,9 @@
#include "clang/ASTMatchers/Dynamic/Registry.h"
#include "clang/ASTMatchers/Dynamic/VariantValue.h"
#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/Optional.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
+#include <optional>
#include <utility>
#include <vector>
@@ -95,9 +95,9 @@ public:
///
/// \param MatcherName The matcher name found by the parser.
///
- /// \return The matcher constructor, or Optional<MatcherCtor>() if not
+ /// \return The matcher constructor, or std::optional<MatcherCtor>() if not
/// found.
- virtual llvm::Optional<MatcherCtor>
+ virtual std::optional<MatcherCtor>
lookupMatcherCtor(StringRef MatcherName) = 0;
virtual bool isBuilderMatcher(MatcherCtor) const = 0;
@@ -138,7 +138,7 @@ public:
public:
~RegistrySema() override;
- llvm::Optional<MatcherCtor>
+ std::optional<MatcherCtor>
lookupMatcherCtor(StringRef MatcherName) override;
VariantMatcher actOnMatcherExpression(MatcherCtor Ctor,
@@ -180,14 +180,14 @@ public:
/// Optional if an error occurred. In that case, \c Error will contain a
/// description of the error.
/// The caller takes ownership of the DynTypedMatcher object returned.
- static llvm::Optional<DynTypedMatcher>
+ static std::optional<DynTypedMatcher>
parseMatcherExpression(StringRef &MatcherCode, Sema *S,
const NamedValueMap *NamedValues, Diagnostics *Error);
- static llvm::Optional<DynTypedMatcher>
+ static std::optional<DynTypedMatcher>
parseMatcherExpression(StringRef &MatcherCode, Sema *S, Diagnostics *Error) {
return parseMatcherExpression(MatcherCode, S, nullptr, Error);
}
- static llvm::Optional<DynTypedMatcher>
+ static std::optional<DynTypedMatcher>
parseMatcherExpression(StringRef &MatcherCode, Diagnostics *Error) {
return parseMatcherExpression(MatcherCode, nullptr, Error);
}
@@ -254,7 +254,7 @@ private:
const TokenInfo &OpenToken, VariantValue *Value);
bool parseMatcherExpressionImpl(const TokenInfo &NameToken,
const TokenInfo &OpenToken,
- llvm::Optional<MatcherCtor> Ctor,
+ std::optional<MatcherCtor> Ctor,
VariantValue *Value);
bool parseIdentifierPrefixImpl(VariantValue *Value);
@@ -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..50711addc6e3 100644
--- a/contrib/llvm-project/clang/include/clang/ASTMatchers/Dynamic/Registry.h
+++ b/contrib/llvm-project/clang/include/clang/ASTMatchers/Dynamic/Registry.h
@@ -19,8 +19,8 @@
#include "clang/ASTMatchers/Dynamic/Diagnostics.h"
#include "clang/ASTMatchers/Dynamic/VariantValue.h"
#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/Optional.h"
#include "llvm/ADT/StringRef.h"
+#include <optional>
#include <string>
#include <utility>
#include <vector>
@@ -94,8 +94,8 @@ public:
/// Look up a matcher in the registry by name,
///
/// \return An opaque value which may be used to refer to the matcher
- /// constructor, or Optional<MatcherCtor>() if not found.
- static llvm::Optional<MatcherCtor> lookupMatcherCtor(StringRef MatcherName);
+ /// constructor, or std::optional<MatcherCtor>() if not found.
+ static std::optional<MatcherCtor> lookupMatcherCtor(StringRef MatcherName);
/// Compute the list of completion types for \p Context.
///
@@ -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..c99d32f5f784 100644
--- a/contrib/llvm-project/clang/include/clang/ASTMatchers/Dynamic/VariantValue.h
+++ b/contrib/llvm-project/clang/include/clang/ASTMatchers/Dynamic/VariantValue.h
@@ -20,8 +20,8 @@
#include "clang/ASTMatchers/ASTMatchers.h"
#include "clang/ASTMatchers/ASTMatchersInternal.h"
#include "llvm/ADT/IntrusiveRefCntPtr.h"
-#include "llvm/ADT/Optional.h"
#include <memory>
+#include <optional>
#include <vector>
namespace clang {
@@ -117,8 +117,8 @@ class VariantMatcher {
/// Constructs a variadic typed matcher from \p InnerMatchers.
/// Will try to convert each inner matcher to the destination type and
- /// return llvm::None if it fails to do so.
- llvm::Optional<DynTypedMatcher>
+ /// return std::nullopt if it fails to do so.
+ std::optional<DynTypedMatcher>
constructVariadicOperator(DynTypedMatcher::VariadicOperator Op,
ArrayRef<VariantMatcher> InnerMatchers) const;
@@ -132,9 +132,9 @@ class VariantMatcher {
class Payload {
public:
virtual ~Payload();
- virtual llvm::Optional<DynTypedMatcher> getSingleMatcher() const = 0;
+ virtual std::optional<DynTypedMatcher> getSingleMatcher() const = 0;
virtual std::string getTypeAsString() const = 0;
- virtual llvm::Optional<DynTypedMatcher>
+ virtual std::optional<DynTypedMatcher>
getTypedMatcher(const MatcherOps &Ops) const = 0;
virtual bool isConvertibleTo(ASTNodeKind Kind,
unsigned *Specificity) const = 0;
@@ -171,7 +171,7 @@ public:
/// \returns the matcher, if there is only one matcher. An empty Optional, if
/// the underlying matcher is a polymorphic matcher with more than one
/// representation.
- llvm::Optional<DynTypedMatcher> getSingleMatcher() const;
+ std::optional<DynTypedMatcher> getSingleMatcher() const;
/// Determines if the contained matcher can be converted to
/// \c Matcher<T>.
@@ -188,7 +188,7 @@ public:
bool hasTypedMatcher(ASTNodeKind NK) const {
if (!Value) return false;
- return Value->getTypedMatcher(MatcherOps(NK)).hasValue();
+ return Value->getTypedMatcher(MatcherOps(NK)).has_value();
}
/// Determines if the contained matcher can be converted to \p Kind.
@@ -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..6a1528a2da24 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;
@@ -29,7 +28,7 @@ class Stmt;
/// \enum IfThen -- then branch of the if statement has no call.
/// \enum IfElse -- else branch of the if statement has no call.
/// \enum Switch -- one of the switch cases doesn't have a call.
-/// \enum SwitchSkipped -- there is no call if none of the cases appies.
+/// \enum SwitchSkipped -- there is no call if none of the cases applies.
/// \enum LoopEntered -- no call when the loop is entered.
/// \enum LoopSkipped -- no call when the loop is not entered.
/// \enum FallbackReason -- fallback case when we were not able to figure out
@@ -80,7 +79,7 @@ public:
/// the path containing the call and not containing the call. This helps us
/// to pinpoint a bad path for the user.
/// \param Parameter -- parameter that should be called once.
- /// \param Function -- function declaration where the problem occured.
+ /// \param Function -- function declaration where the problem occurred.
/// \param Where -- the least common ancestor statement.
/// \param Reason -- a reason describing the path without a call.
/// \param IsCalledDirectly -- true, if parameter actually gets called on
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..3e2788cac3c9 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,11 @@ 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) {}
+
+ // The copy assignment operator is defined as deleted pending further
+ // motivation.
+ ConsumedStateMap &operator=(const ConsumedStateMap &) = delete;
/// Warn if any of the parameters being tracked are not in the state
/// they were declared to be in upon return from a function.
@@ -241,7 +244,7 @@ namespace consumed {
ConsumedBlockInfo BlockInfo;
std::unique_ptr<ConsumedStateMap> CurrStates;
- ConsumedState ExpectedReturnState;
+ ConsumedState ExpectedReturnState = CS_None;
void determineExpectedReturnState(AnalysisDeclContext &AC,
const FunctionDecl *D);
@@ -259,7 +262,7 @@ namespace consumed {
/// Check a function's CFG for consumed violations.
///
/// We traverse the blocks in the CFG, keeping track of the state of each
- /// value who's type has uniquness annotations. If methods are invoked in
+ /// value who's type has uniqueness annotations. If methods are invoked in
/// the wrong state a warning is issued. Each block in the CFG is traversed
/// exactly once.
void run(AnalysisDeclContext &AC);
diff --git a/contrib/llvm-project/clang/include/clang/Analysis/Analyses/Dominators.h b/contrib/llvm-project/clang/include/clang/Analysis/Analyses/Dominators.h
index 25a5ba9d83fe..7dd54c5ce262 100644
--- a/contrib/llvm-project/clang/include/clang/Analysis/Analyses/Dominators.h
+++ b/contrib/llvm-project/clang/include/clang/Analysis/Analyses/Dominators.h
@@ -193,7 +193,7 @@ namespace IDFCalculatorDetail {
/// Specialize ChildrenGetterTy to skip nullpointer successors.
template <bool IsPostDom>
struct ChildrenGetterTy<clang::CFGBlock, IsPostDom> {
- using NodeRef = typename GraphTraits<clang::CFGBlock>::NodeRef;
+ using NodeRef = typename GraphTraits<clang::CFGBlock *>::NodeRef;
using ChildrenTy = SmallVector<NodeRef, 8>;
ChildrenTy get(const NodeRef &N) {
@@ -202,7 +202,7 @@ struct ChildrenGetterTy<clang::CFGBlock, IsPostDom> {
auto Children = children<OrderedNodeTy>(N);
ChildrenTy Ret{Children.begin(), Children.end()};
- Ret.erase(std::remove(Ret.begin(), Ret.end(), nullptr), Ret.end());
+ llvm::erase(Ret, nullptr);
return Ret;
}
};
diff --git a/contrib/llvm-project/clang/include/clang/Analysis/Analyses/ExprMutationAnalyzer.h b/contrib/llvm-project/clang/include/clang/Analysis/Analyses/ExprMutationAnalyzer.h
index 9397c5df78ab..1ceef944fbc3 100644
--- a/contrib/llvm-project/clang/include/clang/Analysis/Analyses/ExprMutationAnalyzer.h
+++ b/contrib/llvm-project/clang/include/clang/Analysis/Analyses/ExprMutationAnalyzer.h
@@ -38,6 +38,8 @@ public:
}
const Stmt *findPointeeMutation(const Expr *Exp);
const Stmt *findPointeeMutation(const Decl *Dec);
+ static bool isUnevaluated(const Stmt *Smt, const Stmt &Stm,
+ ASTContext &Context);
private:
using MutationFinder = const Stmt *(ExprMutationAnalyzer::*)(const Expr *);
diff --git a/contrib/llvm-project/clang/include/clang/Analysis/Analyses/IntervalPartition.h b/contrib/llvm-project/clang/include/clang/Analysis/Analyses/IntervalPartition.h
new file mode 100644
index 000000000000..28a7afad41a7
--- /dev/null
+++ b/contrib/llvm-project/clang/include/clang/Analysis/Analyses/IntervalPartition.h
@@ -0,0 +1,123 @@
+//===- IntervalPartition.h - CFG Partitioning into Intervals -----*- 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 functionality for partitioning a CFG into intervals and
+// building a weak topological order (WTO) of the nodes, based on the
+// partitioning. The concepts and implementations for the graph partitioning
+// are based on the presentation in "Compilers" by Aho, Sethi and Ullman (the
+// "dragon book"), pages 664-666. The concepts around WTOs is taken from the
+// paper "Efficient chaotic iteration strategies with widenings," by
+// F. Bourdoncle ([Bourdoncle1993]).
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_ANALYSIS_ANALYSES_INTERVALPARTITION_H
+#define LLVM_CLANG_ANALYSIS_ANALYSES_INTERVALPARTITION_H
+
+#include "clang/Analysis/CFG.h"
+#include "llvm/ADT/DenseSet.h"
+#include <deque>
+#include <memory>
+#include <vector>
+
+namespace clang {
+/// A _weak topological ordering_ (WTO) of CFG nodes provides a total order over
+/// the CFG (defined in `WTOCompare`, below), which can guide the order in which
+/// to visit nodes in fixpoint computations over the CFG.
+///
+/// Roughly, a WTO a) groups the blocks so that loop heads are grouped with
+/// their bodies and any nodes they dominate after the loop and b) orders the
+/// groups topologically. As a result, the blocks in a series of loops are
+/// ordered such that all nodes in loop `i` are earlier in the order than nodes
+/// in loop `j`. This ordering, when combined with widening, bounds the number
+/// of times a node must be visited for a dataflow algorithm to reach a
+/// fixpoint. For the precise definition of a WTO and its properties, see
+/// [Bourdoncle1993].
+///
+/// Here, we provide a simplified WTO which drops its nesting structure,
+/// maintaining only the ordering itself. The ordering is built from the limit
+/// flow graph of `Cfg` (derived from iteratively partitioning it into
+/// intervals) if and only if it is reducible (its limit flow graph has one
+/// node). Returns `nullopt` when `Cfg` is not reducible.
+///
+/// This WTO construction is described in Section 4.2 of [Bourdoncle1993].
+using WeakTopologicalOrdering = std::vector<const CFGBlock *>;
+std::optional<WeakTopologicalOrdering> getIntervalWTO(const CFG &Cfg);
+
+struct WTOCompare {
+ WTOCompare(const WeakTopologicalOrdering &WTO);
+
+ bool operator()(const CFGBlock *B1, const CFGBlock *B2) const {
+ auto ID1 = B1->getBlockID();
+ auto ID2 = B2->getBlockID();
+
+ unsigned V1 = ID1 >= BlockOrder.size() ? 0 : BlockOrder[ID1];
+ unsigned V2 = ID2 >= BlockOrder.size() ? 0 : BlockOrder[ID2];
+ return V1 > V2;
+ }
+
+ std::vector<unsigned> BlockOrder;
+};
+
+namespace internal {
+// An interval is a strongly-connected component of the CFG along with a
+// trailing acyclic structure. An interval can be constructed directly from CFG
+// blocks or from a graph of other intervals. Each interval has one _header_
+// block, from which the interval is built. The _header_ of the interval is
+// either the graph's entry block or has at least one predecessor outside of the
+// interval. All other blocks in the interval have only predecessors also in the
+// interval.
+struct CFGIntervalNode {
+ CFGIntervalNode() = default;
+ CFGIntervalNode(unsigned ID) : ID(ID) {}
+
+ CFGIntervalNode(unsigned ID, std::vector<const CFGBlock *> Nodes)
+ : ID(ID), Nodes(std::move(Nodes)) {}
+
+ const llvm::SmallDenseSet<const CFGIntervalNode *> &preds() const {
+ return Predecessors;
+ }
+ const llvm::SmallDenseSet<const CFGIntervalNode *> &succs() const {
+ return Successors;
+ }
+
+ // Unique identifier of this interval relative to other intervals in the same
+ // graph.
+ unsigned ID;
+
+ std::vector<const CFGBlock *> Nodes;
+
+ // Predessor intervals of this interval: those intervals for which there
+ // exists an edge from a node in that other interval to the head of this
+ // interval.
+ llvm::SmallDenseSet<const CFGIntervalNode *> Predecessors;
+
+ // Successor intervals of this interval: those intervals for which there
+ // exists an edge from a node in this interval to the head of that other
+ // interval.
+ llvm::SmallDenseSet<const CFGIntervalNode *> Successors;
+};
+
+// Since graphs are built from pointers to nodes, we use a deque to ensure
+// pointer stability.
+using CFGIntervalGraph = std::deque<CFGIntervalNode>;
+
+std::vector<const CFGBlock *> buildInterval(const CFGBlock *Header);
+
+// Partitions `Cfg` into intervals and constructs the graph of the intervals
+// based on the edges between nodes in these intervals.
+CFGIntervalGraph partitionIntoIntervals(const CFG &Cfg);
+
+// (Further) partitions `Graph` into intervals and constructs the graph of the
+// intervals based on the edges between nodes (themselves intervals) in these
+// intervals.
+CFGIntervalGraph partitionIntoIntervals(const CFGIntervalGraph &Graph);
+} // namespace internal
+} // namespace clang
+
+#endif // LLVM_CLANG_ANALYSIS_ANALYSES_INTERVALPARTITION_H
diff --git a/contrib/llvm-project/clang/include/clang/Analysis/Analyses/PostOrderCFGView.h b/contrib/llvm-project/clang/include/clang/Analysis/Analyses/PostOrderCFGView.h
index 100029894560..4356834adf76 100644
--- a/contrib/llvm-project/clang/include/clang/Analysis/Analyses/PostOrderCFGView.h
+++ b/contrib/llvm-project/clang/include/clang/Analysis/Analyses/PostOrderCFGView.h
@@ -18,7 +18,6 @@
#include "clang/Basic/LLVM.h"
#include "llvm/ADT/BitVector.h"
#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/None.h"
#include "llvm/ADT/PostOrderIterator.h"
#include <utility>
#include <vector>
@@ -48,17 +47,18 @@ public:
/// Set the bit associated with a particular CFGBlock.
/// This is the important method for the SetType template parameter.
- std::pair<llvm::NoneType, bool> insert(const CFGBlock *Block) {
+ std::pair<std::nullopt_t, bool> insert(const CFGBlock *Block) {
// Note that insert() is called by po_iterator, which doesn't check to
// make sure that Block is non-null. Moreover, the CFGBlock iterator will
// occasionally hand out null pointers for pruned edges, so we catch those
// here.
if (!Block)
- return std::make_pair(None, false); // if an edge is trivially false.
+ return std::make_pair(std::nullopt,
+ false); // if an edge is trivially false.
if (VisitedBlockIDs.test(Block->getBlockID()))
- return std::make_pair(None, false);
+ return std::make_pair(std::nullopt, false);
VisitedBlockIDs.set(Block->getBlockID());
- return std::make_pair(None, true);
+ return std::make_pair(std::nullopt, true);
}
/// Check if the bit for a CFGBlock has been already set.
diff --git a/contrib/llvm-project/clang/include/clang/Analysis/Analyses/ReachableCode.h b/contrib/llvm-project/clang/include/clang/Analysis/Analyses/ReachableCode.h
index 514b9458d331..f1b63f74b6c8 100644
--- a/contrib/llvm-project/clang/include/clang/Analysis/Analyses/ReachableCode.h
+++ b/contrib/llvm-project/clang/include/clang/Analysis/Analyses/ReachableCode.h
@@ -48,11 +48,9 @@ class Callback {
virtual void anchor();
public:
virtual ~Callback() {}
- virtual void HandleUnreachable(UnreachableKind UK,
- SourceLocation L,
- SourceRange ConditionVal,
- SourceRange R1,
- SourceRange R2) = 0;
+ virtual void HandleUnreachable(UnreachableKind UK, SourceLocation L,
+ SourceRange ConditionVal, SourceRange R1,
+ SourceRange R2, bool HasFallThroughAttr) = 0;
};
/// ScanReachableFromBlock - Mark all blocks reachable from Start.
diff --git a/contrib/llvm-project/clang/include/clang/Analysis/Analyses/ThreadSafety.h b/contrib/llvm-project/clang/include/clang/Analysis/Analyses/ThreadSafety.h
index bfa9870a1e1f..0866b09bab29 100644
--- a/contrib/llvm-project/clang/include/clang/Analysis/Analyses/ThreadSafety.h
+++ b/contrib/llvm-project/clang/include/clang/Analysis/Analyses/ThreadSafety.h
@@ -47,7 +47,13 @@ enum ProtectedOperationKind {
POK_PassByRef,
/// Passing a pt-guarded variable by reference.
- POK_PtPassByRef
+ POK_PtPassByRef,
+
+ /// Returning a guarded variable by reference.
+ POK_ReturnByRef,
+
+ /// Returning a pt-guarded variable by reference.
+ POK_PtReturnByRef,
};
/// This enum distinguishes between different kinds of lock actions. For
@@ -98,9 +104,8 @@ public:
virtual ~ThreadSafetyHandler();
/// Warn about lock expressions which fail to resolve to lockable objects.
- /// \param Kind -- the capability's name parameter (role, mutex, etc).
/// \param Loc -- the SourceLocation of the unresolved expression.
- virtual void handleInvalidLockExp(StringRef Kind, SourceLocation Loc) {}
+ virtual void handleInvalidLockExp(SourceLocation Loc) {}
/// Warn about unlock function calls that do not have a prior matching lock
/// expression.
@@ -169,14 +174,12 @@ public:
SourceLocation Loc2) {}
/// Warn when a protected operation occurs while no locks are held.
- /// \param Kind -- the capability's name parameter (role, mutex, etc).
/// \param D -- The decl for the protected variable or function
/// \param POK -- The kind of protected operation (e.g. variable access)
/// \param AK -- The kind of access (i.e. read or write) that occurred
/// \param Loc -- The location of the protected operation.
- virtual void handleNoMutexHeld(StringRef Kind, const NamedDecl *D,
- ProtectedOperationKind POK, AccessKind AK,
- SourceLocation Loc) {}
+ virtual void handleNoMutexHeld(const NamedDecl *D, ProtectedOperationKind POK,
+ AccessKind AK, SourceLocation Loc) {}
/// Warn when a protected operation occurs while the specific mutex protecting
/// the operation is not locked.
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 4a58fe870944..13e37ac2b56b 100644
--- a/contrib/llvm-project/clang/include/clang/Analysis/Analyses/ThreadSafetyCommon.h
+++ b/contrib/llvm-project/clang/include/clang/Analysis/Analyses/ThreadSafetyCommon.h
@@ -30,6 +30,8 @@
#include "clang/Analysis/CFG.h"
#include "clang/Basic/LLVM.h"
#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/PointerIntPair.h"
+#include "llvm/ADT/PointerUnion.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/Casting.h"
#include <sstream>
@@ -155,7 +157,7 @@ public:
return false;
// Ignore anonymous functions.
- if (!dyn_cast_or_null<NamedDecl>(AC.getDecl()))
+ if (!isa_and_nonnull<NamedDecl>(AC.getDecl()))
return false;
SortedGraph = AC.getAnalysis<PostOrderCFGView>();
@@ -269,28 +271,36 @@ private:
// translateAttrExpr needs it, but that should be moved too.
class CapabilityExpr {
private:
- /// The capability expression.
- const til::SExpr* CapExpr;
+ /// The capability expression and whether it's negated.
+ llvm::PointerIntPair<const til::SExpr *, 1, bool> CapExpr;
- /// True if this is a negative capability.
- bool Negated;
+ /// The kind of capability as specified by @ref CapabilityAttr::getName.
+ StringRef CapKind;
public:
- CapabilityExpr(const til::SExpr *E, bool Neg) : CapExpr(E), Negated(Neg) {}
+ CapabilityExpr() : CapExpr(nullptr, false) {}
+ CapabilityExpr(const til::SExpr *E, StringRef Kind, bool Neg)
+ : CapExpr(E, Neg), CapKind(Kind) {}
- const til::SExpr* sexpr() const { return CapExpr; }
- bool negative() const { return Negated; }
+ // Don't allow implicitly-constructed StringRefs since we'll capture them.
+ template <typename T> CapabilityExpr(const til::SExpr *, T, bool) = delete;
+
+ const til::SExpr *sexpr() const { return CapExpr.getPointer(); }
+ StringRef getKind() const { return CapKind; }
+ bool negative() const { return CapExpr.getInt(); }
CapabilityExpr operator!() const {
- return CapabilityExpr(CapExpr, !Negated);
+ return CapabilityExpr(CapExpr.getPointer(), CapKind, !CapExpr.getInt());
}
bool equals(const CapabilityExpr &other) const {
- return (Negated == other.Negated) && sx::equals(CapExpr, other.CapExpr);
+ return (negative() == other.negative()) &&
+ sx::equals(sexpr(), other.sexpr());
}
bool matches(const CapabilityExpr &other) const {
- return (Negated == other.Negated) && sx::matches(CapExpr, other.CapExpr);
+ return (negative() == other.negative()) &&
+ sx::matches(sexpr(), other.sexpr());
}
bool matchesUniv(const CapabilityExpr &CapE) const {
@@ -298,27 +308,27 @@ public:
}
bool partiallyMatches(const CapabilityExpr &other) const {
- return (Negated == other.Negated) &&
- sx::partiallyMatches(CapExpr, other.CapExpr);
+ return (negative() == other.negative()) &&
+ sx::partiallyMatches(sexpr(), other.sexpr());
}
const ValueDecl* valueDecl() const {
- if (Negated || CapExpr == nullptr)
+ if (negative() || sexpr() == nullptr)
return nullptr;
- if (const auto *P = dyn_cast<til::Project>(CapExpr))
+ if (const auto *P = dyn_cast<til::Project>(sexpr()))
return P->clangDecl();
- if (const auto *P = dyn_cast<til::LiteralPtr>(CapExpr))
+ if (const auto *P = dyn_cast<til::LiteralPtr>(sexpr()))
return P->clangDecl();
return nullptr;
}
std::string toString() const {
- if (Negated)
- return "!" + sx::toString(CapExpr);
- return sx::toString(CapExpr);
+ if (negative())
+ return "!" + sx::toString(sexpr());
+ return sx::toString(sexpr());
}
- bool shouldIgnore() const { return CapExpr == nullptr; }
+ bool shouldIgnore() const { return sexpr() == nullptr; }
bool isInvalid() const { return sexpr() && isa<til::Undefined>(sexpr()); }
@@ -345,13 +355,13 @@ public:
const NamedDecl *AttrDecl;
// Implicit object argument -- e.g. 'this'
- const Expr *SelfArg = nullptr;
+ llvm::PointerUnion<const Expr *, til::SExpr *> SelfArg = nullptr;
// Number of funArgs
unsigned NumArgs = 0;
// Function arguments
- const Expr *const *FunArgs = nullptr;
+ llvm::PointerUnion<const Expr *const *, til::SExpr *> FunArgs = nullptr;
// is Self referred to with -> or .?
bool SelfArrow = false;
@@ -369,10 +379,18 @@ public:
// Translate a clang expression in an attribute to a til::SExpr.
// Constructs the context from D, DeclExp, and SelfDecl.
CapabilityExpr translateAttrExpr(const Expr *AttrExp, const NamedDecl *D,
- const Expr *DeclExp, VarDecl *SelfD=nullptr);
+ const Expr *DeclExp,
+ til::SExpr *Self = nullptr);
CapabilityExpr translateAttrExpr(const Expr *AttrExp, CallingContext *Ctx);
+ // Translate a variable reference.
+ til::LiteralPtr *createVariable(const VarDecl *VD);
+
+ // Create placeholder for this: we don't know the VarDecl on construction yet.
+ std::pair<til::LiteralPtr *, StringRef>
+ createThisPlaceholder(const Expr *Exp);
+
// Translate a clang statement or expression to a TIL expression.
// Also performs substitution of variables; Ctx provides the context.
// Dispatches on the type of S.
@@ -466,8 +484,6 @@ private:
SMap.insert(std::make_pair(S, E));
}
- til::SExpr *getCurrentLVarDefinition(const ValueDecl *VD);
-
til::SExpr *addStatement(til::SExpr *E, const Stmt *S,
const ValueDecl *VD = nullptr);
til::SExpr *lookupVarDecl(const ValueDecl *VD);
@@ -517,4 +533,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/ThreadSafetyTIL.h b/contrib/llvm-project/clang/include/clang/Analysis/Analyses/ThreadSafetyTIL.h
index 77a800c28754..65dd66ee093f 100644
--- a/contrib/llvm-project/clang/include/clang/Analysis/Analyses/ThreadSafetyTIL.h
+++ b/contrib/llvm-project/clang/include/clang/Analysis/Analyses/ThreadSafetyTIL.h
@@ -50,8 +50,6 @@
#include "clang/Analysis/Analyses/ThreadSafetyUtil.h"
#include "clang/Basic/LLVM.h"
#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/None.h"
-#include "llvm/ADT/Optional.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/raw_ostream.h"
@@ -60,6 +58,7 @@
#include <cstddef>
#include <cstdint>
#include <iterator>
+#include <optional>
#include <string>
#include <utility>
@@ -75,7 +74,7 @@ namespace til {
class BasicBlock;
/// Enum for the different distinct classes of SExpr
-enum TIL_Opcode {
+enum TIL_Opcode : unsigned char {
#define TIL_OPCODE_DEF(X) COP_##X,
#include "ThreadSafetyOps.def"
#undef TIL_OPCODE_DEF
@@ -278,7 +277,7 @@ class SExpr {
public:
SExpr() = delete;
- TIL_Opcode opcode() const { return static_cast<TIL_Opcode>(Opcode); }
+ TIL_Opcode opcode() const { return Opcode; }
// Subclasses of SExpr must define the following:
//
@@ -320,8 +319,9 @@ public:
protected:
SExpr(TIL_Opcode Op) : Opcode(Op) {}
SExpr(const SExpr &E) : Opcode(E.Opcode), Flags(E.Flags) {}
+ SExpr &operator=(const SExpr &) = delete;
- const unsigned char Opcode;
+ const TIL_Opcode Opcode;
unsigned char Reserved = 0;
unsigned short Flags = 0;
unsigned SExprID = 0;
@@ -332,7 +332,7 @@ protected:
namespace ThreadSafetyTIL {
inline bool isTrivial(const SExpr *E) {
- unsigned Op = E->opcode();
+ TIL_Opcode Op = E->opcode();
return Op == COP_Variable || Op == COP_Literal || Op == COP_LiteralPtr;
}
@@ -489,6 +489,10 @@ public:
Undefined(const Stmt *S = nullptr) : SExpr(COP_Undefined), Cstmt(S) {}
Undefined(const Undefined &U) : SExpr(U), Cstmt(U.Cstmt) {}
+ // The copy assignment operator is defined as deleted pending further
+ // motivation.
+ Undefined &operator=(const Undefined &) = delete;
+
static bool classof(const SExpr *E) { return E->opcode() == COP_Undefined; }
template <class V>
@@ -567,6 +571,10 @@ public:
LiteralT(T Dat) : Literal(ValueType::getValueType<T>()), Val(Dat) {}
LiteralT(const LiteralT<T> &L) : Literal(L), Val(L.Val) {}
+ // The copy assignment operator is defined as deleted pending further
+ // motivation.
+ LiteralT &operator=(const LiteralT<T> &) = delete;
+
T value() const { return Val;}
T& value() { return Val; }
@@ -634,15 +642,14 @@ typename V::R_SExpr Literal::traverse(V &Vs, typename V::R_Ctx Ctx) {
/// At compile time, pointer literals are represented by symbolic names.
class LiteralPtr : public SExpr {
public:
- LiteralPtr(const ValueDecl *D) : SExpr(COP_LiteralPtr), Cvdecl(D) {
- assert(D && "ValueDecl must not be null");
- }
+ LiteralPtr(const ValueDecl *D) : SExpr(COP_LiteralPtr), Cvdecl(D) {}
LiteralPtr(const LiteralPtr &) = default;
static bool classof(const SExpr *E) { return E->opcode() == COP_LiteralPtr; }
// The clang declaration for the value that this pointer points to.
const ValueDecl *clangDecl() const { return Cvdecl; }
+ void setClangDecl(const ValueDecl *VD) { Cvdecl = VD; }
template <class V>
typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
@@ -651,6 +658,8 @@ public:
template <class C>
typename C::CType compare(const LiteralPtr* E, C& Cmp) const {
+ if (!Cvdecl || !E->Cvdecl)
+ return Cmp.comparePointers(this, E);
return Cmp.comparePointers(Cvdecl, E->Cvdecl);
}
@@ -957,7 +966,7 @@ public:
private:
SExpr* Rec;
- mutable llvm::Optional<std::string> SlotName;
+ mutable std::optional<std::string> SlotName;
const ValueDecl *Cvdecl;
};
@@ -1430,9 +1439,7 @@ public:
BasicBlock *elseBlock() { return Branches[1]; }
/// Return the list of basic blocks that this terminator can branch to.
- ArrayRef<BasicBlock*> successors() {
- return llvm::makeArrayRef(Branches);
- }
+ ArrayRef<BasicBlock *> successors() { return llvm::ArrayRef(Branches); }
template <class V>
typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
@@ -1463,7 +1470,7 @@ public:
static bool classof(const SExpr *E) { return E->opcode() == COP_Return; }
/// Return an empty list.
- ArrayRef<BasicBlock *> successors() { return None; }
+ ArrayRef<BasicBlock *> successors() { return std::nullopt; }
SExpr *returnValue() { return Retval; }
const SExpr *returnValue() const { return Retval; }
@@ -1489,7 +1496,7 @@ inline ArrayRef<BasicBlock*> Terminator::successors() {
case COP_Branch: return cast<Branch>(this)->successors();
case COP_Return: return cast<Return>(this)->successors();
default:
- return None;
+ return std::nullopt;
}
}
diff --git a/contrib/llvm-project/clang/include/clang/Analysis/Analyses/ThreadSafetyTraverse.h b/contrib/llvm-project/clang/include/clang/Analysis/Analyses/ThreadSafetyTraverse.h
index e81c00d3dddb..6fc55130655a 100644
--- a/contrib/llvm-project/clang/include/clang/Analysis/Analyses/ThreadSafetyTraverse.h
+++ b/contrib/llvm-project/clang/include/clang/Analysis/Analyses/ThreadSafetyTraverse.h
@@ -623,7 +623,10 @@ protected:
}
void printLiteralPtr(const LiteralPtr *E, StreamType &SS) {
- SS << E->clangDecl()->getNameAsString();
+ if (const NamedDecl *D = E->clangDecl())
+ SS << D->getNameAsString();
+ else
+ SS << "<temporary>";
}
void printVariable(const Variable *V, StreamType &SS, bool IsVarDecl=false) {
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..ac7b24cdb4a6 100644
--- a/contrib/llvm-project/clang/include/clang/Analysis/Analyses/ThreadSafetyUtil.h
+++ b/contrib/llvm-project/clang/include/clang/Analysis/Analyses/ThreadSafetyUtil.h
@@ -204,11 +204,11 @@ public:
}
llvm::iterator_range<reverse_iterator> reverse() {
- return llvm::make_range(rbegin(), rend());
+ return llvm::reverse(*this);
}
llvm::iterator_range<const_reverse_iterator> reverse() const {
- return llvm::make_range(rbegin(), rend());
+ return llvm::reverse(*this);
}
private:
@@ -240,6 +240,10 @@ class CopyOnWriteVector {
VectorData() = default;
VectorData(const VectorData &VD) : Vect(VD.Vect) {}
+
+ // The copy assignment operator is defined as deleted pending further
+ // motivation.
+ VectorData &operator=(const VectorData &) = delete;
};
public:
@@ -354,4 +358,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/Analyses/UnsafeBufferUsage.h b/contrib/llvm-project/clang/include/clang/Analysis/Analyses/UnsafeBufferUsage.h
new file mode 100644
index 000000000000..b28f2c6b99c5
--- /dev/null
+++ b/contrib/llvm-project/clang/include/clang/Analysis/Analyses/UnsafeBufferUsage.h
@@ -0,0 +1,122 @@
+//===- UnsafeBufferUsage.h - Replace pointers with modern C++ ---*- 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 analysis that aids replacing buffer accesses through
+// raw pointers with safer C++ abstractions such as containers and views/spans.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_ANALYSIS_ANALYSES_UNSAFEBUFFERUSAGE_H
+#define LLVM_CLANG_ANALYSIS_ANALYSES_UNSAFEBUFFERUSAGE_H
+
+#include "clang/AST/Decl.h"
+#include "clang/AST/Stmt.h"
+#include "llvm/Support/Debug.h"
+
+namespace clang {
+
+using VarGrpTy = std::vector<const VarDecl *>;
+using VarGrpRef = ArrayRef<const VarDecl *>;
+
+class VariableGroupsManager {
+public:
+ VariableGroupsManager() = default;
+ virtual ~VariableGroupsManager() = default;
+ /// Returns the set of variables (including `Var`) that need to be fixed
+ /// together in one step.
+ ///
+ /// `Var` must be a variable that needs fix (so it must be in a group).
+ /// `HasParm` is an optional argument that will be set to true if the set of
+ /// variables, where `Var` is in, contains parameters.
+ virtual VarGrpRef getGroupOfVar(const VarDecl *Var,
+ bool *HasParm = nullptr) const =0;
+
+ /// Returns the non-empty group of variables that include parameters of the
+ /// analyzing function, if such a group exists. An empty group, otherwise.
+ virtual VarGrpRef getGroupOfParms() const =0;
+};
+
+/// The interface that lets the caller handle unsafe buffer usage analysis
+/// results by overriding this class's handle... methods.
+class UnsafeBufferUsageHandler {
+#ifndef NDEBUG
+public:
+ // A self-debugging facility that you can use to notify the user when
+ // suggestions or fixits are incomplete.
+ // Uses std::function to avoid computing the message when it won't
+ // actually be displayed.
+ using DebugNote = std::pair<SourceLocation, std::string>;
+ using DebugNoteList = std::vector<DebugNote>;
+ using DebugNoteByVar = std::map<const VarDecl *, DebugNoteList>;
+ DebugNoteByVar DebugNotesByVar;
+#endif
+
+public:
+ UnsafeBufferUsageHandler() = default;
+ virtual ~UnsafeBufferUsageHandler() = default;
+
+ /// This analyses produces large fixits that are organized into lists
+ /// of primitive fixits (individual insertions/removals/replacements).
+ using FixItList = llvm::SmallVectorImpl<FixItHint>;
+
+ /// Invoked when an unsafe operation over raw pointers is found.
+ virtual void handleUnsafeOperation(const Stmt *Operation,
+ bool IsRelatedToDecl, ASTContext &Ctx) = 0;
+
+ /// Invoked when a fix is suggested against a variable. This function groups
+ /// all variables that must be fixed together (i.e their types must be changed
+ /// to the same target type to prevent type mismatches) into a single fixit.
+ ///
+ /// `D` is the declaration of the callable under analysis that owns `Variable`
+ /// and all of its group mates.
+ virtual void handleUnsafeVariableGroup(const VarDecl *Variable,
+ const VariableGroupsManager &VarGrpMgr,
+ FixItList &&Fixes, const Decl *D) = 0;
+
+#ifndef NDEBUG
+public:
+ bool areDebugNotesRequested() {
+ DEBUG_WITH_TYPE("SafeBuffers", return true);
+ return false;
+ }
+
+ void addDebugNoteForVar(const VarDecl *VD, SourceLocation Loc,
+ std::string Text) {
+ if (areDebugNotesRequested())
+ DebugNotesByVar[VD].push_back(std::make_pair(Loc, Text));
+ }
+
+ void clearDebugNotes() {
+ if (areDebugNotesRequested())
+ DebugNotesByVar.clear();
+ }
+#endif
+
+public:
+ /// Returns a reference to the `Preprocessor`:
+ virtual bool isSafeBufferOptOut(const SourceLocation &Loc) const = 0;
+
+ virtual std::string
+ getUnsafeBufferUsageAttributeTextAt(SourceLocation Loc,
+ StringRef WSSuffix = "") const = 0;
+};
+
+// This function invokes the analysis and allows the caller to react to it
+// through the handler class.
+void checkUnsafeBufferUsage(const Decl *D, UnsafeBufferUsageHandler &Handler,
+ bool EmitSuggestions);
+
+namespace internal {
+// Tests if any two `FixItHint`s in `FixIts` conflict. Two `FixItHint`s
+// conflict if they have overlapping source ranges.
+bool anyConflict(const llvm::SmallVectorImpl<FixItHint> &FixIts,
+ const SourceManager &SM);
+} // namespace internal
+} // end namespace clang
+
+#endif /* LLVM_CLANG_ANALYSIS_ANALYSES_UNSAFEBUFFERUSAGE_H */
diff --git a/contrib/llvm-project/clang/include/clang/Analysis/Analyses/UnsafeBufferUsageGadgets.def b/contrib/llvm-project/clang/include/clang/Analysis/Analyses/UnsafeBufferUsageGadgets.def
new file mode 100644
index 000000000000..c97661688365
--- /dev/null
+++ b/contrib/llvm-project/clang/include/clang/Analysis/Analyses/UnsafeBufferUsageGadgets.def
@@ -0,0 +1,46 @@
+//=- UnsafeBufferUsageGadgets.def - List of ways to use a buffer --*- 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
+//
+//===----------------------------------------------------------------------===//
+
+/// A gadget is an individual operation in the code that may be of interest to
+/// the UnsafeBufferUsage analysis.
+#ifndef GADGET
+#define GADGET(name)
+#endif
+
+/// Unsafe gadgets correspond to unsafe code patterns that warrant
+/// an immediate warning.
+#ifndef WARNING_GADGET
+#define WARNING_GADGET(name) GADGET(name)
+#endif
+
+/// Safe gadgets correspond to code patterns that aren't unsafe but need to be
+/// properly recognized in order to emit correct warnings and fixes over unsafe
+/// gadgets.
+#ifndef FIXABLE_GADGET
+#define FIXABLE_GADGET(name) GADGET(name)
+#endif
+
+WARNING_GADGET(Increment)
+WARNING_GADGET(Decrement)
+WARNING_GADGET(ArraySubscript)
+WARNING_GADGET(PointerArithmetic)
+WARNING_GADGET(UnsafeBufferUsageAttr)
+WARNING_GADGET(DataInvocation)
+FIXABLE_GADGET(ULCArraySubscript) // `DRE[any]` in an Unspecified Lvalue Context
+FIXABLE_GADGET(DerefSimplePtrArithFixable)
+FIXABLE_GADGET(PointerDereference)
+FIXABLE_GADGET(UPCAddressofArraySubscript) // '&DRE[any]' in an Unspecified Pointer Context
+FIXABLE_GADGET(UPCStandalonePointer)
+FIXABLE_GADGET(UPCPreIncrement) // '++Ptr' in an Unspecified Pointer Context
+FIXABLE_GADGET(UUCAddAssign) // 'Ptr += n' in an Unspecified Untyped Context
+FIXABLE_GADGET(PointerAssignment)
+FIXABLE_GADGET(PointerInit)
+
+#undef FIXABLE_GADGET
+#undef WARNING_GADGET
+#undef GADGET
diff --git a/contrib/llvm-project/clang/include/clang/Analysis/AnalysisDeclContext.h b/contrib/llvm-project/clang/include/clang/Analysis/AnalysisDeclContext.h
index 102970a1d55e..a517a4e757c9 100644
--- a/contrib/llvm-project/clang/include/clang/Analysis/AnalysisDeclContext.h
+++ b/contrib/llvm-project/clang/include/clang/Analysis/AnalysisDeclContext.h
@@ -229,7 +229,9 @@ private:
protected:
LocationContext(ContextKind k, AnalysisDeclContext *ctx,
const LocationContext *parent, int64_t ID)
- : Kind(k), Ctx(ctx), Parent(parent), ID(ID) {}
+ : Kind(k), Ctx(ctx), Parent(parent), ID(ID) {
+ assert(ctx);
+ }
public:
virtual ~LocationContext();
@@ -238,8 +240,10 @@ public:
int64_t getID() const { return ID; }
+ LLVM_ATTRIBUTE_RETURNS_NONNULL
AnalysisDeclContext *getAnalysisDeclContext() const { return Ctx; }
+ /// It might return null.
const LocationContext *getParent() const { return Parent; }
bool isParentOf(const LocationContext *LC) const;
@@ -327,7 +331,7 @@ public:
unsigned getIndex() const { return Index; }
CFGElement getCallSiteCFGElement() const { return (*Block)[Index]; }
-
+
void Profile(llvm::FoldingSetNodeID &ID) override;
static void Profile(llvm::FoldingSetNodeID &ID, AnalysisDeclContext *ADC,
diff --git a/contrib/llvm-project/clang/include/clang/Analysis/AnalysisDiagnostic.h b/contrib/llvm-project/clang/include/clang/Analysis/AnalysisDiagnostic.h
deleted file mode 100644
index fd5f2ffe6483..000000000000
--- a/contrib/llvm-project/clang/include/clang/Analysis/AnalysisDiagnostic.h
+++ /dev/null
@@ -1,14 +0,0 @@
-//===--- DiagnosticAnalysis.h - Diagnostics for libanalysis -----*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_ANALYSIS_ANALYSISDIAGNOSTIC_H
-#define LLVM_CLANG_ANALYSIS_ANALYSISDIAGNOSTIC_H
-
-#include "clang/Basic/DiagnosticAnalysis.h"
-
-#endif
diff --git a/contrib/llvm-project/clang/include/clang/Analysis/AnyCall.h b/contrib/llvm-project/clang/include/clang/Analysis/AnyCall.h
index 846ff7719ce1..48abce062d13 100644
--- a/contrib/llvm-project/clang/include/clang/Analysis/AnyCall.h
+++ b/contrib/llvm-project/clang/include/clang/Analysis/AnyCall.h
@@ -10,12 +10,13 @@
//
//===----------------------------------------------------------------------===//
//
-#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"
#include "clang/AST/ExprObjC.h"
+#include <optional>
namespace clang {
@@ -108,8 +109,8 @@ public:
}
/// If @c E is a generic call (to ObjC method /function/block/etc),
- /// return a constructed @c AnyCall object. Return None otherwise.
- static Optional<AnyCall> forExpr(const Expr *E) {
+ /// return a constructed @c AnyCall object. Return std::nullopt otherwise.
+ static std::optional<AnyCall> forExpr(const Expr *E) {
if (const auto *ME = dyn_cast<ObjCMessageExpr>(E)) {
return AnyCall(ME);
} else if (const auto *CE = dyn_cast<CallExpr>(E)) {
@@ -123,26 +124,26 @@ public:
} else if (const auto *CXCIE = dyn_cast<CXXInheritedCtorInitExpr>(E)) {
return AnyCall(CXCIE);
} else {
- return None;
+ return std::nullopt;
}
}
/// If @c D is a callable (Objective-C method or a function), return
- /// a constructed @c AnyCall object. Return None otherwise.
+ /// a constructed @c AnyCall object. Return std::nullopt otherwise.
// FIXME: block support.
- static Optional<AnyCall> forDecl(const Decl *D) {
+ static std::optional<AnyCall> forDecl(const Decl *D) {
if (const auto *FD = dyn_cast<FunctionDecl>(D)) {
return AnyCall(FD);
} else if (const auto *MD = dyn_cast<ObjCMethodDecl>(D)) {
return AnyCall(MD);
}
- return None;
+ return std::nullopt;
}
/// \returns formal parameters for direct calls (including virtual calls)
ArrayRef<ParmVarDecl *> parameters() const {
if (!D)
- return None;
+ return std::nullopt;
if (const auto *FD = dyn_cast<FunctionDecl>(D)) {
return FD->parameters();
@@ -151,7 +152,7 @@ public:
} else if (const auto *BD = dyn_cast<BlockDecl>(D)) {
return BD->parameters();
} else {
- return None;
+ return std::nullopt;
}
}
@@ -215,4 +216,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..52be29cb7885 100644
--- a/contrib/llvm-project/clang/include/clang/Analysis/BodyFarm.h
+++ b/contrib/llvm-project/clang/include/clang/Analysis/BodyFarm.h
@@ -11,20 +11,19 @@
//
//===----------------------------------------------------------------------===//
-#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"
#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/Optional.h"
+#include <optional>
namespace clang {
class ASTContext;
class FunctionDecl;
class ObjCMethodDecl;
-class ObjCPropertyDecl;
class Stmt;
class CodeInjector;
@@ -41,8 +40,11 @@ public:
/// Remove copy constructor to avoid accidental copying.
BodyFarm(const BodyFarm &other) = delete;
+ /// Delete copy assignment operator.
+ BodyFarm &operator=(const BodyFarm &other) = delete;
+
private:
- typedef llvm::DenseMap<const Decl *, Optional<Stmt *>> BodyMap;
+ typedef llvm::DenseMap<const Decl *, std::optional<Stmt *>> BodyMap;
ASTContext &C;
BodyMap Bodies;
diff --git a/contrib/llvm-project/clang/include/clang/Analysis/CFG.h b/contrib/llvm-project/clang/include/clang/Analysis/CFG.h
index 9e32eb8e066a..9f776ca6cc26 100644
--- a/contrib/llvm-project/clang/include/clang/Analysis/CFG.h
+++ b/contrib/llvm-project/clang/include/clang/Analysis/CFG.h
@@ -14,15 +14,14 @@
#ifndef LLVM_CLANG_ANALYSIS_CFG_H
#define LLVM_CLANG_ANALYSIS_CFG_H
-#include "clang/Analysis/Support/BumpVector.h"
-#include "clang/Analysis/ConstructionContext.h"
+#include "clang/AST/Attr.h"
#include "clang/AST/ExprCXX.h"
#include "clang/AST/ExprObjC.h"
+#include "clang/Analysis/ConstructionContext.h"
+#include "clang/Analysis/Support/BumpVector.h"
#include "clang/Basic/LLVM.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/GraphTraits.h"
-#include "llvm/ADT/None.h"
-#include "llvm/ADT/Optional.h"
#include "llvm/ADT/PointerIntPair.h"
#include "llvm/ADT/iterator_range.h"
#include "llvm/Support/Allocator.h"
@@ -32,6 +31,7 @@
#include <cstddef>
#include <iterator>
#include <memory>
+#include <optional>
#include <vector>
namespace clang {
@@ -75,7 +75,8 @@ public:
MemberDtor,
TemporaryDtor,
DTOR_BEGIN = AutomaticObjectDtor,
- DTOR_END = TemporaryDtor
+ DTOR_END = TemporaryDtor,
+ CleanupFunction,
};
protected:
@@ -103,12 +104,11 @@ public:
return t;
}
- /// Convert to the specified CFGElement type, returning None if this
+ /// Convert to the specified CFGElement type, returning std::nullopt if this
/// CFGElement is not of the desired type.
- template<typename T>
- Optional<T> getAs() const {
+ template <typename T> std::optional<T> getAs() const {
if (!T::isKind(*this))
- return None;
+ return std::nullopt;
T t;
CFGElement& e = t;
e = *this;
@@ -131,7 +131,7 @@ public:
class CFGStmt : public CFGElement {
public:
- explicit CFGStmt(Stmt *S, Kind K = Statement) : CFGElement(K, S) {
+ explicit CFGStmt(const Stmt *S, Kind K = Statement) : CFGElement(K, S) {
assert(isKind(*this));
}
@@ -155,7 +155,8 @@ protected:
/// this is only used by the analyzer's CFG.
class CFGConstructor : public CFGStmt {
public:
- explicit CFGConstructor(CXXConstructExpr *CE, const ConstructionContext *C)
+ explicit CFGConstructor(const CXXConstructExpr *CE,
+ const ConstructionContext *C)
: CFGStmt(CE, Constructor) {
assert(C);
Data2.setPointer(const_cast<ConstructionContext *>(C));
@@ -185,7 +186,7 @@ class CFGCXXRecordTypedCall : public CFGStmt {
public:
/// Returns true when call expression \p CE needs to be represented
/// by CFGCXXRecordTypedCall, as opposed to a regular CFGStmt.
- static bool isCXXRecordTypedCall(Expr *E) {
+ static bool isCXXRecordTypedCall(const Expr *E) {
assert(isa<CallExpr>(E) || isa<ObjCMessageExpr>(E));
// There is no such thing as reference-type expression. If the function
// returns a reference, it'll return the respective lvalue or xvalue
@@ -194,7 +195,7 @@ public:
E->getType().getCanonicalType()->getAsCXXRecordDecl();
}
- explicit CFGCXXRecordTypedCall(Expr *E, const ConstructionContext *C)
+ explicit CFGCXXRecordTypedCall(const Expr *E, const ConstructionContext *C)
: CFGStmt(E, CXXRecordTypedCall) {
assert(isCXXRecordTypedCall(E));
assert(C && (isa<TemporaryObjectConstructionContext>(C) ||
@@ -202,7 +203,8 @@ public:
isa<ReturnedValueConstructionContext>(C) ||
isa<VariableConstructionContext>(C) ||
isa<ConstructorInitializerConstructionContext>(C) ||
- isa<ArgumentConstructionContext>(C)));
+ isa<ArgumentConstructionContext>(C) ||
+ isa<LambdaCaptureConstructionContext>(C)));
Data2.setPointer(const_cast<ConstructionContext *>(C));
}
@@ -224,7 +226,7 @@ private:
/// list.
class CFGInitializer : public CFGElement {
public:
- explicit CFGInitializer(CXXCtorInitializer *initializer)
+ explicit CFGInitializer(const CXXCtorInitializer *initializer)
: CFGElement(Initializer, initializer) {}
CXXCtorInitializer* getInitializer() const {
@@ -263,7 +265,7 @@ private:
};
/// Represents the point where a loop ends.
-/// This element is is only produced when building the CFG for the static
+/// This element is only produced when building the CFG for the static
/// analyzer and hidden behind the 'cfg-loopexit' analyzer config flag.
///
/// Note: a loop exit element can be reached even when the loop body was never
@@ -383,6 +385,32 @@ private:
}
};
+class CFGCleanupFunction final : public CFGElement {
+public:
+ CFGCleanupFunction() = default;
+ CFGCleanupFunction(const VarDecl *VD)
+ : CFGElement(Kind::CleanupFunction, VD) {
+ assert(VD->hasAttr<CleanupAttr>());
+ }
+
+ const VarDecl *getVarDecl() const {
+ return static_cast<VarDecl *>(Data1.getPointer());
+ }
+
+ /// Returns the function to be called when cleaning up the var decl.
+ const FunctionDecl *getFunctionDecl() const {
+ const CleanupAttr *A = getVarDecl()->getAttr<CleanupAttr>();
+ return A->getFunctionDecl();
+ }
+
+private:
+ friend class CFGElement;
+
+ static bool isKind(const CFGElement E) {
+ return E.getKind() == Kind::CleanupFunction;
+ }
+};
+
/// Represents C++ object destructor implicitly generated for automatic object
/// or temporary bound to const reference at the point of leaving its local
/// scope.
@@ -481,7 +509,7 @@ private:
/// expression for temporary object.
class CFGTemporaryDtor : public CFGImplicitDtor {
public:
- CFGTemporaryDtor(CXXBindTemporaryExpr *expr)
+ CFGTemporaryDtor(const CXXBindTemporaryExpr *expr)
: CFGImplicitDtor(TemporaryDtor, expr, nullptr) {}
const CXXBindTemporaryExpr *getBindTemporaryExpr() const {
@@ -515,7 +543,7 @@ public:
/// of the most derived class while we're in the base class.
VirtualBaseBranch,
- /// Number of different kinds, for sanity checks. We subtract 1 so that
+ /// Number of different kinds, for assertions. We subtract 1 so that
/// to keep receiving compiler warnings when we don't cover all enum values
/// in a switch.
NumKindsMinusOne = VirtualBaseBranch
@@ -707,7 +735,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);
@@ -1122,19 +1150,10 @@ public:
Elements.push_back(CFGScopeBegin(VD, S), C);
}
- void prependScopeBegin(const VarDecl *VD, const Stmt *S,
- BumpVectorContext &C) {
- Elements.insert(Elements.rbegin(), 1, CFGScopeBegin(VD, S), C);
- }
-
void appendScopeEnd(const VarDecl *VD, const Stmt *S, BumpVectorContext &C) {
Elements.push_back(CFGScopeEnd(VD, S), C);
}
- void prependScopeEnd(const VarDecl *VD, const Stmt *S, BumpVectorContext &C) {
- Elements.insert(Elements.rbegin(), 1, CFGScopeEnd(VD, S), C);
- }
-
void appendBaseDtor(const CXXBaseSpecifier *BS, BumpVectorContext &C) {
Elements.push_back(CFGBaseDtor(BS), C);
}
@@ -1151,6 +1170,10 @@ public:
Elements.push_back(CFGAutomaticObjDtor(VD, S), C);
}
+ void appendCleanupFunction(const VarDecl *VD, BumpVectorContext &C) {
+ Elements.push_back(CFGCleanupFunction(VD), C);
+ }
+
void appendLifetimeEnds(VarDecl *VD, Stmt *S, BumpVectorContext &C) {
Elements.push_back(CFGLifetimeEnds(VD, S), C);
}
@@ -1162,44 +1185,6 @@ public:
void appendDeleteDtor(CXXRecordDecl *RD, CXXDeleteExpr *DE, BumpVectorContext &C) {
Elements.push_back(CFGDeleteDtor(RD, DE), C);
}
-
- // Destructors must be inserted in reversed order. So insertion is in two
- // steps. First we prepare space for some number of elements, then we insert
- // the elements beginning at the last position in prepared space.
- iterator beginAutomaticObjDtorsInsert(iterator I, size_t Cnt,
- BumpVectorContext &C) {
- return iterator(Elements.insert(I.base(), Cnt,
- CFGAutomaticObjDtor(nullptr, nullptr), C));
- }
- iterator insertAutomaticObjDtor(iterator I, VarDecl *VD, Stmt *S) {
- *I = CFGAutomaticObjDtor(VD, S);
- return ++I;
- }
-
- // Scope leaving must be performed in reversed order. So insertion is in two
- // steps. First we prepare space for some number of elements, then we insert
- // the elements beginning at the last position in prepared space.
- iterator beginLifetimeEndsInsert(iterator I, size_t Cnt,
- BumpVectorContext &C) {
- return iterator(
- Elements.insert(I.base(), Cnt, CFGLifetimeEnds(nullptr, nullptr), C));
- }
- iterator insertLifetimeEnds(iterator I, VarDecl *VD, Stmt *S) {
- *I = CFGLifetimeEnds(VD, S);
- return ++I;
- }
-
- // Scope leaving must be performed in reversed order. So insertion is in two
- // steps. First we prepare space for some number of elements, then we insert
- // the elements beginning at the last position in prepared space.
- iterator beginScopeEndInsert(iterator I, size_t Cnt, BumpVectorContext &C) {
- return iterator(
- Elements.insert(I.base(), Cnt, CFGScopeEnd(nullptr, nullptr), C));
- }
- iterator insertScopeEnd(iterator I, VarDecl *VD, Stmt *S) {
- *I = CFGScopeEnd(VD, S);
- return ++I;
- }
};
/// CFGCallback defines methods that should be called when a logical
@@ -1209,6 +1194,7 @@ public:
CFGCallback() = default;
virtual ~CFGCallback() = default;
+ virtual void logicAlwaysTrue(const BinaryOperator *B, bool isAlwaysTrue) {}
virtual void compareAlwaysTrue(const BinaryOperator *B, bool isAlwaysTrue) {}
virtual void compareBitwiseEquality(const BinaryOperator *B,
bool isAlwaysTrue) {}
@@ -1229,7 +1215,9 @@ public:
//===--------------------------------------------------------------------===//
class BuildOptions {
- std::bitset<Stmt::lastStmtConstant> alwaysAddMask;
+ // Stmt::lastStmtConstant has the same value as the last Stmt kind,
+ // so make sure we add one to account for this!
+ std::bitset<Stmt::lastStmtConstant + 1> alwaysAddMask;
public:
using ForcedBlkExprs = llvm::DenseMap<const Stmt *, const CFGBlock *>;
@@ -1337,6 +1325,7 @@ public:
const CFGBlock * getIndirectGotoBlock() const { return IndirectGotoBlock; }
using try_block_iterator = std::vector<const CFGBlock *>::const_iterator;
+ using try_block_range = llvm::iterator_range<try_block_iterator>;
try_block_iterator try_blocks_begin() const {
return TryDispatchBlocks.begin();
@@ -1346,6 +1335,10 @@ public:
return TryDispatchBlocks.end();
}
+ try_block_range try_blocks() const {
+ return try_block_range(try_blocks_begin(), try_blocks_end());
+ }
+
void addTryDispatchBlock(const CFGBlock *block) {
TryDispatchBlocks.push_back(block);
}
@@ -1393,7 +1386,7 @@ public:
for (const_iterator I = begin(), E = end(); I != E; ++I)
for (CFGBlock::const_iterator BI = (*I)->begin(), BE = (*I)->end();
BI != BE; ++BI) {
- if (Optional<CFGStmt> stmt = BI->getAs<CFGStmt>())
+ if (std::optional<CFGStmt> stmt = BI->getAs<CFGStmt>())
O(const_cast<Stmt *>(stmt->getStmt()));
}
}
@@ -1460,6 +1453,8 @@ private:
llvm::DenseMap<const DeclStmt *, const DeclStmt *> SyntheticDeclStmts;
};
+Expr *extractElementInitializerFromNestedAILE(const ArrayInitLoopExpr *AILE);
+
} // namespace clang
//===----------------------------------------------------------------------===//
@@ -1489,9 +1484,6 @@ template <> struct GraphTraits< ::clang::CFGBlock *> {
static ChildIteratorType child_end(NodeRef N) { return N->succ_end(); }
};
-template <> struct GraphTraits<clang::CFGBlock>
- : GraphTraits<clang::CFGBlock *> {};
-
template <> struct GraphTraits< const ::clang::CFGBlock *> {
using NodeRef = const ::clang::CFGBlock *;
using ChildIteratorType = ::clang::CFGBlock::const_succ_iterator;
@@ -1501,9 +1493,6 @@ template <> struct GraphTraits< const ::clang::CFGBlock *> {
static ChildIteratorType child_end(NodeRef N) { return N->succ_end(); }
};
-template <> struct GraphTraits<const clang::CFGBlock>
- : GraphTraits<clang::CFGBlock *> {};
-
template <> struct GraphTraits<Inverse< ::clang::CFGBlock *>> {
using NodeRef = ::clang::CFGBlock *;
using ChildIteratorType = ::clang::CFGBlock::const_pred_iterator;
@@ -1516,9 +1505,6 @@ template <> struct GraphTraits<Inverse< ::clang::CFGBlock *>> {
static ChildIteratorType child_end(NodeRef N) { return N->pred_end(); }
};
-template <> struct GraphTraits<Inverse<clang::CFGBlock>>
- : GraphTraits<clang::CFGBlock *> {};
-
template <> struct GraphTraits<Inverse<const ::clang::CFGBlock *>> {
using NodeRef = const ::clang::CFGBlock *;
using ChildIteratorType = ::clang::CFGBlock::const_pred_iterator;
@@ -1531,9 +1517,6 @@ template <> struct GraphTraits<Inverse<const ::clang::CFGBlock *>> {
static ChildIteratorType child_end(NodeRef N) { return N->pred_end(); }
};
-template <> struct GraphTraits<const Inverse<clang::CFGBlock>>
- : GraphTraits<clang::CFGBlock *> {};
-
// Traits for: CFG
template <> struct GraphTraits< ::clang::CFG* >
diff --git a/contrib/llvm-project/clang/include/clang/Analysis/CFGStmtMap.h b/contrib/llvm-project/clang/include/clang/Analysis/CFGStmtMap.h
index 8cf02372ff0f..93cd9cfc5bdf 100644
--- a/contrib/llvm-project/clang/include/clang/Analysis/CFGStmtMap.h
+++ b/contrib/llvm-project/clang/include/clang/Analysis/CFGStmtMap.h
@@ -26,6 +26,8 @@ class CFGStmtMap {
void *M;
CFGStmtMap(ParentMap *pm, void *m) : PM(pm), M(m) {}
+ CFGStmtMap(const CFGStmtMap &) = delete;
+ CFGStmtMap &operator=(const CFGStmtMap &) = delete;
public:
~CFGStmtMap();
diff --git a/contrib/llvm-project/clang/include/clang/Analysis/CallGraph.h b/contrib/llvm-project/clang/include/clang/Analysis/CallGraph.h
index 999ac5da8acb..78f8d1155501 100644
--- a/contrib/llvm-project/clang/include/clang/Analysis/CallGraph.h
+++ b/contrib/llvm-project/clang/include/clang/Analysis/CallGraph.h
@@ -66,7 +66,7 @@ public:
/// Determine if a declaration should be included in the graph.
static bool includeInGraph(const Decl *D);
- /// Determine if a declaration should be included in the graph for the
+ /// Determine if a declaration should be included in the graph for the
/// purposes of being a callee. This is similar to includeInGraph except
/// it permits declarations, not just definitions.
static bool includeCalleeInGraph(const Decl *D);
diff --git a/contrib/llvm-project/clang/include/clang/Analysis/CloneDetection.h b/contrib/llvm-project/clang/include/clang/Analysis/CloneDetection.h
index db827c3a6d6f..3385579584b5 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"
@@ -208,13 +208,7 @@ public:
// The initial assumption is that there is only one clone group and every
// statement is a clone of the others. This clone group will then be
// split up with the help of the constraints.
- CloneGroup AllClones;
- AllClones.reserve(Sequences.size());
- for (const auto &C : Sequences) {
- AllClones.push_back(C);
- }
-
- Result.push_back(AllClones);
+ Result.push_back(Sequences);
constrainClones(Result, ConstraintList...);
}
@@ -235,9 +229,7 @@ public:
static void filterGroups(
std::vector<CloneDetector::CloneGroup> &CloneGroups,
llvm::function_ref<bool(const CloneDetector::CloneGroup &)> Filter) {
- CloneGroups.erase(
- std::remove_if(CloneGroups.begin(), CloneGroups.end(), Filter),
- CloneGroups.end());
+ llvm::erase_if(CloneGroups, Filter);
}
/// Splits the given CloneGroups until the given Compare function returns true
@@ -268,7 +260,7 @@ public:
///
/// Clones that aren't type II clones are moved into separate clone groups.
/// In contrast to the RecursiveCloneTypeIIHashConstraint, all clones in a clone
-/// group are guaranteed to be be type II clones of each other, but it is too
+/// group are guaranteed to be type II clones of each other, but it is too
/// slow to efficiently handle large amounts of clones.
class RecursiveCloneTypeIIVerifyConstraint {
public:
@@ -443,4 +435,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/ConstructionContext.h b/contrib/llvm-project/clang/include/clang/Analysis/ConstructionContext.h
index 4fa5c8b454a0..e19a20500095 100644
--- a/contrib/llvm-project/clang/include/clang/Analysis/ConstructionContext.h
+++ b/contrib/llvm-project/clang/include/clang/Analysis/ConstructionContext.h
@@ -36,13 +36,14 @@ public:
ElidedDestructorKind,
ElidableConstructorKind,
ArgumentKind,
- STATEMENT_WITH_INDEX_KIND_BEGIN=ArgumentKind,
- STATEMENT_WITH_INDEX_KIND_END=ArgumentKind,
+ LambdaCaptureKind,
+ STATEMENT_WITH_INDEX_KIND_BEGIN = ArgumentKind,
+ STATEMENT_WITH_INDEX_KIND_END = LambdaCaptureKind,
STATEMENT_KIND_BEGIN = VariableKind,
- STATEMENT_KIND_END = ArgumentKind,
+ STATEMENT_KIND_END = LambdaCaptureKind,
InitializerKind,
- INITIALIZER_KIND_BEGIN=InitializerKind,
- INITIALIZER_KIND_END=InitializerKind
+ INITIALIZER_KIND_BEGIN = InitializerKind,
+ INITIALIZER_KIND_END = InitializerKind
};
LLVM_DUMP_METHOD static StringRef getKindAsString(ItemKind K) {
@@ -55,6 +56,8 @@ public:
case ElidedDestructorKind: return "elide destructor";
case ElidableConstructorKind: return "elide constructor";
case ArgumentKind: return "construct into argument";
+ case LambdaCaptureKind:
+ return "construct into lambda captured variable";
case InitializerKind: return "construct into member variable";
};
llvm_unreachable("Unknown ItemKind");
@@ -72,7 +75,7 @@ private:
bool hasIndex() const {
return Kind >= STATEMENT_WITH_INDEX_KIND_BEGIN &&
- Kind >= STATEMENT_WITH_INDEX_KIND_END;
+ Kind <= STATEMENT_WITH_INDEX_KIND_END;
}
bool hasInitializer() const {
@@ -120,12 +123,16 @@ public:
ConstructionContextItem(const Expr *E, unsigned Index)
: Data(E), Kind(ArgumentKind), Index(Index) {
assert(isa<CallExpr>(E) || isa<CXXConstructExpr>(E) ||
- isa<CXXInheritedCtorInitExpr>(E) || isa<ObjCMessageExpr>(E));
+ isa<CXXDeleteExpr>(E) || isa<CXXInheritedCtorInitExpr>(E) ||
+ isa<ObjCMessageExpr>(E));
}
ConstructionContextItem(const CXXCtorInitializer *Init)
: Data(Init), Kind(InitializerKind), Index(0) {}
+ ConstructionContextItem(const LambdaExpr *LE, unsigned Index)
+ : Data(LE), Kind(LambdaCaptureKind), Index(Index) {}
+
ItemKind getKind() const { return Kind; }
LLVM_DUMP_METHOD StringRef getKindAsString() const {
@@ -253,7 +260,8 @@ public:
CXX17ElidedCopyReturnedValueKind,
RETURNED_VALUE_BEGIN = SimpleReturnedValueKind,
RETURNED_VALUE_END = CXX17ElidedCopyReturnedValueKind,
- ArgumentKind
+ ArgumentKind,
+ LambdaCaptureKind
};
protected:
@@ -297,6 +305,11 @@ public:
const ConstructionContextLayer *TopLayer);
Kind getKind() const { return K; }
+
+ virtual const ArrayInitLoopExpr *getArrayInitLoop() const { return nullptr; }
+
+ // Only declared to silence -Wnon-virtual-dtor warnings.
+ virtual ~ConstructionContext() = default;
};
/// An abstract base class for local variable constructors.
@@ -313,6 +326,12 @@ protected:
public:
const DeclStmt *getDeclStmt() const { return DS; }
+ const ArrayInitLoopExpr *getArrayInitLoop() const override {
+ const auto *Var = cast<VarDecl>(DS->getSingleDecl());
+
+ return dyn_cast<ArrayInitLoopExpr>(Var->getInit());
+ }
+
static bool classof(const ConstructionContext *CC) {
return CC->getKind() >= VARIABLE_BEGIN &&
CC->getKind() <= VARIABLE_END;
@@ -380,6 +399,10 @@ protected:
public:
const CXXCtorInitializer *getCXXCtorInitializer() const { return I; }
+ const ArrayInitLoopExpr *getArrayInitLoop() const override {
+ return dyn_cast<ArrayInitLoopExpr>(I->getInit());
+ }
+
static bool classof(const ConstructionContext *CC) {
return CC->getKind() >= INITIALIZER_BEGIN &&
CC->getKind() <= INITIALIZER_END;
@@ -519,7 +542,7 @@ public:
/// of being immediately copied by an elidable copy/move constructor.
/// For example, T t = T(123); includes a temporary T(123) that is immediately
/// copied to variable t. In such cases the elidable copy can (but not
-/// necessarily should) be omitted ("elided") accodring to the rules of the
+/// necessarily should) be omitted ("elided") according to the rules of the
/// language; the constructor would then construct variable t directly.
/// This construction context contains information of the elidable constructor
/// and its respective construction context.
@@ -658,6 +681,42 @@ public:
}
};
+class LambdaCaptureConstructionContext : public ConstructionContext {
+ // The lambda of which the initializer we capture.
+ const LambdaExpr *LE;
+
+ // Index of the captured element in the captured list.
+ unsigned Index;
+
+ friend class ConstructionContext; // Allows to create<>() itself.
+
+ explicit LambdaCaptureConstructionContext(const LambdaExpr *LE,
+ unsigned Index)
+ : ConstructionContext(LambdaCaptureKind), LE(LE), Index(Index) {}
+
+public:
+ const LambdaExpr *getLambdaExpr() const { return LE; }
+ unsigned getIndex() const { return Index; }
+
+ const Expr *getInitializer() const {
+ return *(LE->capture_init_begin() + Index);
+ }
+
+ const FieldDecl *getFieldDecl() const {
+ auto It = LE->getLambdaClass()->field_begin();
+ std::advance(It, Index);
+ return *It;
+ }
+
+ const ArrayInitLoopExpr *getArrayInitLoop() const override {
+ return dyn_cast_or_null<ArrayInitLoopExpr>(getInitializer());
+ }
+
+ static bool classof(const ConstructionContext *CC) {
+ return CC->getKind() == LambdaCaptureKind;
+ }
+};
+
} // end namespace clang
#endif // LLVM_CLANG_ANALYSIS_CONSTRUCTIONCONTEXT_H
diff --git a/contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/Arena.h b/contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/Arena.h
new file mode 100644
index 000000000000..394ce054e65f
--- /dev/null
+++ b/contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/Arena.h
@@ -0,0 +1,152 @@
+//===-- Arena.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
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_CLANG_ANALYSIS_FLOWSENSITIVE__ARENA_H
+#define LLVM_CLANG_ANALYSIS_FLOWSENSITIVE__ARENA_H
+
+#include "clang/Analysis/FlowSensitive/Formula.h"
+#include "clang/Analysis/FlowSensitive/StorageLocation.h"
+#include "clang/Analysis/FlowSensitive/Value.h"
+#include "llvm/ADT/StringRef.h"
+#include <vector>
+
+namespace clang::dataflow {
+
+/// The Arena owns the objects that model data within an analysis.
+/// For example, `Value`, `StorageLocation`, `Atom`, and `Formula`.
+class Arena {
+public:
+ Arena()
+ : True(Formula::create(Alloc, Formula::Literal, {}, 1)),
+ False(Formula::create(Alloc, Formula::Literal, {}, 0)) {}
+ Arena(const Arena &) = delete;
+ Arena &operator=(const Arena &) = delete;
+
+ /// Creates a `T` (some subclass of `StorageLocation`), forwarding `args` to
+ /// the constructor, and returns a reference to it.
+ ///
+ /// The `Arena` takes ownership of the created object. The object will be
+ /// destroyed when the `Arena` is destroyed.
+ template <typename T, typename... Args>
+ std::enable_if_t<std::is_base_of<StorageLocation, T>::value, T &>
+ create(Args &&...args) {
+ // Note: If allocation of individual `StorageLocation`s turns out to be
+ // costly, consider creating specializations of `create<T>` for commonly
+ // used `StorageLocation` subclasses and make them use a `BumpPtrAllocator`.
+ return *cast<T>(
+ Locs.emplace_back(std::make_unique<T>(std::forward<Args>(args)...))
+ .get());
+ }
+
+ /// Creates a `T` (some subclass of `Value`), forwarding `args` to the
+ /// constructor, and returns a reference to it.
+ ///
+ /// The `Arena` takes ownership of the created object. The object will be
+ /// destroyed when the `Arena` is destroyed.
+ template <typename T, typename... Args>
+ std::enable_if_t<std::is_base_of<Value, T>::value, T &>
+ create(Args &&...args) {
+ // Note: If allocation of individual `Value`s turns out to be costly,
+ // consider creating specializations of `create<T>` for commonly used
+ // `Value` subclasses and make them use a `BumpPtrAllocator`.
+ return *cast<T>(
+ Vals.emplace_back(std::make_unique<T>(std::forward<Args>(args)...))
+ .get());
+ }
+
+ /// Creates a BoolValue wrapping a particular formula.
+ ///
+ /// Passing in the same formula will result in the same BoolValue.
+ /// FIXME: Interning BoolValues but not other Values is inconsistent.
+ /// Decide whether we want Value interning or not.
+ BoolValue &makeBoolValue(const Formula &);
+
+ /// Creates a fresh atom and wraps in in an AtomicBoolValue.
+ /// FIXME: For now, identical-address AtomicBoolValue <=> identical atom.
+ /// Stop relying on pointer identity and remove this guarantee.
+ AtomicBoolValue &makeAtomValue() {
+ return cast<AtomicBoolValue>(makeBoolValue(makeAtomRef(makeAtom())));
+ }
+
+ /// Creates a fresh Top boolean value.
+ TopBoolValue &makeTopValue() {
+ // No need for deduplicating: there's no way to create aliasing Tops.
+ return create<TopBoolValue>(makeAtomRef(makeAtom()));
+ }
+
+ /// Returns a symbolic integer value that models an integer literal equal to
+ /// `Value`. These literals are the same every time.
+ /// Integer literals are not typed; the type is determined by the `Expr` that
+ /// an integer literal is associated with.
+ IntegerValue &makeIntLiteral(llvm::APInt Value);
+
+ // Factories for boolean formulas.
+ // Formulas are interned: passing the same arguments return the same result.
+ // For commutative operations like And/Or, interning ignores order.
+ // Simplifications are applied: makeOr(X, X) => X, etc.
+
+ /// Returns a formula for the conjunction of `LHS` and `RHS`.
+ const Formula &makeAnd(const Formula &LHS, const Formula &RHS);
+
+ /// Returns a formula for the disjunction of `LHS` and `RHS`.
+ const Formula &makeOr(const Formula &LHS, const Formula &RHS);
+
+ /// Returns a formula for the negation of `Val`.
+ const Formula &makeNot(const Formula &Val);
+
+ /// Returns a formula for `LHS => RHS`.
+ const Formula &makeImplies(const Formula &LHS, const Formula &RHS);
+
+ /// Returns a formula for `LHS <=> RHS`.
+ const Formula &makeEquals(const Formula &LHS, const Formula &RHS);
+
+ /// Returns a formula for the variable A.
+ const Formula &makeAtomRef(Atom A);
+
+ /// Returns a formula for a literal true/false.
+ const Formula &makeLiteral(bool Value) { return Value ? True : False; }
+
+ // Parses a formula from its textual representation.
+ // This may refer to atoms that were not produced by makeAtom() yet!
+ llvm::Expected<const Formula &> parseFormula(llvm::StringRef);
+
+ /// Returns a new atomic boolean variable, distinct from any other.
+ Atom makeAtom() { return static_cast<Atom>(NextAtom++); };
+
+ /// Creates a fresh flow condition and returns a token that identifies it. The
+ /// token can be used to perform various operations on the flow condition such
+ /// as adding constraints to it, forking it, joining it with another flow
+ /// condition, or checking implications.
+ Atom makeFlowConditionToken() { return makeAtom(); }
+
+private:
+ llvm::BumpPtrAllocator Alloc;
+
+ // Storage for the state of a program.
+ std::vector<std::unique_ptr<StorageLocation>> Locs;
+ std::vector<std::unique_ptr<Value>> Vals;
+
+ // Indices that are used to avoid recreating the same integer literals and
+ // composite boolean values.
+ llvm::DenseMap<llvm::APInt, IntegerValue *> IntegerLiterals;
+ using FormulaPair = std::pair<const Formula *, const Formula *>;
+ llvm::DenseMap<FormulaPair, const Formula *> Ands;
+ llvm::DenseMap<FormulaPair, const Formula *> Ors;
+ llvm::DenseMap<const Formula *, const Formula *> Nots;
+ llvm::DenseMap<FormulaPair, const Formula *> Implies;
+ llvm::DenseMap<FormulaPair, const Formula *> Equals;
+ llvm::DenseMap<Atom, const Formula *> AtomRefs;
+
+ llvm::DenseMap<const Formula *, BoolValue *> FormulaValues;
+ unsigned NextAtom = 0;
+
+ const Formula &True, &False;
+};
+
+} // namespace clang::dataflow
+
+#endif // LLVM_CLANG_ANALYSIS_FLOWSENSITIVE__ARENA_H
diff --git a/contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/CFGMatchSwitch.h b/contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/CFGMatchSwitch.h
new file mode 100644
index 000000000000..ecd8558970f9
--- /dev/null
+++ b/contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/CFGMatchSwitch.h
@@ -0,0 +1,98 @@
+//===---- CFGMatchSwitch.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 the `CFGMatchSwitch` abstraction for building a "switch"
+// statement for control flow graph elements. Each case of the switch is
+// defined by an ASTMatcher which is applied on the AST node contained in the
+// input `CFGElement`.
+//
+// Currently, the `CFGMatchSwitch` only handles `CFGElement`s of
+// `Kind::Statement` and `Kind::Initializer`.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_CFGMATCHSWITCH_H_
+#define LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_CFGMATCHSWITCH_H_
+
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/Stmt.h"
+#include "clang/Analysis/CFG.h"
+#include "clang/Analysis/FlowSensitive/MatchSwitch.h"
+#include <functional>
+#include <utility>
+
+namespace clang {
+namespace dataflow {
+
+template <typename State, typename Result = void>
+using CFGMatchSwitch =
+ std::function<Result(const CFGElement &, ASTContext &, State &)>;
+
+/// Collects cases of a "match switch": a collection of matchers paired with
+/// callbacks, which together define a switch that can be applied to an AST node
+/// contained in a CFG element.
+template <typename State, typename Result = void> class CFGMatchSwitchBuilder {
+public:
+ /// Registers an action `A` for `CFGStmt`s that will be triggered by the match
+ /// of the pattern `M` against the `Stmt` contained in the input `CFGStmt`.
+ ///
+ /// Requirements:
+ ///
+ /// `NodeT` should be derived from `Stmt`.
+ template <typename NodeT>
+ CFGMatchSwitchBuilder &&
+ CaseOfCFGStmt(MatchSwitchMatcher<Stmt> M,
+ MatchSwitchAction<NodeT, State, Result> A) && {
+ std::move(StmtBuilder).template CaseOf<NodeT>(M, A);
+ return std::move(*this);
+ }
+
+ /// Registers an action `A` for `CFGInitializer`s that will be triggered by
+ /// the match of the pattern `M` against the `CXXCtorInitializer` contained in
+ /// the input `CFGInitializer`.
+ ///
+ /// Requirements:
+ ///
+ /// `NodeT` should be derived from `CXXCtorInitializer`.
+ template <typename NodeT>
+ CFGMatchSwitchBuilder &&
+ CaseOfCFGInit(MatchSwitchMatcher<CXXCtorInitializer> M,
+ MatchSwitchAction<NodeT, State, Result> A) && {
+ std::move(InitBuilder).template CaseOf<NodeT>(M, A);
+ return std::move(*this);
+ }
+
+ CFGMatchSwitch<State, Result> Build() && {
+ return [StmtMS = std::move(StmtBuilder).Build(),
+ InitMS = std::move(InitBuilder).Build()](const CFGElement &Element,
+ ASTContext &Context,
+ State &S) -> Result {
+ switch (Element.getKind()) {
+ case CFGElement::Initializer:
+ return InitMS(*Element.castAs<CFGInitializer>().getInitializer(),
+ Context, S);
+ case CFGElement::Statement:
+ case CFGElement::Constructor:
+ case CFGElement::CXXRecordTypedCall:
+ return StmtMS(*Element.castAs<CFGStmt>().getStmt(), Context, S);
+ default:
+ // FIXME: Handle other kinds of CFGElement.
+ return Result();
+ }
+ };
+ }
+
+private:
+ ASTMatchSwitchBuilder<Stmt, State, Result> StmtBuilder;
+ ASTMatchSwitchBuilder<CXXCtorInitializer, State, Result> InitBuilder;
+};
+
+} // namespace dataflow
+} // namespace clang
+
+#endif // LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_CFGMATCHSWITCH_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..405e93287a05
--- /dev/null
+++ b/contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/ControlFlowContext.h
@@ -0,0 +1,79 @@
+//===-- 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/BitVector.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 a `FunctionDecl`.
+ /// `Func.doesThisDeclarationHaveABody()` must be true, and
+ /// `Func.isTemplated()` must be false.
+ static llvm::Expected<ControlFlowContext> build(const FunctionDecl &Func);
+
+ /// Builds a ControlFlowContext from an AST node. `D` is the function in which
+ /// `S` resides. `D.isTemplated()` must be false.
+ static llvm::Expected<ControlFlowContext> build(const Decl &D, Stmt &S,
+ ASTContext &C);
+
+ /// Returns the `Decl` containing the statement used to construct the CFG, if
+ /// available.
+ const Decl &getDecl() const { return ContainingDecl; }
+
+ /// 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;
+ }
+
+ /// Returns whether `B` is reachable from the entry block.
+ bool isBlockReachable(const CFGBlock &B) const {
+ return BlockReachable[B.getBlockID()];
+ }
+
+private:
+ ControlFlowContext(const Decl &D, std::unique_ptr<CFG> Cfg,
+ llvm::DenseMap<const Stmt *, const CFGBlock *> StmtToBlock,
+ llvm::BitVector BlockReachable)
+ : ContainingDecl(D), Cfg(std::move(Cfg)),
+ StmtToBlock(std::move(StmtToBlock)),
+ BlockReachable(std::move(BlockReachable)) {}
+
+ /// The `Decl` containing the statement used to construct the CFG.
+ const Decl &ContainingDecl;
+ std::unique_ptr<CFG> Cfg;
+ llvm::DenseMap<const Stmt *, const CFGBlock *> StmtToBlock;
+ llvm::BitVector BlockReachable;
+};
+
+} // 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
new file mode 100644
index 000000000000..b95095d2184c
--- /dev/null
+++ b/contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/DataflowAnalysis.h
@@ -0,0 +1,332 @@
+//===- DataflowAnalysis.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 base types and functions for building dataflow analyses
+// that run over Control-Flow Graphs (CFGs).
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_DATAFLOWANALYSIS_H
+#define LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_DATAFLOWANALYSIS_H
+
+#include <iterator>
+#include <optional>
+#include <type_traits>
+#include <utility>
+#include <vector>
+
+#include "clang/AST/ASTContext.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 "clang/Analysis/FlowSensitive/MatchSwitch.h"
+#include "clang/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.h"
+#include "clang/Analysis/FlowSensitive/WatchedLiteralsSolver.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/STLFunctionalExtras.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/Support/Errc.h"
+#include "llvm/Support/Error.h"
+
+namespace clang {
+namespace dataflow {
+
+/// Base class template for dataflow analyses built on a single lattice type.
+///
+/// Requirements:
+///
+/// `Derived` must be derived from a specialization of this class template and
+/// must provide the following public members:
+/// * `LatticeT initialElement()` - returns a lattice element that models the
+/// initial state of a basic block;
+/// * `void transfer(const CFGElement &, LatticeT &, Environment &)` - applies
+/// the analysis transfer function for a given CFG element and lattice
+/// element.
+///
+/// `Derived` can optionally provide the following members:
+/// * `void transferBranch(bool Branch, const Stmt *Stmt, TypeErasedLattice &E,
+/// Environment &Env)` - applies the analysis transfer
+/// function for a given edge from a CFG block of a conditional statement.
+///
+/// `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:
+/// * `LatticeJoinEffect join(const LatticeT &)` - joins the object and the
+/// argument by computing their least upper bound, modifies the object if
+/// necessary, and returns an effect indicating whether any changes were
+/// made to it;
+/// FIXME: make it `static LatticeT join(const LatticeT&, const LatticeT&)`
+/// * `bool operator==(const LatticeT &) const` - returns true if and only if
+/// the object is equal to the argument.
+///
+/// `LatticeT` can optionally provide the following members:
+/// * `LatticeJoinEffect widen(const LatticeT &Previous)` - replaces the
+/// lattice element with an approximation that can reach a fixed point more
+/// quickly than iterated application of the transfer function alone. The
+/// previous value is provided to inform the choice of widened value. The
+/// function must also serve as a comparison operation, by indicating whether
+/// the widened value is equivalent to the previous value with the returned
+/// `LatticeJoinEffect`.
+template <typename Derived, typename LatticeT>
+class DataflowAnalysis : public TypeErasedDataflowAnalysis {
+public:
+ /// Bounded join-semilattice that is used in the analysis.
+ using Lattice = LatticeT;
+
+ explicit DataflowAnalysis(ASTContext &Context) : Context(Context) {}
+
+ explicit DataflowAnalysis(ASTContext &Context,
+ DataflowAnalysisOptions Options)
+ : TypeErasedDataflowAnalysis(Options), Context(Context) {}
+
+ ASTContext &getASTContext() final { return Context; }
+
+ TypeErasedLattice typeErasedInitialElement() final {
+ return {static_cast<Derived *>(this)->initialElement()};
+ }
+
+ TypeErasedLattice joinTypeErased(const TypeErasedLattice &E1,
+ const TypeErasedLattice &E2) final {
+ // FIXME: change the signature of join() to avoid copying here.
+ Lattice L1 = llvm::any_cast<const Lattice &>(E1.Value);
+ const Lattice &L2 = llvm::any_cast<const Lattice &>(E2.Value);
+ L1.join(L2);
+ return {std::move(L1)};
+ }
+
+ LatticeJoinEffect widenTypeErased(TypeErasedLattice &Current,
+ const TypeErasedLattice &Previous) final {
+ Lattice &C = llvm::any_cast<Lattice &>(Current.Value);
+ const Lattice &P = llvm::any_cast<const Lattice &>(Previous.Value);
+ return widenInternal(Rank0{}, C, P);
+ }
+
+ bool isEqualTypeErased(const TypeErasedLattice &E1,
+ const TypeErasedLattice &E2) final {
+ const Lattice &L1 = llvm::any_cast<const Lattice &>(E1.Value);
+ const Lattice &L2 = llvm::any_cast<const Lattice &>(E2.Value);
+ return L1 == L2;
+ }
+
+ void transferTypeErased(const CFGElement &Element, TypeErasedLattice &E,
+ Environment &Env) final {
+ Lattice &L = llvm::any_cast<Lattice &>(E.Value);
+ static_cast<Derived *>(this)->transfer(Element, L, Env);
+ }
+
+ void transferBranchTypeErased(bool Branch, const Stmt *Stmt,
+ TypeErasedLattice &E, Environment &Env) final {
+ transferBranchInternal(Rank0{}, *static_cast<Derived *>(this), Branch, Stmt,
+ E, Env);
+ }
+
+private:
+ // These `Rank` structs are used for template metaprogramming to choose
+ // between overloads.
+ struct Rank1 {};
+ struct Rank0 : Rank1 {};
+
+ // The first-choice implementation: use `widen` when it is available.
+ template <typename T>
+ static auto widenInternal(Rank0, T &Current, const T &Prev)
+ -> decltype(Current.widen(Prev)) {
+ return Current.widen(Prev);
+ }
+
+ // The second-choice implementation: `widen` is unavailable. Widening is
+ // merged with equality checking, so when widening is unimplemented, we
+ // default to equality checking.
+ static LatticeJoinEffect widenInternal(Rank1, const Lattice &Current,
+ const Lattice &Prev) {
+ return Prev == Current ? LatticeJoinEffect::Unchanged
+ : LatticeJoinEffect::Changed;
+ }
+
+ // The first-choice implementation: `transferBranch` is implemented.
+ template <typename Analysis>
+ static auto transferBranchInternal(Rank0, Analysis &A, bool Branch,
+ const Stmt *Stmt, TypeErasedLattice &L,
+ Environment &Env)
+ -> std::void_t<decltype(A.transferBranch(
+ Branch, Stmt, std::declval<LatticeT &>(), Env))> {
+ A.transferBranch(Branch, Stmt, llvm::any_cast<Lattice &>(L.Value), Env);
+ }
+
+ // The second-choice implementation: `transferBranch` is unimplemented. No-op.
+ template <typename Analysis>
+ static void transferBranchInternal(Rank1, Analysis &A, bool, const Stmt *,
+ TypeErasedLattice &, Environment &) {}
+
+ ASTContext &Context;
+};
+
+// Model of the program at a given program point.
+template <typename LatticeT> struct DataflowAnalysisState {
+ // Model of a program property.
+ LatticeT Lattice;
+
+ // Model of the state of the program (store and heap).
+ Environment Env;
+};
+
+/// Performs dataflow analysis and returns a mapping from basic block IDs to
+/// dataflow analysis states that model the respective basic blocks. The
+/// returned vector, if any, will have the same size as the number of CFG
+/// blocks, with indices corresponding to basic block IDs. Returns an error if
+/// the dataflow analysis cannot be performed successfully. Otherwise, calls
+/// `PostVisitCFG` on each CFG element with the final analysis results at that
+/// program point.
+///
+/// `MaxBlockVisits` caps the number of block visits during analysis. See
+/// `runTypeErasedDataflowAnalysis` for a full description. The default value is
+/// essentially arbitrary -- large enough to accommodate what seems like any
+/// reasonable CFG, but still small enough to limit the cost of hitting the
+/// limit.
+template <typename AnalysisT>
+llvm::Expected<std::vector<
+ std::optional<DataflowAnalysisState<typename AnalysisT::Lattice>>>>
+runDataflowAnalysis(
+ const ControlFlowContext &CFCtx, AnalysisT &Analysis,
+ const Environment &InitEnv,
+ std::function<void(const CFGElement &, const DataflowAnalysisState<
+ typename AnalysisT::Lattice> &)>
+ PostVisitCFG = nullptr,
+ std::int32_t MaxBlockVisits = 20'000) {
+ std::function<void(const CFGElement &,
+ const TypeErasedDataflowAnalysisState &)>
+ PostVisitCFGClosure = nullptr;
+ if (PostVisitCFG) {
+ PostVisitCFGClosure = [&PostVisitCFG](
+ const CFGElement &Element,
+ const TypeErasedDataflowAnalysisState &State) {
+ auto *Lattice =
+ llvm::any_cast<typename AnalysisT::Lattice>(&State.Lattice.Value);
+ // FIXME: we should not be copying the environment here!
+ // Ultimately the PostVisitCFG only gets a const reference anyway.
+ PostVisitCFG(Element, DataflowAnalysisState<typename AnalysisT::Lattice>{
+ *Lattice, State.Env.fork()});
+ };
+ }
+
+ auto TypeErasedBlockStates = runTypeErasedDataflowAnalysis(
+ CFCtx, Analysis, InitEnv, PostVisitCFGClosure, MaxBlockVisits);
+ if (!TypeErasedBlockStates)
+ return TypeErasedBlockStates.takeError();
+
+ std::vector<std::optional<DataflowAnalysisState<typename AnalysisT::Lattice>>>
+ BlockStates;
+ BlockStates.reserve(TypeErasedBlockStates->size());
+
+ llvm::transform(
+ std::move(*TypeErasedBlockStates), std::back_inserter(BlockStates),
+ [](auto &OptState) {
+ return llvm::transformOptional(
+ std::move(OptState), [](TypeErasedDataflowAnalysisState &&State) {
+ return DataflowAnalysisState<typename AnalysisT::Lattice>{
+ llvm::any_cast<typename AnalysisT::Lattice>(
+ std::move(State.Lattice.Value)),
+ std::move(State.Env)};
+ });
+ });
+ return std::move(BlockStates);
+}
+
+// Create an analysis class that is derived from `DataflowAnalysis`. This is an
+// SFINAE adapter that allows us to call two different variants of constructor
+// (either with or without the optional `Environment` parameter).
+// FIXME: Make all classes derived from `DataflowAnalysis` take an `Environment`
+// parameter in their constructor so that we can get rid of this abomination.
+template <typename AnalysisT>
+auto createAnalysis(ASTContext &ASTCtx, Environment &Env)
+ -> decltype(AnalysisT(ASTCtx, Env)) {
+ return AnalysisT(ASTCtx, Env);
+}
+template <typename AnalysisT>
+auto createAnalysis(ASTContext &ASTCtx, Environment &Env)
+ -> decltype(AnalysisT(ASTCtx)) {
+ return AnalysisT(ASTCtx);
+}
+
+/// Runs a dataflow analysis over the given function and then runs `Diagnoser`
+/// over the results. Returns a list of diagnostics for `FuncDecl` or an
+/// error. Currently, errors can occur (at least) because the analysis requires
+/// too many iterations over the CFG or the SAT solver times out.
+///
+/// The default value of `MaxSATIterations` was chosen based on the following
+/// observations:
+/// - Non-pathological calls to the solver typically require only a few hundred
+/// iterations.
+/// - This limit is still low enough to keep runtimes acceptable (on typical
+/// machines) in cases where we hit the limit.
+///
+/// `MaxBlockVisits` caps the number of block visits during analysis. See
+/// `runDataflowAnalysis` for a full description and explanation of the default
+/// value.
+template <typename AnalysisT, typename Diagnostic>
+llvm::Expected<llvm::SmallVector<Diagnostic>> diagnoseFunction(
+ const FunctionDecl &FuncDecl, ASTContext &ASTCtx,
+ llvm::function_ref<llvm::SmallVector<Diagnostic>(
+ const CFGElement &, ASTContext &,
+ const TransferStateForDiagnostics<typename AnalysisT::Lattice> &)>
+ Diagnoser,
+ std::int64_t MaxSATIterations = 1'000'000'000,
+ std::int32_t MaxBlockVisits = 20'000) {
+ llvm::Expected<ControlFlowContext> Context =
+ ControlFlowContext::build(FuncDecl);
+ if (!Context)
+ return Context.takeError();
+
+ auto OwnedSolver = std::make_unique<WatchedLiteralsSolver>(MaxSATIterations);
+ const WatchedLiteralsSolver *Solver = OwnedSolver.get();
+ DataflowAnalysisContext AnalysisContext(std::move(OwnedSolver));
+ Environment Env(AnalysisContext, FuncDecl);
+ AnalysisT Analysis = createAnalysis<AnalysisT>(ASTCtx, Env);
+ llvm::SmallVector<Diagnostic> Diagnostics;
+ if (llvm::Error Err =
+ runTypeErasedDataflowAnalysis(
+ *Context, Analysis, Env,
+ [&ASTCtx, &Diagnoser, &Diagnostics](
+ const CFGElement &Elt,
+ const TypeErasedDataflowAnalysisState &State) mutable {
+ auto EltDiagnostics = Diagnoser(
+ Elt, ASTCtx,
+ TransferStateForDiagnostics<typename AnalysisT::Lattice>(
+ llvm::any_cast<const typename AnalysisT::Lattice &>(
+ State.Lattice.Value),
+ State.Env));
+ llvm::move(EltDiagnostics, std::back_inserter(Diagnostics));
+ },
+ MaxBlockVisits)
+ .takeError())
+ return std::move(Err);
+
+ if (Solver->reachedLimit())
+ return llvm::createStringError(llvm::errc::interrupted,
+ "SAT solver timed out");
+
+ return Diagnostics;
+}
+
+/// Abstract base class for dataflow "models": reusable analysis components that
+/// model a particular aspect of program semantics in the `Environment`. For
+/// example, a model may capture a type and its related functions.
+class DataflowModel : public Environment::ValueModel {
+public:
+ /// Return value indicates whether the model processed the `Element`.
+ virtual bool transfer(const CFGElement &Element, Environment &Env) = 0;
+};
+
+} // namespace dataflow
+} // namespace clang
+
+#endif // LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_DATAFLOWANALYSIS_H
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..20e45cc27b01
--- /dev/null
+++ b/contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/DataflowAnalysisContext.h
@@ -0,0 +1,304 @@
+//===-- 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/AST/TypeOrdering.h"
+#include "clang/Analysis/FlowSensitive/Arena.h"
+#include "clang/Analysis/FlowSensitive/ControlFlowContext.h"
+#include "clang/Analysis/FlowSensitive/Solver.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/ADT/SetVector.h"
+#include "llvm/Support/Compiler.h"
+#include <cassert>
+#include <memory>
+#include <optional>
+#include <type_traits>
+#include <utility>
+#include <vector>
+
+namespace clang {
+namespace dataflow {
+class Logger;
+
+/// Skip past nodes that the CFG does not emit. These nodes are invisible to
+/// flow-sensitive analysis, and should be ignored as they will effectively not
+/// exist.
+///
+/// * `ParenExpr` - The CFG takes the operator precedence into account, but
+/// otherwise omits the node afterwards.
+///
+/// * `ExprWithCleanups` - The CFG will generate the appropriate calls to
+/// destructors and then omit the node.
+///
+const Expr &ignoreCFGOmittedNodes(const Expr &E);
+const Stmt &ignoreCFGOmittedNodes(const Stmt &S);
+
+/// A set of `FieldDecl *`. Use `SmallSetVector` to guarantee deterministic
+/// iteration order.
+using FieldSet = llvm::SmallSetVector<const FieldDecl *, 4>;
+
+/// Returns the set of all fields in the type.
+FieldSet getObjectFields(QualType Type);
+
+/// Returns whether `Fields` and `FieldLocs` contain the same fields.
+bool containsSameFields(const FieldSet &Fields,
+ const RecordStorageLocation::FieldToLoc &FieldLocs);
+
+struct ContextSensitiveOptions {
+ /// The maximum depth to analyze. A value of zero is equivalent to disabling
+ /// context-sensitive analysis entirely.
+ unsigned Depth = 2;
+};
+
+/// Owns objects that encompass the state of a program and stores context that
+/// is used during dataflow analysis.
+class DataflowAnalysisContext {
+public:
+ struct Options {
+ /// Options for analyzing function bodies when present in the translation
+ /// unit, or empty to disable context-sensitive analysis. Note that this is
+ /// fundamentally limited: some constructs, such as recursion, are
+ /// explicitly unsupported.
+ std::optional<ContextSensitiveOptions> ContextSensitiveOpts;
+
+ /// If provided, analysis details will be recorded here.
+ /// (This is always non-null within an AnalysisContext, the framework
+ /// provides a fallback no-op logger).
+ Logger *Log = nullptr;
+ };
+
+ /// Constructs a dataflow analysis context.
+ ///
+ /// Requirements:
+ ///
+ /// `S` must not be null.
+ DataflowAnalysisContext(std::unique_ptr<Solver> S,
+ Options Opts = Options{
+ /*ContextSensitiveOpts=*/std::nullopt,
+ /*Logger=*/nullptr});
+ ~DataflowAnalysisContext();
+
+ /// Sets a callback that returns the names and types of the synthetic fields
+ /// to add to a `RecordStorageLocation` of a given type.
+ /// Typically, this is called from the constructor of a `DataflowAnalysis`
+ ///
+ /// To maintain the invariant that all `RecordStorageLocation`s of a given
+ /// type have the same fields:
+ /// * The callback must always return the same result for a given type
+ /// * `setSyntheticFieldCallback()` must be called before any
+ // `RecordStorageLocation`s are created.
+ void setSyntheticFieldCallback(
+ std::function<llvm::StringMap<QualType>(QualType)> CB) {
+ assert(!RecordStorageLocationCreated);
+ SyntheticFieldCallback = CB;
+ }
+
+ /// Returns a new storage location appropriate for `Type`.
+ ///
+ /// A null `Type` is interpreted as the pointee type of `std::nullptr_t`.
+ StorageLocation &createStorageLocation(QualType Type);
+
+ /// Creates a `RecordStorageLocation` for the given type and with the given
+ /// fields.
+ ///
+ /// Requirements:
+ ///
+ /// `FieldLocs` must contain exactly the fields returned by
+ /// `getModeledFields(Type)`.
+ /// `SyntheticFields` must contain exactly the fields returned by
+ /// `getSyntheticFields(Type)`.
+ RecordStorageLocation &createRecordStorageLocation(
+ QualType Type, RecordStorageLocation::FieldToLoc FieldLocs,
+ RecordStorageLocation::SyntheticFieldMap SyntheticFields);
+
+ /// Returns a stable storage location for `D`.
+ StorageLocation &getStableStorageLocation(const ValueDecl &D);
+
+ /// Returns a stable storage location for `E`.
+ StorageLocation &getStableStorageLocation(const Expr &E);
+
+ /// Returns a pointer value that represents a null pointer. Calls with
+ /// `PointeeType` that are canonically equivalent will return the same result.
+ /// A null `PointeeType` can be used for the pointee of `std::nullptr_t`.
+ PointerValue &getOrCreateNullPointerValue(QualType PointeeType);
+
+ /// Adds `Constraint` to current and future flow conditions in this context.
+ ///
+ /// Invariants must contain only flow-insensitive information, i.e. facts that
+ /// are true on all paths through the program.
+ /// Information can be added eagerly (when analysis begins), or lazily (e.g.
+ /// when values are first used). The analysis must be careful that the same
+ /// information is added regardless of which order blocks are analyzed in.
+ void addInvariant(const Formula &Constraint);
+
+ /// Adds `Constraint` to the flow condition identified by `Token`.
+ void addFlowConditionConstraint(Atom Token, const Formula &Constraint);
+
+ /// Creates a new flow condition with the same constraints as the flow
+ /// condition identified by `Token` and returns its token.
+ Atom forkFlowCondition(Atom Token);
+
+ /// Creates a new flow condition that represents the disjunction of the flow
+ /// conditions identified by `FirstToken` and `SecondToken`, and returns its
+ /// token.
+ Atom joinFlowConditions(Atom FirstToken, Atom SecondToken);
+
+ /// Returns true if the constraints of the flow condition identified by
+ /// `Token` imply that `F` is true.
+ /// Returns false if the flow condition does not imply `F` or if the solver
+ /// times out.
+ bool flowConditionImplies(Atom Token, const Formula &F);
+
+ /// Returns true if the constraints of the flow condition identified by
+ /// `Token` still allow `F` to be true.
+ /// Returns false if the flow condition implies that `F` is false or if the
+ /// solver times out.
+ bool flowConditionAllows(Atom Token, const Formula &F);
+
+ /// Returns true if `Val1` is equivalent to `Val2`.
+ /// Note: This function doesn't take into account constraints on `Val1` and
+ /// `Val2` imposed by the flow condition.
+ bool equivalentFormulas(const Formula &Val1, const Formula &Val2);
+
+ LLVM_DUMP_METHOD void dumpFlowCondition(Atom Token,
+ llvm::raw_ostream &OS = llvm::dbgs());
+
+ /// Returns the `ControlFlowContext` registered for `F`, if any. Otherwise,
+ /// returns null.
+ const ControlFlowContext *getControlFlowContext(const FunctionDecl *F);
+
+ const Options &getOptions() { return Opts; }
+
+ Arena &arena() { return *A; }
+
+ /// Returns the outcome of satisfiability checking on `Constraints`.
+ ///
+ /// Flow conditions are not incorporated, so they may need to be manually
+ /// included in `Constraints` to provide contextually-accurate results, e.g.
+ /// if any definitions or relationships of the values in `Constraints` have
+ /// been stored in flow conditions.
+ Solver::Result querySolver(llvm::SetVector<const Formula *> Constraints);
+
+ /// Returns the fields of `Type`, limited to the set of fields modeled by this
+ /// context.
+ FieldSet getModeledFields(QualType Type);
+
+ /// Returns the names and types of the synthetic fields for the given record
+ /// type.
+ llvm::StringMap<QualType> getSyntheticFields(QualType Type) {
+ assert(Type->isRecordType());
+ if (SyntheticFieldCallback)
+ return SyntheticFieldCallback(Type);
+ return {};
+ }
+
+private:
+ friend class Environment;
+
+ struct NullableQualTypeDenseMapInfo : private llvm::DenseMapInfo<QualType> {
+ static QualType getEmptyKey() {
+ // Allow a NULL `QualType` by using a different value as the empty key.
+ return QualType::getFromOpaquePtr(reinterpret_cast<Type *>(1));
+ }
+
+ using DenseMapInfo::getHashValue;
+ using DenseMapInfo::getTombstoneKey;
+ using DenseMapInfo::isEqual;
+ };
+
+ // Extends the set of modeled field declarations.
+ void addModeledFields(const FieldSet &Fields);
+
+ /// Adds all constraints of the flow condition identified by `Token` and all
+ /// of its transitive dependencies to `Constraints`.
+ void
+ addTransitiveFlowConditionConstraints(Atom Token,
+ llvm::SetVector<const Formula *> &Out);
+
+ /// Returns true if the solver is able to prove that there is a satisfying
+ /// assignment for `Constraints`.
+ bool isSatisfiable(llvm::SetVector<const Formula *> Constraints) {
+ return querySolver(std::move(Constraints)).getStatus() ==
+ Solver::Result::Status::Satisfiable;
+ }
+
+ /// Returns true if the solver is able to prove that there is no satisfying
+ /// assignment for `Constraints`
+ bool isUnsatisfiable(llvm::SetVector<const Formula *> Constraints) {
+ return querySolver(std::move(Constraints)).getStatus() ==
+ Solver::Result::Status::Unsatisfiable;
+ }
+
+ std::unique_ptr<Solver> S;
+ std::unique_ptr<Arena> A;
+
+ // 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;
+
+ // Null pointer values, keyed by the canonical pointee type.
+ //
+ // FIXME: The pointer values are indexed by the pointee types which are
+ // required to initialize the `PointeeLoc` field in `PointerValue`. Consider
+ // creating a type-independent `NullPointerValue` without a `PointeeLoc`
+ // field.
+ llvm::DenseMap<QualType, PointerValue *, NullableQualTypeDenseMapInfo>
+ NullPointerVals;
+
+ Options Opts;
+
+ // Flow conditions are tracked symbolically: each unique flow condition is
+ // associated with a fresh symbolic variable (token), bound to the clause that
+ // defines the flow condition. Conceptually, each binding corresponds to an
+ // "iff" of the form `FC <=> (C1 ^ C2 ^ ...)` where `FC` is a flow condition
+ // token (an atomic boolean) and `Ci`s are the set of constraints in the flow
+ // flow condition clause. The set of constraints (C1 ^ C2 ^ ...) are stored in
+ // the `FlowConditionConstraints` map, keyed by the token of the flow
+ // condition.
+ //
+ // Flow conditions depend on other flow conditions if they are created using
+ // `forkFlowCondition` or `joinFlowConditions`. The graph of flow condition
+ // dependencies is stored in the `FlowConditionDeps` map.
+ llvm::DenseMap<Atom, llvm::DenseSet<Atom>> FlowConditionDeps;
+ llvm::DenseMap<Atom, const Formula *> FlowConditionConstraints;
+ const Formula *Invariant = nullptr;
+
+ llvm::DenseMap<const FunctionDecl *, ControlFlowContext> FunctionContexts;
+
+ // Fields modeled by environments covered by this context.
+ FieldSet ModeledFields;
+
+ std::unique_ptr<Logger> LogOwner; // If created via flags.
+
+ std::function<llvm::StringMap<QualType>(QualType)> SyntheticFieldCallback;
+
+ /// Has any `RecordStorageLocation` been created yet?
+ bool RecordStorageLocationCreated = false;
+};
+
+} // 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
new file mode 100644
index 000000000000..1543f900e401
--- /dev/null
+++ b/contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h
@@ -0,0 +1,739 @@
+//===-- DataflowEnvironment.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 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.
+//
+//===----------------------------------------------------------------------===//
+
+#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/Analysis/FlowSensitive/ControlFlowContext.h"
+#include "clang/Analysis/FlowSensitive/DataflowAnalysisContext.h"
+#include "clang/Analysis/FlowSensitive/DataflowLattice.h"
+#include "clang/Analysis/FlowSensitive/Formula.h"
+#include "clang/Analysis/FlowSensitive/Logger.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/ADT/MapVector.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/ErrorHandling.h"
+#include <memory>
+#include <type_traits>
+#include <utility>
+
+namespace clang {
+namespace dataflow {
+
+/// Indicates the result of a tentative comparison.
+enum class ComparisonResult {
+ Same,
+ Different,
+ Unknown,
+};
+
+/// Holds the state of the program (store and heap) at a given program point.
+///
+/// WARNING: Symbolic values that are created by the environment for static
+/// local and global variables are not currently invalidated on function calls.
+/// This is unsound and should be taken into account when designing dataflow
+/// analyses.
+class Environment {
+public:
+ /// Supplements `Environment` with non-standard comparison and join
+ /// operations.
+ class ValueModel {
+ public:
+ virtual ~ValueModel() = default;
+
+ /// Returns:
+ /// `Same`: `Val1` is equivalent to `Val2`, according to the model.
+ /// `Different`: `Val1` is distinct from `Val2`, according to the model.
+ /// `Unknown`: The model can't determine a relationship between `Val1` and
+ /// `Val2`.
+ ///
+ /// Requirements:
+ ///
+ /// `Val1` and `Val2` must be distinct.
+ ///
+ /// `Val1` and `Val2` must model values of type `Type`.
+ ///
+ /// `Val1` and `Val2` must be assigned to the same storage location in
+ /// `Env1` and `Env2` respectively.
+ virtual ComparisonResult compare(QualType Type, const Value &Val1,
+ const Environment &Env1, const Value &Val2,
+ const Environment &Env2) {
+ // FIXME: Consider adding QualType to RecordValue and removing the Type
+ // argument here.
+ return ComparisonResult::Unknown;
+ }
+
+ /// 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 `MergedEnv`.
+ ///
+ /// `Env1` and `Env2` can be used to query child values and path condition
+ /// implications of `Val1` and `Val2` respectively.
+ ///
+ /// Requirements:
+ ///
+ /// `Val1` and `Val2` must be distinct.
+ ///
+ /// `Val1`, `Val2`, and `MergedVal` must model values of type `Type`.
+ ///
+ /// `Val1` and `Val2` must be assigned to the same storage location in
+ /// `Env1` and `Env2` respectively.
+ virtual bool merge(QualType Type, const Value &Val1,
+ const Environment &Env1, const Value &Val2,
+ const Environment &Env2, Value &MergedVal,
+ Environment &MergedEnv) {
+ return true;
+ }
+
+ /// This function may widen the current value -- replace it with an
+ /// approximation that can reach a fixed point more quickly than iterated
+ /// application of the transfer function alone. The previous value is
+ /// provided to inform the choice of widened value. The function must also
+ /// serve as a comparison operation, by indicating whether the widened value
+ /// is equivalent to the previous value.
+ ///
+ /// Returns either:
+ ///
+ /// `nullptr`, if this value is not of interest to the model, or
+ ///
+ /// `&Prev`, if the widened value is equivalent to `Prev`, or
+ ///
+ /// A non-null value that approximates `Current`. `Prev` is available to
+ /// inform the chosen approximation.
+ ///
+ /// `PrevEnv` and `CurrentEnv` can be used to query child values and path
+ /// condition implications of `Prev` and `Current`, respectively.
+ ///
+ /// Requirements:
+ ///
+ /// `Prev` and `Current` must model values of type `Type`.
+ ///
+ /// `Prev` and `Current` must be assigned to the same storage location in
+ /// `PrevEnv` and `CurrentEnv`, respectively.
+ virtual Value *widen(QualType Type, Value &Prev, const Environment &PrevEnv,
+ Value &Current, Environment &CurrentEnv) {
+ // The default implementation reduces to just comparison, since comparison
+ // is required by the API, even if no widening is performed.
+ switch (compare(Type, Prev, PrevEnv, Current, CurrentEnv)) {
+ case ComparisonResult::Same:
+ return &Prev;
+ case ComparisonResult::Different:
+ return &Current;
+ case ComparisonResult::Unknown:
+ return nullptr;
+ }
+ llvm_unreachable("all cases in switch covered");
+ }
+ };
+
+ /// Creates an environment that uses `DACtx` to store objects that encompass
+ /// the state of a program.
+ explicit Environment(DataflowAnalysisContext &DACtx);
+
+ // Copy-constructor is private, Environments should not be copied. See fork().
+ Environment &operator=(const Environment &Other) = delete;
+
+ Environment(Environment &&Other) = default;
+ Environment &operator=(Environment &&Other) = default;
+
+ /// 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);
+
+ /// Assigns storage locations and values to all parameters, captures, global
+ /// variables, fields and functions referenced in the function currently being
+ /// analyzed.
+ ///
+ /// Requirements:
+ ///
+ /// The function must have a body, i.e.
+ /// `FunctionDecl::doesThisDecalarationHaveABody()` must be true.
+ void initialize();
+
+ /// Returns a new environment that is a copy of this one.
+ ///
+ /// The state of the program is initially the same, but can be mutated without
+ /// affecting the original.
+ ///
+ /// However the original should not be further mutated, as this may interfere
+ /// with the fork. (In practice, values are stored independently, but the
+ /// forked flow condition references the original).
+ Environment fork() const;
+
+ /// Creates and returns an environment to use for an inline analysis of the
+ /// callee. Uses the storage location from each argument in the `Call` as the
+ /// storage location for the corresponding parameter in the callee.
+ ///
+ /// Requirements:
+ ///
+ /// The callee of `Call` must be a `FunctionDecl`.
+ ///
+ /// The body of the callee must not reference globals.
+ ///
+ /// The arguments of `Call` must map 1:1 to the callee's parameters.
+ Environment pushCall(const CallExpr *Call) const;
+ Environment pushCall(const CXXConstructExpr *Call) const;
+
+ /// Moves gathered information back into `this` from a `CalleeEnv` created via
+ /// `pushCall`.
+ void popCall(const CallExpr *Call, const Environment &CalleeEnv);
+ void popCall(const CXXConstructExpr *Call, const Environment &CalleeEnv);
+
+ /// Returns true if and only if the environment is equivalent to `Other`, i.e
+ /// the two environments:
+ /// - have the same mappings from declarations to storage locations,
+ /// - have the same mappings from expressions to storage locations,
+ /// - have the same or equivalent (according to `Model`) values assigned to
+ /// the same storage locations.
+ ///
+ /// Requirements:
+ ///
+ /// `Other` and `this` must use the same `DataflowAnalysisContext`.
+ bool equivalentTo(const Environment &Other,
+ Environment::ValueModel &Model) const;
+
+ /// Joins two environments by taking the intersection of storage locations and
+ /// values that are stored in them. Distinct values that are assigned to the
+ /// same storage locations in `EnvA` and `EnvB` are merged using `Model`.
+ ///
+ /// Requirements:
+ ///
+ /// `EnvA` and `EnvB` must use the same `DataflowAnalysisContext`.
+ static Environment join(const Environment &EnvA, const Environment &EnvB,
+ Environment::ValueModel &Model);
+
+ /// Widens the environment point-wise, using `PrevEnv` as needed to inform the
+ /// approximation.
+ ///
+ /// Requirements:
+ ///
+ /// `PrevEnv` must be the immediate previous version of the environment.
+ /// `PrevEnv` and `this` must use the same `DataflowAnalysisContext`.
+ LatticeJoinEffect widen(const Environment &PrevEnv,
+ Environment::ValueModel &Model);
+
+ // 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 ValueDecl &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 already have a storage location in the environment.
+ void setStorageLocation(const ValueDecl &D, StorageLocation &Loc);
+
+ /// Returns the storage location assigned to `D` in the environment, or null
+ /// if `D` isn't assigned a storage location in the environment.
+ StorageLocation *getStorageLocation(const ValueDecl &D) const;
+
+ /// Removes the location assigned to `D` in the environment (if any).
+ void removeDecl(const ValueDecl &D);
+
+ /// Assigns `Loc` as the storage location of the glvalue `E` in the
+ /// environment.
+ ///
+ /// Requirements:
+ ///
+ /// `E` must not be assigned a storage location in the environment.
+ /// `E` must be a glvalue or a `BuiltinType::BuiltinFn`
+ void setStorageLocation(const Expr &E, StorageLocation &Loc);
+
+ /// Returns the storage location assigned to the glvalue `E` in the
+ /// environment, or null if `E` isn't assigned a storage location in the
+ /// environment.
+ ///
+ /// Requirements:
+ /// `E` must be a glvalue or a `BuiltinType::BuiltinFn`
+ StorageLocation *getStorageLocation(const Expr &E) const;
+
+ /// Returns the result of casting `getStorageLocation(...)` to a subclass of
+ /// `StorageLocation` (using `cast_or_null<T>`).
+ /// This assert-fails if the result of `getStorageLocation(...)` is not of
+ /// type `T *`; if the storage location is not guaranteed to have type `T *`,
+ /// consider using `dyn_cast_or_null<T>(getStorageLocation(...))` instead.
+ template <typename T>
+ std::enable_if_t<std::is_base_of_v<StorageLocation, T>, T *>
+ get(const ValueDecl &D) const {
+ return cast_or_null<T>(getStorageLocation(D));
+ }
+ template <typename T>
+ std::enable_if_t<std::is_base_of_v<StorageLocation, T>, T *>
+ get(const Expr &E) const {
+ return cast_or_null<T>(getStorageLocation(E));
+ }
+
+ /// 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.
+ RecordStorageLocation *getThisPointeeStorageLocation() const {
+ return ThisPointeeLoc;
+ }
+
+ /// Sets the storage location assigned to the `this` pointee in the
+ /// environment.
+ void setThisPointeeStorageLocation(RecordStorageLocation &Loc) {
+ ThisPointeeLoc = &Loc;
+ }
+
+ /// Returns the location of the result object for a record-type prvalue.
+ ///
+ /// In C++, prvalues of record type serve only a limited purpose: They can
+ /// only be used to initialize a result object (e.g. a variable or a
+ /// temporary). This function returns the location of that result object.
+ ///
+ /// When creating a prvalue of record type, we already need the storage
+ /// location of the result object to pass in `this`, even though prvalues are
+ /// otherwise not associated with storage locations.
+ ///
+ /// FIXME: Currently, this simply returns a stable storage location for `E`,
+ /// but this doesn't do the right thing in scenarios like the following:
+ /// ```
+ /// MyClass c = some_condition()? MyClass(foo) : MyClass(bar);
+ /// ```
+ /// Here, `MyClass(foo)` and `MyClass(bar)` will have two different storage
+ /// locations, when in fact their storage locations should be the same.
+ /// Eventually, we want to propagate storage locations from result objects
+ /// down to the prvalues that initialize them, similar to the way that this is
+ /// done in Clang's CodeGen.
+ ///
+ /// Requirements:
+ /// `E` must be a prvalue of record type.
+ RecordStorageLocation &
+ getResultObjectLocation(const Expr &RecordPRValue) const;
+
+ /// Returns the return value of the current function. This can be null if:
+ /// - The function has a void return type
+ /// - No return value could be determined for the function, for example
+ /// because it calls a function without a body.
+ ///
+ /// Requirements:
+ /// The current function must have a non-reference return type.
+ Value *getReturnValue() const {
+ assert(getCurrentFunc() != nullptr &&
+ !getCurrentFunc()->getReturnType()->isReferenceType());
+ return ReturnVal;
+ }
+
+ /// Returns the storage location for the reference returned by the current
+ /// function. This can be null if function doesn't return a single consistent
+ /// reference.
+ ///
+ /// Requirements:
+ /// The current function must have a reference return type.
+ StorageLocation *getReturnStorageLocation() const {
+ assert(getCurrentFunc() != nullptr &&
+ getCurrentFunc()->getReturnType()->isReferenceType());
+ return ReturnLoc;
+ }
+
+ /// Sets the return value of the current function.
+ ///
+ /// Requirements:
+ /// The current function must have a non-reference return type.
+ void setReturnValue(Value *Val) {
+ assert(getCurrentFunc() != nullptr &&
+ !getCurrentFunc()->getReturnType()->isReferenceType());
+ ReturnVal = Val;
+ }
+
+ /// Sets the storage location for the reference returned by the current
+ /// function.
+ ///
+ /// Requirements:
+ /// The current function must have a reference return type.
+ void setReturnStorageLocation(StorageLocation *Loc) {
+ assert(getCurrentFunc() != nullptr &&
+ getCurrentFunc()->getReturnType()->isReferenceType());
+ ReturnLoc = Loc;
+ }
+
+ /// Returns a pointer value that represents a null pointer. Calls with
+ /// `PointeeType` that are canonically equivalent will return the same result.
+ PointerValue &getOrCreateNullPointerValue(QualType PointeeType);
+
+ /// Creates a value appropriate for `Type`, if `Type` is supported, otherwise
+ /// returns 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.
+ ///
+ /// If `Type` is a class, struct, or union type, creates values for all
+ /// modeled fields (including synthetic fields) and calls `setValue()` to
+ /// associate the `RecordValue` with its storage location
+ /// (`RecordValue::getLoc()`).
+ ///
+ /// If `Type` is one of the following types, this function will always return
+ /// a non-null pointer:
+ /// - `bool`
+ /// - Any integer type
+ /// - Any class, struct, or union type
+ ///
+ /// Requirements:
+ ///
+ /// `Type` must not be null.
+ Value *createValue(QualType Type);
+
+ /// Creates an object (i.e. a storage location with an associated value) of
+ /// type `Ty`. If `InitExpr` is non-null and has a value associated with it,
+ /// initializes the object with this value. Otherwise, initializes the object
+ /// with a value created using `createValue()`.
+ StorageLocation &createObject(QualType Ty, const Expr *InitExpr = nullptr) {
+ return createObjectInternal(nullptr, Ty, InitExpr);
+ }
+
+ /// Creates an object for the variable declaration `D`. If `D` has an
+ /// initializer and this initializer is associated with a value, initializes
+ /// the object with this value. Otherwise, initializes the object with a
+ /// value created using `createValue()`. Uses the storage location returned by
+ /// `DataflowAnalysisContext::getStableStorageLocation(D)`.
+ StorageLocation &createObject(const VarDecl &D) {
+ return createObjectInternal(&D, D.getType(), D.getInit());
+ }
+
+ /// Creates an object for the variable declaration `D`. If `InitExpr` is
+ /// non-null and has a value associated with it, initializes the object with
+ /// this value. Otherwise, initializes the object with a value created using
+ /// `createValue()`. Uses the storage location returned by
+ /// `DataflowAnalysisContext::getStableStorageLocation(D)`.
+ StorageLocation &createObject(const ValueDecl &D, const Expr *InitExpr) {
+ return createObjectInternal(&D, D.getType(), InitExpr);
+ }
+
+ /// Assigns `Val` as the value of `Loc` in the environment.
+ void setValue(const StorageLocation &Loc, Value &Val);
+
+ /// Clears any association between `Loc` and a value in the environment.
+ void clearValue(const StorageLocation &Loc) { LocToVal.erase(&Loc); }
+
+ /// Assigns `Val` as the value of the prvalue `E` in the environment.
+ ///
+ /// Requirements:
+ ///
+ /// - `E` must be a prvalue
+ /// - If `Val` is a `RecordValue`, its `RecordStorageLocation` must be
+ /// `getResultObjectLocation(E)`. An exception to this is if `E` is an
+ /// expression that originally creates a `RecordValue` (such as a
+ /// `CXXConstructExpr` or `CallExpr`), as these establish the location of
+ /// the result object in the first place.
+ void setValue(const Expr &E, 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))` if `D` is assigned a
+ /// storage location in the environment, otherwise returns null.
+ Value *getValue(const ValueDecl &D) const;
+
+ /// Equivalent to `getValue(getStorageLocation(E, SP))` if `E` is assigned a
+ /// storage location in the environment, otherwise returns null.
+ Value *getValue(const Expr &E) const;
+
+ /// Returns the result of casting `getValue(...)` to a subclass of `Value`
+ /// (using `cast_or_null<T>`).
+ /// This assert-fails if the result of `getValue(...)` is not of type `T *`;
+ /// if the value is not guaranteed to have type `T *`, consider using
+ /// `dyn_cast_or_null<T>(getValue(...))` instead.
+ template <typename T>
+ std::enable_if_t<std::is_base_of_v<Value, T>, T *>
+ get(const StorageLocation &Loc) const {
+ return cast_or_null<T>(getValue(Loc));
+ }
+ template <typename T>
+ std::enable_if_t<std::is_base_of_v<Value, T>, T *>
+ get(const ValueDecl &D) const {
+ return cast_or_null<T>(getValue(D));
+ }
+ template <typename T>
+ std::enable_if_t<std::is_base_of_v<Value, T>, T *> get(const Expr &E) const {
+ return cast_or_null<T>(getValue(E));
+ }
+
+ // FIXME: should we deprecate the following & call arena().create() directly?
+
+ /// Creates a `T` (some subclass of `Value`), forwarding `args` to the
+ /// constructor, and returns a reference to it.
+ ///
+ /// The analysis context takes ownership of the created object. The object
+ /// will be destroyed when the analysis context is destroyed.
+ template <typename T, typename... Args>
+ std::enable_if_t<std::is_base_of<Value, T>::value, T &>
+ create(Args &&...args) {
+ return arena().create<T>(std::forward<Args>(args)...);
+ }
+
+ /// Returns a symbolic integer value that models an integer literal equal to
+ /// `Value`
+ IntegerValue &getIntLiteralValue(llvm::APInt Value) const {
+ return arena().makeIntLiteral(Value);
+ }
+
+ /// Returns a symbolic boolean value that models a boolean literal equal to
+ /// `Value`
+ BoolValue &getBoolLiteralValue(bool Value) const {
+ return arena().makeBoolValue(arena().makeLiteral(Value));
+ }
+
+ /// Returns an atomic boolean value.
+ BoolValue &makeAtomicBoolValue() const {
+ return arena().makeAtomValue();
+ }
+
+ /// Returns a unique instance of boolean Top.
+ BoolValue &makeTopBoolValue() const {
+ return arena().makeTopValue();
+ }
+
+ /// Returns a boolean value that represents the conjunction of `LHS` and
+ /// `RHS`. Subsequent calls with the same arguments, regardless of their
+ /// order, will return the same result. If the given boolean values represent
+ /// the same value, the result will be the value itself.
+ BoolValue &makeAnd(BoolValue &LHS, BoolValue &RHS) const {
+ return arena().makeBoolValue(
+ arena().makeAnd(LHS.formula(), RHS.formula()));
+ }
+
+ /// Returns a boolean value that represents the disjunction of `LHS` and
+ /// `RHS`. Subsequent calls with the same arguments, regardless of their
+ /// order, will return the same result. If the given boolean values represent
+ /// the same value, the result will be the value itself.
+ BoolValue &makeOr(BoolValue &LHS, BoolValue &RHS) const {
+ return arena().makeBoolValue(
+ arena().makeOr(LHS.formula(), RHS.formula()));
+ }
+
+ /// Returns a boolean value that represents the negation of `Val`. Subsequent
+ /// calls with the same argument will return the same result.
+ BoolValue &makeNot(BoolValue &Val) const {
+ return arena().makeBoolValue(arena().makeNot(Val.formula()));
+ }
+
+ /// Returns a boolean value represents `LHS` => `RHS`. Subsequent calls with
+ /// the same arguments, will return the same result. If the given boolean
+ /// values represent the same value, the result will be a value that
+ /// represents the true boolean literal.
+ BoolValue &makeImplication(BoolValue &LHS, BoolValue &RHS) const {
+ return arena().makeBoolValue(
+ arena().makeImplies(LHS.formula(), RHS.formula()));
+ }
+
+ /// Returns a boolean value represents `LHS` <=> `RHS`. Subsequent calls with
+ /// the same arguments, regardless of their order, will return the same
+ /// result. If the given boolean values represent the same value, the result
+ /// will be a value that represents the true boolean literal.
+ BoolValue &makeIff(BoolValue &LHS, BoolValue &RHS) const {
+ return arena().makeBoolValue(
+ arena().makeEquals(LHS.formula(), RHS.formula()));
+ }
+
+ /// Returns a boolean variable that identifies the flow condition (FC).
+ ///
+ /// The flow condition is a set of facts that are necessarily true when the
+ /// program reaches the current point, expressed as boolean formulas.
+ /// The flow condition token is equivalent to the AND of these facts.
+ ///
+ /// These may e.g. constrain the value of certain variables. A pointer
+ /// variable may have a consistent modeled PointerValue throughout, but at a
+ /// given point the Environment may tell us that the value must be non-null.
+ ///
+ /// The FC is necessary but not sufficient for this point to be reachable.
+ /// In particular, where the FC token appears in flow conditions of successor
+ /// environments, it means "point X may have been reached", not
+ /// "point X was reached".
+ Atom getFlowConditionToken() const { return FlowConditionToken; }
+
+ /// Record a fact that must be true if this point in the program is reached.
+ void assume(const Formula &);
+
+ /// Returns true if the formula is always true when this point is reached.
+ /// Returns false if the formula may be false (or the flow condition isn't
+ /// sufficiently precise to prove that it is true) or if the solver times out.
+ ///
+ /// Note that there is an asymmetry between this function and `allows()` in
+ /// that they both return false if the solver times out. The assumption is
+ /// that if `proves()` or `allows()` returns true, this will result in a
+ /// diagnostic, and we want to bias towards false negatives in the case where
+ /// the solver times out.
+ bool proves(const Formula &) const;
+
+ /// Returns true if the formula may be true when this point is reached.
+ /// Returns false if the formula is always false when this point is reached
+ /// (or the flow condition is overly constraining) or if the solver times out.
+ bool allows(const Formula &) const;
+
+ /// Returns the `DeclContext` of the block being analysed, if any. Otherwise,
+ /// returns null.
+ const DeclContext *getDeclCtx() const { return CallStack.back(); }
+
+ /// Returns the function currently being analyzed, or null if the code being
+ /// analyzed isn't part of a function.
+ const FunctionDecl *getCurrentFunc() const {
+ return dyn_cast<FunctionDecl>(getDeclCtx());
+ }
+
+ /// Returns the size of the call stack.
+ size_t callStackSize() const { return CallStack.size(); }
+
+ /// Returns whether this `Environment` can be extended to analyze the given
+ /// `Callee` (i.e. if `pushCall` can be used), with recursion disallowed and a
+ /// given `MaxDepth`.
+ bool canDescend(unsigned MaxDepth, const DeclContext *Callee) const;
+
+ /// Returns the `DataflowAnalysisContext` used by the environment.
+ DataflowAnalysisContext &getDataflowAnalysisContext() const { return *DACtx; }
+
+ Arena &arena() const { return DACtx->arena(); }
+
+ LLVM_DUMP_METHOD void dump() const;
+ LLVM_DUMP_METHOD void dump(raw_ostream &OS) const;
+
+private:
+ // The copy-constructor is for use in fork() only.
+ Environment(const Environment &) = default;
+
+ /// 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,
+ int Depth, int &CreatedValuesCount);
+
+ /// Creates a storage location for `Ty`. Also creates and associates a value
+ /// with the storage location, unless values of this type are not supported or
+ /// we hit one of the limits at which we stop producing values (controlled by
+ /// `Visited`, `Depth`, and `CreatedValuesCount`).
+ StorageLocation &createLocAndMaybeValue(QualType Ty,
+ llvm::DenseSet<QualType> &Visited,
+ int Depth, int &CreatedValuesCount);
+
+ /// Shared implementation of `createObject()` overloads.
+ /// `D` and `InitExpr` may be null.
+ StorageLocation &createObjectInternal(const ValueDecl *D, QualType Ty,
+ const Expr *InitExpr);
+
+ /// Shared implementation of `pushCall` overloads. Note that unlike
+ /// `pushCall`, this member is invoked on the environment of the callee, not
+ /// of the caller.
+ void pushCallInternal(const FunctionDecl *FuncDecl,
+ ArrayRef<const Expr *> Args);
+
+ /// Assigns storage locations and values to all global variables, fields
+ /// and functions referenced in `FuncDecl`. `FuncDecl` must have a body.
+ void initFieldsGlobalsAndFuncs(const FunctionDecl *FuncDecl);
+
+ // `DACtx` is not null and not owned by this object.
+ DataflowAnalysisContext *DACtx;
+
+ // FIXME: move the fields `CallStack`, `ReturnVal`, `ReturnLoc` and
+ // `ThisPointeeLoc` into a separate call-context object, shared between
+ // environments in the same call.
+ // https://github.com/llvm/llvm-project/issues/59005
+
+ // `DeclContext` of the block being analysed if provided.
+ std::vector<const DeclContext *> CallStack;
+
+ // Value returned by the function (if it has non-reference return type).
+ Value *ReturnVal = nullptr;
+ // Storage location of the reference returned by the function (if it has
+ // reference return type).
+ StorageLocation *ReturnLoc = nullptr;
+ // The storage location of the `this` pointee. Should only be null if the
+ // function being analyzed is only a function and not a method.
+ RecordStorageLocation *ThisPointeeLoc = nullptr;
+
+ // Maps from declarations and glvalue expression 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;
+ // Maps from prvalue expressions and storage locations to the values that
+ // are assigned to them.
+ // We preserve insertion order so that join/widen process values in
+ // deterministic sequence. This in turn produces deterministic SAT formulas.
+ llvm::MapVector<const Expr *, Value *> ExprToVal;
+ llvm::MapVector<const StorageLocation *, Value *> LocToVal;
+
+ Atom FlowConditionToken;
+};
+
+/// Returns the storage location for the implicit object of a
+/// `CXXMemberCallExpr`, or null if none is defined in the environment.
+/// Dereferences the pointer if the member call expression was written using
+/// `->`.
+RecordStorageLocation *getImplicitObjectLocation(const CXXMemberCallExpr &MCE,
+ const Environment &Env);
+
+/// Returns the storage location for the base object of a `MemberExpr`, or null
+/// if none is defined in the environment. Dereferences the pointer if the
+/// member expression was written using `->`.
+RecordStorageLocation *getBaseObjectLocation(const MemberExpr &ME,
+ const Environment &Env);
+
+/// Returns the fields of `RD` that are initialized by an `InitListExpr`, in the
+/// order in which they appear in `InitListExpr::inits()`.
+std::vector<FieldDecl *> getFieldsForInitListExpr(const RecordDecl *RD);
+
+/// Associates a new `RecordValue` with `Loc` and returns the new value.
+RecordValue &refreshRecordValue(RecordStorageLocation &Loc, Environment &Env);
+
+/// Associates a new `RecordValue` with `Expr` and returns the new value.
+RecordValue &refreshRecordValue(const Expr &Expr, Environment &Env);
+
+} // namespace dataflow
+} // namespace clang
+
+#endif // LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_DATAFLOWENVIRONMENT_H
diff --git a/contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/DataflowLattice.h b/contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/DataflowLattice.h
new file mode 100644
index 000000000000..0c81e2f078c2
--- /dev/null
+++ b/contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/DataflowLattice.h
@@ -0,0 +1,31 @@
+//===- DataflowLattice.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 base types for building lattices to be used in dataflow
+// analyses that run over Control-Flow Graphs (CFGs).
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_DATAFLOWLATTICE_H
+#define LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_DATAFLOWLATTICE_H
+
+namespace clang {
+namespace dataflow {
+
+/// Effect indicating whether a lattice join operation resulted in a new value.
+// FIXME: Rename to `LatticeEffect` since `widen` uses it as well, and we are
+// likely removing it from `join`.
+enum class LatticeJoinEffect {
+ Unchanged,
+ Changed,
+};
+
+} // namespace dataflow
+} // namespace clang
+
+#endif // LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_DATAFLOWLATTICE_H
diff --git a/contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/DataflowValues.h b/contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/DataflowValues.h
index ab96cd5169a2..2248bcdf3a51 100644
--- a/contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/DataflowValues.h
+++ b/contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/DataflowValues.h
@@ -134,7 +134,7 @@ public:
/// getBlockDataMap - Retrieves the internal map between CFGBlocks and
/// dataflow values. If the dataflow analysis operates in the forward
/// direction, the values correspond to the dataflow values at the start
- /// of the block. Otherwise, for a backward analysis, the values correpsond
+ /// of the block. Otherwise, for a backward analysis, the values correspond
/// to the dataflow values at the end of the block.
BlockDataMapTy& getBlockDataMap() { return BlockDataMap; }
const BlockDataMapTy& getBlockDataMap() const { return BlockDataMap; }
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 90095735ad3d..f1d05743bf7f 100644
--- a/contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/DataflowWorklist.h
+++ b/contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/DataflowWorklist.h
@@ -12,6 +12,7 @@
#ifndef LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_DATAFLOWWORKLIST_H
#define LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_DATAFLOWWORKLIST_H
+#include "clang/Analysis/Analyses/IntervalPartition.h"
#include "clang/Analysis/Analyses/PostOrderCFGView.h"
#include "clang/Analysis/CFG.h"
#include "llvm/ADT/PriorityQueue.h"
@@ -21,16 +22,13 @@ namespace clang {
/// on the order defined by 'Comp'.
template <typename Comp, unsigned QueueSize> class DataflowWorklistBase {
llvm::BitVector EnqueuedBlocks;
- PostOrderCFGView *POV;
llvm::PriorityQueue<const CFGBlock *,
SmallVector<const CFGBlock *, QueueSize>, Comp>
WorkList;
public:
- DataflowWorklistBase(const CFG &Cfg, PostOrderCFGView *POV, Comp C)
- : EnqueuedBlocks(Cfg.getNumBlockIDs()), POV(POV), WorkList(C) {}
-
- const PostOrderCFGView *getCFGView() const { return POV; }
+ DataflowWorklistBase(const CFG &Cfg, Comp C)
+ : EnqueuedBlocks(Cfg.getNumBlockIDs()), WorkList(C) {}
void enqueueBlock(const CFGBlock *Block) {
if (Block && !EnqueuedBlocks[Block->getBlockID()]) {
@@ -61,11 +59,25 @@ struct ReversePostOrderCompare {
/// the same block multiple times at once.
struct ForwardDataflowWorklist
: DataflowWorklistBase<ReversePostOrderCompare, 20> {
+ ForwardDataflowWorklist(const CFG &Cfg, PostOrderCFGView *POV)
+ : DataflowWorklistBase(Cfg,
+ ReversePostOrderCompare{POV->getComparator()}) {}
+
ForwardDataflowWorklist(const CFG &Cfg, AnalysisDeclContext &Ctx)
- : DataflowWorklistBase(
- Cfg, Ctx.getAnalysis<PostOrderCFGView>(),
- ReversePostOrderCompare{
- Ctx.getAnalysis<PostOrderCFGView>()->getComparator()}) {}
+ : ForwardDataflowWorklist(Cfg, Ctx.getAnalysis<PostOrderCFGView>()) {}
+
+ void enqueueSuccessors(const CFGBlock *Block) {
+ for (auto B : Block->succs())
+ enqueueBlock(B);
+ }
+};
+
+/// A worklist implementation for forward dataflow analysis based on a weak
+/// topological ordering of the nodes. The worklist cannot contain the same
+/// block multiple times at once.
+struct WTODataflowWorklist : DataflowWorklistBase<WTOCompare, 20> {
+ WTODataflowWorklist(const CFG &Cfg, const WTOCompare &Cmp)
+ : DataflowWorklistBase(Cfg, Cmp) {}
void enqueueSuccessors(const CFGBlock *Block) {
for (auto B : Block->succs())
@@ -80,8 +92,7 @@ struct BackwardDataflowWorklist
: DataflowWorklistBase<PostOrderCFGView::BlockOrderCompare, 20> {
BackwardDataflowWorklist(const CFG &Cfg, AnalysisDeclContext &Ctx)
: DataflowWorklistBase(
- Cfg, Ctx.getAnalysis<PostOrderCFGView>(),
- Ctx.getAnalysis<PostOrderCFGView>()->getComparator()) {}
+ Cfg, Ctx.getAnalysis<PostOrderCFGView>()->getComparator()) {}
void enqueuePredecessors(const CFGBlock *Block) {
for (auto B : Block->preds())
@@ -91,4 +102,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/DebugSupport.h b/contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/DebugSupport.h
new file mode 100644
index 000000000000..6b9f3681490a
--- /dev/null
+++ b/contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/DebugSupport.h
@@ -0,0 +1,36 @@
+//===-- DebugSupport.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 functions which generate more readable forms of data
+// structures used in the dataflow analyses, for debugging purposes.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_DEBUGSUPPORT_H_
+#define LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_DEBUGSUPPORT_H_
+
+#include <string>
+#include <vector>
+
+#include "clang/Analysis/FlowSensitive/Solver.h"
+#include "clang/Analysis/FlowSensitive/Value.h"
+#include "llvm/ADT/StringRef.h"
+
+namespace clang {
+namespace dataflow {
+
+/// Returns a string representation of a value kind.
+llvm::StringRef debugString(Value::Kind Kind);
+
+/// Returns a string representation of the result status of a SAT check.
+llvm::StringRef debugString(Solver::Result::Status Status);
+
+} // namespace dataflow
+} // namespace clang
+
+#endif // LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_DEBUGSUPPORT_H_
diff --git a/contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/Formula.h b/contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/Formula.h
new file mode 100644
index 000000000000..0e6352403a83
--- /dev/null
+++ b/contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/Formula.h
@@ -0,0 +1,147 @@
+//===- Formula.h - Boolean formulas -----------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_FORMULA_H
+#define LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_FORMULA_H
+
+#include "clang/Basic/LLVM.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/DenseMapInfo.h"
+#include "llvm/Support/Allocator.h"
+#include "llvm/Support/raw_ostream.h"
+#include <cassert>
+#include <string>
+
+namespace clang::dataflow {
+
+/// Identifies an atomic boolean variable such as "V1".
+///
+/// This often represents an assertion that is interesting to the analysis but
+/// cannot immediately be proven true or false. For example:
+/// - V1 may mean "the program reaches this point",
+/// - V2 may mean "the parameter was null"
+///
+/// We can use these variables in formulas to describe relationships we know
+/// to be true: "if the parameter was null, the program reaches this point".
+/// We also express hypotheses as formulas, and use a SAT solver to check
+/// whether they are consistent with the known facts.
+enum class Atom : unsigned {};
+
+/// A boolean expression such as "true" or "V1 & !V2".
+/// Expressions may refer to boolean atomic variables. These should take a
+/// consistent true/false value across the set of formulas being considered.
+///
+/// (Formulas are always expressions in terms of boolean variables rather than
+/// e.g. integers because our underlying model is SAT rather than e.g. SMT).
+///
+/// Simple formulas such as "true" and "V1" are self-contained.
+/// Compound formulas connect other formulas, e.g. "(V1 & V2) || V3" is an 'or'
+/// formula, with pointers to its operands "(V1 & V2)" and "V3" stored as
+/// trailing objects.
+/// For this reason, Formulas are Arena-allocated and over-aligned.
+class Formula;
+class alignas(const Formula *) Formula {
+public:
+ enum Kind : unsigned {
+ /// A reference to an atomic boolean variable.
+ /// We name these e.g. "V3", where 3 == atom identity == Value.
+ AtomRef,
+ /// Constant true or false.
+ Literal,
+
+ Not, /// True if its only operand is false
+
+ // These kinds connect two operands LHS and RHS
+ And, /// True if LHS and RHS are both true
+ Or, /// True if either LHS or RHS is true
+ Implies, /// True if LHS is false or RHS is true
+ Equal, /// True if LHS and RHS have the same truth value
+ };
+ Kind kind() const { return FormulaKind; }
+
+ Atom getAtom() const {
+ assert(kind() == AtomRef);
+ return static_cast<Atom>(Value);
+ }
+
+ bool literal() const {
+ assert(kind() == Literal);
+ return static_cast<bool>(Value);
+ }
+
+ bool isLiteral(bool b) const {
+ return kind() == Literal && static_cast<bool>(Value) == b;
+ }
+
+ ArrayRef<const Formula *> operands() const {
+ return ArrayRef(reinterpret_cast<Formula *const *>(this + 1),
+ numOperands(kind()));
+ }
+
+ using AtomNames = llvm::DenseMap<Atom, std::string>;
+ // Produce a stable human-readable representation of this formula.
+ // For example: (V3 | !(V1 & V2))
+ // If AtomNames is provided, these override the default V0, V1... names.
+ void print(llvm::raw_ostream &OS, const AtomNames * = nullptr) const;
+
+ // Allocate Formulas using Arena rather than calling this function directly.
+ static const Formula &create(llvm::BumpPtrAllocator &Alloc, Kind K,
+ ArrayRef<const Formula *> Operands,
+ unsigned Value = 0);
+
+private:
+ Formula() = default;
+ Formula(const Formula &) = delete;
+ Formula &operator=(const Formula &) = delete;
+
+ static unsigned numOperands(Kind K) {
+ switch (K) {
+ case AtomRef:
+ case Literal:
+ return 0;
+ case Not:
+ return 1;
+ case And:
+ case Or:
+ case Implies:
+ case Equal:
+ return 2;
+ }
+ llvm_unreachable("Unhandled Formula::Kind enum");
+ }
+
+ Kind FormulaKind;
+ // Some kinds of formula have scalar values, e.g. AtomRef's atom number.
+ unsigned Value;
+};
+
+// The default names of atoms are V0, V1 etc in order of creation.
+inline llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, Atom A) {
+ return OS << 'V' << static_cast<unsigned>(A);
+}
+inline llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const Formula &F) {
+ F.print(OS);
+ return OS;
+}
+
+} // namespace clang::dataflow
+namespace llvm {
+template <> struct DenseMapInfo<clang::dataflow::Atom> {
+ using Atom = clang::dataflow::Atom;
+ using Underlying = std::underlying_type_t<Atom>;
+
+ static inline Atom getEmptyKey() { return Atom(Underlying(-1)); }
+ static inline Atom getTombstoneKey() { return Atom(Underlying(-2)); }
+ static unsigned getHashValue(const Atom &Val) {
+ return DenseMapInfo<Underlying>::getHashValue(Underlying(Val));
+ }
+ static bool isEqual(const Atom &LHS, const Atom &RHS) { return LHS == RHS; }
+};
+} // namespace llvm
+#endif
diff --git a/contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/Logger.h b/contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/Logger.h
new file mode 100644
index 000000000000..f4bd39f6ed49
--- /dev/null
+++ b/contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/Logger.h
@@ -0,0 +1,91 @@
+//===-- Logger.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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_LOGGER_H
+#define LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_LOGGER_H
+
+#include "clang/Analysis/CFG.h"
+#include "llvm/Support/raw_ostream.h"
+#include <memory>
+
+namespace clang::dataflow {
+// Forward declarations so we can use Logger anywhere in the framework.
+class ControlFlowContext;
+class TypeErasedDataflowAnalysis;
+struct TypeErasedDataflowAnalysisState;
+
+/// A logger is notified as the analysis progresses.
+/// It can produce a report of the analysis's findings and how it came to them.
+///
+/// The framework reports key structural events (e.g. traversal of blocks).
+/// The specific analysis can add extra details to be presented in context.
+class Logger {
+public:
+ /// Returns a dummy logger that does nothing.
+ static Logger &null();
+ /// A logger that simply writes messages to the specified ostream in real
+ /// time.
+ static std::unique_ptr<Logger> textual(llvm::raw_ostream &);
+ /// A logger that builds an HTML UI to inspect the analysis results.
+ /// Each function's analysis is written to a stream obtained from the factory.
+ static std::unique_ptr<Logger>
+ html(std::function<std::unique_ptr<llvm::raw_ostream>()>);
+
+ virtual ~Logger() = default;
+
+ /// Called by the framework as we start analyzing a new function or statement.
+ /// Forms a pair with endAnalysis().
+ virtual void beginAnalysis(const ControlFlowContext &,
+ TypeErasedDataflowAnalysis &) {}
+ virtual void endAnalysis() {}
+
+ // At any time during the analysis, we're computing the state for some target
+ // program point.
+
+ /// Called when we start (re-)processing a block in the CFG.
+ /// The target program point is the entry to the specified block.
+ /// Calls to log() describe transferBranch(), join() etc.
+ /// `PostVisit` specifies whether we're processing the block for the
+ /// post-visit callback.
+ virtual void enterBlock(const CFGBlock &, bool PostVisit) {}
+ /// Called when we start processing an element in the current CFG block.
+ /// The target program point is after the specified element.
+ /// Calls to log() describe the transfer() function.
+ virtual void enterElement(const CFGElement &) {}
+
+ /// Records the analysis state computed for the current program point.
+ virtual void recordState(TypeErasedDataflowAnalysisState &) {}
+ /// Records that the analysis state for the current block is now final.
+ virtual void blockConverged() {}
+
+ /// Called by the framework or user code to report some event.
+ /// The event is associated with the current context (program point).
+ /// The Emit function produces the log message. It may or may not be called,
+ /// depending on if the logger is interested; it should have no side effects.
+ void log(llvm::function_ref<void(llvm::raw_ostream &)> Emit) {
+ if (!ShouldLogText)
+ return;
+ std::string S;
+ llvm::raw_string_ostream OS(S);
+ Emit(OS);
+ logText(S);
+ }
+
+protected:
+ /// ShouldLogText should be false for trivial loggers that ignore logText().
+ /// This allows log() to skip evaluating its Emit function.
+ Logger(bool ShouldLogText = true) : ShouldLogText(ShouldLogText) {}
+
+private:
+ bool ShouldLogText;
+ virtual void logText(llvm::StringRef) {}
+};
+
+} // namespace clang::dataflow
+
+#endif
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..16b0c978779a
--- /dev/null
+++ b/contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/MapLattice.h
@@ -0,0 +1,143 @@
+//===------------------------ 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(); }
+
+ std::pair<iterator, bool>
+ insert(const std::pair<const key_type, mapped_type> &P) {
+ return C.insert(P);
+ }
+
+ std::pair<iterator, bool> insert(std::pair<const key_type, mapped_type> &&P) {
+ return 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/MatchSwitch.h b/contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/MatchSwitch.h
new file mode 100644
index 000000000000..085308f7db54
--- /dev/null
+++ b/contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/MatchSwitch.h
@@ -0,0 +1,174 @@
+//===---- MatchSwitch.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 the `ASTMatchSwitch` abstraction for building a "switch"
+// statement, where each case of the switch is defined by an AST matcher. The
+// cases are considered in order, like pattern matching in functional
+// languages.
+//
+// Currently, the design is catered towards simplifying the implementation of
+// `DataflowAnalysis` transfer functions. Based on experience here, this
+// library may be generalized and moved to ASTMatchers.
+//
+//===----------------------------------------------------------------------===//
+//
+// FIXME: Rename to ASTMatchSwitch.h
+
+#ifndef LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_MATCHSWITCH_H_
+#define LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_MATCHSWITCH_H_
+
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/Stmt.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/ASTMatchers/ASTMatchers.h"
+#include "clang/Analysis/FlowSensitive/DataflowEnvironment.h"
+#include "llvm/ADT/StringRef.h"
+#include <functional>
+#include <string>
+#include <type_traits>
+#include <utility>
+#include <vector>
+
+namespace clang {
+namespace dataflow {
+
+/// A common form of state shared between the cases of a transfer function.
+template <typename LatticeT> struct TransferState {
+ TransferState(LatticeT &Lattice, Environment &Env)
+ : Lattice(Lattice), Env(Env) {}
+
+ /// Current lattice element.
+ LatticeT &Lattice;
+ Environment &Env;
+};
+
+/// A read-only version of TransferState.
+///
+/// FIXME: this type is being used as a general (typed) view type for untyped
+/// dataflow analysis state, rather than strictly for transfer-function
+/// purposes. Move it (and rename it) to DataflowAnalysis.h.
+template <typename LatticeT> struct TransferStateForDiagnostics {
+ TransferStateForDiagnostics(const LatticeT &Lattice, const Environment &Env)
+ : Lattice(Lattice), Env(Env) {}
+
+ /// Current lattice element.
+ const LatticeT &Lattice;
+ const Environment &Env;
+};
+
+template <typename T>
+using MatchSwitchMatcher = ast_matchers::internal::Matcher<T>;
+
+template <typename T, typename State, typename Result = void>
+using MatchSwitchAction = std::function<Result(
+ const T *, const ast_matchers::MatchFinder::MatchResult &, State &)>;
+
+template <typename BaseT, typename State, typename Result = void>
+using ASTMatchSwitch =
+ std::function<Result(const BaseT &, ASTContext &, State &)>;
+
+/// Collects cases of a "match switch": a collection of matchers paired with
+/// callbacks, which together define a switch that can be applied to a node
+/// whose type derives from `BaseT`. This structure can simplify the definition
+/// of `transfer` functions that rely on pattern-matching.
+///
+/// For example, consider an analysis that handles particular function calls. It
+/// can define the `ASTMatchSwitch` once, in the constructor of the analysis,
+/// and then reuse it each time that `transfer` is called, with a fresh state
+/// value.
+///
+/// \code
+/// ASTMatchSwitch<Stmt, TransferState<MyLattice> BuildSwitch() {
+/// return ASTMatchSwitchBuilder<TransferState<MyLattice>>()
+/// .CaseOf(callExpr(callee(functionDecl(hasName("foo")))), TransferFooCall)
+/// .CaseOf(callExpr(argumentCountIs(2),
+/// callee(functionDecl(hasName("bar")))),
+/// TransferBarCall)
+/// .Build();
+/// }
+/// \endcode
+template <typename BaseT, typename State, typename Result = void>
+class ASTMatchSwitchBuilder {
+public:
+ /// Registers an action that will be triggered by the match of a pattern
+ /// against the input statement.
+ ///
+ /// Requirements:
+ ///
+ /// `NodeT` should be derived from `BaseT`.
+ template <typename NodeT>
+ ASTMatchSwitchBuilder &&CaseOf(MatchSwitchMatcher<BaseT> M,
+ MatchSwitchAction<NodeT, State, Result> A) && {
+ static_assert(std::is_base_of<BaseT, NodeT>::value,
+ "NodeT must be derived from BaseT.");
+ Matchers.push_back(std::move(M));
+ Actions.push_back(
+ [A = std::move(A)](const BaseT *Node,
+ const ast_matchers::MatchFinder::MatchResult &R,
+ State &S) { return A(cast<NodeT>(Node), R, S); });
+ return std::move(*this);
+ }
+
+ ASTMatchSwitch<BaseT, State, Result> Build() && {
+ return [Matcher = BuildMatcher(), Actions = std::move(Actions)](
+ const BaseT &Node, ASTContext &Context, State &S) -> Result {
+ auto Results = ast_matchers::matchDynamic(Matcher, Node, Context);
+ if (Results.empty()) {
+ return Result();
+ }
+ // Look through the map for the first binding of the form "TagN..." use
+ // that to select the action.
+ for (const auto &Element : Results[0].getMap()) {
+ llvm::StringRef ID(Element.first);
+ size_t Index = 0;
+ if (ID.consume_front("Tag") && !ID.getAsInteger(10, Index) &&
+ Index < Actions.size()) {
+ return Actions[Index](
+ &Node,
+ ast_matchers::MatchFinder::MatchResult(Results[0], &Context), S);
+ }
+ }
+ return Result();
+ };
+ }
+
+private:
+ ast_matchers::internal::DynTypedMatcher BuildMatcher() {
+ using ast_matchers::anything;
+ using ast_matchers::stmt;
+ using ast_matchers::unless;
+ using ast_matchers::internal::DynTypedMatcher;
+ if (Matchers.empty())
+ return stmt(unless(anything()));
+ for (int I = 0, N = Matchers.size(); I < N; ++I) {
+ std::string Tag = ("Tag" + llvm::Twine(I)).str();
+ // Many matchers are not bindable, so ensure that tryBind will work.
+ Matchers[I].setAllowBind(true);
+ auto M = *Matchers[I].tryBind(Tag);
+ // Each anyOf explicitly controls the traversal kind. The anyOf itself is
+ // set to `TK_AsIs` to ensure no nodes are skipped, thereby deferring to
+ // the kind of the branches. Then, each branch is either left as is, if
+ // the kind is already set, or explicitly set to `TK_AsIs`. We choose this
+ // setting because it is the default interpretation of matchers.
+ Matchers[I] =
+ !M.getTraversalKind() ? M.withTraversalKind(TK_AsIs) : std::move(M);
+ }
+ // The matcher type on the cases ensures that `Expr` kind is compatible with
+ // all of the matchers.
+ return DynTypedMatcher::constructVariadic(
+ DynTypedMatcher::VO_AnyOf, ASTNodeKind::getFromNodeKind<BaseT>(),
+ std::move(Matchers));
+ }
+
+ std::vector<ast_matchers::internal::DynTypedMatcher> Matchers;
+ std::vector<MatchSwitchAction<BaseT, State, Result>> Actions;
+};
+
+} // namespace dataflow
+} // namespace clang
+#endif // LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_MATCHSWITCH_H_
diff --git a/contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/Models/ChromiumCheckModel.h b/contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/Models/ChromiumCheckModel.h
new file mode 100644
index 000000000000..b4315e41d79f
--- /dev/null
+++ b/contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/Models/ChromiumCheckModel.h
@@ -0,0 +1,38 @@
+//===-- ChromiumCheckModel.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 dataflow model for Chromium's family of CHECK functions.
+//
+//===----------------------------------------------------------------------===//
+#ifndef CLANG_ANALYSIS_FLOWSENSITIVE_MODELS_CHROMIUMCHECKMODEL_H
+#define CLANG_ANALYSIS_FLOWSENSITIVE_MODELS_CHROMIUMCHECKMODEL_H
+
+#include "clang/AST/DeclCXX.h"
+#include "clang/Analysis/FlowSensitive/DataflowAnalysis.h"
+#include "clang/Analysis/FlowSensitive/DataflowEnvironment.h"
+#include "llvm/ADT/DenseSet.h"
+
+namespace clang {
+namespace dataflow {
+
+/// Models the behavior of Chromium's CHECK, DCHECK, etc. macros, so that code
+/// after a call to `*CHECK` can rely on the condition being true.
+class ChromiumCheckModel : public DataflowModel {
+public:
+ ChromiumCheckModel() = default;
+ bool transfer(const CFGElement &Element, Environment &Env) override;
+
+private:
+ /// Declarations for `::logging::CheckError::.*Check`, lazily initialized.
+ llvm::SmallDenseSet<const CXXMethodDecl *> CheckDecls;
+};
+
+} // namespace dataflow
+} // namespace clang
+
+#endif // CLANG_ANALYSIS_FLOWSENSITIVE_MODELS_CHROMIUMCHECKMODEL_H
diff --git a/contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/Models/UncheckedOptionalAccessModel.h b/contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/Models/UncheckedOptionalAccessModel.h
new file mode 100644
index 000000000000..09eb8b938226
--- /dev/null
+++ b/contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/Models/UncheckedOptionalAccessModel.h
@@ -0,0 +1,80 @@
+//===-- UncheckedOptionalAccessModel.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 dataflow analysis that detects unsafe uses of optional
+// values.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef CLANG_ANALYSIS_FLOWSENSITIVE_MODELS_UNCHECKEDOPTIONALACCESSMODEL_H
+#define CLANG_ANALYSIS_FLOWSENSITIVE_MODELS_UNCHECKEDOPTIONALACCESSMODEL_H
+
+#include "clang/AST/ASTContext.h"
+#include "clang/Analysis/CFG.h"
+#include "clang/Analysis/FlowSensitive/CFGMatchSwitch.h"
+#include "clang/Analysis/FlowSensitive/DataflowAnalysis.h"
+#include "clang/Analysis/FlowSensitive/DataflowEnvironment.h"
+#include "clang/Analysis/FlowSensitive/NoopLattice.h"
+#include "clang/Basic/SourceLocation.h"
+#include "llvm/ADT/SmallVector.h"
+
+namespace clang {
+namespace dataflow {
+
+// FIXME: Explore using an allowlist-approach, where constructs supported by the
+// analysis are always enabled and additional constructs are enabled through the
+// `Options`.
+struct UncheckedOptionalAccessModelOptions {
+ /// In generating diagnostics, ignore optionals reachable through overloaded
+ /// `operator*` or `operator->` (other than those of the optional type
+ /// itself). The analysis does not equate the results of such calls, so it
+ /// can't identify when their results are used safely (across calls),
+ /// resulting in false positives in all such cases. Note: this option does not
+ /// cover access through `operator[]`.
+ bool IgnoreSmartPointerDereference = false;
+};
+
+/// Dataflow analysis that models whether optionals hold values or not.
+///
+/// Models the `std::optional`, `absl::optional`, and `base::Optional` types.
+class UncheckedOptionalAccessModel
+ : public DataflowAnalysis<UncheckedOptionalAccessModel, NoopLattice> {
+public:
+ UncheckedOptionalAccessModel(ASTContext &Ctx, dataflow::Environment &Env);
+
+ /// Returns a matcher for the optional classes covered by this model.
+ static ast_matchers::DeclarationMatcher optionalClassDecl();
+
+ static NoopLattice initialElement() { return {}; }
+
+ void transfer(const CFGElement &Elt, NoopLattice &L, Environment &Env);
+
+private:
+ CFGMatchSwitch<TransferState<NoopLattice>> TransferMatchSwitch;
+};
+
+class UncheckedOptionalAccessDiagnoser {
+public:
+ UncheckedOptionalAccessDiagnoser(
+ UncheckedOptionalAccessModelOptions Options = {});
+
+ llvm::SmallVector<SourceLocation>
+ operator()(const CFGElement &Elt, ASTContext &Ctx,
+ const TransferStateForDiagnostics<NoopLattice> &State) {
+ return DiagnoseMatchSwitch(Elt, Ctx, State.Env);
+ }
+
+private:
+ CFGMatchSwitch<const Environment, llvm::SmallVector<SourceLocation>>
+ DiagnoseMatchSwitch;
+};
+
+} // namespace dataflow
+} // namespace clang
+
+#endif // CLANG_ANALYSIS_FLOWSENSITIVE_MODELS_UNCHECKEDOPTIONALACCESSMODEL_H
diff --git a/contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/NoopAnalysis.h b/contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/NoopAnalysis.h
new file mode 100644
index 000000000000..393f68300cb8
--- /dev/null
+++ b/contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/NoopAnalysis.h
@@ -0,0 +1,41 @@
+//===-- NoopAnalysis.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 NoopAnalysis class that just uses the builtin transfer.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_NOOPANALYSIS_H
+#define LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_NOOPANALYSIS_H
+
+#include "clang/AST/ASTContext.h"
+#include "clang/Analysis/CFG.h"
+#include "clang/Analysis/FlowSensitive/DataflowAnalysis.h"
+#include "clang/Analysis/FlowSensitive/DataflowEnvironment.h"
+#include "clang/Analysis/FlowSensitive/NoopLattice.h"
+
+namespace clang {
+namespace dataflow {
+
+class NoopAnalysis : public DataflowAnalysis<NoopAnalysis, NoopLattice> {
+public:
+ NoopAnalysis(ASTContext &Context)
+ : DataflowAnalysis<NoopAnalysis, NoopLattice>(Context) {}
+
+ NoopAnalysis(ASTContext &Context, DataflowAnalysisOptions Options)
+ : DataflowAnalysis<NoopAnalysis, NoopLattice>(Context, Options) {}
+
+ static NoopLattice initialElement() { return {}; }
+
+ void transfer(const CFGElement &E, NoopLattice &L, Environment &Env) {}
+};
+
+} // namespace dataflow
+} // namespace clang
+
+#endif // LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_NOOPANALYSIS_H
diff --git a/contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/NoopLattice.h b/contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/NoopLattice.h
new file mode 100644
index 000000000000..019219328111
--- /dev/null
+++ b/contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/NoopLattice.h
@@ -0,0 +1,41 @@
+//===-- NoopLattice.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 the lattice with exactly one element.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_NOOP_LATTICE_H
+#define LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_NOOP_LATTICE_H
+
+#include "clang/Analysis/FlowSensitive/DataflowLattice.h"
+#include <ostream>
+
+namespace clang {
+namespace dataflow {
+
+/// Trivial lattice for dataflow analysis with exactly one element.
+///
+/// Useful for analyses that only need the Environment and nothing more.
+class NoopLattice {
+public:
+ bool operator==(const NoopLattice &Other) const { return true; }
+
+ LatticeJoinEffect join(const NoopLattice &Other) {
+ return LatticeJoinEffect::Unchanged;
+ }
+};
+
+inline std::ostream &operator<<(std::ostream &OS, const NoopLattice &) {
+ return OS << "noop";
+}
+
+} // namespace dataflow
+} // namespace clang
+
+#endif // LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_NOOP_LATTICE_H
diff --git a/contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/RecordOps.h b/contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/RecordOps.h
new file mode 100644
index 000000000000..783e53e980aa
--- /dev/null
+++ b/contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/RecordOps.h
@@ -0,0 +1,68 @@
+//===-- RecordOps.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
+//
+//===----------------------------------------------------------------------===//
+//
+// Operations on records (structs, classes, and unions).
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_RECORDOPS_H
+#define LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_RECORDOPS_H
+
+#include "clang/Analysis/FlowSensitive/DataflowEnvironment.h"
+#include "clang/Analysis/FlowSensitive/StorageLocation.h"
+
+namespace clang {
+namespace dataflow {
+
+/// Copies a record (struct, class, or union) from `Src` to `Dst`.
+///
+/// This performs a deep copy, i.e. it copies every field (including synthetic
+/// fields) and recurses on fields of record type.
+///
+/// If there is a `RecordValue` associated with `Dst` in the environment, this
+/// function creates a new `RecordValue` and associates it with `Dst`; clients
+/// need to be aware of this and must not assume that the `RecordValue`
+/// associated with `Dst` remains the same after the call.
+///
+/// Requirements:
+///
+/// `Src` and `Dst` must have the same canonical unqualified type.
+void copyRecord(RecordStorageLocation &Src, RecordStorageLocation &Dst,
+ Environment &Env);
+
+/// Returns whether the records `Loc1` and `Loc2` are equal.
+///
+/// Values for `Loc1` are retrieved from `Env1`, and values for `Loc2` are
+/// retrieved from `Env2`. A convenience overload retrieves values for `Loc1`
+/// and `Loc2` from the same environment.
+///
+/// This performs a deep comparison, i.e. it compares every field (including
+/// synthetic fields) and recurses on fields of record type. Fields of reference
+/// type compare equal if they refer to the same storage location.
+///
+/// Note on how to interpret the result:
+/// - If this returns true, the records are guaranteed to be equal at runtime.
+/// - If this returns false, the records may still be equal at runtime; our
+/// analysis merely cannot guarantee that they will be equal.
+///
+/// Requirements:
+///
+/// `Src` and `Dst` must have the same canonical unqualified type.
+bool recordsEqual(const RecordStorageLocation &Loc1, const Environment &Env1,
+ const RecordStorageLocation &Loc2, const Environment &Env2);
+
+inline bool recordsEqual(const RecordStorageLocation &Loc1,
+ const RecordStorageLocation &Loc2,
+ const Environment &Env) {
+ return recordsEqual(Loc1, Env, Loc2, Env);
+}
+
+} // namespace dataflow
+} // namespace clang
+
+#endif // LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_RECORDOPS_H
diff --git a/contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/SimplifyConstraints.h b/contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/SimplifyConstraints.h
new file mode 100644
index 000000000000..fadb3caf0a4c
--- /dev/null
+++ b/contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/SimplifyConstraints.h
@@ -0,0 +1,49 @@
+//===-- SimplifyConstraints.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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_SIMPLIFYCONSTRAINTS_H
+#define LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_SIMPLIFYCONSTRAINTS_H
+
+#include "clang/Analysis/FlowSensitive/Arena.h"
+#include "clang/Analysis/FlowSensitive/Formula.h"
+#include "llvm/ADT/SetVector.h"
+
+namespace clang {
+namespace dataflow {
+
+/// Information on the way a set of constraints was simplified.
+struct SimplifyConstraintsInfo {
+ /// List of equivalence classes of atoms. For each equivalence class, the
+ /// original constraints imply that all atoms in it must be equivalent.
+ /// Simplification replaces all occurrences of atoms in an equivalence class
+ /// with a single representative atom from the class.
+ /// Does not contain equivalence classes with just one member or atoms
+ /// contained in `TrueAtoms` or `FalseAtoms`.
+ llvm::SmallVector<llvm::SmallVector<Atom>> EquivalentAtoms;
+ /// Atoms that the original constraints imply must be true.
+ /// Simplification replaces all occurrences of these atoms by a true literal
+ /// (which may enable additional simplifications).
+ llvm::SmallVector<Atom> TrueAtoms;
+ /// Atoms that the original constraints imply must be false.
+ /// Simplification replaces all occurrences of these atoms by a false literal
+ /// (which may enable additional simplifications).
+ llvm::SmallVector<Atom> FalseAtoms;
+};
+
+/// Simplifies a set of constraints (implicitly connected by "and") in a way
+/// that does not change satisfiability of the constraints. This does _not_ mean
+/// that the set of solutions is the same before and after simplification.
+/// `Info`, if non-null, will be populated with information about the
+/// simplifications that were made to the formula (e.g. to display to the user).
+void simplifyConstraints(llvm::SetVector<const Formula *> &Constraints,
+ Arena &arena, SimplifyConstraintsInfo *Info = nullptr);
+
+} // namespace dataflow
+} // namespace clang
+
+#endif // LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_SIMPLIFYCONSTRAINTS_H
diff --git a/contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/Solver.h b/contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/Solver.h
new file mode 100644
index 000000000000..079f6802f241
--- /dev/null
+++ b/contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/Solver.h
@@ -0,0 +1,98 @@
+//===- Solver.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 an interface for a SAT solver that can be used by
+// dataflow analyses.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_SOLVER_H
+#define LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_SOLVER_H
+
+#include "clang/Analysis/FlowSensitive/Formula.h"
+#include "clang/Basic/LLVM.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/DenseMap.h"
+#include <optional>
+#include <vector>
+
+namespace clang {
+namespace dataflow {
+
+/// An interface for a SAT solver that can be used by dataflow analyses.
+class Solver {
+public:
+ struct Result {
+ enum class Status {
+ /// Indicates that there exists a satisfying assignment for a boolean
+ /// formula.
+ Satisfiable,
+
+ /// Indicates that there is no satisfying assignment for a boolean
+ /// formula.
+ Unsatisfiable,
+
+ /// Indicates that the solver gave up trying to find a satisfying
+ /// assignment for a boolean formula.
+ TimedOut,
+ };
+
+ /// A boolean value is set to true or false in a truth assignment.
+ enum class Assignment : uint8_t { AssignedFalse = 0, AssignedTrue = 1 };
+
+ /// Constructs a result indicating that the queried boolean formula is
+ /// satisfiable. The result will hold a solution found by the solver.
+ static Result Satisfiable(llvm::DenseMap<Atom, Assignment> Solution) {
+ return Result(Status::Satisfiable, std::move(Solution));
+ }
+
+ /// Constructs a result indicating that the queried boolean formula is
+ /// unsatisfiable.
+ static Result Unsatisfiable() { return Result(Status::Unsatisfiable, {}); }
+
+ /// Constructs a result indicating that satisfiability checking on the
+ /// queried boolean formula was not completed.
+ static Result TimedOut() { return Result(Status::TimedOut, {}); }
+
+ /// Returns the status of satisfiability checking on the queried boolean
+ /// formula.
+ Status getStatus() const { return SATCheckStatus; }
+
+ /// Returns a truth assignment to boolean values that satisfies the queried
+ /// boolean formula if available. Otherwise, an empty optional is returned.
+ std::optional<llvm::DenseMap<Atom, Assignment>> getSolution() const {
+ return Solution;
+ }
+
+ private:
+ Result(Status SATCheckStatus,
+ std::optional<llvm::DenseMap<Atom, Assignment>> Solution)
+ : SATCheckStatus(SATCheckStatus), Solution(std::move(Solution)) {}
+
+ Status SATCheckStatus;
+ std::optional<llvm::DenseMap<Atom, Assignment>> Solution;
+ };
+
+ virtual ~Solver() = default;
+
+ /// Checks if the conjunction of `Vals` is satisfiable and returns the
+ /// corresponding result.
+ ///
+ /// Requirements:
+ ///
+ /// All elements in `Vals` must not be null.
+ virtual Result solve(llvm::ArrayRef<const Formula *> Vals) = 0;
+};
+
+llvm::raw_ostream &operator<<(llvm::raw_ostream &, const Solver::Result &);
+llvm::raw_ostream &operator<<(llvm::raw_ostream &, Solver::Result::Assignment);
+
+} // namespace dataflow
+} // namespace clang
+
+#endif // LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_SOLVER_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..8fcc6a44027a
--- /dev/null
+++ b/contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/StorageLocation.h
@@ -0,0 +1,181 @@
+//===-- 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"
+#include "llvm/Support/Debug.h"
+#include <cassert>
+
+#define DEBUG_TYPE "dataflow"
+
+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,
+ Record,
+ };
+
+ StorageLocation(Kind LocKind, QualType Type) : LocKind(LocKind), Type(Type) {
+ assert(Type.isNull() || !Type->isReferenceType());
+ }
+
+ // Non-copyable because addresses of storage locations are used as their
+ // identities throughout framework and user code. The framework is responsible
+ // for construction and destruction of storage locations.
+ StorageLocation(const StorageLocation &) = delete;
+ StorageLocation &operator=(const StorageLocation &) = delete;
+
+ 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 for a record (struct, class, or union).
+///
+/// Contains storage locations for all modeled fields of the record (also
+/// referred to as "children"). The child map is flat, so accessible members of
+/// the base class are directly accessible as children of this location.
+///
+/// Record storage locations may also contain so-called synthetic fields. These
+/// are typically used to model the internal state of a class (e.g. the value
+/// stored in a `std::optional`) without having to depend on that class's
+/// implementation details. All `RecordStorageLocation`s of a given type should
+/// have the same synthetic fields.
+///
+/// The storage location for a field of reference type may be null. This
+/// typically occurs in one of two situations:
+/// - The record has not been fully initialized.
+/// - The maximum depth for modelling a self-referential data structure has been
+/// reached.
+/// Storage locations for fields of all other types must be non-null.
+///
+/// FIXME: Currently, the storage location of unions is modelled the same way as
+/// that of structs or classes. Eventually, we need to change this modelling so
+/// that all of the members of a given union have the same storage location.
+class RecordStorageLocation final : public StorageLocation {
+public:
+ using FieldToLoc = llvm::DenseMap<const ValueDecl *, StorageLocation *>;
+ using SyntheticFieldMap = llvm::StringMap<StorageLocation *>;
+
+ RecordStorageLocation(QualType Type, FieldToLoc TheChildren,
+ SyntheticFieldMap TheSyntheticFields)
+ : StorageLocation(Kind::Record, Type), Children(std::move(TheChildren)),
+ SyntheticFields(std::move(TheSyntheticFields)) {
+ assert(!Type.isNull());
+ assert(Type->isRecordType());
+ assert([this] {
+ for (auto [Field, Loc] : Children) {
+ if (!Field->getType()->isReferenceType() && Loc == nullptr)
+ return false;
+ }
+ return true;
+ }());
+ }
+
+ static bool classof(const StorageLocation *Loc) {
+ return Loc->getKind() == Kind::Record;
+ }
+
+ /// Returns the child storage location for `D`.
+ ///
+ /// May return null if `D` has reference type; guaranteed to return non-null
+ /// in all other cases.
+ ///
+ /// Note that it is an error to call this with a field that does not exist.
+ /// The function does not return null in this case.
+ StorageLocation *getChild(const ValueDecl &D) const {
+ auto It = Children.find(&D);
+ LLVM_DEBUG({
+ if (It == Children.end()) {
+ llvm::dbgs() << "Couldn't find child " << D.getNameAsString()
+ << " on StorageLocation " << this << " of type "
+ << getType() << "\n";
+ llvm::dbgs() << "Existing children:\n";
+ for ([[maybe_unused]] auto [Field, Loc] : Children) {
+ llvm::dbgs() << Field->getNameAsString() << "\n";
+ }
+ }
+ });
+ assert(It != Children.end());
+ return It->second;
+ }
+
+ /// Returns the storage location for the synthetic field `Name`.
+ /// The synthetic field must exist.
+ StorageLocation &getSyntheticField(llvm::StringRef Name) const {
+ StorageLocation *Loc = SyntheticFields.lookup(Name);
+ assert(Loc != nullptr);
+ return *Loc;
+ }
+
+ llvm::iterator_range<SyntheticFieldMap::const_iterator>
+ synthetic_fields() const {
+ return {SyntheticFields.begin(), SyntheticFields.end()};
+ }
+
+ /// Changes the child storage location for a field `D` of reference type.
+ /// All other fields cannot change their storage location and always retain
+ /// the storage location passed to the `RecordStorageLocation` constructor.
+ ///
+ /// Requirements:
+ ///
+ /// `D` must have reference type.
+ void setChild(const ValueDecl &D, StorageLocation *Loc) {
+ assert(D.getType()->isReferenceType());
+ Children[&D] = Loc;
+ }
+
+ llvm::iterator_range<FieldToLoc::const_iterator> children() const {
+ return {Children.begin(), Children.end()};
+ }
+
+private:
+ FieldToLoc Children;
+ SyntheticFieldMap SyntheticFields;
+};
+
+} // namespace dataflow
+} // namespace clang
+
+#undef DEBUG_TYPE
+
+#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..7713df747cb7
--- /dev/null
+++ b/contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/Transfer.h
@@ -0,0 +1,61 @@
+//===-- 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/DataflowAnalysisContext.h"
+#include "clang/Analysis/FlowSensitive/DataflowEnvironment.h"
+#include "clang/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.h"
+
+namespace clang {
+namespace dataflow {
+
+/// Maps statements to the environments of basic blocks that contain them.
+class StmtToEnvMap {
+public:
+ // `CurBlockID` is the ID of the block currently being processed, and
+ // `CurState` is the pending state currently associated with this block. These
+ // are supplied separately as the pending state for the current block may not
+ // yet be represented in `BlockToState`.
+ StmtToEnvMap(const ControlFlowContext &CFCtx,
+ llvm::ArrayRef<std::optional<TypeErasedDataflowAnalysisState>>
+ BlockToState,
+ unsigned CurBlockID,
+ const TypeErasedDataflowAnalysisState &CurState)
+ : CFCtx(CFCtx), BlockToState(BlockToState), CurBlockID(CurBlockID),
+ CurState(CurState) {}
+
+ /// Returns the environment of the basic block that contains `S`.
+ /// The result is guaranteed never to be null.
+ const Environment *getEnvironment(const Stmt &S) const;
+
+private:
+ const ControlFlowContext &CFCtx;
+ llvm::ArrayRef<std::optional<TypeErasedDataflowAnalysisState>> BlockToState;
+ unsigned CurBlockID;
+ const TypeErasedDataflowAnalysisState &CurState;
+};
+
+/// Evaluates `S` and updates `Env` accordingly.
+///
+/// Requirements:
+///
+/// `S` must not be `ParenExpr` or `ExprWithCleanups`.
+void transfer(const StmtToEnvMap &StmtToEnv, 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
new file mode 100644
index 000000000000..a0ca7440230b
--- /dev/null
+++ b/contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.h
@@ -0,0 +1,159 @@
+//===- TypeErasedDataflowAnalysis.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 type-erased base types and functions for building dataflow
+// analyses that run over Control-Flow Graphs (CFGs).
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_TYPEERASEDDATAFLOWANALYSIS_H
+#define LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_TYPEERASEDDATAFLOWANALYSIS_H
+
+#include <optional>
+#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/DataflowAnalysisContext.h"
+#include "clang/Analysis/FlowSensitive/DataflowEnvironment.h"
+#include "clang/Analysis/FlowSensitive/DataflowLattice.h"
+#include "llvm/ADT/Any.h"
+#include "llvm/Support/Error.h"
+
+namespace clang {
+namespace dataflow {
+
+struct DataflowAnalysisOptions {
+ /// Options for the built-in model, or empty to not apply them.
+ // FIXME: Remove this option once the framework supports composing analyses
+ // (at which point the built-in transfer functions can be simply a standalone
+ // analysis).
+ std::optional<DataflowAnalysisContext::Options> BuiltinOpts =
+ DataflowAnalysisContext::Options{};
+};
+
+/// Type-erased lattice element container.
+///
+/// Requirements:
+///
+/// The type of the object stored in the container must be a bounded
+/// join-semilattice.
+struct TypeErasedLattice {
+ llvm::Any Value;
+};
+
+/// Type-erased base class for dataflow analyses built on a single lattice type.
+class TypeErasedDataflowAnalysis : public Environment::ValueModel {
+ DataflowAnalysisOptions Options;
+
+public:
+ TypeErasedDataflowAnalysis() : Options({}) {}
+
+ TypeErasedDataflowAnalysis(DataflowAnalysisOptions Options)
+ : Options(Options) {}
+
+ virtual ~TypeErasedDataflowAnalysis() {}
+
+ /// Returns the `ASTContext` that is used by the analysis.
+ virtual ASTContext &getASTContext() = 0;
+
+ /// Returns a type-erased lattice element that models the initial state of a
+ /// basic block.
+ virtual TypeErasedLattice typeErasedInitialElement() = 0;
+
+ /// Joins two type-erased lattice elements by computing their least upper
+ /// bound. Places the join result in the left element and returns an effect
+ /// indicating whether any changes were made to it.
+ virtual TypeErasedLattice joinTypeErased(const TypeErasedLattice &,
+ const TypeErasedLattice &) = 0;
+
+ /// Chooses a lattice element that approximates the current element at a
+ /// program point, given the previous element at that point. Places the
+ /// widened result in the current element (`Current`). Widening is optional --
+ /// it is only needed to either accelerate convergence (for lattices with
+ /// non-trivial height) or guarantee convergence (for lattices with infinite
+ /// height).
+ ///
+ /// Returns an indication of whether any changes were made to `Current` in
+ /// order to widen. This saves a separate call to `isEqualTypeErased` after
+ /// the widening.
+ virtual LatticeJoinEffect
+ widenTypeErased(TypeErasedLattice &Current,
+ const TypeErasedLattice &Previous) = 0;
+
+ /// Returns true if and only if the two given type-erased lattice elements are
+ /// equal.
+ virtual bool isEqualTypeErased(const TypeErasedLattice &,
+ const TypeErasedLattice &) = 0;
+
+ /// Applies the analysis transfer function for a given control flow graph
+ /// element and type-erased lattice element.
+ virtual void transferTypeErased(const CFGElement &, TypeErasedLattice &,
+ Environment &) = 0;
+
+ /// Applies the analysis transfer function for a given edge from a CFG block
+ /// of a conditional statement.
+ /// @param Stmt The condition which is responsible for the split in the CFG.
+ /// @param Branch True if the edge goes to the basic block where the
+ /// condition is true.
+ // FIXME: Change `Stmt` argument to a reference.
+ virtual void transferBranchTypeErased(bool Branch, const Stmt *,
+ TypeErasedLattice &, Environment &) = 0;
+
+ /// If the built-in model is enabled, returns the options to be passed to
+ /// them. Otherwise returns empty.
+ const std::optional<DataflowAnalysisContext::Options> &
+ builtinOptions() const {
+ return Options.BuiltinOpts;
+ }
+};
+
+/// Type-erased model of the program at a given program point.
+struct TypeErasedDataflowAnalysisState {
+ /// Type-erased model of a program property.
+ TypeErasedLattice Lattice;
+
+ /// 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)) {}
+
+ TypeErasedDataflowAnalysisState fork() const {
+ return TypeErasedDataflowAnalysisState(Lattice, Env.fork());
+ }
+};
+
+/// 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. Returns an error if the
+/// dataflow analysis cannot be performed successfully. Otherwise, calls
+/// `PostVisitCFG` on each CFG element with the final analysis results at that
+/// program point.
+///
+/// `MaxBlockVisits` caps the number of block visits during analysis. It doesn't
+/// distinguish between repeat visits to the same block and visits to distinct
+/// blocks. This parameter is a backstop to prevent infinite loops, in the case
+/// of bugs in the lattice and/or transfer functions that prevent the analysis
+/// from converging.
+llvm::Expected<std::vector<std::optional<TypeErasedDataflowAnalysisState>>>
+runTypeErasedDataflowAnalysis(
+ const ControlFlowContext &CFCtx, TypeErasedDataflowAnalysis &Analysis,
+ const Environment &InitEnv,
+ std::function<void(const CFGElement &,
+ const TypeErasedDataflowAnalysisState &)>
+ PostVisitCFG,
+ std::int32_t MaxBlockVisits);
+
+} // namespace dataflow
+} // namespace clang
+
+#endif // LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_TYPEERASEDDATAFLOWANALYSIS_H
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..be1bf9324c87
--- /dev/null
+++ b/contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/Value.h
@@ -0,0 +1,231 @@
+//===-- 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/Formula.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.
+///
+/// Don't use `Value` instances by value. All `Value` instances are allocated
+/// and owned by `DataflowAnalysisContext`.
+class Value {
+public:
+ enum class Kind {
+ Integer,
+ Pointer,
+ Record,
+
+ // TODO: Top values should not be need to be type-specific.
+ TopBool,
+ AtomicBool,
+ FormulaBool,
+ };
+
+ explicit Value(Kind ValKind) : ValKind(ValKind) {}
+
+ // Non-copyable because addresses of values are used as their identities
+ // throughout framework and user code. The framework is responsible for
+ // construction and destruction of values.
+ Value(const Value &) = delete;
+ Value &operator=(const Value &) = delete;
+
+ virtual ~Value() = default;
+
+ Kind getKind() const { return ValKind; }
+
+ /// 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 {
+ return Properties.lookup(Name);
+ }
+
+ /// Assigns `Val` as the value of the synthetic property with the given
+ /// `Name`.
+ ///
+ /// Properties may not be set on `RecordValue`s; use synthetic fields instead
+ /// (for details, see documentation for `RecordStorageLocation`).
+ void setProperty(llvm::StringRef Name, Value &Val) {
+ assert(getKind() != Kind::Record);
+ Properties.insert_or_assign(Name, &Val);
+ }
+
+ llvm::iterator_range<llvm::StringMap<Value *>::const_iterator>
+ properties() const {
+ return {Properties.begin(), Properties.end()};
+ }
+
+private:
+ Kind ValKind;
+ llvm::StringMap<Value *> Properties;
+};
+
+/// An equivalence relation for values. It obeys reflexivity, symmetry and
+/// transitivity. It does *not* include comparison of `Properties`.
+///
+/// Computes equivalence for these subclasses:
+/// * PointerValue -- pointee locations are equal. Does not compute deep
+/// equality of `Value` at said location.
+/// * TopBoolValue -- both are `TopBoolValue`s.
+///
+/// Otherwise, falls back to pointer equality.
+bool areEquivalentValues(const Value &Val1, const Value &Val2);
+
+/// Models a boolean.
+class BoolValue : public Value {
+ const Formula *F;
+
+public:
+ explicit BoolValue(Kind ValueKind, const Formula &F)
+ : Value(ValueKind), F(&F) {}
+
+ static bool classof(const Value *Val) {
+ return Val->getKind() == Kind::TopBool ||
+ Val->getKind() == Kind::AtomicBool ||
+ Val->getKind() == Kind::FormulaBool;
+ }
+
+ const Formula &formula() const { return *F; }
+};
+
+/// A TopBoolValue represents a boolean that is explicitly unconstrained.
+///
+/// This is equivalent to an AtomicBoolValue that does not appear anywhere
+/// else in a system of formula.
+/// Knowing the value is unconstrained is useful when e.g. reasoning about
+/// convergence.
+class TopBoolValue final : public BoolValue {
+public:
+ TopBoolValue(const Formula &F) : BoolValue(Kind::TopBool, F) {
+ assert(F.kind() == Formula::AtomRef);
+ }
+
+ static bool classof(const Value *Val) {
+ return Val->getKind() == Kind::TopBool;
+ }
+
+ Atom getAtom() const { return formula().getAtom(); }
+};
+
+/// Models an atomic boolean.
+///
+/// FIXME: Merge this class into FormulaBoolValue.
+/// When we want to specify atom identity, use Atom.
+class AtomicBoolValue final : public BoolValue {
+public:
+ explicit AtomicBoolValue(const Formula &F) : BoolValue(Kind::AtomicBool, F) {
+ assert(F.kind() == Formula::AtomRef);
+ }
+
+ static bool classof(const Value *Val) {
+ return Val->getKind() == Kind::AtomicBool;
+ }
+
+ Atom getAtom() const { return formula().getAtom(); }
+};
+
+/// Models a compound boolean formula.
+class FormulaBoolValue final : public BoolValue {
+public:
+ explicit FormulaBoolValue(const Formula &F)
+ : BoolValue(Kind::FormulaBool, F) {
+ assert(F.kind() != Formula::AtomRef && "For now, use AtomicBoolValue");
+ }
+
+ static bool classof(const Value *Val) {
+ return Val->getKind() == Kind::FormulaBool;
+ }
+};
+
+/// Models an integer.
+class IntegerValue : public Value {
+public:
+ explicit IntegerValue() : Value(Kind::Integer) {}
+
+ static bool classof(const Value *Val) {
+ return Val->getKind() == Kind::Integer;
+ }
+};
+
+/// Models a symbolic pointer. Specifically, any value of type `T*`.
+class PointerValue final : public Value {
+public:
+ explicit PointerValue(StorageLocation &PointeeLoc)
+ : Value(Kind::Pointer), PointeeLoc(PointeeLoc) {}
+
+ static bool classof(const Value *Val) {
+ return Val->getKind() == Kind::Pointer;
+ }
+
+ StorageLocation &getPointeeLoc() const { return PointeeLoc; }
+
+private:
+ StorageLocation &PointeeLoc;
+};
+
+/// Models a value of `struct` or `class` type.
+/// In C++, prvalues of class type serve only a limited purpose: They can only
+/// be used to initialize a result object. It is not possible to access member
+/// variables or call member functions on a prvalue of class type.
+/// Correspondingly, `RecordValue` also serves only a limited purpose: It
+/// conveys a prvalue of class type from the place where the object is
+/// constructed to the result object that it initializes.
+///
+/// When creating a prvalue of class type, we already need a storage location
+/// for `this`, even though prvalues are otherwise not associated with storage
+/// locations. `RecordValue` is therefore essentially a wrapper for a storage
+/// location, which is then used to set the storage location for the result
+/// object when we process the AST node for that result object.
+///
+/// For example:
+/// MyStruct S = MyStruct(3);
+///
+/// In this example, `MyStruct(3) is a prvalue, which is modeled as a
+/// `RecordValue` that wraps a `RecordStorageLocation`. This
+/// `RecordStorageLocation` is then used as the storage location for `S`.
+///
+/// Over time, we may eliminate `RecordValue` entirely. See also the discussion
+/// here: https://reviews.llvm.org/D155204#inline-1503204
+class RecordValue final : public Value {
+public:
+ explicit RecordValue(RecordStorageLocation &Loc)
+ : Value(Kind::Record), Loc(Loc) {}
+
+ static bool classof(const Value *Val) {
+ return Val->getKind() == Kind::Record;
+ }
+
+ /// Returns the storage location that this `RecordValue` is associated with.
+ RecordStorageLocation &getLoc() const { return Loc; }
+
+private:
+ RecordStorageLocation &Loc;
+};
+
+raw_ostream &operator<<(raw_ostream &OS, const Value &Val);
+
+} // namespace dataflow
+} // namespace clang
+
+#endif // LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_VALUE_H
diff --git a/contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/WatchedLiteralsSolver.h b/contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/WatchedLiteralsSolver.h
new file mode 100644
index 000000000000..5448eecf6d41
--- /dev/null
+++ b/contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/WatchedLiteralsSolver.h
@@ -0,0 +1,58 @@
+//===- WatchedLiteralsSolver.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 SAT solver implementation that can be used by dataflow
+// analyses.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_WATCHEDLITERALSSOLVER_H
+#define LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_WATCHEDLITERALSSOLVER_H
+
+#include "clang/Analysis/FlowSensitive/Formula.h"
+#include "clang/Analysis/FlowSensitive/Solver.h"
+#include "llvm/ADT/ArrayRef.h"
+#include <limits>
+
+namespace clang {
+namespace dataflow {
+
+/// A SAT solver that is an implementation of Algorithm D from Knuth's The Art
+/// of Computer Programming Volume 4: Satisfiability, Fascicle 6. It is based on
+/// the Davis-Putnam-Logemann-Loveland (DPLL) algorithm, keeps references to a
+/// single "watched" literal per clause, and uses a set of "active" variables
+/// for unit propagation.
+class WatchedLiteralsSolver : public Solver {
+ // Count of the iterations of the main loop of the solver. This spans *all*
+ // calls to the underlying solver across the life of this object. It is
+ // reduced with every (non-trivial) call to the solver.
+ //
+ // We give control over the abstract count of iterations instead of concrete
+ // measurements like CPU cycles or time to ensure deterministic results.
+ std::int64_t MaxIterations = std::numeric_limits<std::int64_t>::max();
+
+public:
+ WatchedLiteralsSolver() = default;
+
+ // `Work` specifies a computational limit on the solver. Units of "work"
+ // roughly correspond to attempts to assign a value to a single
+ // variable. Since the algorithm is exponential in the number of variables,
+ // this is the most direct (abstract) unit to target.
+ explicit WatchedLiteralsSolver(std::int64_t WorkLimit)
+ : MaxIterations(WorkLimit) {}
+
+ Result solve(llvm::ArrayRef<const Formula *> Vals) override;
+
+ // The solver reached its maximum number of iterations.
+ bool reachedLimit() const { return MaxIterations == 0; }
+};
+
+} // namespace dataflow
+} // namespace clang
+
+#endif // LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_WATCHEDLITERALSSOLVER_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/MacroExpansionContext.h b/contrib/llvm-project/clang/include/clang/Analysis/MacroExpansionContext.h
index 57934bfc09d9..2a27aba76656 100644
--- a/contrib/llvm-project/clang/include/clang/Analysis/MacroExpansionContext.h
+++ b/contrib/llvm-project/clang/include/clang/Analysis/MacroExpansionContext.h
@@ -13,9 +13,9 @@
#include "clang/Basic/SourceLocation.h"
#include "clang/Lex/Preprocessor.h"
#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/Optional.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/SmallVector.h"
+#include <optional>
namespace clang {
@@ -85,14 +85,16 @@ public:
/// \param MacroExpansionLoc Must be the expansion location of a macro.
/// \return The textual representation of the token sequence which was
/// substituted in place of the macro after the preprocessing.
- /// If no macro was expanded at that location, returns llvm::None.
- Optional<StringRef> getExpandedText(SourceLocation MacroExpansionLoc) const;
+ /// If no macro was expanded at that location, returns std::nullopt.
+ std::optional<StringRef>
+ getExpandedText(SourceLocation MacroExpansionLoc) const;
/// \param MacroExpansionLoc Must be the expansion location of a macro.
/// \return The text from the original source code which were substituted by
/// the macro expansion chain from the given location.
- /// If no macro was expanded at that location, returns llvm::None.
- Optional<StringRef> getOriginalText(SourceLocation MacroExpansionLoc) const;
+ /// If no macro was expanded at that location, returns std::nullopt.
+ std::optional<StringRef>
+ getOriginalText(SourceLocation MacroExpansionLoc) const;
LLVM_DUMP_METHOD void dumpExpansionRangesToStream(raw_ostream &OS) const;
LLVM_DUMP_METHOD void dumpExpandedTextsToStream(raw_ostream &OS) const;
diff --git a/contrib/llvm-project/clang/include/clang/Analysis/PathDiagnostic.h b/contrib/llvm-project/clang/include/clang/Analysis/PathDiagnostic.h
index 539aa20b8168..90559e7efb06 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"
@@ -19,7 +19,6 @@
#include "clang/Basic/SourceLocation.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/FoldingSet.h"
-#include "llvm/ADT/Optional.h"
#include "llvm/ADT/PointerUnion.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
@@ -30,6 +29,7 @@
#include <list>
#include <map>
#include <memory>
+#include <optional>
#include <set>
#include <string>
#include <utility>
@@ -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;
@@ -75,14 +73,8 @@ struct PathDiagnosticConsumerOptions {
bool ShouldSerializeStats = false;
/// If the consumer intends to produce multiple output files, should it
- /// use randomly generated file names for these files (with the tiny risk of
- /// having random collisions) or deterministic human-readable file names
- /// (with a larger risk of deterministic collisions or invalid characters
- /// in the file name). We should not really give this choice to the users
- /// because deterministic mode is always superior when done right, but
- /// for some consumers this mode is experimental and needs to be
- /// off by default.
- bool ShouldWriteStableReportFilename = false;
+ /// use a pseudo-random file name or a human-readable file name.
+ bool ShouldWriteVerboseReportFilename = false;
/// Whether the consumer should treat consumed diagnostics as hard errors.
/// Useful for breaking your build when issues are found.
@@ -151,11 +143,14 @@ public:
/// Only runs visitors, no output generated.
None,
- /// Used for HTML, SARIF, and text output.
+ /// Used for SARIF and text output.
Minimal,
/// Used for plist output, used for "arrows" generation.
Extensive,
+
+ /// Used for HTML, shows both "arrows" and control notes.
+ Everything
};
virtual PathGenerationScheme getGenerationScheme() const { return Minimal; }
@@ -164,7 +159,11 @@ public:
return getGenerationScheme() != None;
}
- bool shouldAddPathEdges() const { return getGenerationScheme() == Extensive; }
+ bool shouldAddPathEdges() const { return getGenerationScheme() >= Extensive; }
+ bool shouldAddControlNotes() const {
+ return getGenerationScheme() == Minimal ||
+ getGenerationScheme() == Everything;
+ }
virtual bool supportsLogicalOpControlFlow() const { return false; }
@@ -533,7 +532,7 @@ public:
};
class PathDiagnosticEventPiece : public PathDiagnosticSpotPiece {
- Optional<bool> IsPrunable;
+ std::optional<bool> IsPrunable;
public:
PathDiagnosticEventPiece(const PathDiagnosticLocation &pos,
@@ -545,15 +544,13 @@ public:
/// flag may have been previously set, at which point it will not
/// be reset unless one specifies to do so.
void setPrunable(bool isPrunable, bool override = false) {
- if (IsPrunable.hasValue() && !override)
- return;
+ if (IsPrunable && !override)
+ return;
IsPrunable = isPrunable;
}
/// Return true if the diagnostic piece is prunable.
- bool isPrunable() const {
- return IsPrunable.hasValue() ? IsPrunable.getValue() : false;
- }
+ bool isPrunable() const { return IsPrunable.value_or(false); }
void dump() const override;
@@ -904,4 +901,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..b9339570e1ae 100644
--- a/contrib/llvm-project/clang/include/clang/Analysis/ProgramPoint.h
+++ b/contrib/llvm-project/clang/include/clang/Analysis/ProgramPoint.h
@@ -18,19 +18,18 @@
#include "clang/Analysis/CFG.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/FoldingSet.h"
-#include "llvm/ADT/Optional.h"
#include "llvm/ADT/PointerIntPair.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/DataTypes.h"
#include <cassert>
+#include <optional>
#include <string>
#include <utility>
namespace clang {
class AnalysisDeclContext;
-class FunctionDecl;
class LocationContext;
/// ProgramPoints can be "tagged" as representing points specific to a given
@@ -96,35 +95,33 @@ private:
llvm::PointerIntPair<const ProgramPointTag *, 2, unsigned> Tag;
+ CFGBlock::ConstCFGElementRef ElemRef = {nullptr, 0};
+
protected:
ProgramPoint() = default;
- ProgramPoint(const void *P,
- Kind k,
- const LocationContext *l,
- const ProgramPointTag *tag = nullptr)
- : Data1(P),
- Data2(nullptr, (((unsigned) k) >> 0) & 0x3),
- L(l, (((unsigned) k) >> 2) & 0x3),
- Tag(tag, (((unsigned) k) >> 4) & 0x3) {
- assert(getKind() == k);
- assert(getLocationContext() == l);
- assert(getData1() == P);
- }
-
- ProgramPoint(const void *P1,
- const void *P2,
- Kind k,
- const LocationContext *l,
- const ProgramPointTag *tag = nullptr)
- : Data1(P1),
- Data2(P2, (((unsigned) k) >> 0) & 0x3),
- L(l, (((unsigned) k) >> 2) & 0x3),
- Tag(tag, (((unsigned) k) >> 4) & 0x3) {}
+ ProgramPoint(const void *P, Kind k, const LocationContext *l,
+ const ProgramPointTag *tag = nullptr,
+ CFGBlock::ConstCFGElementRef ElemRef = {nullptr, 0})
+ : Data1(P), Data2(nullptr, (((unsigned)k) >> 0) & 0x3),
+ L(l, (((unsigned)k) >> 2) & 0x3), Tag(tag, (((unsigned)k) >> 4) & 0x3),
+ ElemRef(ElemRef) {
+ assert(getKind() == k);
+ assert(getLocationContext() == l);
+ assert(getData1() == P);
+ }
+
+ ProgramPoint(const void *P1, const void *P2, Kind k, const LocationContext *l,
+ const ProgramPointTag *tag = nullptr,
+ CFGBlock::ConstCFGElementRef ElemRef = {nullptr, 0})
+ : Data1(P1), Data2(P2, (((unsigned)k) >> 0) & 0x3),
+ L(l, (((unsigned)k) >> 2) & 0x3), Tag(tag, (((unsigned)k) >> 4) & 0x3),
+ ElemRef(ElemRef) {}
protected:
const void *getData1() const { return Data1; }
const void *getData2() const { return Data2.getPointer(); }
void setData2(const void *d) { Data2.setPointer(d); }
+ CFGBlock::ConstCFGElementRef getElementRef() const { return ElemRef; }
public:
/// Create a new ProgramPoint object that is the same as the original
@@ -145,12 +142,11 @@ public:
return t;
}
- /// Convert to the specified ProgramPoint type, returning None if this
+ /// Convert to the specified ProgramPoint type, returning std::nullopt if this
/// ProgramPoint is not of the desired type.
- template<typename T>
- Optional<T> getAs() const {
+ template <typename T> std::optional<T> getAs() const {
if (!T::isKind(*this))
- return None;
+ return std::nullopt;
T t;
ProgramPoint& PP = t;
PP = *this;
@@ -192,17 +188,13 @@ public:
}
bool operator==(const ProgramPoint & RHS) const {
- return Data1 == RHS.Data1 &&
- Data2 == RHS.Data2 &&
- L == RHS.L &&
- Tag == RHS.Tag;
+ return Data1 == RHS.Data1 && Data2 == RHS.Data2 && L == RHS.L &&
+ Tag == RHS.Tag && ElemRef == RHS.ElemRef;
}
bool operator!=(const ProgramPoint &RHS) const {
- return Data1 != RHS.Data1 ||
- Data2 != RHS.Data2 ||
- L != RHS.L ||
- Tag != RHS.Tag;
+ return Data1 != RHS.Data1 || Data2 != RHS.Data2 || L != RHS.L ||
+ Tag != RHS.Tag || ElemRef != RHS.ElemRef;
}
void Profile(llvm::FoldingSetNodeID& ID) const {
@@ -211,6 +203,8 @@ public:
ID.AddPointer(getData2());
ID.AddPointer(getLocationContext());
ID.AddPointer(getTag());
+ ID.AddPointer(ElemRef.getParent());
+ ID.AddInteger(ElemRef.getIndexInBlock());
}
void printJson(llvm::raw_ostream &Out, const char *NL = "\n") const;
@@ -234,9 +228,9 @@ public:
return reinterpret_cast<const CFGBlock*>(getData1());
}
- Optional<CFGElement> getFirstElement() const {
+ std::optional<CFGElement> getFirstElement() const {
const CFGBlock *B = getBlock();
- return B->empty() ? Optional<CFGElement>() : B->front();
+ return B->empty() ? std::optional<CFGElement>() : B->front();
}
private:
@@ -268,6 +262,7 @@ private:
}
};
+// FIXME: Eventually we want to take a CFGElementRef as parameter here too.
class StmtPoint : public ProgramPoint {
public:
StmtPoint(const Stmt *S, const void *p2, Kind k, const LocationContext *L,
@@ -559,8 +554,9 @@ private:
class ImplicitCallPoint : public ProgramPoint {
public:
ImplicitCallPoint(const Decl *D, SourceLocation Loc, Kind K,
- const LocationContext *L, const ProgramPointTag *Tag)
- : ProgramPoint(Loc.getPtrEncoding(), D, K, L, Tag) {}
+ const LocationContext *L, const ProgramPointTag *Tag,
+ CFGBlock::ConstCFGElementRef ElemRef)
+ : ProgramPoint(Loc.getPtrEncoding(), D, K, L, Tag, ElemRef) {}
const Decl *getDecl() const { return static_cast<const Decl *>(getData2()); }
SourceLocation getLocation() const {
@@ -583,8 +579,9 @@ private:
class PreImplicitCall : public ImplicitCallPoint {
public:
PreImplicitCall(const Decl *D, SourceLocation Loc, const LocationContext *L,
+ CFGBlock::ConstCFGElementRef ElemRef,
const ProgramPointTag *Tag = nullptr)
- : ImplicitCallPoint(D, Loc, PreImplicitCallKind, L, Tag) {}
+ : ImplicitCallPoint(D, Loc, PreImplicitCallKind, L, Tag, ElemRef) {}
private:
friend class ProgramPoint;
@@ -600,8 +597,9 @@ private:
class PostImplicitCall : public ImplicitCallPoint {
public:
PostImplicitCall(const Decl *D, SourceLocation Loc, const LocationContext *L,
+ CFGBlock::ConstCFGElementRef ElemRef,
const ProgramPointTag *Tag = nullptr)
- : ImplicitCallPoint(D, Loc, PostImplicitCallKind, L, Tag) {}
+ : ImplicitCallPoint(D, Loc, PostImplicitCallKind, L, Tag, ElemRef) {}
private:
friend class ProgramPoint;
diff --git a/contrib/llvm-project/clang/include/clang/Analysis/RetainSummaryManager.h b/contrib/llvm-project/clang/include/clang/Analysis/RetainSummaryManager.h
index b7ccb0317830..86865b9da421 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"
@@ -25,6 +25,7 @@
#include "clang/Analysis/AnyCall.h"
#include "clang/Analysis/SelectorExtras.h"
#include "llvm/ADT/STLExtras.h"
+#include <optional>
using namespace clang;
@@ -648,8 +649,9 @@ public:
IdentityOrZero
};
- Optional<BehaviorSummary> canEval(const CallExpr *CE, const FunctionDecl *FD,
- bool &hasTrustedImplementationAnnotation);
+ std::optional<BehaviorSummary>
+ canEval(const CallExpr *CE, const FunctionDecl *FD,
+ bool &hasTrustedImplementationAnnotation);
/// \return Whether the type corresponds to a known smart pointer
/// implementation (that is, everything about it is inlineable).
@@ -686,8 +688,8 @@ private:
Selector S, QualType RetTy);
/// Determine if there is a special return effect for this function or method.
- Optional<RetEffect> getRetEffectFromAnnotations(QualType RetTy,
- const Decl *D);
+ std::optional<RetEffect> getRetEffectFromAnnotations(QualType RetTy,
+ const Decl *D);
void updateSummaryFromAnnotations(const RetainSummary *&Summ,
const ObjCMethodDecl *MD);
@@ -719,14 +721,14 @@ private:
/// type for functions/methods) @c QT has any of the given attributes,
/// provided they pass necessary validation checks AND tracking the given
/// attribute is enabled.
- /// Returns the object kind corresponding to the present attribute, or None,
- /// if none of the specified attributes are present.
+ /// Returns the object kind corresponding to the present attribute, or
+ /// std::nullopt, if none of the specified attributes are present.
/// Crashes if passed an attribute which is not explicitly handled.
template <class T>
- Optional<ObjKind> hasAnyEnabledAttrOf(const Decl *D, QualType QT);
+ std::optional<ObjKind> hasAnyEnabledAttrOf(const Decl *D, QualType QT);
template <class T1, class T2, class... Others>
- Optional<ObjKind> hasAnyEnabledAttrOf(const Decl *D, QualType QT);
+ std::optional<ObjKind> hasAnyEnabledAttrOf(const Decl *D, QualType QT);
friend class RetainSummaryTemplate;
};
diff --git a/contrib/llvm-project/clang/include/clang/Analysis/SelectorExtras.h b/contrib/llvm-project/clang/include/clang/Analysis/SelectorExtras.h
index d26e9159a937..1e1daf5706bb 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"
@@ -16,7 +16,7 @@ namespace clang {
template <typename... IdentifierInfos>
static inline Selector getKeywordSelector(ASTContext &Ctx,
IdentifierInfos *... IIs) {
- static_assert(sizeof...(IdentifierInfos),
+ static_assert(sizeof...(IdentifierInfos) > 0,
"keyword selectors must have at least one argument");
SmallVector<IdentifierInfo *, 10> II({&Ctx.Idents.get(IIs)...});
diff --git a/contrib/llvm-project/clang/include/clang/Analysis/Support/BumpVector.h b/contrib/llvm-project/clang/include/clang/Analysis/Support/BumpVector.h
index 74092dabbfda..6c3f11e99306 100644
--- a/contrib/llvm-project/clang/include/clang/Analysis/Support/BumpVector.h
+++ b/contrib/llvm-project/clang/include/clang/Analysis/Support/BumpVector.h
@@ -42,6 +42,15 @@ public:
Other.Alloc.setPointer(nullptr);
}
+ // The move assignment operator is defined as deleted pending further
+ // motivation.
+ BumpVectorContext &operator=(BumpVectorContext &&) = delete;
+
+ // The copy constrcutor and copy assignment operator is defined as deleted
+ // pending further motivation.
+ BumpVectorContext(const BumpVectorContext &) = delete;
+ BumpVectorContext &operator=(const BumpVectorContext &) = delete;
+
/// Construct a new BumpVectorContext that reuses an existing
/// BumpPtrAllocator. This BumpPtrAllocator is not destroyed when the
/// BumpVectorContext object is destroyed.
diff --git a/contrib/llvm-project/clang/include/clang/Basic/AArch64SVEACLETypes.def b/contrib/llvm-project/clang/include/clang/Basic/AArch64SVEACLETypes.def
index b98a07436e94..fa9c1ac0491c 100644
--- a/contrib/llvm-project/clang/include/clang/Basic/AArch64SVEACLETypes.def
+++ b/contrib/llvm-project/clang/include/clang/Basic/AArch64SVEACLETypes.def
@@ -49,6 +49,11 @@
SVE_TYPE(Name, Id, SingletonId)
#endif
+#ifndef SVE_OPAQUE_TYPE
+#define SVE_OPAQUE_TYPE(Name, MangledName, Id, SingletonId) \
+ SVE_TYPE(Name, Id, SingletonId)
+#endif
+
//===- Vector point types -----------------------------------------------===//
@@ -66,7 +71,7 @@ SVE_VECTOR_TYPE("__SVFloat16_t", "__SVFloat16_t", SveFloat16, SveFloat16Ty, 8, 1
SVE_VECTOR_TYPE("__SVFloat32_t", "__SVFloat32_t", SveFloat32, SveFloat32Ty, 4, 32, true, true, false)
SVE_VECTOR_TYPE("__SVFloat64_t", "__SVFloat64_t", SveFloat64, SveFloat64Ty, 2, 64, true, true, false)
-SVE_VECTOR_TYPE("__SVBFloat16_t", "__SVBFloat16_t", SveBFloat16, SveBFloat16Ty, 8, 16, true, false, true)
+SVE_VECTOR_TYPE("__SVBfloat16_t", "__SVBfloat16_t", SveBFloat16, SveBFloat16Ty, 8, 16, true, false, true)
//
// x2
@@ -124,7 +129,12 @@ SVE_VECTOR_TYPE("__clang_svfloat64x4_t", "svfloat64x4_t", SveFloat64x4, SveFloat
SVE_VECTOR_TYPE("__clang_svbfloat16x4_t", "svbfloat16x4_t", SveBFloat16x4, SveBFloat16x4Ty, 32, 16, true, false, true)
SVE_PREDICATE_TYPE("__SVBool_t", "__SVBool_t", SveBool, SveBoolTy, 16)
+SVE_PREDICATE_TYPE("__clang_svboolx2_t", "svboolx2_t", SveBoolx2, SveBoolx2Ty, 32)
+SVE_PREDICATE_TYPE("__clang_svboolx4_t", "svboolx4_t", SveBoolx4, SveBoolx4Ty, 64)
+
+SVE_OPAQUE_TYPE("__SVCount_t", "__SVCount_t", SveCount, SveCountTy)
#undef SVE_VECTOR_TYPE
#undef SVE_PREDICATE_TYPE
+#undef SVE_OPAQUE_TYPE
#undef SVE_TYPE
diff --git a/contrib/llvm-project/clang/include/clang/Basic/AddressSpaces.h b/contrib/llvm-project/clang/include/clang/Basic/AddressSpaces.h
index 99bb67fd26d1..7b723d508fff 100644
--- a/contrib/llvm-project/clang/include/clang/Basic/AddressSpaces.h
+++ b/contrib/llvm-project/clang/include/clang/Basic/AddressSpaces.h
@@ -56,6 +56,12 @@ enum class LangAS : unsigned {
ptr32_uptr,
ptr64,
+ // HLSL specific address spaces.
+ hlsl_groupshared,
+
+ // Wasm specific address spaces.
+ wasm_funcref,
+
// This denotes the count of language-specific address spaces and also
// the offset added to the target-specific address spaces, which are usually
// specified by address space attributes __attribute__(address_space(n))).
diff --git a/contrib/llvm-project/clang/include/clang/Basic/AlignedAllocation.h b/contrib/llvm-project/clang/include/clang/Basic/AlignedAllocation.h
index ab9f19da5d59..ac26eb4a276d 100644
--- a/contrib/llvm-project/clang/include/clang/Basic/AlignedAllocation.h
+++ b/contrib/llvm-project/clang/include/clang/Basic/AlignedAllocation.h
@@ -12,12 +12,12 @@
///
//===----------------------------------------------------------------------===//
-#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"
#include "llvm/Support/VersionTuple.h"
+#include "llvm/TargetParser/Triple.h"
namespace clang {
@@ -26,8 +26,8 @@ inline llvm::VersionTuple alignedAllocMinVersion(llvm::Triple::OSType OS) {
default:
break;
case llvm::Triple::Darwin:
- case llvm::Triple::MacOSX: // Earliest supporting version is 10.14.
- return llvm::VersionTuple(10U, 14U);
+ case llvm::Triple::MacOSX: // Earliest supporting version is 10.13.
+ return llvm::VersionTuple(10U, 13U);
case llvm::Triple::IOS:
case llvm::Triple::TvOS: // Earliest supporting version is 11.0.0.
return llvm::VersionTuple(11U);
@@ -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 12d09181a2ea..dbf2dd2120fb 100644
--- a/contrib/llvm-project/clang/include/clang/Basic/Attr.td
+++ b/contrib/llvm-project/clang/include/clang/Basic/Attr.td
@@ -19,10 +19,19 @@ def DocCatType : DocumentationCategory<"Type Attributes">;
def DocCatStmt : DocumentationCategory<"Statement Attributes">;
def DocCatDecl : DocumentationCategory<"Declaration Attributes">;
-// Attributes listed under the Undocumented category do not generate any public
-// documentation. Ideally, this category should be used for internal-only
-// attributes which contain no spellings.
-def DocCatUndocumented : DocumentationCategory<"Undocumented">;
+// This category is for attributes which have not yet been properly documented,
+// but should be.
+def DocCatUndocumented : DocumentationCategory<"Undocumented"> {
+ let Content = [{
+This section lists attributes which are recognized by Clang, but which are
+currently missing documentation.
+}];
+}
+
+// Attributes listed under the InternalOnly category do not generate any entry
+// in the documentation. This category should be used only when we _want_
+// to not document the attribute, e.g. if the attribute has no spellings.
+def DocCatInternalOnly : DocumentationCategory<"InternalOnly">;
class DocDeprecated<string replacement = ""> {
// If the Replacement field is empty, no replacement will be listed with the
@@ -48,11 +57,17 @@ class Documentation {
DocDeprecated Deprecated;
}
-// Specifies that the attribute is explicitly undocumented. This can be a
-// helpful placeholder for the attribute while working on the implementation,
-// but should not be used once feature work has been completed.
+// Specifies that the attribute is explicitly omitted from the documentation,
+// because it is not intended to be user-facing.
+def InternalOnly : Documentation {
+ let Category = DocCatInternalOnly;
+}
+
+// Specifies that the attribute is undocumented, but that it _should_ have
+// documentation.
def Undocumented : Documentation {
let Category = DocCatUndocumented;
+ let Content = "No documentation.";
}
include "clang/Basic/AttrDocs.td"
@@ -92,6 +107,10 @@ def NonBitField : SubsetSubject<Field,
[{!S->isBitField()}],
"non-bit-field non-static data members">;
+def BitField : SubsetSubject<Field,
+ [{S->isBitField()}],
+ "bit-field data members">;
+
def NonStaticCXXMethod : SubsetSubject<CXXMethod,
[{!S->isStatic()}],
"non-static member functions">;
@@ -118,6 +137,17 @@ def SharedVar : SubsetSubject<Var,
def GlobalVar : SubsetSubject<Var,
[{S->hasGlobalStorage()}], "global variables">;
+def ExternalGlobalVar : SubsetSubject<Var,
+ [{S->hasGlobalStorage() &&
+ S->getStorageClass()!=StorageClass::SC_Static &&
+ !S->isLocalExternDecl()}],
+ "external global variables">;
+
+def NonTLSGlobalVar : SubsetSubject<Var,
+ [{S->hasGlobalStorage() &&
+ S->getTLSKind() == 0}],
+ "non-TLS global variables">;
+
def InlineFunction : SubsetSubject<Function,
[{S->isInlineSpecified()}], "inline functions">;
@@ -126,6 +156,14 @@ def FunctionTmpl
FunctionDecl::TK_FunctionTemplate}],
"function templates">;
+def HLSLEntry
+ : SubsetSubject<Function,
+ [{S->isExternallyVisible() && !isa<CXXMethodDecl>(S)}],
+ "global functions">;
+def HLSLBufferObj : SubsetSubject<HLSLBuffer,
+ [{isa<HLSLBufferDecl>(S)}],
+ "cbuffer/tbuffer">;
+
def ClassTmpl : SubsetSubject<CXXRecord, [{S->getDescribedClassTemplate()}],
"class templates">;
@@ -139,6 +177,12 @@ def FunctionLike : SubsetSubject<DeclBase,
[{S->getFunctionType(false) != nullptr}],
"functions, function pointers">;
+// Function Pointer is a stricter version of FunctionLike that only allows function
+// pointers.
+def FunctionPointer : SubsetSubject<DeclBase,
+ [{S->isFunctionPointerType()}],
+ "functions pointers">;
+
def OpenCLKernelFunction
: SubsetSubject<Function, [{S->hasAttr<OpenCLKernelAttr>()}],
"kernel functions">;
@@ -201,6 +245,7 @@ class DeclArgument<DeclNode kind, string name, bit opt = 0, bit fake = 0>
// OMPTraitProperty := {Kind}
//
class OMPTraitInfoArgument<string name> : Argument<name, 0>;
+class VariadicOMPInteropInfoArgument<string name> : Argument<name, 0>;
class TypeArgument<string name, bit opt = 0> : Argument<name, opt>;
class UnsignedArgument<string name, bit opt = 0> : Argument<name, opt>;
@@ -237,64 +282,91 @@ class DefaultIntArgument<string name, int default> : IntArgument<name, 1> {
int Default = default;
}
-// This argument is more complex, it includes the enumerator type name,
-// a list of strings to accept, and a list of enumerators to map them to.
+// This argument is more complex, it includes the enumerator type
+// name, whether the enum type is externally defined, a list of
+// strings to accept, and a list of enumerators to map them to.
class EnumArgument<string name, string type, list<string> values,
- list<string> enums, bit opt = 0, bit fake = 0>
+ list<string> enums, bit opt = 0, bit fake = 0,
+ bit isExternalType = 0>
: Argument<name, opt, fake> {
string Type = type;
list<string> Values = values;
list<string> Enums = enums;
+ bit IsExternalType = isExternalType;
}
// FIXME: There should be a VariadicArgument type that takes any other type
// of argument and generates the appropriate type.
class VariadicEnumArgument<string name, string type, list<string> values,
- list<string> enums> : Argument<name, 1> {
+ list<string> enums, bit isExternalType = 0>
+ : Argument<name, 1> {
string Type = type;
list<string> Values = values;
list<string> Enums = enums;
+ bit IsExternalType = isExternalType;
}
+// Represents an attribute wrapped by another attribute.
+class WrappedAttr<string name, bit opt = 0> : Argument<name, opt>;
+
// This handles one spelling of an attribute.
-class Spelling<string name, string variety> {
+class Spelling<string name, string variety, int version = 1> {
string Name = name;
string Variety = variety;
+ int Version = version;
}
class GNU<string name> : Spelling<name, "GNU">;
-class Declspec<string name> : Spelling<name, "Declspec">;
+class Declspec<string name> : Spelling<name, "Declspec"> {
+ bit PrintOnLeft = 1;
+}
class Microsoft<string name> : Spelling<name, "Microsoft">;
class CXX11<string namespace, string name, int version = 1>
- : Spelling<name, "CXX11"> {
+ : Spelling<name, "CXX11", version> {
+ bit CanPrintOnLeft = 0;
string Namespace = namespace;
- int Version = version;
}
-class C2x<string namespace, string name, int version = 1>
- : Spelling<name, "C2x"> {
+class C23<string namespace, string name, int version = 1>
+ : Spelling<name, "C23", version> {
string Namespace = namespace;
- int Version = version;
}
-class Keyword<string name> : Spelling<name, "Keyword">;
+class Keyword<string name, bit hasOwnParseRules>
+ : Spelling<name, "Keyword"> {
+ bit HasOwnParseRules = hasOwnParseRules;
+}
+
+// A keyword that can appear wherever a standard attribute can appear,
+// and that appertains to whatever a standard attribute would appertain to.
+// This is useful for things that affect semantics but that should otherwise
+// be treated like standard attributes.
+class RegularKeyword<string name> : Keyword<name, 0> {}
+
+// A keyword that has its own individual parsing rules.
+class CustomKeyword<string name> : Keyword<name, 1> {}
+
class Pragma<string namespace, string name> : Spelling<name, "Pragma"> {
string Namespace = namespace;
}
// The GCC spelling implies GNU<name>, CXX11<"gnu", name>, and optionally,
-// C2x<"gnu", name>. This spelling should be used for any GCC-compatible
+// C23<"gnu", name>. This spelling should be used for any GCC-compatible
// attributes.
class GCC<string name, bit allowInC = 1> : Spelling<name, "GCC"> {
bit AllowInC = allowInC;
}
// The Clang spelling implies GNU<name>, CXX11<"clang", name>, and optionally,
-// C2x<"clang", name>. This spelling should be used for any Clang-specific
+// C23<"clang", name>. This spelling should be used for any Clang-specific
// attributes.
-class Clang<string name, bit allowInC = 1> : Spelling<name, "Clang"> {
+class Clang<string name, bit allowInC = 1, int version = 1>
+ : Spelling<name, "Clang", version> {
bit AllowInC = allowInC;
}
+// HLSL Semantic spellings
+class HLSLSemantic<string name> : Spelling<name, "HLSLSemantic">;
+
class Accessor<string name, list<Spelling> spellings> {
string Name = name;
list<Spelling> Spellings = spellings;
@@ -336,6 +408,8 @@ def ObjCAutoRefCount : LangOpt<"ObjCAutoRefCount">;
def ObjCNonFragileRuntime
: LangOpt<"", "LangOpts.ObjCRuntime.allowsClassStubs()">;
+def HLSL : LangOpt<"HLSL">;
+
// Language option for CMSE extensions
def Cmse : LangOpt<"Cmse">;
@@ -361,10 +435,11 @@ class TargetArch<list<string> arches> : TargetSpec {
let Arches = arches;
}
def TargetARM : TargetArch<["arm", "thumb", "armeb", "thumbeb"]>;
-def TargetAArch64 : TargetArch<["aarch64"]>;
+def TargetAArch64 : TargetArch<["aarch64", "aarch64_be", "aarch64_32"]>;
def TargetAnyArm : TargetArch<!listconcat(TargetARM.Arches, TargetAArch64.Arches)>;
def TargetAVR : TargetArch<["avr"]>;
def TargetBPF : TargetArch<["bpfel", "bpfeb"]>;
+def TargetLoongArch : TargetArch<["loongarch32", "loongarch64"]>;
def TargetMips32 : TargetArch<["mips", "mipsel"]>;
def TargetAnyMips : TargetArch<["mips", "mipsel", "mips64", "mips64el"]>;
def TargetMSP430 : TargetArch<["msp430"]>;
@@ -373,6 +448,10 @@ def TargetRISCV : TargetArch<["riscv32", "riscv64"]>;
def TargetX86 : TargetArch<["x86"]>;
def TargetAnyX86 : TargetArch<["x86", "x86_64"]>;
def TargetWebAssembly : TargetArch<["wasm32", "wasm64"]>;
+def TargetNVPTX : TargetArch<["nvptx", "nvptx64"]>;
+def TargetWindows : TargetSpec {
+ let OSes = ["Win32"];
+}
def TargetHasDLLImportExport : TargetSpec {
let CustomCode = [{ Target.getTriple().hasDLLImportExport() }];
}
@@ -385,10 +464,19 @@ def TargetMicrosoftCXXABI : TargetArch<["x86", "x86_64", "arm", "thumb", "aarch6
def TargetELF : TargetSpec {
let ObjectFormats = ["ELF"];
}
+def TargetELFOrMachO : TargetSpec {
+ let ObjectFormats = ["ELF", "MachO"];
+}
def TargetSupportsInitPriority : TargetSpec {
let CustomCode = [{ !Target.getTriple().isOSzOS() }];
}
+
+class TargetSpecificSpelling<TargetSpec target, list<Spelling> spellings> {
+ TargetSpec Target = target;
+ list<Spelling> Spellings = spellings;
+}
+
// Attribute subject match rules that are used for #pragma clang attribute.
//
// A instance of AttrSubjectMatcherRule represents an individual match rule.
@@ -501,6 +589,12 @@ class AttrSubjectMatcherAggregateRule<AttrSubject subject> {
def SubjectMatcherForNamed : AttrSubjectMatcherAggregateRule<Named>;
class Attr {
+ // Specifies that when printed, this attribute is meaningful on the
+ // 'left side' of the declaration.
+ bit CanPrintOnLeft = 1;
+ // Specifies that when printed, this attribute is required to be printed on
+ // the 'left side' of the declaration.
+ bit PrintOnLeft = 0;
// The various ways in which an attribute can be spelled in source
list<Spelling> Spellings;
// The things to which an attribute can appertain
@@ -509,6 +603,8 @@ class Attr {
list<Argument> Args = [];
// Accessors which should be generated for the attribute.
list<Accessor> Accessors = [];
+ // Specify targets for spellings.
+ list<TargetSpecificSpelling> TargetSpecificSpellings = [];
// Set to true for attributes with arguments which require delayed parsing.
bit LateParsed = 0;
// Set to false to prevent an attribute from being propagated from a template
@@ -541,6 +637,8 @@ class Attr {
// match rules.
// - It has GNU/CXX11 spelling and doesn't require delayed parsing.
bit PragmaAttributeSupport;
+ // Set to true if this attribute accepts parameter pack expansion expressions.
+ bit AcceptsExprPack = 0;
// Lists language options, one of which is required to be true for the
// attribute to be applicable. If empty, no language options are required.
list<LangOpt> LangOpts = [];
@@ -580,6 +678,9 @@ class DeclOrTypeAttr : InheritableAttr;
/// A attribute is either a declaration attribute or a statement attribute.
class DeclOrStmtAttr : InheritableAttr;
+/// An attribute class for HLSL Annotations.
+class HLSLAnnotationAttr : InheritableAttr;
+
/// A target-specific attribute. This class is meant to be used as a mixin
/// with InheritableAttr or Attr depending on the attribute's needs.
class TargetSpecificAttr<TargetSpec target> {
@@ -614,7 +715,7 @@ class IgnoredAttr : Attr {
let Ignored = 1;
let ASTNode = 0;
let SemaHandler = 0;
- let Documentation = [Undocumented];
+ let Documentation = [InternalOnly];
}
//
@@ -644,7 +745,7 @@ def Alias : Attr {
def BuiltinAlias : Attr {
let Spellings = [CXX11<"clang", "builtin_alias">,
- C2x<"clang", "builtin_alias">,
+ C23<"clang", "builtin_alias">,
GNU<"clang_builtin_alias">];
let Args = [IdentifierArgument<"BuiltinName">];
let Subjects = SubjectList<[Function], ErrorDiag>;
@@ -659,13 +760,13 @@ def ArmBuiltinAlias : InheritableAttr, TargetSpecificAttr<TargetAnyArm> {
}
def Aligned : InheritableAttr {
- let Spellings = [GCC<"aligned">, Declspec<"align">, Keyword<"alignas">,
- Keyword<"_Alignas">];
+ let Spellings = [GCC<"aligned">, Declspec<"align">, CustomKeyword<"alignas">,
+ CustomKeyword<"_Alignas">];
let Args = [AlignedArgument<"Alignment", 1>];
let Accessors = [Accessor<"isGNU", [GCC<"aligned">]>,
- Accessor<"isC11", [Keyword<"_Alignas">]>,
- Accessor<"isAlignas", [Keyword<"alignas">,
- Keyword<"_Alignas">]>,
+ Accessor<"isC11", [CustomKeyword<"_Alignas">]>,
+ Accessor<"isAlignas", [CustomKeyword<"alignas">,
+ CustomKeyword<"_Alignas">]>,
Accessor<"isDeclspec",[Declspec<"align">]>];
let Documentation = [Undocumented];
}
@@ -694,19 +795,23 @@ def AlignMac68k : InheritableAttr {
// This attribute has no spellings as it is only ever created implicitly.
let Spellings = [];
let SemaHandler = 0;
- let Documentation = [Undocumented];
+ let Documentation = [InternalOnly];
}
def AlignNatural : InheritableAttr {
// This attribute has no spellings as it is only ever created implicitly.
let Spellings = [];
let SemaHandler = 0;
- let Documentation = [Undocumented];
+ let Documentation = [InternalOnly];
}
-def AlwaysInline : InheritableAttr {
- let Spellings = [GCC<"always_inline">, Keyword<"__forceinline">];
- let Subjects = SubjectList<[Function]>;
+def AlwaysInline : DeclOrStmtAttr {
+ let Spellings = [GCC<"always_inline">, CXX11<"clang", "always_inline">,
+ C23<"clang", "always_inline">, CustomKeyword<"__forceinline">];
+ let Accessors = [Accessor<"isClangAlwaysInline", [CXX11<"clang", "always_inline">,
+ C23<"clang", "always_inline">]>];
+ let Subjects = SubjectList<[Function, Stmt], WarnDiag,
+ "functions and statements">;
let Documentation = [AlwaysInlineDocs];
}
@@ -745,7 +850,8 @@ def XRayLogArgs : InheritableAttr {
def PatchableFunctionEntry
: InheritableAttr,
TargetSpecificAttr<TargetArch<
- ["aarch64", "aarch64_be", "riscv32", "riscv64", "x86", "x86_64"]>> {
+ ["aarch64", "aarch64_be", "loongarch32", "loongarch64", "riscv32",
+ "riscv64", "x86", "x86_64"]>> {
let Spellings = [GCC<"patchable_function_entry">];
let Subjects = SubjectList<[Function, ObjCMethod]>;
let Args = [UnsignedArgument<"Count">, DefaultIntArgument<"Offset", 0>];
@@ -779,14 +885,23 @@ def Annotate : InheritableParamAttr {
return AnnotateAttr::Create(Ctx, Annotation, nullptr, 0, CommonInfo);
}
static AnnotateAttr *CreateImplicit(ASTContext &Ctx, llvm::StringRef Annotation, \
- const AttributeCommonInfo &CommonInfo = {SourceRange{}}) {
+ const AttributeCommonInfo &CommonInfo) {
return AnnotateAttr::CreateImplicit(Ctx, Annotation, nullptr, 0, CommonInfo);
}
}];
let PragmaAttributeSupport = 1;
+ let AcceptsExprPack = 1;
let Documentation = [Undocumented];
}
+def AnnotateType : TypeAttr {
+ let Spellings = [CXX11<"clang", "annotate_type">, C23<"clang", "annotate_type">];
+ let Args = [StringArgument<"Annotation">, VariadicExprArgument<"Args">];
+ let HasCustomParsing = 1;
+ let AcceptsExprPack = 1;
+ let Documentation = [AnnotateTypeDocs];
+}
+
def ARMInterrupt : InheritableAttr, TargetSpecificAttr<TargetARM> {
// NOTE: If you add any additional spellings, M68kInterrupt's,
// MSP430Interrupt's, MipsInterrupt's and AnyX86Interrupt's spellings
@@ -815,7 +930,8 @@ def AVRSignal : InheritableAttr, TargetSpecificAttr<TargetAVR> {
}
def AsmLabel : InheritableAttr {
- let Spellings = [Keyword<"asm">, Keyword<"__asm__">];
+ let CanPrintOnLeft = 0;
+ let Spellings = [CustomKeyword<"asm">, CustomKeyword<"__asm__">];
let Args = [
// Label specifies the mangled name for the decl.
StringArgument<"Label">,
@@ -848,10 +964,12 @@ def Availability : InheritableAttr {
[{static llvm::StringRef getPrettyPlatformName(llvm::StringRef Platform) {
return llvm::StringSwitch<llvm::StringRef>(Platform)
.Case("android", "Android")
+ .Case("fuchsia", "Fuchsia")
.Case("ios", "iOS")
.Case("macos", "macOS")
.Case("tvos", "tvOS")
.Case("watchos", "watchOS")
+ .Case("driverkit", "DriverKit")
.Case("ios_app_extension", "iOS (App Extension)")
.Case("macos_app_extension", "macOS (App Extension)")
.Case("tvos_app_extension", "tvOS (App Extension)")
@@ -859,6 +977,8 @@ def Availability : InheritableAttr {
.Case("maccatalyst", "macCatalyst")
.Case("maccatalyst_app_extension", "macCatalyst (App Extension)")
.Case("swift", "Swift")
+ .Case("shadermodel", "HLSL ShaderModel")
+ .Case("ohos", "OpenHarmony OS")
.Default(llvm::StringRef());
}
static llvm::StringRef getPlatformNameSourceSpelling(llvm::StringRef Platform) {
@@ -874,6 +994,7 @@ static llvm::StringRef getPlatformNameSourceSpelling(llvm::StringRef Platform) {
.Case("maccatalyst", "macCatalyst")
.Case("maccatalyst_app_extension", "macCatalystApplicationExtension")
.Case("zos", "z/OS")
+ .Case("shadermodel", "ShaderModel")
.Default(Platform);
}
static llvm::StringRef canonicalizePlatformName(llvm::StringRef Platform) {
@@ -888,6 +1009,7 @@ static llvm::StringRef canonicalizePlatformName(llvm::StringRef Platform) {
.Case("watchOSApplicationExtension", "watchos_app_extension")
.Case("macCatalyst", "maccatalyst")
.Case("macCatalystApplicationExtension", "maccatalyst_app_extension")
+ .Case("ShaderModel", "shadermodel")
.Default(Platform);
} }];
let HasCustomParsing = 1;
@@ -897,10 +1019,12 @@ static llvm::StringRef canonicalizePlatformName(llvm::StringRef Platform) {
}
def ExternalSourceSymbol : InheritableAttr {
- let Spellings = [Clang<"external_source_symbol">];
+ let Spellings = [Clang<"external_source_symbol", /*allowInC=*/1,
+ /*version=*/20230206>];
let Args = [StringArgument<"language", 1>,
StringArgument<"definedIn", 1>,
- BoolArgument<"generatedDeclaration", 1>];
+ BoolArgument<"generatedDeclaration", 1>,
+ StringArgument<"USR", 1>];
let HasCustomParsing = 1;
let Subjects = SubjectList<[Named]>;
let Documentation = [ExternalSourceSymbolDocs];
@@ -925,7 +1049,7 @@ def CarriesDependency : InheritableParamAttr {
}
def CDecl : DeclOrTypeAttr {
- let Spellings = [GCC<"cdecl">, Keyword<"__cdecl">, Keyword<"_cdecl">];
+ let Spellings = [GCC<"cdecl">, CustomKeyword<"__cdecl">, CustomKeyword<"_cdecl">];
// let Subjects = [Function, ObjCMethod];
let Documentation = [Undocumented];
}
@@ -970,6 +1094,50 @@ def CFConsumed : InheritableParamAttr {
let Documentation = [RetainBehaviorDocs];
}
+
+// coro_only_destroy_when_complete indicates the coroutines whose return type
+// is marked by coro_only_destroy_when_complete can only be destroyed when the
+// coroutine completes. Then the space for the destroy functions can be saved.
+def CoroOnlyDestroyWhenComplete : InheritableAttr {
+ let Spellings = [Clang<"coro_only_destroy_when_complete">];
+ let Subjects = SubjectList<[CXXRecord]>;
+ let LangOpts = [CPlusPlus];
+ let Documentation = [CoroOnlyDestroyWhenCompleteDocs];
+ let SimpleHandler = 1;
+}
+
+def CoroReturnType : InheritableAttr {
+ let Spellings = [Clang<"coro_return_type">];
+ let Subjects = SubjectList<[CXXRecord]>;
+ let LangOpts = [CPlusPlus];
+ let Documentation = [CoroReturnTypeAndWrapperDoc];
+ let SimpleHandler = 1;
+}
+
+def CoroWrapper : InheritableAttr {
+ let Spellings = [Clang<"coro_wrapper">];
+ let Subjects = SubjectList<[Function]>;
+ let LangOpts = [CPlusPlus];
+ let Documentation = [CoroReturnTypeAndWrapperDoc];
+ let SimpleHandler = 1;
+}
+
+def CoroLifetimeBound : InheritableAttr {
+ let Spellings = [Clang<"coro_lifetimebound">];
+ let Subjects = SubjectList<[CXXRecord]>;
+ let LangOpts = [CPlusPlus];
+ let Documentation = [CoroLifetimeBoundDoc];
+ let SimpleHandler = 1;
+}
+
+def CoroDisableLifetimeBound : InheritableAttr {
+ let Spellings = [Clang<"coro_disable_lifetimebound">];
+ let Subjects = SubjectList<[Function]>;
+ let LangOpts = [CPlusPlus];
+ let Documentation = [CoroLifetimeBoundDoc];
+ let SimpleHandler = 1;
+}
+
// OSObject-based attributes.
def OSConsumed : InheritableParamAttr {
let Spellings = [Clang<"os_consumed">];
@@ -1012,7 +1180,7 @@ def Cleanup : InheritableAttr {
let Spellings = [GCC<"cleanup">];
let Args = [DeclArgument<Function, "FunctionDecl">];
let Subjects = SubjectList<[LocalVar]>;
- let Documentation = [Undocumented];
+ let Documentation = [CleanupDocs];
}
def CmseNSEntry : InheritableAttr, TargetSpecificAttr<TargetARM> {
@@ -1031,7 +1199,7 @@ def CmseNSCall : TypeAttr, TargetSpecificAttr<TargetARM> {
def Cold : InheritableAttr {
let Spellings = [GCC<"cold">];
let Subjects = SubjectList<[Function]>;
- let Documentation = [Undocumented];
+ let Documentation = [ColdFunctionEntryDocs];
let SimpleHandler = 1;
}
@@ -1050,10 +1218,10 @@ def Const : InheritableAttr {
def ConstInit : InheritableAttr {
// This attribute does not have a C [[]] spelling because it requires the
// CPlusPlus language option.
- let Spellings = [Keyword<"constinit">,
+ let Spellings = [CustomKeyword<"constinit">,
Clang<"require_constant_initialization", 0>];
let Subjects = SubjectList<[GlobalVar], ErrorDiag>;
- let Accessors = [Accessor<"isConstinit", [Keyword<"constinit">]>];
+ let Accessors = [Accessor<"isConstinit", [CustomKeyword<"constinit">]>];
let Documentation = [ConstInitDocs];
let LangOpts = [CPlusPlus];
let SimpleHandler = 1;
@@ -1063,7 +1231,7 @@ def Constructor : InheritableAttr {
let Spellings = [GCC<"constructor">];
let Args = [DefaultIntArgument<"Priority", 65535>];
let Subjects = SubjectList<[Function]>;
- let Documentation = [Undocumented];
+ let Documentation = [CtorDtorDocs];
}
def CPUSpecific : InheritableAttr {
@@ -1150,6 +1318,12 @@ def CUDAHost : InheritableAttr {
}
def : MutualExclusions<[CUDAGlobal, CUDAHost]>;
+def NVPTXKernel : InheritableAttr, TargetSpecificAttr<TargetNVPTX> {
+ let Spellings = [Clang<"nvptx_kernel">];
+ let Subjects = SubjectList<[Function]>;
+ let Documentation = [Undocumented];
+}
+
def HIPManaged : InheritableAttr {
let Spellings = [GNU<"managed">, Declspec<"__managed__">];
let Subjects = SubjectList<[Var]>;
@@ -1161,12 +1335,13 @@ def CUDAInvalidTarget : InheritableAttr {
let Spellings = [];
let Subjects = SubjectList<[Function]>;
let LangOpts = [CUDA];
- let Documentation = [Undocumented];
+ let Documentation = [InternalOnly];
}
def CUDALaunchBounds : InheritableAttr {
let Spellings = [GNU<"launch_bounds">, Declspec<"__launch_bounds__">];
- let Args = [ExprArgument<"MaxThreads">, ExprArgument<"MinBlocks", 1>];
+ let Args = [ExprArgument<"MaxThreads">, ExprArgument<"MinBlocks", 1>,
+ ExprArgument<"MaxBlocks", 1>];
let LangOpts = [CUDA];
let Subjects = SubjectList<[ObjCMethod, FunctionLike]>;
// An AST node is created for this attribute, but is not used by other parts
@@ -1190,24 +1365,31 @@ 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 Spellings = [CustomKeyword<"_Noreturn">];
let Subjects = SubjectList<[Function], ErrorDiag>;
let SemaHandler = 0;
let Documentation = [C11NoReturnDocs];
}
def CXX11NoReturn : InheritableAttr {
- let Spellings = [CXX11<"", "noreturn", 200809>];
+ let Spellings = [CXX11<"", "noreturn", 200809>,
+ C23<"", "noreturn", 202202>, C23<"", "_Noreturn", 202202>];
let Subjects = SubjectList<[Function], ErrorDiag>;
let Documentation = [CXX11NoReturnDocs];
- let SimpleHandler = 1;
}
// Similar to CUDA, OpenCL attributes do not receive a [[]] spelling because
// the specification does not expose them with one currently.
def OpenCLKernel : InheritableAttr {
- let Spellings = [Keyword<"__kernel">, Keyword<"kernel">];
+ let Spellings = [CustomKeyword<"__kernel">, CustomKeyword<"kernel">];
let Subjects = SubjectList<[Function], ErrorDiag>;
let Documentation = [Undocumented];
let SimpleHandler = 1;
@@ -1231,26 +1413,28 @@ def OpenCLIntelReqdSubGroupSize: InheritableAttr {
// This attribute is both a type attribute, and a declaration attribute (for
// parameter variables).
def OpenCLAccess : Attr {
- let Spellings = [Keyword<"__read_only">, Keyword<"read_only">,
- Keyword<"__write_only">, Keyword<"write_only">,
- Keyword<"__read_write">, Keyword<"read_write">];
+ let Spellings = [CustomKeyword<"__read_only">, CustomKeyword<"read_only">,
+ CustomKeyword<"__write_only">, CustomKeyword<"write_only">,
+ CustomKeyword<"__read_write">, CustomKeyword<"read_write">];
let Subjects = SubjectList<[ParmVar, TypedefName], ErrorDiag>;
- let Accessors = [Accessor<"isReadOnly", [Keyword<"__read_only">,
- Keyword<"read_only">]>,
- Accessor<"isReadWrite", [Keyword<"__read_write">,
- Keyword<"read_write">]>,
- Accessor<"isWriteOnly", [Keyword<"__write_only">,
- Keyword<"write_only">]>];
+ let Accessors = [Accessor<"isReadOnly", [CustomKeyword<"__read_only">,
+ CustomKeyword<"read_only">]>,
+ Accessor<"isReadWrite", [CustomKeyword<"__read_write">,
+ CustomKeyword<"read_write">]>,
+ Accessor<"isWriteOnly", [CustomKeyword<"__write_only">,
+ CustomKeyword<"write_only">]>];
let Documentation = [OpenCLAccessDocs];
}
def OpenCLPrivateAddressSpace : TypeAttr {
- let Spellings = [Keyword<"__private">, Keyword<"private">, Clang<"opencl_private">];
+ let Spellings = [CustomKeyword<"__private">, CustomKeyword<"private">,
+ Clang<"opencl_private">];
let Documentation = [OpenCLAddressSpacePrivateDocs];
}
def OpenCLGlobalAddressSpace : TypeAttr {
- let Spellings = [Keyword<"__global">, Keyword<"global">, Clang<"opencl_global">];
+ let Spellings = [CustomKeyword<"__global">, CustomKeyword<"global">,
+ Clang<"opencl_global">];
let Documentation = [OpenCLAddressSpaceGlobalDocs];
}
@@ -1265,17 +1449,20 @@ def OpenCLGlobalHostAddressSpace : TypeAttr {
}
def OpenCLLocalAddressSpace : TypeAttr {
- let Spellings = [Keyword<"__local">, Keyword<"local">, Clang<"opencl_local">];
+ let Spellings = [CustomKeyword<"__local">, CustomKeyword<"local">,
+ Clang<"opencl_local">];
let Documentation = [OpenCLAddressSpaceLocalDocs];
}
def OpenCLConstantAddressSpace : TypeAttr {
- let Spellings = [Keyword<"__constant">, Keyword<"constant">, Clang<"opencl_constant">];
+ let Spellings = [CustomKeyword<"__constant">, CustomKeyword<"constant">,
+ Clang<"opencl_constant">];
let Documentation = [OpenCLAddressSpaceConstantDocs];
}
def OpenCLGenericAddressSpace : TypeAttr {
- let Spellings = [Keyword<"__generic">, Keyword<"generic">, Clang<"opencl_generic">];
+ let Spellings = [CustomKeyword<"__generic">, CustomKeyword<"generic">,
+ Clang<"opencl_generic">];
let Documentation = [OpenCLAddressSpaceGenericDocs];
}
@@ -1298,7 +1485,7 @@ def RenderScriptKernel : Attr {
def Deprecated : InheritableAttr {
let Spellings = [GCC<"deprecated">, Declspec<"deprecated">,
CXX11<"","deprecated", 201309>,
- C2x<"", "deprecated", 201904>];
+ C23<"", "deprecated", 201904>];
let Args = [StringArgument<"Message", 1>,
// An optional string argument that enables us to provide a
// Fix-It.
@@ -1311,7 +1498,7 @@ def Destructor : InheritableAttr {
let Spellings = [GCC<"destructor">];
let Args = [DefaultIntArgument<"Priority", 65535>];
let Subjects = SubjectList<[Function]>;
- let Documentation = [Undocumented];
+ let Documentation = [CtorDtorDocs];
}
def EmptyBases : InheritableAttr, TargetSpecificAttr<TargetMicrosoftCXXABI> {
@@ -1331,6 +1518,7 @@ def AllocSize : InheritableAttr {
}
def EnableIf : InheritableAttr {
+ let CanPrintOnLeft = 0;
// Does not have a [[]] spelling because this attribute requires the ability
// to parse function arguments but the attribute is not written in the type
// position.
@@ -1356,7 +1544,7 @@ def ExtVectorType : Attr {
def FallThrough : StmtAttr {
let Spellings = [CXX11<"", "fallthrough", 201603>,
- C2x<"", "fallthrough", 201904>,
+ C23<"", "fallthrough", 201910>,
CXX11<"clang", "fallthrough">, GCC<"fallthrough">];
// The attribute only applies to a NullStmt, but we have special fix-it
// behavior if applied to a case label.
@@ -1366,12 +1554,12 @@ def FallThrough : StmtAttr {
}
def Likely : StmtAttr {
- let Spellings = [CXX11<"", "likely", 201803>, C2x<"clang", "likely">];
+ let Spellings = [CXX11<"", "likely", 201803>, C23<"clang", "likely">];
let Documentation = [LikelihoodDocs];
}
def Unlikely : StmtAttr {
- let Spellings = [CXX11<"", "unlikely", 201803>, C2x<"clang", "unlikely">];
+ let Spellings = [CXX11<"", "unlikely", 201803>, C23<"clang", "unlikely">];
let Documentation = [LikelihoodDocs];
}
def : MutualExclusions<[Likely, Unlikely]>;
@@ -1379,10 +1567,8 @@ def : MutualExclusions<[Likely, Unlikely]>;
def NoMerge : DeclOrStmtAttr {
let Spellings = [Clang<"nomerge">];
let Documentation = [NoMergeDocs];
- let InheritEvenIfAlreadyPresent = 1;
- let Subjects = SubjectList<[Function, Stmt], ErrorDiag,
- "functions and statements">;
- let SimpleHandler = 1;
+ let Subjects = SubjectList<[Function, Stmt, Var], ErrorDiag,
+ "functions, statements and variables">;
}
def MustTail : StmtAttr {
@@ -1392,28 +1578,31 @@ def MustTail : StmtAttr {
}
def FastCall : DeclOrTypeAttr {
- let Spellings = [GCC<"fastcall">, Keyword<"__fastcall">,
- Keyword<"_fastcall">];
+ let Spellings = [GCC<"fastcall">, CustomKeyword<"__fastcall">,
+ CustomKeyword<"_fastcall">];
// let Subjects = [Function, ObjCMethod];
let Documentation = [FastCallDocs];
}
def RegCall : DeclOrTypeAttr {
- let Spellings = [GCC<"regcall">, Keyword<"__regcall">];
+ let Spellings = [GCC<"regcall">, CustomKeyword<"__regcall">];
let Documentation = [RegCallDocs];
}
def Final : InheritableAttr {
- let Spellings = [Keyword<"final">, Keyword<"sealed">];
- let Accessors = [Accessor<"isSpelledAsSealed", [Keyword<"sealed">]>];
+ let CanPrintOnLeft = 0;
+ let Spellings = [CustomKeyword<"final">, CustomKeyword<"sealed">];
+ let Accessors = [Accessor<"isSpelledAsSealed", [CustomKeyword<"sealed">]>];
let SemaHandler = 0;
- let Documentation = [Undocumented];
+ // Omitted from docs, since this is language syntax, not an attribute, as far
+ // as users are concerned.
+ let Documentation = [InternalOnly];
}
def MinSize : InheritableAttr {
let Spellings = [Clang<"minsize">];
let Subjects = SubjectList<[Function, ObjCMethod], ErrorDiag>;
- let Documentation = [Undocumented];
+ let Documentation = [MinSizeDocs];
}
def FlagEnum : InheritableAttr {
@@ -1469,9 +1658,7 @@ def GNUInline : InheritableAttr {
def Hot : InheritableAttr {
let Spellings = [GCC<"hot">];
let Subjects = SubjectList<[Function]>;
- // An AST node is created for this attribute, but not actually used beyond
- // semantic checking for mutual exclusion with the Cold attribute.
- let Documentation = [Undocumented];
+ let Documentation = [HotFunctionEntryDocs];
let SimpleHandler = 1;
}
def : MutualExclusions<[Hot, Cold]>;
@@ -1499,7 +1686,7 @@ def IBOutletCollection : InheritableAttr {
let Documentation = [Undocumented];
}
-def IFunc : Attr, TargetSpecificAttr<TargetELF> {
+def IFunc : Attr, TargetSpecificAttr<TargetELFOrMachO> {
let Spellings = [GCC<"ifunc">];
let Args = [StringArgument<"Resolver">];
let Subjects = SubjectList<[Function]>;
@@ -1549,7 +1736,7 @@ def MaxFieldAlignment : InheritableAttr {
let Spellings = [];
let Args = [UnsignedArgument<"Alignment">];
let SemaHandler = 0;
- let Documentation = [Undocumented];
+ let Documentation = [InternalOnly];
}
def MayAlias : InheritableAttr {
@@ -1686,11 +1873,14 @@ def ArmMveStrictPolymorphism : TypeAttr, TargetSpecificAttr<TargetARM> {
let Documentation = [ArmMveStrictPolymorphismDocs];
}
-def NoUniqueAddress : InheritableAttr, TargetSpecificAttr<TargetItaniumCXXABI> {
- let Spellings = [CXX11<"", "no_unique_address", 201803>];
+def NoUniqueAddress : InheritableAttr {
let Subjects = SubjectList<[NonBitField], ErrorDiag>;
+ let Spellings = [CXX11<"", "no_unique_address", 201803>, CXX11<"msvc", "no_unique_address", 201803>];
+ let TargetSpecificSpellings = [
+ TargetSpecificSpelling<TargetItaniumCXXABI, [CXX11<"", "no_unique_address", 201803>]>,
+ TargetSpecificSpelling<TargetMicrosoftCXXABI, [CXX11<"msvc", "no_unique_address", 201803>]>,
+ ];
let Documentation = [NoUniqueAddressDocs];
- let SimpleHandler = 1;
}
def ReturnsTwice : InheritableAttr {
@@ -1750,10 +1940,15 @@ def Convergent : InheritableAttr {
let SimpleHandler = 1;
}
-def NoInline : InheritableAttr {
- let Spellings = [GCC<"noinline">, Declspec<"noinline">];
- let Subjects = SubjectList<[Function]>;
- let Documentation = [Undocumented];
+def NoInline : DeclOrStmtAttr {
+ let Spellings = [CustomKeyword<"__noinline__">, GCC<"noinline">,
+ CXX11<"clang", "noinline">, C23<"clang", "noinline">,
+ Declspec<"noinline">];
+ let Accessors = [Accessor<"isClangNoInline", [CXX11<"clang", "noinline">,
+ C23<"clang", "noinline">]>];
+ let Documentation = [NoInlineDocs];
+ let Subjects = SubjectList<[Function, Stmt], WarnDiag,
+ "functions and statements">;
let SimpleHandler = 1;
}
@@ -1775,13 +1970,23 @@ def RISCVInterrupt : InheritableAttr, TargetSpecificAttr<TargetRISCV> {
let Spellings = [GCC<"interrupt">];
let Subjects = SubjectList<[Function]>;
let Args = [EnumArgument<"Interrupt", "InterruptType",
- ["user", "supervisor", "machine"],
- ["user", "supervisor", "machine"],
+ ["supervisor", "machine"],
+ ["supervisor", "machine"],
1>];
let ParseKind = "Interrupt";
let Documentation = [RISCVInterruptDocs];
}
+def RISCVRVVVectorBits : TypeAttr {
+ let Spellings = [GNU<"riscv_rvv_vector_bits">];
+ let Subjects = SubjectList<[TypedefName], ErrorDiag>;
+ let Args = [UnsignedArgument<"NumBits">];
+ let Documentation = [RISCVRVVVectorBitsDocs];
+ let PragmaAttributeSupport = 0;
+ // Represented as VectorType instead.
+ let ASTNode = 0;
+}
+
// This is not a TargetSpecificAttr so that is silently accepted and
// ignored on other targets as encouraged by the OpenCL spec.
//
@@ -1827,6 +2032,11 @@ def AMDGPUNumVGPR : InheritableAttr {
let Subjects = SubjectList<[Function], ErrorDiag, "kernel functions">;
}
+def AMDGPUKernelCall : DeclOrTypeAttr {
+ let Spellings = [Clang<"amdgpu_kernel">];
+ let Documentation = [Undocumented];
+}
+
def BPFPreserveAccessIndex : InheritableAttr,
TargetSpecificAttr<TargetBPF> {
let Spellings = [Clang<"preserve_access_index">];
@@ -1835,6 +2045,30 @@ def BPFPreserveAccessIndex : InheritableAttr,
let LangOpts = [COnly];
}
+def BPFPreserveStaticOffset : InheritableAttr,
+ TargetSpecificAttr<TargetBPF> {
+ let Spellings = [Clang<"preserve_static_offset">];
+ let Subjects = SubjectList<[Record], ErrorDiag>;
+ let Documentation = [BPFPreserveStaticOffsetDocs];
+ let LangOpts = [COnly];
+}
+
+def BTFDeclTag : InheritableAttr {
+ let Spellings = [Clang<"btf_decl_tag">];
+ let Args = [StringArgument<"BTFDeclTag">];
+ let Subjects = SubjectList<[Var, Function, Record, Field, TypedefName],
+ ErrorDiag>;
+ let Documentation = [BTFDeclTagDocs];
+ let LangOpts = [COnly];
+}
+
+def BTFTypeTag : TypeAttr {
+ let Spellings = [Clang<"btf_type_tag">];
+ let Args = [StringArgument<"BTFTypeTag">];
+ let Documentation = [BTFTypeTagDocs];
+ let LangOpts = [COnly];
+}
+
def WebAssemblyExportName : InheritableAttr,
TargetSpecificAttr<TargetWebAssembly> {
let Spellings = [Clang<"export_name">];
@@ -1875,9 +2109,9 @@ def NonNull : InheritableParamAttr {
bool isNonNull(unsigned IdxAST) const {
if (!args_size())
return true;
- return args_end() != std::find_if(
- args_begin(), args_end(),
- [=](const ParamIdx &Idx) { return Idx.getASTIndex() == IdxAST; });
+ return llvm::any_of(args(), [=](const ParamIdx &Idx) {
+ return Idx.getASTIndex() == IdxAST;
+ });
}
}];
// FIXME: We should merge duplicates into a single nonnull attribute.
@@ -1911,22 +2145,22 @@ def PassObjectSize : InheritableParamAttr {
// Nullability type attributes.
def TypeNonNull : TypeAttr {
- let Spellings = [Keyword<"_Nonnull">];
+ let Spellings = [CustomKeyword<"_Nonnull">];
let Documentation = [TypeNonNullDocs];
}
def TypeNullable : TypeAttr {
- let Spellings = [Keyword<"_Nullable">];
+ let Spellings = [CustomKeyword<"_Nullable">];
let Documentation = [TypeNullableDocs];
}
def TypeNullableResult : TypeAttr {
- let Spellings = [Keyword<"_Nullable_result">];
+ let Spellings = [CustomKeyword<"_Nullable_result">];
let Documentation = [TypeNullableResultDocs];
}
def TypeNullUnspecified : TypeAttr {
- let Spellings = [Keyword<"_Null_unspecified">];
+ let Spellings = [CustomKeyword<"_Null_unspecified">];
let Documentation = [TypeNullUnspecifiedDocs];
}
@@ -1934,12 +2168,12 @@ def TypeNullUnspecified : TypeAttr {
// ignored because ARC is not enabled. The usual representation for this
// qualifier is as an ObjCOwnership attribute with Kind == "none".
def ObjCInertUnsafeUnretained : TypeAttr {
- let Spellings = [Keyword<"__unsafe_unretained">];
- let Documentation = [Undocumented];
+ let Spellings = [CustomKeyword<"__unsafe_unretained">];
+ let Documentation = [InternalOnly];
}
def ObjCKindOf : TypeAttr {
- let Spellings = [Keyword<"__kindof">];
+ let Spellings = [CustomKeyword<"__kindof">];
let Documentation = [Undocumented];
}
@@ -1949,6 +2183,13 @@ def NoEscape : Attr {
let Documentation = [NoEscapeDocs];
}
+def MaybeUndef : InheritableAttr {
+ let Spellings = [Clang<"maybe_undef">];
+ let Subjects = SubjectList<[ParmVar]>;
+ let Documentation = [MaybeUndefDocs];
+ let SimpleHandler = 1;
+}
+
def AssumeAligned : InheritableAttr {
let Spellings = [GCC<"assume_aligned">];
let Subjects = SubjectList<[ObjCMethod, Function]>;
@@ -1971,7 +2212,7 @@ def NoReturn : InheritableAttr {
def NoInstrumentFunction : InheritableAttr {
let Spellings = [GCC<"no_instrument_function">];
- let Subjects = SubjectList<[Function]>;
+ let Subjects = SubjectList<[Function, ObjCMethod]>;
let Documentation = [Undocumented];
let SimpleHandler = 1;
}
@@ -1992,18 +2233,33 @@ def NotTailCalled : InheritableAttr {
def : MutualExclusions<[AlwaysInline, NotTailCalled]>;
def NoStackProtector : InheritableAttr {
- let Spellings = [Clang<"no_stack_protector">];
+ let Spellings = [Clang<"no_stack_protector">, CXX11<"gnu", "no_stack_protector">,
+ C23<"gnu", "no_stack_protector">, Declspec<"safebuffers">];
let Subjects = SubjectList<[Function]>;
let Documentation = [NoStackProtectorDocs];
let SimpleHandler = 1;
}
+def StrictGuardStackCheck : InheritableAttr {
+ let Spellings = [Declspec<"strict_gs_check">];
+ let Subjects = SubjectList<[Function]>;
+ let Documentation = [StrictGuardStackCheckDocs];
+ let SimpleHandler = 1;
+}
+
def NoThrow : InheritableAttr {
let Spellings = [GCC<"nothrow">, Declspec<"nothrow">];
let Subjects = SubjectList<[FunctionLike]>;
let Documentation = [NoThrowDocs];
}
+def NoUwtable : InheritableAttr {
+ let Spellings = [Clang<"nouwtable">];
+ let Subjects = SubjectList<[FunctionLike]>;
+ let Documentation = [NoUwtableDocs];
+ let SimpleHandler = 1;
+}
+
def NvWeak : IgnoredAttr {
// No Declspec spelling of this attribute; the CUDA headers use
// __attribute__((nv_weak)) unconditionally. Does not receive an [[]]
@@ -2039,7 +2295,7 @@ def ObjCBridgeRelated : InheritableAttr {
def NSErrorDomain : InheritableAttr {
let Spellings = [GNU<"ns_error_domain">];
let Subjects = SubjectList<[Enum], ErrorDiag>;
- let Args = [DeclArgument<Var, "ErrorDomain">];
+ let Args = [IdentifierArgument<"ErrorDomain">];
let Documentation = [NSErrorDomainDocs];
}
@@ -2217,9 +2473,12 @@ def Overloadable : Attr {
}
def Override : InheritableAttr {
- let Spellings = [Keyword<"override">];
+ let CanPrintOnLeft = 0;
+ let Spellings = [CustomKeyword<"override">];
let SemaHandler = 0;
- let Documentation = [Undocumented];
+ // Omitted from docs, since this is language syntax, not an attribute, as far
+ // as users are concerned.
+ let Documentation = [InternalOnly];
}
def Ownership : InheritableAttr {
@@ -2268,6 +2527,74 @@ def AArch64VectorPcs: DeclOrTypeAttr {
let Documentation = [AArch64VectorPcsDocs];
}
+def AArch64SVEPcs: DeclOrTypeAttr {
+ let Spellings = [Clang<"aarch64_sve_pcs">];
+ let Documentation = [AArch64SVEPcsDocs];
+}
+
+def ArmStreaming : TypeAttr, TargetSpecificAttr<TargetAArch64> {
+ let Spellings = [RegularKeyword<"__arm_streaming">];
+ let Subjects = SubjectList<[HasFunctionProto], ErrorDiag>;
+ let Documentation = [ArmSmeStreamingDocs];
+}
+
+def ArmStreamingCompatible : TypeAttr, TargetSpecificAttr<TargetAArch64> {
+ let Spellings = [RegularKeyword<"__arm_streaming_compatible">];
+ let Subjects = SubjectList<[HasFunctionProto], ErrorDiag>;
+ let Documentation = [ArmSmeStreamingCompatibleDocs];
+}
+
+def ArmNew : InheritableAttr, TargetSpecificAttr<TargetAArch64> {
+ let Spellings = [RegularKeyword<"__arm_new">];
+ let Args = [VariadicStringArgument<"NewArgs">];
+ let Subjects = SubjectList<[Function], ErrorDiag>;
+ let Documentation = [ArmNewDocs];
+
+ let AdditionalMembers = [{
+ bool isNewZA() const {
+ return llvm::is_contained(newArgs(), "za");
+ }
+ bool isNewZT0() const {
+ return llvm::is_contained(newArgs(), "zt0");
+ }
+ }];
+}
+
+def ArmIn : TypeAttr, TargetSpecificAttr<TargetAArch64> {
+ let Spellings = [RegularKeyword<"__arm_in">];
+ let Args = [VariadicStringArgument<"InArgs">];
+ let Subjects = SubjectList<[HasFunctionProto], ErrorDiag>;
+ let Documentation = [ArmInDocs];
+}
+
+def ArmOut : TypeAttr, TargetSpecificAttr<TargetAArch64> {
+ let Spellings = [RegularKeyword<"__arm_out">];
+ let Args = [VariadicStringArgument<"OutArgs">];
+ let Subjects = SubjectList<[HasFunctionProto], ErrorDiag>;
+ let Documentation = [ArmOutDocs];
+}
+
+def ArmInOut : TypeAttr, TargetSpecificAttr<TargetAArch64> {
+ let Spellings = [RegularKeyword<"__arm_inout">];
+ let Args = [VariadicStringArgument<"InOutArgs">];
+ let Subjects = SubjectList<[HasFunctionProto], ErrorDiag>;
+ let Documentation = [ArmInOutDocs];
+}
+
+def ArmPreserves : TypeAttr, TargetSpecificAttr<TargetAArch64> {
+ let Spellings = [RegularKeyword<"__arm_preserves">];
+ let Args = [VariadicStringArgument<"PreserveArgs">];
+ let Subjects = SubjectList<[HasFunctionProto], ErrorDiag>;
+ let Documentation = [ArmPreservesDocs];
+}
+
+def ArmLocallyStreaming : InheritableAttr, TargetSpecificAttr<TargetAArch64> {
+ let Spellings = [RegularKeyword<"__arm_locally_streaming">];
+ let Subjects = SubjectList<[Function], ErrorDiag>;
+ let Documentation = [ArmSmeLocallyStreamingDocs];
+}
+
+
def Pure : InheritableAttr {
let Spellings = [GCC<"pure">];
let Documentation = [Undocumented];
@@ -2293,6 +2620,7 @@ def SwiftAttr : InheritableAttr {
let Spellings = [GNU<"swift_attr">];
let Args = [StringArgument<"Attribute">];
let Documentation = [SwiftAttrDocs];
+ let PragmaAttributeSupport = 1;
}
def SwiftBridge : InheritableAttr {
@@ -2328,6 +2656,22 @@ def SwiftError : InheritableAttr {
let Documentation = [SwiftErrorDocs];
}
+def SwiftImportAsNonGeneric : InheritableAttr {
+ // This attribute has no spellings as it is only ever created implicitly
+ // from API notes.
+ let Spellings = [];
+ let SemaHandler = 0;
+ let Documentation = [InternalOnly];
+}
+
+def SwiftImportPropertyAsAccessors : InheritableAttr {
+ // This attribute has no spellings as it is only ever created implicitly
+ // from API notes.
+ let Spellings = [];
+ let SemaHandler = 0;
+ let Documentation = [InternalOnly];
+}
+
def SwiftName : InheritableAttr {
let Spellings = [GNU<"swift_name">];
let Args = [StringArgument<"Name">];
@@ -2349,6 +2693,31 @@ def SwiftPrivate : InheritableAttr {
let SimpleHandler = 1;
}
+def SwiftVersionedAddition : Attr {
+ // This attribute has no spellings as it is only ever created implicitly
+ // from API notes.
+ let Spellings = [];
+ let Args = [VersionArgument<"Version">, WrappedAttr<"AdditionalAttr">,
+ BoolArgument<"IsReplacedByActive">];
+ let SemaHandler = 0;
+ let Documentation = [InternalOnly];
+}
+
+def SwiftVersionedRemoval : Attr {
+ // This attribute has no spellings as it is only ever created implicitly
+ // from API notes.
+ let Spellings = [];
+ let Args = [VersionArgument<"Version">, UnsignedArgument<"RawKind">,
+ BoolArgument<"IsReplacedByActive">];
+ let SemaHandler = 0;
+ let Documentation = [InternalOnly];
+ let AdditionalMembers = [{
+ attr::Kind getAttrKindToRemove() const {
+ return static_cast<attr::Kind>(getRawKind());
+ }
+ }];
+}
+
def NoDeref : TypeAttr {
let Spellings = [Clang<"noderef">];
let Documentation = [NoDerefDocs];
@@ -2402,7 +2771,7 @@ def PragmaClangBSSSection : InheritableAttr {
let Spellings = [];
let Args = [StringArgument<"Name">];
let Subjects = SubjectList<[GlobalVar], ErrorDiag>;
- let Documentation = [Undocumented];
+ let Documentation = [InternalOnly];
}
def PragmaClangDataSection : InheritableAttr {
@@ -2410,7 +2779,7 @@ def PragmaClangDataSection : InheritableAttr {
let Spellings = [];
let Args = [StringArgument<"Name">];
let Subjects = SubjectList<[GlobalVar], ErrorDiag>;
- let Documentation = [Undocumented];
+ let Documentation = [InternalOnly];
}
def PragmaClangRodataSection : InheritableAttr {
@@ -2418,7 +2787,7 @@ def PragmaClangRodataSection : InheritableAttr {
let Spellings = [];
let Args = [StringArgument<"Name">];
let Subjects = SubjectList<[GlobalVar], ErrorDiag>;
- let Documentation = [Undocumented];
+ let Documentation = [InternalOnly];
}
def PragmaClangRelroSection : InheritableAttr {
@@ -2426,7 +2795,7 @@ def PragmaClangRelroSection : InheritableAttr {
let Spellings = [];
let Args = [StringArgument<"Name">];
let Subjects = SubjectList<[GlobalVar], ErrorDiag>;
- let Documentation = [Undocumented];
+ let Documentation = [InternalOnly];
}
def StrictFP : InheritableAttr {
@@ -2434,7 +2803,7 @@ def StrictFP : InheritableAttr {
// Function uses strict floating point operations.
let Spellings = [];
let Subjects = SubjectList<[Function]>;
- let Documentation = [Undocumented];
+ let Documentation = [InternalOnly];
}
def PragmaClangTextSection : InheritableAttr {
@@ -2442,7 +2811,16 @@ def PragmaClangTextSection : InheritableAttr {
let Spellings = [];
let Args = [StringArgument<"Name">];
let Subjects = SubjectList<[Function], ErrorDiag>;
- let Documentation = [Undocumented];
+ let Documentation = [InternalOnly];
+}
+
+def CodeModel : InheritableAttr, TargetSpecificAttr<TargetLoongArch> {
+ let Spellings = [GCC<"model">];
+ let Args = [EnumArgument<"Model", "llvm::CodeModel::Model",
+ ["normal", "medium", "extreme"], ["Small", "Medium", "Large"],
+ /*opt=*/0, /*fake=*/0, /*isExternalType=*/1>];
+ let Subjects = SubjectList<[NonTLSGlobalVar], ErrorDiag>;
+ let Documentation = [CodeModelDocs];
}
def Sentinel : InheritableAttr {
@@ -2454,7 +2832,8 @@ def Sentinel : InheritableAttr {
}
def StdCall : DeclOrTypeAttr {
- let Spellings = [GCC<"stdcall">, Keyword<"__stdcall">, Keyword<"_stdcall">];
+ let Spellings = [GCC<"stdcall">, CustomKeyword<"__stdcall">,
+ CustomKeyword<"_stdcall">];
// let Subjects = [Function, ObjCMethod];
let Documentation = [StdCallDocs];
}
@@ -2510,9 +2889,10 @@ def SwiftAsyncError : InheritableAttr {
let Documentation = [SwiftAsyncErrorDocs];
}
-def Suppress : StmtAttr {
- let Spellings = [CXX11<"gsl", "suppress">];
+def Suppress : DeclOrStmtAttr {
+ let Spellings = [CXX11<"gsl", "suppress">, Clang<"suppress">];
let Args = [VariadicStringArgument<"DiagnosticIdentifiers">];
+ let Accessors = [Accessor<"isGSL", [CXX11<"gsl", "suppress">]>];
let Documentation = [SuppressDocs];
}
@@ -2523,21 +2903,35 @@ def SysVABI : DeclOrTypeAttr {
}
def ThisCall : DeclOrTypeAttr {
- let Spellings = [GCC<"thiscall">, Keyword<"__thiscall">,
- Keyword<"_thiscall">];
+ let Spellings = [GCC<"thiscall">, CustomKeyword<"__thiscall">,
+ CustomKeyword<"_thiscall">];
// let Subjects = [Function, ObjCMethod];
let Documentation = [ThisCallDocs];
}
def VectorCall : DeclOrTypeAttr {
- let Spellings = [Clang<"vectorcall">, Keyword<"__vectorcall">,
- Keyword<"_vectorcall">];
+ let Spellings = [Clang<"vectorcall">, CustomKeyword<"__vectorcall">,
+ CustomKeyword<"_vectorcall">];
// let Subjects = [Function, ObjCMethod];
let Documentation = [VectorCallDocs];
}
+def ZeroCallUsedRegs : InheritableAttr {
+ let Spellings = [GCC<"zero_call_used_regs">];
+ let Subjects = SubjectList<[Function], ErrorDiag>;
+ let Args = [
+ EnumArgument<"ZeroCallUsedRegs", "ZeroCallUsedRegsKind",
+ ["skip", "used-gpr-arg", "used-gpr", "used-arg", "used",
+ "all-gpr-arg", "all-gpr", "all-arg", "all"],
+ ["Skip", "UsedGPRArg", "UsedGPR", "UsedArg", "Used",
+ "AllGPRArg", "AllGPR", "AllArg", "All"]>
+ ];
+ let Documentation = [ZeroCallUsedRegsDocs];
+}
+
def Pascal : DeclOrTypeAttr {
- let Spellings = [Clang<"pascal">, Keyword<"__pascal">, Keyword<"_pascal">];
+ let Spellings = [Clang<"pascal">, CustomKeyword<"__pascal">,
+ CustomKeyword<"_pascal">];
// let Subjects = [Function, ObjCMethod];
let Documentation = [Undocumented];
}
@@ -2562,16 +2956,17 @@ def PreserveAll : DeclOrTypeAttr {
let Documentation = [PreserveAllDocs];
}
+def M68kRTD: DeclOrTypeAttr {
+ let Spellings = [Clang<"m68k_rtd">];
+ let Documentation = [M68kRTDDocs];
+}
+
def Target : InheritableAttr {
let Spellings = [GCC<"target">];
let Args = [StringArgument<"featuresStr">];
let Subjects = SubjectList<[Function], ErrorDiag>;
let Documentation = [TargetDocs];
let AdditionalMembers = [{
- ParsedTargetAttr parse() const {
- return parse(getFeaturesStr());
- }
-
StringRef getArchitecture() const {
StringRef Features = getFeaturesStr();
if (Features == "default") return {};
@@ -2581,7 +2976,7 @@ def Target : InheritableAttr {
for (auto &Feature : AttrFeatures) {
Feature = Feature.trim();
- if (Feature.startswith("arch="))
+ if (Feature.starts_with("arch="))
return Feature.drop_front(sizeof("arch=") - 1);
}
return "";
@@ -2599,66 +2994,81 @@ def Target : InheritableAttr {
for (auto &Feature : AttrFeatures) {
Feature = Feature.trim();
- if (!Feature.startswith("no-") && !Feature.startswith("arch=") &&
- !Feature.startswith("fpmath=") && !Feature.startswith("tune="))
+ if (!Feature.starts_with("no-") && !Feature.starts_with("arch=") &&
+ !Feature.starts_with("fpmath=") && !Feature.starts_with("tune="))
Out.push_back(Feature);
}
}
- template<class Compare>
- ParsedTargetAttr parse(Compare cmp) const {
- ParsedTargetAttr Attrs = parse();
- llvm::sort(std::begin(Attrs.Features), std::end(Attrs.Features), cmp);
- return Attrs;
- }
-
bool isDefaultVersion() const { return getFeaturesStr() == "default"; }
+ }];
+}
- static ParsedTargetAttr parse(StringRef Features) {
- ParsedTargetAttr Ret;
- if (Features == "default") return Ret;
- SmallVector<StringRef, 1> AttrFeatures;
- Features.split(AttrFeatures, ",");
+def TargetVersion : InheritableAttr {
+ let Spellings = [GCC<"target_version">];
+ let Args = [StringArgument<"NamesStr">];
+ let Subjects = SubjectList<[Function], ErrorDiag>;
+ let Documentation = [TargetVersionDocs];
+ let AdditionalMembers = [{
+ StringRef getName() const { return getNamesStr().trim(); }
+ bool isDefaultVersion() const {
+ return getName() == "default";
+ }
+ void getFeatures(llvm::SmallVectorImpl<StringRef> &Out) const {
+ if (isDefaultVersion()) return;
+ StringRef Features = getName();
+
+ SmallVector<StringRef, 8> AttrFeatures;
+ Features.split(AttrFeatures, "+");
- // Grab the various features and prepend a "+" to turn on the feature to
- // the backend and add them to our existing set of features.
for (auto &Feature : AttrFeatures) {
- // Go ahead and trim whitespace rather than either erroring or
- // accepting it weirdly.
Feature = Feature.trim();
-
- // TODO: Support the fpmath option. It will require checking
- // overall feature validity for the function with the rest of the
- // attributes on the function.
- if (Feature.startswith("fpmath="))
- continue;
-
- if (Feature.startswith("branch-protection=")) {
- Ret.BranchProtection = Feature.split('=').second.trim();
- continue;
- }
-
- // While we're here iterating check for a different target cpu.
- if (Feature.startswith("arch=")) {
- if (!Ret.Architecture.empty())
- Ret.DuplicateArchitecture = true;
- else
- Ret.Architecture = Feature.split("=").second.trim();
- } else if (Feature.startswith("tune=")) {
- if (!Ret.Tune.empty())
- Ret.DuplicateTune = true;
- else
- Ret.Tune = Feature.split("=").second.trim();
- } else if (Feature.startswith("no-"))
- Ret.Features.push_back("-" + Feature.split("-").second.str());
- else
- Ret.Features.push_back("+" + Feature.str());
+ Out.push_back(Feature);
}
- return Ret;
}
}];
}
+def TargetClones : InheritableAttr {
+ let Spellings = [GCC<"target_clones">];
+ let Args = [VariadicStringArgument<"featuresStrs">];
+ let Documentation = [TargetClonesDocs];
+ let Subjects = SubjectList<[Function], ErrorDiag>;
+ let AdditionalMembers = [{
+ StringRef getFeatureStr(unsigned Index) const {
+ return *(featuresStrs_begin() + Index);
+ }
+ // Given an index into the 'featuresStrs' sequence, compute a unique
+ // ID to be used with function name mangling for the associated variant.
+ // This mapping is necessary due to a requirement that the mangling ID
+ // used for the "default" variant be the largest mangling ID in the
+ // variant set. Duplicate variants present in 'featuresStrs' are also
+ // assigned their own unique ID (the mapping is bijective).
+ unsigned getMangledIndex(unsigned Index) const {
+ if (getFeatureStr(Index) == "default")
+ return std::count_if(featuresStrs_begin(), featuresStrs_end(),
+ [](StringRef S) { return S != "default"; });
+
+ return std::count_if(featuresStrs_begin(), featuresStrs_begin() + Index,
+ [](StringRef S) { return S != "default"; });
+ }
+
+ // Given an index into the 'featuresStrs' sequence, determine if the
+ // index corresponds to the first instance of the named variant. This
+ // is used to skip over duplicate variant instances when iterating over
+ // 'featuresStrs'.
+ bool isFirstOfVersion(unsigned Index) const {
+ StringRef FeatureStr(getFeatureStr(Index));
+ return 0 == std::count_if(
+ featuresStrs_begin(), featuresStrs_begin() + Index,
+ [FeatureStr](StringRef S) { return S == FeatureStr; });
+
+ }
+ }];
+}
+
+def : MutualExclusions<[TargetClones, TargetVersion, Target, CPUDispatch, CPUSpecific]>;
+
def MinVectorWidth : InheritableAttr {
let Spellings = [Clang<"min_vector_width">];
let Args = [UnsignedArgument<"VectorWidth">];
@@ -2685,9 +3095,11 @@ def Unavailable : InheritableAttr {
"IR_ARCInitReturnsUnrelated",
"IR_ARCFieldWithOwnership"], 1, /*fake*/ 1>];
let Documentation = [Undocumented];
+ let MeaningfulToClassTemplateDefinition = 1;
}
def DiagnoseIf : InheritableAttr {
+ let CanPrintOnLeft = 0;
// Does not have a [[]] spelling because this attribute requires the ability
// to parse function arguments but the attribute is not written in the type
// position.
@@ -2738,7 +3150,7 @@ def ObjCRequiresPropertyDefs : InheritableAttr {
def Unused : InheritableAttr {
let Spellings = [CXX11<"", "maybe_unused", 201603>, GCC<"unused">,
- C2x<"", "maybe_unused", 201904>];
+ C23<"", "maybe_unused", 202106>];
let Subjects = SubjectList<[Var, ObjCIvar, Type, Enum, EnumConstant, Label,
Field, ObjCMethod, FunctionLike]>;
let Documentation = [WarnMaybeUnusedDocs];
@@ -2832,10 +3244,10 @@ def WarnUnused : InheritableAttr {
def WarnUnusedResult : InheritableAttr {
let Spellings = [CXX11<"", "nodiscard", 201907>,
- C2x<"", "nodiscard", 201904>,
+ C23<"", "nodiscard", 202003>,
CXX11<"clang", "warn_unused_result">,
GCC<"warn_unused_result">];
- let Subjects = SubjectList<[ObjCMethod, Enum, Record, FunctionLike]>;
+ let Subjects = SubjectList<[ObjCMethod, Enum, Record, FunctionLike, TypedefName]>;
let Args = [StringArgument<"Message", 1>];
let Documentation = [WarnUnusedResultsDocs];
let AdditionalMembers = [{
@@ -2850,7 +3262,7 @@ def WarnUnusedResult : InheritableAttr {
def Weak : InheritableAttr {
let Spellings = [GCC<"weak">];
let Subjects = SubjectList<[Var, Function, CXXRecord]>;
- let Documentation = [Undocumented];
+ let Documentation = [WeakDocs];
let SimpleHandler = 1;
}
@@ -2881,7 +3293,7 @@ def AnyX86Interrupt : InheritableAttr, TargetSpecificAttr<TargetAnyX86> {
let Subjects = SubjectList<[HasFunctionProto]>;
let ParseKind = "Interrupt";
let HasCustomParsing = 1;
- let Documentation = [Undocumented];
+ let Documentation = [AnyX86InterruptDocs];
}
def AnyX86NoCallerSavedRegisters : InheritableAttr,
@@ -2940,6 +3352,13 @@ def NoSanitizeSpecific : InheritableAttr {
let ASTNode = 0;
}
+def DisableSanitizerInstrumentation : InheritableAttr {
+ let Spellings = [Clang<"disable_sanitizer_instrumentation">];
+ let Subjects = SubjectList<[Function, ObjCMethod, GlobalVar]>;
+ let Documentation = [DisableSanitizerInstrumentationDocs];
+ let SimpleHandler = 1;
+}
+
def CFICanonicalJumpTable : InheritableAttr {
let Spellings = [Clang<"cfi_canonical_jump_table">];
let Subjects = SubjectList<[Function], ErrorDiag>;
@@ -3325,6 +3744,14 @@ def : MutualExclusions<[Owner, Pointer]>;
// Microsoft-related attributes
+def MSConstexpr : InheritableAttr {
+ let LangOpts = [MicrosoftExt];
+ let Spellings = [CXX11<"msvc", "constexpr">];
+ let Subjects = SubjectList<[Function, ReturnStmt], ErrorDiag,
+ "functions and return statements">;
+ let Documentation = [MSConstexprDocs];
+}
+
def MSNoVTable : InheritableAttr, TargetSpecificAttr<TargetMicrosoftCXXABI> {
let Spellings = [Declspec<"novtable">];
let Subjects = SubjectList<[CXXRecord]>;
@@ -3342,10 +3769,10 @@ def MSAllocator : InheritableAttr {
let Documentation = [MSAllocatorDocs];
}
-def CFGuard : InheritableAttr {
+def CFGuard : InheritableAttr, TargetSpecificAttr<TargetWindows> {
// Currently only the __declspec(guard(nocf)) modifier is supported. In future
// we might also want to support __declspec(guard(suppress)).
- let Spellings = [Declspec<"guard">];
+ let Spellings = [Declspec<"guard">, Clang<"guard">];
let Subjects = SubjectList<[Function]>;
let Args = [EnumArgument<"Guard", "GuardArg", ["nocf"], ["nocf"]>];
let Documentation = [CFGuardDocs];
@@ -3372,7 +3799,7 @@ def DLLExportStaticLocal : InheritableAttr, TargetSpecificAttr<TargetHasDLLImpor
// the function has local static variables, the function is dllexported too.
let Spellings = [];
let Subjects = SubjectList<[Function]>;
- let Documentation = [Undocumented];
+ let Documentation = [InternalOnly];
}
def DLLImport : InheritableAttr, TargetSpecificAttr<TargetHasDLLImportExport> {
@@ -3398,7 +3825,7 @@ def DLLImportStaticLocal : InheritableAttr, TargetSpecificAttr<TargetHasDLLImpor
// attribute is used to determine whether the variables are imported or not.
let Spellings = [];
let Subjects = SubjectList<[Function]>;
- let Documentation = [Undocumented];
+ let Documentation = [InternalOnly];
}
def SelectAny : InheritableAttr {
@@ -3415,37 +3842,37 @@ def Thread : Attr {
}
def Win64 : IgnoredAttr {
- let Spellings = [Keyword<"__w64">];
+ let Spellings = [CustomKeyword<"__w64">];
let LangOpts = [MicrosoftExt];
}
def Ptr32 : TypeAttr {
- let Spellings = [Keyword<"__ptr32">];
+ let Spellings = [CustomKeyword<"__ptr32">];
let Documentation = [Ptr32Docs];
}
def Ptr64 : TypeAttr {
- let Spellings = [Keyword<"__ptr64">];
+ let Spellings = [CustomKeyword<"__ptr64">];
let Documentation = [Ptr64Docs];
}
def SPtr : TypeAttr {
- let Spellings = [Keyword<"__sptr">];
+ let Spellings = [CustomKeyword<"__sptr">];
let Documentation = [SPtrDocs];
}
def UPtr : TypeAttr {
- let Spellings = [Keyword<"__uptr">];
+ let Spellings = [CustomKeyword<"__uptr">];
let Documentation = [UPtrDocs];
}
def MSInheritance : InheritableAttr {
let LangOpts = [MicrosoftExt];
let Args = [DefaultBoolArgument<"BestCase", /*default*/1, /*fake*/1>];
- let Spellings = [Keyword<"__single_inheritance">,
- Keyword<"__multiple_inheritance">,
- Keyword<"__virtual_inheritance">,
- Keyword<"__unspecified_inheritance">];
+ let Spellings = [CustomKeyword<"__single_inheritance">,
+ CustomKeyword<"__multiple_inheritance">,
+ CustomKeyword<"__virtual_inheritance">,
+ CustomKeyword<"__unspecified_inheritance">];
let AdditionalMembers = [{
MSInheritanceModel getInheritanceModel() const {
// The spelling enum should agree with MSInheritanceModel.
@@ -3464,7 +3891,7 @@ def MSVtorDisp : InheritableAttr {
let AdditionalMembers = [{
MSVtorDispMode getVtorDispMode() const { return MSVtorDispMode(vdm); }
}];
- let Documentation = [Undocumented];
+ let Documentation = [InternalOnly];
}
def InitSeg : Attr {
@@ -3556,21 +3983,21 @@ def CapturedRecord : InheritableAttr {
// This attribute has no spellings as it is only ever created implicitly.
let Spellings = [];
let SemaHandler = 0;
- let Documentation = [Undocumented];
+ let Documentation = [InternalOnly];
}
def OMPThreadPrivateDecl : InheritableAttr {
// This attribute has no spellings as it is only ever created implicitly.
let Spellings = [];
let SemaHandler = 0;
- let Documentation = [Undocumented];
+ let Documentation = [InternalOnly];
}
def OMPCaptureNoInit : InheritableAttr {
// This attribute has no spellings as it is only ever created implicitly.
let Spellings = [];
let SemaHandler = 0;
- let Documentation = [Undocumented];
+ let Documentation = [InternalOnly];
}
def OMPCaptureKind : Attr {
@@ -3578,7 +4005,7 @@ def OMPCaptureKind : Attr {
let Spellings = [];
let SemaHandler = 0;
let Args = [UnsignedArgument<"CaptureKindVal">];
- let Documentation = [Undocumented];
+ let Documentation = [InternalOnly];
let AdditionalMembers = [{
llvm::omp::Clause getCaptureKind() const {
return static_cast<llvm::omp::Clause>(getCaptureKindVal());
@@ -3591,7 +4018,7 @@ def OMPReferencedVar : Attr {
let Spellings = [];
let SemaHandler = 0;
let Args = [ExprArgument<"Ref">];
- let Documentation = [Undocumented];
+ let Documentation = [InternalOnly];
}
def OMPDeclareSimdDecl : Attr {
@@ -3622,20 +4049,22 @@ def OMPDeclareTargetDecl : InheritableAttr {
let Documentation = [OMPDeclareTargetDocs];
let Args = [
EnumArgument<"MapType", "MapTypeTy",
- [ "to", "link" ],
- [ "MT_To", "MT_Link" ]>,
+ [ "to", "enter", "link" ],
+ [ "MT_To", "MT_Enter", "MT_Link" ]>,
EnumArgument<"DevType", "DevTypeTy",
[ "host", "nohost", "any" ],
[ "DT_Host", "DT_NoHost", "DT_Any" ]>,
+ ExprArgument<"IndirectExpr">,
+ BoolArgument<"Indirect">,
UnsignedArgument<"Level">
];
let AdditionalMembers = [{
void printPrettyPragma(raw_ostream &OS, const PrintingPolicy &Policy) const;
- static llvm::Optional<MapTypeTy>
+ static std::optional<MapTypeTy>
isDeclareTargetDeclaration(const ValueDecl *VD);
- static llvm::Optional<OMPDeclareTargetDeclAttr*> getActiveAttr(const ValueDecl *VD);
- static llvm::Optional<DevTypeTy> getDeviceType(const ValueDecl *VD);
- static llvm::Optional<SourceLocation> getLocation(const ValueDecl *VD);
+ static std::optional<OMPDeclareTargetDeclAttr*> getActiveAttr(const ValueDecl *VD);
+ static std::optional<DevTypeTy> getDeviceType(const ValueDecl *VD);
+ static std::optional<SourceLocation> getLocation(const ValueDecl *VD);
}];
}
@@ -3659,9 +4088,10 @@ def OMPAllocateDecl : InheritableAttr {
"OMPCGroupMemAlloc", "OMPPTeamMemAlloc", "OMPThreadMemAlloc",
"OMPUserDefinedMemAlloc"
]>,
- ExprArgument<"Allocator">
+ ExprArgument<"Allocator">,
+ ExprArgument<"Alignment">
];
- let Documentation = [Undocumented];
+ let Documentation = [InternalOnly];
}
def OMPDeclareVariant : InheritableAttr {
@@ -3674,11 +4104,21 @@ def OMPDeclareVariant : InheritableAttr {
let Args = [
ExprArgument<"VariantFuncRef">,
OMPTraitInfoArgument<"TraitInfos">,
+ VariadicExprArgument<"AdjustArgsNothing">,
+ VariadicExprArgument<"AdjustArgsNeedDevicePtr">,
+ VariadicOMPInteropInfoArgument<"AppendArgs">,
];
let AdditionalMembers = [{
OMPTraitInfo &getTraitInfo() { return *traitInfos; }
void printPrettyPragma(raw_ostream & OS, const PrintingPolicy &Policy)
const;
+ static StringRef getInteropTypeString(const OMPInteropInfo *I) {
+ if (I->IsTarget && I->IsTargetSync)
+ return "target,targetsync";
+ if (I->IsTarget)
+ return "target";
+ return "targetsync";
+ }
}];
}
@@ -3800,17 +4240,31 @@ def ReleaseHandle : InheritableParamAttr {
let Documentation = [ReleaseHandleDocs];
}
+def UnsafeBufferUsage : InheritableAttr {
+ let Spellings = [Clang<"unsafe_buffer_usage">];
+ let Subjects = SubjectList<[Function]>;
+ let Documentation = [UnsafeBufferUsageDocs];
+}
+
+def DiagnoseAsBuiltin : InheritableAttr {
+ let Spellings = [Clang<"diagnose_as_builtin">];
+ let Args = [DeclArgument<Function, "Function">,
+ VariadicUnsignedArgument<"ArgIndices">];
+ let Subjects = SubjectList<[Function]>;
+ let Documentation = [DiagnoseAsBuiltinDocs];
+}
+
def Builtin : InheritableAttr {
let Spellings = [];
let Args = [UnsignedArgument<"ID">];
let Subjects = SubjectList<[Function]>;
let SemaHandler = 0;
- let Documentation = [Undocumented];
+ let Documentation = [InternalOnly];
}
def EnforceTCB : InheritableAttr {
let Spellings = [Clang<"enforce_tcb">];
- let Subjects = SubjectList<[Function]>;
+ let Subjects = SubjectList<[Function, ObjCMethod]>;
let Args = [StringArgument<"TCBName">];
let Documentation = [EnforceTCBDocs];
bit InheritEvenIfAlreadyPresent = 1;
@@ -3818,8 +4272,191 @@ def EnforceTCB : InheritableAttr {
def EnforceTCBLeaf : InheritableAttr {
let Spellings = [Clang<"enforce_tcb_leaf">];
- let Subjects = SubjectList<[Function]>;
+ let Subjects = SubjectList<[Function, ObjCMethod]>;
let Args = [StringArgument<"TCBName">];
let Documentation = [EnforceTCBLeafDocs];
bit InheritEvenIfAlreadyPresent = 1;
}
+
+def Error : InheritableAttr {
+ let Spellings = [GCC<"error">, GCC<"warning">];
+ let Accessors = [Accessor<"isError", [GCC<"error">]>,
+ Accessor<"isWarning", [GCC<"warning">]>];
+ let Args = [StringArgument<"UserDiagnostic">];
+ let Subjects = SubjectList<[Function], ErrorDiag>;
+ let Documentation = [ErrorAttrDocs];
+}
+
+def HLSLNumThreads: InheritableAttr {
+ let Spellings = [Microsoft<"numthreads">];
+ let Args = [IntArgument<"X">, IntArgument<"Y">, IntArgument<"Z">];
+ let Subjects = SubjectList<[HLSLEntry]>;
+ let LangOpts = [HLSL];
+ let Documentation = [NumThreadsDocs];
+}
+
+def HLSLSV_GroupIndex: HLSLAnnotationAttr {
+ let Spellings = [HLSLSemantic<"SV_GroupIndex">];
+ let Subjects = SubjectList<[ParmVar, GlobalVar]>;
+ let LangOpts = [HLSL];
+ let Documentation = [HLSLSV_GroupIndexDocs];
+}
+
+def HLSLResourceBinding: InheritableAttr {
+ let Spellings = [HLSLSemantic<"register">];
+ let Subjects = SubjectList<[HLSLBufferObj, ExternalGlobalVar]>;
+ let LangOpts = [HLSL];
+ let Args = [StringArgument<"Slot">, StringArgument<"Space", 1>];
+ let Documentation = [HLSLResourceBindingDocs];
+}
+
+def HLSLSV_DispatchThreadID: HLSLAnnotationAttr {
+ let Spellings = [HLSLSemantic<"SV_DispatchThreadID">];
+ let Subjects = SubjectList<[ParmVar, Field]>;
+ let LangOpts = [HLSL];
+ let Documentation = [HLSLSV_DispatchThreadIDDocs];
+}
+
+def HLSLShader : InheritableAttr {
+ let Spellings = [Microsoft<"shader">];
+ let Subjects = SubjectList<[HLSLEntry]>;
+ let LangOpts = [HLSL];
+ let Args = [
+ EnumArgument<"Type", "ShaderType",
+ ["pixel", "vertex", "geometry", "hull", "domain", "compute",
+ "raygeneration", "intersection", "anyhit", "closesthit",
+ "miss", "callable", "mesh", "amplification"],
+ ["Pixel", "Vertex", "Geometry", "Hull", "Domain", "Compute",
+ "RayGeneration", "Intersection", "AnyHit", "ClosestHit",
+ "Miss", "Callable", "Mesh", "Amplification"]>
+ ];
+ let Documentation = [HLSLSV_ShaderTypeAttrDocs];
+}
+
+def HLSLResource : InheritableAttr {
+ let Spellings = [];
+ let Subjects = SubjectList<[Struct]>;
+ let LangOpts = [HLSL];
+ let Args = [EnumArgument<"ResourceClass", "llvm::hlsl::ResourceClass",
+ ["SRV", "UAV", "CBuffer", "Sampler"],
+ ["SRV", "UAV", "CBuffer", "Sampler"],
+ /*opt=*/0, /*fake=*/0, /*isExternalType=*/1>,
+ EnumArgument<"ResourceKind", "llvm::hlsl::ResourceKind",
+ ["Texture1D", "Texture2D", "Texture2DMS",
+ "Texture3D", "TextureCube", "Texture1DArray",
+ "Texture2DArray", "Texture2DMSArray",
+ "TextureCubeArray", "TypedBuffer", "RawBuffer",
+ "StructuredBuffer", "CBuffer", "Sampler",
+ "TBuffer", "RTAccelerationStructure",
+ "FeedbackTexture2D", "FeedbackTexture2DArray"],
+ ["Texture1D", "Texture2D", "Texture2DMS",
+ "Texture3D", "TextureCube", "Texture1DArray",
+ "Texture2DArray", "Texture2DMSArray",
+ "TextureCubeArray", "TypedBuffer", "RawBuffer",
+ "StructuredBuffer", "CBuffer", "Sampler",
+ "TBuffer", "RTAccelerationStructure",
+ "FeedbackTexture2D", "FeedbackTexture2DArray"],
+ /*opt=*/0, /*fake=*/0, /*isExternalType=*/1>,
+ DefaultBoolArgument<"isROV", /*default=*/0>
+ ];
+ let Documentation = [InternalOnly];
+}
+
+def HLSLGroupSharedAddressSpace : TypeAttr {
+ let Spellings = [CustomKeyword<"groupshared">];
+ let Subjects = SubjectList<[Var]>;
+ let Documentation = [HLSLGroupSharedAddressSpaceDocs];
+}
+
+def HLSLParamModifier : TypeAttr {
+ let Spellings = [CustomKeyword<"in">, CustomKeyword<"inout">, CustomKeyword<"out">];
+ let Accessors = [Accessor<"isIn", [CustomKeyword<"in">]>,
+ Accessor<"isInOut", [CustomKeyword<"inout">]>,
+ Accessor<"isOut", [CustomKeyword<"out">]>,
+ Accessor<"isAnyOut", [CustomKeyword<"out">, CustomKeyword<"inout">]>,
+ Accessor<"isAnyIn", [CustomKeyword<"in">, CustomKeyword<"inout">]>];
+ let Subjects = SubjectList<[ParmVar]>;
+ let Documentation = [HLSLParamQualifierDocs];
+ let Args = [DefaultBoolArgument<"MergedSpelling", /*default*/0, /*fake*/1>];
+}
+
+def RandomizeLayout : InheritableAttr {
+ let Spellings = [GCC<"randomize_layout">];
+ let Subjects = SubjectList<[Record]>;
+ let Documentation = [ClangRandomizeLayoutDocs];
+ let LangOpts = [COnly];
+}
+
+def NoRandomizeLayout : InheritableAttr {
+ let Spellings = [GCC<"no_randomize_layout">];
+ let Subjects = SubjectList<[Record]>;
+ let Documentation = [ClangRandomizeLayoutDocs];
+ let LangOpts = [COnly];
+}
+def : MutualExclusions<[RandomizeLayout, NoRandomizeLayout]>;
+
+def FunctionReturnThunks : InheritableAttr,
+ TargetSpecificAttr<TargetAnyX86> {
+ let Spellings = [GCC<"function_return">];
+ let Args = [EnumArgument<"ThunkType", "Kind",
+ ["keep", "thunk-extern"],
+ ["Keep", "Extern"]
+ >];
+ let Subjects = SubjectList<[Function]>;
+ let Documentation = [FunctionReturnThunksDocs];
+}
+
+def WebAssemblyFuncref : TypeAttr, TargetSpecificAttr<TargetWebAssembly> {
+ let Spellings = [CustomKeyword<"__funcref">];
+ let Documentation = [WebAssemblyExportNameDocs];
+ let Subjects = SubjectList<[FunctionPointer], ErrorDiag>;
+}
+
+def ReadOnlyPlacement : InheritableAttr {
+ let Spellings = [Clang<"enforce_read_only_placement">];
+ let Subjects = SubjectList<[Record]>;
+ let Documentation = [ReadOnlyPlacementDocs];
+}
+
+def AvailableOnlyInDefaultEvalMethod : InheritableAttr {
+ let Spellings = [Clang<"available_only_in_default_eval_method">];
+ let Subjects = SubjectList<[TypedefName], ErrorDiag>;
+ let Documentation = [Undocumented];
+}
+
+def PreferredType: InheritableAttr {
+ let Spellings = [Clang<"preferred_type">];
+ let Subjects = SubjectList<[BitField], ErrorDiag>;
+ let Args = [TypeArgument<"Type", 1>];
+ let Documentation = [PreferredTypeDocumentation];
+}
+
+def CodeAlign: StmtAttr {
+ let Spellings = [Clang<"code_align">];
+ let Subjects = SubjectList<[ForStmt, CXXForRangeStmt, WhileStmt, DoStmt],
+ ErrorDiag, "'for', 'while', and 'do' statements">;
+ let Args = [ExprArgument<"Alignment">];
+ let Documentation = [CodeAlignAttrDocs];
+ let AdditionalMembers = [{
+ static constexpr int MinimumAlignment = 1;
+ static constexpr int MaximumAlignment = 4096;
+ }];
+}
+
+def CountedBy : InheritableAttr {
+ let Spellings = [Clang<"counted_by">];
+ let Subjects = SubjectList<[Field]>;
+ let Args = [IdentifierArgument<"CountedByField">];
+ let Documentation = [CountedByDocs];
+ let LangOpts = [COnly];
+ // FIXME: This is ugly. Let using a DeclArgument would be nice, but a Decl
+ // isn't yet available due to the fact that we're still parsing the
+ // structure. Maybe that code could be changed sometime in the future.
+ code AdditionalMembers = [{
+ private:
+ SourceRange CountedByFieldLoc;
+ public:
+ SourceRange getCountedByFieldLoc() const { return CountedByFieldLoc; }
+ void setCountedByFieldLoc(SourceRange Loc) { CountedByFieldLoc = Loc; }
+ }];
+}
diff --git a/contrib/llvm-project/clang/include/clang/Basic/AttrDocs.td b/contrib/llvm-project/clang/include/clang/Basic/AttrDocs.td
index c265a877e3b1..e02a1201e2ad 100644
--- a/contrib/llvm-project/clang/include/clang/Basic/AttrDocs.td
+++ b/contrib/llvm-project/clang/include/clang/Basic/AttrDocs.td
@@ -22,7 +22,7 @@
// Windows (from within the clang\docs directory):
// make.bat html
// Non-Windows (from within the clang\docs directory):
-// make -f Makefile.sphinx html
+// sphinx-build -b html _build/html
def GlobalDocumentation {
code Intro =[{..
@@ -57,6 +57,15 @@ global variable or function should be in after translation.
let Heading = "section, __declspec(allocate)";
}
+def CodeModelDocs : Documentation {
+ let Category = DocCatVariable;
+ let Content = [{
+The ``model`` attribute allows overriding the translation unit's
+code model (specified by ``-mcmodel``) for a specific global variable.
+ }];
+ let Heading = "model";
+}
+
def UsedDocs : Documentation {
let Category = DocCatFunction;
let Content = [{
@@ -127,6 +136,10 @@ relative ordering of values is important. For example:
``Obj2`` will be initialized *before* ``Obj1`` despite the usual order of
initialization being the opposite.
+On Windows, ``init_seg(compiler)`` is represented with a priority of 200 and
+``init_seg(library)`` is represented with a priority of 400. ``init_seg(user)``
+uses the default 65535 priority.
+
This attribute is only supported for C++ and Objective-C++ and is ignored in
other language modes. Currently, this attribute is not implemented on z/OS.
}];
@@ -187,6 +200,10 @@ primary use is for COFF object files which explicitly specify what interfaces
are imported from external modules. See the dllimport_ documentation on MSDN
for more information.
+Note that a dllimport function may still be inlined, if its definition is
+available and it doesn't reference any non-dllimport functions or global
+variables.
+
.. _dllimport: https://msdn.microsoft.com/en-us/library/3y1sfaz2.aspx
}];
}
@@ -253,6 +270,28 @@ applies to copies of the block. For example:
}];
}
+def MaybeUndefDocs : Documentation {
+ let Category = DocCatVariable;
+ let Content = [{
+The ``maybe_undef`` attribute can be placed on a function parameter. It indicates
+that the parameter is allowed to use undef values. It informs the compiler
+to insert a freeze LLVM IR instruction on the function parameter.
+Please note that this is an attribute that is used as an internal
+implementation detail and not intended to be used by external users.
+
+In languages HIP, CUDA etc., some functions have multi-threaded semantics and
+it is enough for only one or some threads to provide defined arguments.
+Depending on semantics, undef arguments in some threads don't produce
+undefined results in the function call. Since, these functions accept undefined
+arguments, ``maybe_undef`` attribute can be placed.
+
+Sample usage:
+.. code-block:: c
+
+ void maybeundeffunc(int __attribute__((maybe_undef))param);
+ }];
+}
+
def CarriesDependencyDocs : Documentation {
let Category = DocCatFunction;
let Content = [{
@@ -281,6 +320,17 @@ features that are required for the function to be called. The result of this is
that future processors execute the most restrictive version of the function the
new processor can execute.
+In addition, unlike the ICC implementation of this feature, the selection of the
+version does not consider the manufacturer or microarchitecture of the processor.
+It tests solely the list of features that are both supported by the specified
+processor and present in the compiler-rt library. This can be surprising at times,
+as the runtime processor may be from a completely different manufacturer, as long
+as it supports the same feature set.
+
+This can additionally be surprising, as some processors are indistringuishable from
+others based on the list of testable features. When this happens, the variant
+is selected in an unspecified manner.
+
Function versions are defined with ``cpu_specific``, which takes one or more CPU
names as a parameter. For example:
@@ -405,6 +455,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:: text
+
+ 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 = [{
@@ -418,10 +533,14 @@ pointer type.
def CXX11NoReturnDocs : Documentation {
let Category = DocCatFunction;
+ let Heading = "noreturn, _Noreturn";
let Content = [{
A function declared as ``[[noreturn]]`` shall not return to its caller. The
compiler will generate a diagnostic for a function declared as ``[[noreturn]]``
that appears to be capable of returning to its caller.
+
+The ``[[_Noreturn]]`` spelling is deprecated and only exists to ease code
+migration for code using ``[[noreturn]]`` after including ``<stdnoreturn.h>``.
}];
}
@@ -429,17 +548,68 @@ def NoMergeDocs : Documentation {
let Category = DocCatStmt;
let Content = [{
If a statement is marked ``nomerge`` and contains call expressions, those call
-expressions inside the statement will not be merged during optimization. This
+expressions inside the statement will not be merged during optimization. This
attribute can be used to prevent the optimizer from obscuring the source
location of certain calls. For example, it will prevent tail merging otherwise
identical code sequences that raise an exception or terminate the program. Tail
merging normally reduces the precision of source location information, making
stack traces less useful for debugging. This attribute gives the user control
-over the tradeoff between code size and debug information precision.
+over the tradeoff between code size and debug information precision.
+
+``nomerge`` attribute can also be used as function attribute to prevent all
+calls to the specified function from merging. It has no effect on indirect
+calls to such functions. For example:
+
+.. code-block:: c++
+
+ [[clang::nomerge]] void foo(int) {}
+
+ void bar(int x) {
+ auto *ptr = foo;
+ if (x) foo(1); else foo(2); // will not be merged
+ if (x) ptr(1); else ptr(2); // indirect call, can be merged
+ }
+
+``nomerge`` attribute can also be used for pointers to functions to
+prevent calls through such pointer from merging. In such case the
+effect applies only to a specific function pointer. For example:
+
+.. code-block:: c++
+
+ [[clang::nomerge]] void (*foo)(int);
+
+ void bar(int x) {
+ auto *ptr = foo;
+ if (x) foo(1); else foo(2); // will not be merged
+ if (x) ptr(1); else ptr(2); // 'ptr' has no 'nomerge' attribute, can be merged
+ }
+ }];
+}
+
+def NoInlineDocs : Documentation {
+ let Category = DocCatFunction;
+ let Content = [{
+This function attribute suppresses the inlining of a function at the call sites
+of the function.
+
+``[[clang::noinline]]`` spelling can be used as a statement attribute; other
+spellings of the attribute are not supported on statements. If a statement is
+marked ``[[clang::noinline]]`` and contains calls, those calls inside the
+statement will not be inlined by the compiler.
+
+``__noinline__`` can be used as a keyword in CUDA/HIP languages. This is to
+avoid diagnostics due to usage of ``__attribute__((__noinline__))``
+with ``__noinline__`` defined as a macro as ``__attribute__((noinline))``.
+
+.. code-block:: c
+
+ int example(void) {
+ int r;
+ [[clang::noinline]] foo();
+ [[clang::noinline]] r = bar();
+ return r;
+ }
-``nomerge`` attribute can also be used as function attribute to prevent all
-calls to the specified function from merging. It has no effect on indirect
-calls.
}];
}
@@ -466,6 +636,9 @@ Any variables in scope, including all arguments to the function and the
return value must be trivially destructible. The calling convention of the
caller and callee must match, and they must not be variadic functions or have
old style K&R C function declarations.
+
+``clang::musttail`` provides assurances that the tail call can be optimized on
+all targets, not just one.
}];
}
@@ -999,7 +1172,7 @@ caveats to this use of name mangling:
* The ``overloadable`` attribute has almost no meaning when used in C++,
because names will already be mangled and functions are already overloadable.
However, when an ``overloadable`` function occurs within an ``extern "C"``
- linkage specification, it's name *will* be mangled in the same way as it
+ linkage specification, its name *will* be mangled in the same way as it
would in C.
For the purpose of backwards compatibility, at most one function with the same
@@ -1241,6 +1414,10 @@ Example usage:
``[[no_unique_address]]`` is a standard C++20 attribute. Clang supports its use
in C++11 onwards.
+
+On MSVC targets, ``[[no_unique_address]]`` is ignored; use
+``[[msvc::no_unique_address]]`` instead. Currently there is no guarantee of ABI
+compatibility or stability with MSVC.
}];
}
@@ -1445,6 +1622,10 @@ attributes are ignored. Supported platforms are:
Apple's watchOS operating system. The minimum deployment target is specified by
the ``-mwatchos-version-min=*version*`` command-line argument.
+``driverkit``
+ Apple's DriverKit userspace kernel extensions. The minimum deployment target
+ is specified as part of the triple.
+
A declaration can typically be used even when deploying back to a platform
version prior to when the declaration was introduced. When this happens, the
declaration is `weakly linked
@@ -1609,6 +1790,19 @@ defined_in=\ *string-literal*
source containers are modules, so ``defined_in`` should specify the Swift
module name.
+USR=\ *string-literal*
+ String that specifies a unified symbol resolution (USR) value for this
+ declaration. USR string uniquely identifies this particular declaration, and
+ is typically used when constructing an index of a codebase.
+ The USR value in this attribute is expected to be generated by an external
+ compiler that compiled the native declaration using its original source
+ language. The exact format of the USR string and its other attributes
+ are determined by the specification of this declaration's source language.
+ When not specified, Clang's indexer will use the Clang USR for this symbol.
+ User can query to see if Clang supports the use of the ``USR`` clause in
+ the ``external_source_symbol`` attribute with
+ ``__has_attribute(external_source_symbol) >= 20230206``.
+
generated_declaration
This declaration was automatically generated by some tool.
@@ -1677,7 +1871,8 @@ The attribute may be applied to the declaration of a class, a typedef, a
variable, a function or method, a function parameter, an enumeration, an
enumerator, a non-static data member, or a label.
-.. code-block: c++
+.. code-block:: c++
+
#include <cassert>
[[maybe_unused]] void f([[maybe_unused]] bool thing1,
@@ -1706,7 +1901,8 @@ literal contents) are allowed. If there are redeclarations of the entity with
differing string literals, it is unspecified which one will be used by Clang
in any resulting diagnostics.
-.. code-block: c++
+.. code-block:: c++
+
struct [[nodiscard]] error_info { /*...*/ };
error_info enable_missile_safety_mode();
@@ -1723,7 +1919,8 @@ marked with ``[[nodiscard]]`` or a constructor of a type marked
``[[nodiscard]]`` will also diagnose. This also applies to type conversions that
use the annotated ``[[nodiscard]]`` constructor or result in an annotated type.
-.. code-block: c++
+.. code-block:: c++
+
struct [[nodiscard]] marked_type {/*..*/ };
struct marked_ctor {
[[nodiscard]] marked_ctor();
@@ -2012,6 +2209,71 @@ struct or union, similar to clang ``__builtin_preserve_access_index()``.
}];
}
+def BPFPreserveStaticOffsetDocs : Documentation {
+ let Category = DocCatFunction;
+ let Content = [{
+Clang supports the ``__attribute__((preserve_static_offset))``
+attribute for the BPF target. This attribute may be attached to a
+struct or union declaration. Reading or writing fields of types having
+such annotation is guaranteed to generate LDX/ST/STX instruction with
+offset corresponding to the field.
+
+For example:
+
+.. code-block:: c
+
+ struct foo {
+ int a;
+ int b;
+ };
+
+ struct bar {
+ int a;
+ struct foo b;
+ } __attribute__((preserve_static_offset));
+
+ void buz(struct bar *g) {
+ g->b.a = 42;
+ }
+
+The assignment to ``g``'s field would produce an ST instruction with
+offset 8: ``*(u32)(r1 + 8) = 42;``.
+
+Without this attribute generated instructions might be different,
+depending on optimizations behavior. E.g. the example above could be
+rewritten as ``r1 += 8; *(u32)(r1 + 0) = 42;``.
+ }];
+}
+
+def BTFDeclTagDocs : Documentation {
+ let Category = DocCatFunction;
+ let Content = [{
+Clang supports the ``__attribute__((btf_decl_tag("ARGUMENT")))`` attribute for
+all targets. This attribute may be attached to a struct/union, struct/union
+field, function, function parameter, variable or typedef declaration. If -g is
+specified, the ``ARGUMENT`` info will be preserved in IR and be emitted to
+dwarf. For BPF targets, the ``ARGUMENT`` info will be emitted to .BTF ELF
+section too.
+ }];
+}
+
+def BTFTypeTagDocs : Documentation {
+ let Category = DocCatType;
+ let Content = [{
+Clang supports the ``__attribute__((btf_type_tag("ARGUMENT")))`` attribute for
+all targets. It only has effect when ``-g`` is specified on the command line and
+is currently silently ignored when not applied to a pointer type (note: this
+scenario may be diagnosed in the future).
+
+The ``ARGUMENT`` string will be preserved in IR and emitted to DWARF for the
+types used in variable declarations, function declarations, or typedef
+declarations.
+
+For BPF targets, the ``ARGUMENT`` string will also be emitted to .BTF ELF
+section.
+ }];
+}
+
def MipsInterruptDocs : Documentation {
let Category = DocCatFunction;
let Heading = "interrupt (MIPS)";
@@ -2111,7 +2373,7 @@ as ``-mlong-calls`` and ``-mno-long-calls``.
def RISCVInterruptDocs : Documentation {
let Category = DocCatFunction;
- let Heading = "interrupt (RISCV)";
+ let Heading = "interrupt (RISC-V)";
let Content = [{
Clang supports the GNU style ``__attribute__((interrupt))`` attribute on RISCV
targets. This attribute may be attached to a function definition and instructs
@@ -2132,6 +2394,43 @@ Version 1.10.
}];
}
+def RISCVRVVVectorBitsDocs : Documentation {
+ let Category = DocCatType;
+ let Content = [{
+On RISC-V targets, the ``riscv_rvv_vector_bits(N)`` attribute is used to define
+fixed-length variants of sizeless types.
+
+For example:
+
+.. code-block:: c
+
+ #include <riscv_vector.h>
+
+ #if defined(__riscv_v_fixed_vlen)
+ typedef vint8m1_t fixed_vint8m1_t __attribute__((riscv_rvv_vector_bits(__riscv_v_fixed_vlen)));
+ #endif
+
+Creates a type ``fixed_vint8m1_t_t`` that is a fixed-length variant of
+``vint8m1_t`` that contains exactly 512 bits. Unlike ``vint8m1_t``, this type
+can be used in globals, structs, unions, and arrays, all of which are
+unsupported for sizeless types.
+
+The attribute can be attached to a single RVV vector (such as ``vint8m1_t``).
+The attribute will be rejected unless
+``N==(__riscv_v_fixed_vlen*LMUL)``, the implementation defined feature macro that
+is enabled under the ``-mrvv-vector-bits`` flag. ``__riscv_v_fixed_vlen`` can
+only be a power of 2 between 64 and 65536.
+
+For types where LMUL!=1, ``__riscv_v_fixed_vlen`` needs to be scaled by the LMUL
+of the type before passing to the attribute.
+
+For ``vbool*_t`` types, ``__riscv_v_fixed_vlen`` needs to be divided by the
+number from the type name. For example, ``vbool8_t`` needs to use
+``__riscv_v_fixed_vlen`` / 8. If the resulting value is not a multiple of 8,
+the type is not supported for that value of ``__riscv_v_fixed_vlen``.
+}];
+}
+
def AVRInterruptDocs : Documentation {
let Category = DocCatFunction;
let Heading = "interrupt (AVR)";
@@ -2176,9 +2475,12 @@ for the function.
For X86, the attribute also allows ``tune="CPU"`` to optimize the generated
code for the given CPU without changing the available instructions.
-For AArch64, the attribute also allows the "branch-protection=<args>" option,
-where the permissible arguments and their effect on code generation are the same
-as for the command-line option ``-mbranch-protection``.
+For AArch64, ``arch="Arch"`` will set the architecture, similar to the -march
+command line options. ``cpu="CPU"`` can be used to select a specific cpu,
+as per the ``-mcpu`` option, similarly for ``tune=``. The attribute also allows the
+"branch-protection=<args>" option, where the permissible arguments and their
+effect on code generation are the same as for the command-line option
+``-mbranch-protection``.
Example "subtarget features" from the x86 backend include: "mmx", "sse", "sse4.2",
"avx", "xop" and largely correspond to the machine specific options handled by
@@ -2205,6 +2507,73 @@ Additionally, a function may not become multiversioned after its first use.
}];
}
+def TargetVersionDocs : Documentation {
+ let Category = DocCatFunction;
+ let Content = [{
+For AArch64 target clang supports function multiversioning by
+``__attribute__((target_version("OPTIONS")))`` attribute. When applied to a
+function it instructs compiler to emit multiple function versions based on
+``target_version`` attribute strings, which resolved at runtime depend on their
+priority and target features availability. One of the versions is always
+( implicitly or explicitly ) the ``default`` (fallback). Attribute strings can
+contain dependent features names joined by the "+" sign.
+}];
+}
+
+def TargetClonesDocs : Documentation {
+ let Category = DocCatFunction;
+ let Content = [{
+Clang supports the ``target_clones("OPTIONS")`` attribute. This attribute may be
+attached to a function declaration and causes function multiversioning, where
+multiple versions of the function will be emitted with different code
+generation options. Additionally, these versions will be resolved at runtime
+based on the priority of their attribute options. All ``target_clone`` functions
+are considered multiversioned functions.
+
+For AArch64 target:
+The attribute contains comma-separated strings of target features joined by "+"
+sign. For example:
+
+ .. code-block:: c++
+
+ __attribute__((target_clones("sha2+memtag2", "fcma+sve2-pmull128")))
+ void foo() {}
+
+For every multiversioned function a ``default`` (fallback) implementation
+always generated if not specified directly.
+
+For x86/x86-64 targets:
+All multiversioned functions must contain a ``default`` (fallback)
+implementation, otherwise usages of the function are considered invalid.
+Additionally, a function may not become multiversioned after its first use.
+
+The options to ``target_clones`` can either be a target-specific architecture
+(specified as ``arch=CPU``), or one of a list of subtarget features.
+
+Example "subtarget features" from the x86 backend include: "mmx", "sse", "sse4.2",
+"avx", "xop" and largely correspond to the machine specific options handled by
+the front end.
+
+The versions can either be listed as a comma-separated sequence of string
+literals or as a single string literal containing a comma-separated list of
+versions. For compatibility with GCC, the two formats can be mixed. For
+example, the following will emit 4 versions of the function:
+
+ .. code-block:: c++
+
+ __attribute__((target_clones("arch=atom,avx2","arch=ivybridge","default")))
+ void foo() {}
+
+For targets that support the GNU indirect function (IFUNC) feature, dispatch
+is performed by emitting an indirect function that is resolved to the appropriate
+target clone at load time. The indirect function is given the name the
+multiversioned function would have if it had been declared without the attribute.
+For backward compatibility with earlier Clang releases, a function alias with an
+``.ifunc`` suffix is also emitted. The ``.ifunc`` suffixed symbol is a deprecated
+feature and support for it may be removed in the future.
+}];
+}
+
def MinVectorWidthDocs : Documentation {
let Category = DocCatFunction;
let Content = [{
@@ -2302,8 +2671,9 @@ An error will be given if:
- Specified values violate subtarget specifications;
- Specified values are not compatible with values provided through other
attributes;
- - The AMDGPU target backend is unable to create machine code that can meet the
- request.
+
+The AMDGPU target backend will emit a warning whenever it is unable to
+create machine code that meets the request.
}];
}
@@ -2378,6 +2748,32 @@ the Arm Developer website.
}];
}
+def AArch64SVEPcsDocs : Documentation {
+ let Category = DocCatCallingConvs;
+ let Content = [{
+On AArch64 targets, this attribute changes the calling convention of a
+function to preserve additional Scalable Vector registers and Scalable
+Predicate registers relative to the default calling convention used for
+AArch64.
+
+This means it is more efficient to call such functions from code that performs
+extensive scalable vector and scalable predicate calculations, because fewer
+live SVE registers need to be saved. This property makes it well-suited for SVE
+math library functions, which are typically leaf functions that require a small
+number of registers.
+
+However, using this attribute also means that it is more expensive to call
+a function that adheres to the default calling convention from within such
+a function. Therefore, it is recommended that this attribute is only used
+for leaf functions.
+
+For more information, see the documentation for `aarch64_sve_pcs` in the
+ARM C Language Extension (ACLE) documentation.
+
+.. _`aarch64_sve_pcs`: https://github.com/ARM-software/acle/blob/main/main/acle.md#scalable-vector-extension-procedure-call-standard-attribute
+ }];
+}
+
def RegparmDocs : Documentation {
let Category = DocCatCallingConvs;
let Content = [{
@@ -2442,7 +2838,7 @@ On x86 targets, this attribute changes the calling convention to
as possible in registers. It also tries to utilize registers for the
return value whenever it is possible.
-.. _`__regcall`: https://software.intel.com/en-us/node/693069
+.. _`__regcall`: https://www.intel.com/content/www/us/en/docs/dpcpp-cpp-compiler/developer-guide-reference/2023-2/c-c-sycl-calling-conventions.html
}];
}
@@ -2486,6 +2882,18 @@ See the documentation for `__vectorcall`_ on MSDN for more details.
}];
}
+def M68kRTDDocs : Documentation {
+ let Category = DocCatCallingConvs;
+ let Content = [{
+On M68k targets, this attribute changes the calling convention of a function
+to clear parameters off the stack on return. In other words, callee is
+responsible for cleaning out the stack space allocated for incoming paramters.
+This convention does not support variadic calls or unprototyped functions in C.
+When targeting M68010 or newer CPUs, this calling convention is implemented
+using the `rtd` instruction.
+ }];
+}
+
def DocCatConsumed : DocumentationCategory<"Consumed Annotation Checking"> {
let Content = [{
Clang supports additional attributes for checking basic resource management
@@ -2592,6 +3000,18 @@ full list of supported sanitizer flags.
}];
}
+def DisableSanitizerInstrumentationDocs : Documentation {
+ let Category = DocCatFunction;
+ let Content = [{
+Use the ``disable_sanitizer_instrumentation`` attribute on a function,
+Objective-C method, or global variable, to specify that no sanitizer
+instrumentation should be applied.
+
+This is not the same as ``__attribute__((no_sanitize(...)))``, which depending
+on the tool may still insert instrumentation to prevent false positive reports.
+ }];
+}
+
def NoSanitizeAddressDocs : Documentation {
let Category = DocCatFunction;
// This function has multiple distinct spellings, and so it requires a custom
@@ -2873,8 +3293,8 @@ def FormatDocs : Documentation {
let Content = [{
Clang supports the ``format`` attribute, which indicates that the function
-accepts a ``printf`` or ``scanf``-like format string and corresponding
-arguments or a ``va_list`` that contains these arguments.
+accepts (among other possibilities) a ``printf`` or ``scanf``-like format string
+and corresponding arguments or a ``va_list`` that contains these arguments.
Please see `GCC documentation about format attribute
<http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html>`_ to find details
@@ -2928,6 +3348,39 @@ Clang implements two kinds of checks with this attribute.
In this case Clang does not warn because the format string ``s`` and
the corresponding arguments are annotated. If the arguments are
incorrect, the caller of ``foo`` will receive a warning.
+
+As an extension to GCC's behavior, Clang accepts the ``format`` attribute on
+non-variadic functions. Clang checks non-variadic format functions for the same
+classes of issues that can be found on variadic functions, as controlled by the
+same warning flags, except that the types of formatted arguments is forced by
+the function signature. For example:
+
+.. code-block:: c
+
+ __attribute__((__format__(__printf__, 1, 2)))
+ void fmt(const char *s, const char *a, int b);
+
+ void bar(void) {
+ fmt("%s %i", "hello", 123); // OK
+ fmt("%i %g", "hello", 123); // warning: arguments don't match format
+ extern const char *fmt;
+ fmt(fmt, "hello", 123); // warning: format string is not a string literal
+ }
+
+When using the format attribute on a variadic function, the first data parameter
+_must_ be the index of the ellipsis in the parameter list. Clang will generate
+a diagnostic otherwise, as it wouldn't be possible to forward that argument list
+to `printf`-family functions. For instance, this is an error:
+
+.. code-block:: c
+
+ __attribute__((__format__(__printf__, 1, 2)))
+ void fmt(const char *s, int b, ...);
+ // ^ error: format attribute parameter 3 is out of bounds
+ // (must be __printf__, 1, 3)
+
+Using the ``format`` attribute on a non-variadic function emits a GCC
+compatibility diagnostic.
}];
}
@@ -3152,6 +3605,9 @@ If a type is trivial for the purposes of calls, has a non-trivial destructor,
and is passed as an argument by value, the convention is that the callee will
destroy the object before returning.
+If a type is trivial for the purpose of calls, it is assumed to be trivially
+relocatable for the purpose of ``__is_trivially_relocatable``.
+
Attribute ``trivial_abi`` has no effect in the following cases:
- The class directly declares a virtual base or virtual methods.
@@ -3168,7 +3624,7 @@ Attribute ``trivial_abi`` has no effect in the following cases:
def MSInheritanceDocs : Documentation {
let Category = DocCatDecl;
- let Heading = "__single_inhertiance, __multiple_inheritance, __virtual_inheritance";
+ let Heading = "__single_inheritance, __multiple_inheritance, __virtual_inheritance";
let Content = [{
This collection of keywords is enabled under ``-fms-extensions`` and controls
the pointer-to-member representation used on ``*-*-win32`` targets.
@@ -3213,6 +3669,21 @@ an error:
}];
}
+def MSConstexprDocs : Documentation {
+ let Category = DocCatStmt;
+ let Content = [{
+The ``[[msvc::constexpr]]`` attribute can be applied only to a function
+definition or a ``return`` statement. It does not impact function declarations.
+A ``[[msvc::constexpr]]`` function cannot be ``constexpr`` or ``consteval``.
+A ``[[msvc::constexpr]]`` function is treated as if it were a ``constexpr`` function
+when it is evaluated in a constant context of ``[[msvc::constexpr]] return`` statement.
+Otherwise, it is treated as a regular function.
+
+Semantics of this attribute are enabled only under MSVC compatibility
+(``-fms-compatibility-version``) 19.33 and later.
+ }];
+}
+
def MSNoVTableDocs : Documentation {
let Category = DocCatDecl;
let Content = [{
@@ -3301,7 +3772,7 @@ Specifying ``#pragma nounroll`` indicates that the loop should not be unrolled:
}
``#pragma unroll`` and ``#pragma unroll _value_`` have identical semantics to
-``#pragma clang loop unroll(full)`` and
+``#pragma clang loop unroll(enable)`` and
``#pragma clang loop unroll_count(_value_)`` respectively. ``#pragma nounroll``
is equivalent to ``#pragma clang loop unroll(disable)``. See
`language extensions
@@ -3577,7 +4048,7 @@ Whether a particular pointer may be "null" is an important concern when working
with pointers in the C family of languages. The various nullability attributes
indicate whether a particular pointer can be null or not, which makes APIs more
expressive and can help static analysis tools identify bugs involving null
-pointers. Clang supports several kinds of nullability attributes: the
+pointers. Clang supports several kinds of nullability attributes: the
``nonnull`` and ``returns_nonnull`` attributes indicate which function or
method parameters and result types can never be null, while nullability type
qualifiers indicate which pointer types can be null (``_Nullable``) or cannot
@@ -3670,10 +4141,10 @@ completion handler in a Swift async method. For instance, here:
This method asynchronously calls ``completionHandler`` when the data is
available, or calls it with an error. ``_Nullable_result`` indicates to the
Swift importer that this is the uncommon case where ``result`` can get ``nil``
-even if no error has occured, and will therefore import it as a Swift optional
+even if no error has occurred, and will therefore import it as a Swift optional
type. Otherwise, if ``result`` was annotated with ``_Nullable``, the Swift
importer will assume that ``result`` will always be non-nil unless an error
-occured.
+occurred.
}];
}
@@ -3753,7 +4224,7 @@ memory is not available rather than returning a null pointer:
The ``returns_nonnull`` attribute implies that returning a null pointer is
undefined behavior, which the optimizer may take advantage of. The ``_Nonnull``
type qualifier indicates that a pointer cannot be null in a more general manner
-(because it is part of the type system) and does not imply undefined behavior,
+(because it is part of the type system) and does not imply undefined behavior,
making it more widely applicable
}];
}
@@ -4112,6 +4583,7 @@ Clang provides the following context selector extensions, used via
match_none
disable_implicit_base
allow_templates
+ bind_to_declaration
The match extensions change when the *entire* context selector is considered a
match for an OpenMP context. The default is ``all``, with ``none`` no trait in the
@@ -4127,8 +4599,9 @@ The allow extensions change when the ``begin declare variant`` effect is
applied to a definition. If ``allow_templates`` is given, template function
definitions are considered as specializations of existing or assumed template
declarations with the same name. The template parameters for the base functions
-are used to instantiate the specialization.
-
+are used to instantiate the specialization. If ``bind_to_declaration`` is given,
+apply the same variant rules to function declarations. This allows the user to
+override declarations with only a function declaration.
}];
}
@@ -4185,8 +4658,10 @@ spelled "XYZ" in the `OpenMP 5.1 Standard`_).
def NoStackProtectorDocs : Documentation {
let Category = DocCatFunction;
+ let Heading = "no_stack_protector, safebuffers";
let Content = [{
-Clang supports the ``__attribute__((no_stack_protector))`` attribute which disables
+Clang supports the GNU style ``__attribute__((no_stack_protector))`` and Microsoft
+style ``__declspec(safebuffers)`` attribute which disables
the stack protector on the specified function. This attribute is useful for
selectively disabling the stack protector on some functions when building with
``-fstack-protector`` compiler option.
@@ -4205,6 +4680,27 @@ option.
}];
}
+def StrictGuardStackCheckDocs : Documentation {
+ let Category = DocCatFunction;
+ let Content = [{
+Clang supports the Microsoft style ``__declspec((strict_gs_check))`` attribute
+which upgrades the stack protector check from ``-fstack-protector`` to
+``-fstack-protector-strong``.
+
+For example, it upgrades the stack protector for the function ``foo`` to
+``-fstack-protector-strong`` but function ``bar`` will still be built with the
+stack protector with the ``-fstack-protector`` option.
+
+.. code-block:: c
+
+ __declspec((strict_gs_check))
+ int foo(int x); // stack protection will be upgraded for foo.
+
+ int bar(int y); // bar can be built with the standard stack protector checks.
+
+ }];
+}
+
def NotTailCalledDocs : Documentation {
let Category = DocCatFunction;
let Content = [{
@@ -4270,6 +4766,16 @@ guaranteed to not throw an exception.
}];
}
+def NoUwtableDocs : Documentation {
+ let Category = DocCatFunction;
+ let Content = [{
+Clang supports the ``nouwtable`` attribute which skips emitting
+the unwind table entry for the specified function. This attribute is useful for
+selectively emitting the unwind table entry on some functions when building with
+``-funwind-tables`` compiler option.
+ }];
+}
+
def InternalLinkageDocs : Documentation {
let Category = DocCatFunction;
let Content = [{
@@ -4383,6 +4889,54 @@ Marking virtual functions as ``disable_tail_calls`` is legal.
}];
}
+def AnyX86InterruptDocs : Documentation {
+ let Category = DocCatFunction;
+ let Heading = "interrupt (X86)";
+ let Content = [{
+Clang supports the GNU style ``__attribute__((interrupt))`` attribute on X86
+targets. This attribute may be attached to a function definition and instructs
+the backend to generate appropriate function entry/exit code so that it can be
+used directly as an interrupt service routine.
+
+Interrupt handlers have access to the stack frame pushed onto the stack by the processor,
+and return using the ``IRET`` instruction. All registers in an interrupt handler are callee-saved.
+Exception handlers also have access to the error code pushed onto the stack by the processor,
+when applicable.
+
+An interrupt handler must take the following arguments:
+
+ .. code-block:: c
+
+ __attribute__ ((interrupt))
+ void f (struct stack_frame *frame) {
+ ...
+ }
+
+ Where ``struct stack_frame`` is a suitable struct matching the stack frame pushed by the
+ processor.
+
+An exception handler must take the following arguments:
+
+ .. code-block:: c
+
+ __attribute__ ((interrupt))
+ void g (struct stack_frame *frame, unsigned long code) {
+ ...
+ }
+
+ On 32-bit targets, the ``code`` argument should be of type ``unsigned int``.
+
+Exception handlers should only be used when an error code is pushed by the processor.
+Using the incorrect handler type will crash the system.
+
+Interrupt and exception handlers cannot be called by other functions and must have return type ``void``.
+
+Interrupt and exception handlers should only call functions with the 'no_caller_saved_registers'
+attribute, or should be compiled with the '-mgeneral-regs-only' flag to avoid saving unused
+non-GPR registers.
+ }];
+}
+
def AnyX86NoCallerSavedRegistersDocs : Documentation {
let Category = DocCatFunction;
let Content = [{
@@ -4397,6 +4951,10 @@ The user can call functions specified with the 'no_caller_saved_registers'
attribute from an interrupt handler without saving and restoring all
call-clobbered registers.
+Functions specified with the 'no_caller_saved_registers' attribute should only
+call other functions with the 'no_caller_saved_registers' attribute, or should be
+compiled with the '-mgeneral-regs-only' flag to avoid saving unused non-GPR registers.
+
Note that 'no_caller_saved_registers' attribute is not a calling convention.
In fact, it only overrides the decision of which registers should be saved by
the caller, but not how the parameters are passed from the caller to the callee.
@@ -4721,7 +5279,74 @@ the ``int`` parameter is the one that represents the error.
def SuppressDocs : Documentation {
let Category = DocCatStmt;
let Content = [{
-The ``[[gsl::suppress]]`` attribute suppresses specific
+The ``suppress`` attribute suppresses unwanted warnings coming from static
+analysis tools such as the Clang Static Analyzer. The tool will not report
+any issues in source code annotated with the attribute.
+
+The attribute cannot be used to suppress traditional Clang warnings, because
+many such warnings are emitted before the attribute is fully parsed.
+Consider using ``#pragma clang diagnostic`` to control such diagnostics,
+as described in `Controlling Diagnostics via Pragmas
+<https://clang.llvm.org/docs/UsersManual.html#controlling-diagnostics-via-pragmas>`_.
+
+The ``suppress`` attribute can be placed on an individual statement in order to
+suppress warnings about undesirable behavior occurring at that statement:
+
+.. code-block:: c++
+
+ int foo() {
+ int *x = nullptr;
+ ...
+ [[clang::suppress]]
+ return *x; // null pointer dereference warning suppressed here
+ }
+
+Putting the attribute on a compound statement suppresses all warnings in scope:
+
+.. code-block:: c++
+
+ int foo() {
+ [[clang::suppress]] {
+ int *x = nullptr;
+ ...
+ return *x; // warnings suppressed in the entire scope
+ }
+ }
+
+Some static analysis warnings are accompanied by one or more notes, and the
+line of code against which the warning is emitted isn't necessarily the best
+for suppression purposes. In such cases the tools are allowed to implement
+additional ways to suppress specific warnings based on the attribute attached
+to a note location.
+
+For example, the Clang Static Analyzer suppresses memory leak warnings when
+the suppression attribute is placed at the allocation site (highlited by
+a "note: memory is allocated"), which may be different from the line of code
+at which the program "loses track" of the pointer (where the warning
+is ultimately emitted):
+
+.. code-block:: c
+
+ int bar1(bool coin_flip) {
+ __attribute__((suppress))
+ int *result = (int *)malloc(sizeof(int));
+ if (coin_flip)
+ return 1; // warning about this leak path is suppressed
+
+ return *result; // warning about this leak path is also suppressed
+ }
+
+ int bar2(bool coin_flip) {
+ int *result = (int *)malloc(sizeof(int));
+ if (coin_flip)
+ return 1; // leak warning on this path NOT suppressed
+
+ __attribute__((suppress))
+ return *result; // leak warning is suppressed only on this path
+ }
+
+
+When written as ``[[gsl::suppress]]``, this attribute suppresses specific
clang-tidy diagnostics for rules of the `C++ Core Guidelines`_ in a portable
way. The attribute can be attached to declarations, statements, and at
namespace scope.
@@ -4799,6 +5424,12 @@ general this requires the template to be declared at least twice. For example:
clang::preferred_name(wstring)]] basic_string {
// ...
};
+
+
+Note that the ``preferred_name`` attribute will be ignored when the compiler
+writes a C++20 Module interface now. This is due to a compiler issue
+(https://github.com/llvm/llvm-project/issues/56490) that blocks users to modularize
+declarations with `preferred_name`. This is intended to be fixed in the future.
}];
}
@@ -4819,6 +5450,9 @@ apply for values returned in callee-saved registers.
R11. R11 can be used as a scratch register. Floating-point registers
(XMMs/YMMs) are not preserved and need to be saved by the caller.
+- On AArch64 the callee preserve all general purpose registers, except X0-X8 and
+ X16-X18.
+
The idea behind this convention is to support calls to runtime functions
that have a hot path and a cold path. The hot path is usually a small piece
of code that doesn't use many registers. The cold path might need to call out to
@@ -4859,6 +5493,10 @@ returned in callee-saved registers.
R11. R11 can be used as a scratch register. Furthermore it also preserves
all floating-point registers (XMMs/YMMs).
+- On AArch64 the callee preserve all general purpose registers, except X0-X8 and
+ X16-X18. Furthermore it also preserves lower 128 bits of V8-V31 SIMD - floating
+ point registers.
+
The idea behind this convention is to support calls to runtime functions
that don't need to call out to any other functions.
@@ -4909,7 +5547,9 @@ considered inline.
Not all targets support this attribute. ELF target support depends on both the
linker and runtime linker, and is available in at least lld 4.0 and later,
binutils 2.20.1 and later, glibc v2.11.1 and later, and FreeBSD 9.1 and later.
-Non-ELF targets currently do not support this attribute.
+Mach-O targets support it, but with slightly different semantics: the resolver
+is run at first call, instead of at load time by the runtime linker. Targets
+other than ELF and Mach-O currently do not support this attribute.
}];
}
@@ -4968,10 +5608,25 @@ takes precedence over the command line option ``-fpatchable-function-entry=N,M``
``M`` defaults to 0 if omitted.
This attribute is only supported on
-aarch64/aarch64-be/riscv32/riscv64/i386/x86-64 targets.
+aarch64/aarch64-be/loongarch32/loongarch64/riscv32/riscv64/i386/x86-64 targets.
}];
}
+def HotFunctionEntryDocs : Documentation {
+ let Category = DocCatFunction;
+ let Content = [{
+``__attribute__((hot))`` marks a function as hot, as a manual alternative to PGO hotness data.
+If PGO data is available, the annotation ``__attribute__((hot))`` overrides the profile count based hotness (unlike ``__attribute__((cold))``).
+}];
+}
+
+def ColdFunctionEntryDocs : Documentation {
+ let Category = DocCatFunction;
+ let Content = [{
+``__attribute__((cold))`` marks a function as cold, as a manual alternative to PGO hotness data.
+If PGO data is available, the profile count based hotness overrides the ``__attribute__((cold))`` annotation (unlike ``__attribute__((hot))``).
+}];
+}
def TransparentUnionDocs : Documentation {
let Category = DocCatDecl;
let Content = [{
@@ -5242,12 +5897,12 @@ accessed. The following are examples of valid expressions where may not be diagn
``noderef`` is currently only supported for pointers and arrays and not usable
for references or Objective-C object pointers.
-.. code-block: c++
+.. code-block:: c++
int x = 2;
int __attribute__((noderef)) &y = x; // warning: 'noderef' can only be used on an array or pointer type
-.. code-block: objc
+.. code-block:: objc
id __attribute__((noderef)) obj = [NSObject new]; // warning: 'noderef' can only be used on an array or pointer type
}];
@@ -5444,7 +6099,7 @@ by showing the control-flow statement where the path diverges.
if (somePredicate()) {
...
callback();
- } esle {
+ } else {
callback(); // OK: callback is called on every path
}
}
@@ -5615,6 +6270,15 @@ attribute can also be written using C++11 syntax: ``[[mig::server_routine]]``.
}];
}
+def MinSizeDocs : Documentation {
+ let Category = DocCatFunction;
+ let Content = [{
+This function attribute indicates that optimization passes and code generator passes
+make choices that keep the function code size as small as possible. Optimizations may
+also sacrifice runtime performance in order to minimize the size of the generated code.
+ }];
+}
+
def MSAllocatorDocs : Documentation {
let Category = DocCatFunction;
let Content = [{
@@ -5637,15 +6301,15 @@ def CFGuardDocs : Documentation {
let Content = [{
Code can indicate CFG checks are not wanted with the ``__declspec(guard(nocf))``
attribute. This directs the compiler to not insert any CFG checks for the entire
-function. This approach is typically used only sparingly in specific situations
-where the programmer has manually inserted "CFG-equivalent" protection. The
-programmer knows that they are calling through some read-only function table
-whose address is obtained through read-only memory references and for which the
-index is masked to the function table limit. This approach may also be applied
-to small wrapper functions that are not inlined and that do nothing more than
-make a call through a function pointer. Since incorrect usage of this directive
-can compromise the security of CFG, the programmer must be very careful using
-the directive. Typically, this usage is limited to very small functions that
+function. This approach is typically used only sparingly in specific situations
+where the programmer has manually inserted "CFG-equivalent" protection. The
+programmer knows that they are calling through some read-only function table
+whose address is obtained through read-only memory references and for which the
+index is masked to the function table limit. This approach may also be applied
+to small wrapper functions that are not inlined and that do nothing more than
+make a call through a function pointer. Since incorrect usage of this directive
+can compromise the security of CFG, the programmer must be very careful using
+the directive. Typically, this usage is limited to very small functions that
only call one function.
`Control Flow Guard documentation <https://docs.microsoft.com/en-us/windows/win32/secbp/pe-metadata>`
@@ -5782,9 +6446,6 @@ attribute `clang_builtin_alias`.
def NoBuiltinDocs : Documentation {
let Category = DocCatFunction;
let Content = [{
-.. Note:: This attribute is not yet fully implemented, it is validated but has
- no effect on the generated code.
-
The ``__attribute__((no_builtin))`` is similar to the ``-fno-builtin`` flag
except it is specific to the body of a function. The attribute may also be
applied to a virtual function but has no effect on the behavior of overriding
@@ -5831,7 +6492,7 @@ deferring any errors to the point of use. For instance:
does_not_exist x; // error: use of unresolved 'using_if_exists'
-The C++ spelling of the attribte (`[[clang::using_if_exists]]`) is also
+The C++ spelling of the attribute (`[[clang::using_if_exists]]`) is also
supported as a clang extension, since ISO C++ doesn't support attributes in this
position. If the entity referred to by the using-declaration is found by name
lookup, the attribute has no effect. This attribute is useful for libraries
@@ -5859,19 +6520,21 @@ def AcquireHandleDocs : Documentation {
If this annotation is on a function or a function type it is assumed to return
a new handle. In case this annotation is on an output parameter,
the function is assumed to fill the corresponding argument with a new
-handle.
+handle. The attribute requires a string literal argument which used to
+identify the handle with later uses of ``use_handle`` or
+``release_handle``.
.. code-block:: c++
// Output arguments from Zircon.
zx_status_t zx_socket_create(uint32_t options,
- zx_handle_t __attribute__((acquire_handle)) * out0,
- zx_handle_t* out1 [[clang::acquire_handle]]);
+ zx_handle_t __attribute__((acquire_handle("zircon"))) * out0,
+ zx_handle_t* out1 [[clang::acquire_handle("zircon")]]);
// Returned handle.
- [[clang::acquire_handle]] int open(const char *path, int oflag, ... );
- int open(const char *path, int oflag, ... ) __attribute__((acquire_handle));
+ [[clang::acquire_handle("tag")]] int open(const char *path, int oflag, ... );
+ int open(const char *path, int oflag, ... ) __attribute__((acquire_handle("tag")));
}];
}
@@ -5879,12 +6542,13 @@ def UseHandleDocs : Documentation {
let Category = HandleDocs;
let Content = [{
A function taking a handle by value might close the handle. If a function
-parameter is annotated with ``use_handle`` it is assumed to not to change
+parameter is annotated with ``use_handle(tag)`` it is assumed to not to change
the state of the handle. It is also assumed to require an open handle to work with.
+The attribute requires a string literal argument to identify the handle being used.
.. code-block:: c++
- zx_status_t zx_port_wait(zx_handle_t handle [[clang::use_handle]],
+ zx_status_t zx_port_wait(zx_handle_t handle [[clang::use_handle("zircon")]],
zx_time_t deadline,
zx_port_packet_t* packet);
}];
@@ -5893,15 +6557,139 @@ the state of the handle. It is also assumed to require an open handle to work wi
def ReleaseHandleDocs : Documentation {
let Category = HandleDocs;
let Content = [{
-If a function parameter is annotated with ``release_handle`` it is assumed to
-close the handle. It is also assumed to require an open handle to work with.
+If a function parameter is annotated with ``release_handle(tag)`` it is assumed to
+close the handle. It is also assumed to require an open handle to work with. The
+attribute requires a string literal argument to identify the handle being released.
.. code-block:: c++
- zx_status_t zx_handle_close(zx_handle_t handle [[clang::release_handle]]);
+ zx_status_t zx_handle_close(zx_handle_t handle [[clang::release_handle("tag")]]);
}];
}
+def UnsafeBufferUsageDocs : Documentation {
+ let Category = DocCatFunction;
+ let Content = [{
+The attribute ``[[clang::unsafe_buffer_usage]]`` should be placed on functions
+that need to be avoided as they are prone to buffer overflows. It is designed to
+work together with the off-by-default compiler warning ``-Wunsafe-buffer-usage``
+to help codebases transition away from raw pointer based buffer management,
+in favor of safer abstractions such as C++20 ``std::span``. The attribute causes
+``-Wunsafe-buffer-usage`` to warn on every use of the function, and it may
+enable ``-Wunsafe-buffer-usage`` to emit automatic fix-it hints
+which would help the user replace such unsafe functions with safe
+alternatives, though the attribute can be used even when the fix can't be automated.
+
+The attribute does not suppress ``-Wunsafe-buffer-usage`` inside the function
+to which it is attached. These warnings still need to be addressed.
+
+The attribute is warranted even if the only way a function can overflow
+the buffer is by violating the function's preconditions. For example, it
+would make sense to put the attribute on function ``foo()`` below because
+passing an incorrect size parameter would cause a buffer overflow:
+
+.. code-block:: c++
+
+ [[clang::unsafe_buffer_usage]]
+ void foo(int *buf, size_t size) {
+ for (size_t i = 0; i < size; ++i) {
+ buf[i] = i;
+ }
+ }
+
+The attribute is NOT warranted when the function uses safe abstractions,
+assuming that these abstractions weren't misused outside the function.
+For example, function ``bar()`` below doesn't need the attribute,
+because assuming that the container ``buf`` is well-formed (has size that
+fits the original buffer it refers to), overflow cannot occur:
+
+.. code-block:: c++
+
+ void bar(std::span<int> buf) {
+ for (size_t i = 0; i < buf.size(); ++i) {
+ buf[i] = i;
+ }
+ }
+
+In this case function ``bar()`` enables the user to keep the buffer
+"containerized" in a span for as long as possible. On the other hand,
+Function ``foo()`` in the previous example may have internal
+consistency, but by accepting a raw buffer it requires the user to unwrap
+their span, which is undesirable according to the programming model
+behind ``-Wunsafe-buffer-usage``.
+
+The attribute is warranted when a function accepts a raw buffer only to
+immediately put it into a span:
+
+.. code-block:: c++
+
+ [[clang::unsafe_buffer_usage]]
+ void baz(int *buf, size_t size) {
+ std::span<int> sp{ buf, size };
+ for (size_t i = 0; i < sp.size(); ++i) {
+ sp[i] = i;
+ }
+ }
+
+In this case ``baz()`` does not contain any unsafe operations, but the awkward
+parameter type causes the caller to unwrap the span unnecessarily.
+Note that regardless of the attribute, code inside ``baz()`` isn't flagged
+by ``-Wunsafe-buffer-usage`` as unsafe. It is definitely undesirable,
+but if ``baz()`` is on an API surface, there is no way to improve it
+to make it as safe as ``bar()`` without breaking the source and binary
+compatibility with existing users of the function. In such cases
+the proper solution would be to create a different function (possibly
+an overload of ``baz()``) that accepts a safe container like ``bar()``,
+and then use the attribute on the original ``baz()`` to help the users
+update their code to use the new function.
+ }];
+}
+
+def DiagnoseAsBuiltinDocs : Documentation {
+ let Category = DocCatFunction;
+ let Content = [{
+The ``diagnose_as_builtin`` attribute indicates that Fortify diagnostics are to
+be applied to the declared function as if it were the function specified by the
+attribute. The builtin function whose diagnostics are to be mimicked should be
+given. In addition, the order in which arguments should be applied must also
+be given.
+
+For example, the attribute can be used as follows.
+
+.. code-block:: c
+
+ __attribute__((diagnose_as_builtin(__builtin_memset, 3, 2, 1)))
+ void *mymemset(int n, int c, void *s) {
+ // ...
+ }
+
+This indicates that calls to ``mymemset`` should be diagnosed as if they were
+calls to ``__builtin_memset``. The arguments ``3, 2, 1`` indicate by index the
+order in which arguments of ``mymemset`` should be applied to
+``__builtin_memset``. The third argument should be applied first, then the
+second, and then the first. Thus (when Fortify warnings are enabled) the call
+``mymemset(n, c, s)`` will diagnose overflows as if it were the call
+``__builtin_memset(s, c, n)``.
+
+For variadic functions, the variadic arguments must come in the same order as
+they would to the builtin function, after all normal arguments. For instance,
+to diagnose a new function as if it were `sscanf`, we can use the attribute as
+follows.
+
+.. code-block:: c
+
+ __attribute__((diagnose_as_builtin(sscanf, 1, 2)))
+ int mysscanf(const char *str, const char *format, ...) {
+ // ...
+ }
+
+Then the call `mysscanf("abc def", "%4s %4s", buf1, buf2)` will be diagnosed as
+if it were the call `sscanf("abc def", "%4s %4s", buf1, buf2)`.
+
+This attribute cannot be applied to non-static member functions.
+}];
+}
+
def ArmSveVectorBitsDocs : Documentation {
let Category = DocCatType;
let Content = [{
@@ -6002,13 +6790,234 @@ Requirements on Development Tools - Engineering Specification Documentation
}];
}
+def DocCatArmSmeAttributes : DocumentationCategory<"AArch64 SME Attributes"> {
+ let Content = [{
+Clang supports a number of AArch64-specific attributes to manage state
+added by the Scalable Matrix Extension (SME). This state includes the
+runtime mode that the processor is in (e.g. non-streaming or streaming)
+as well as the state of the ``ZA`` Matrix Storage.
+
+The attributes come in the form of type- and declaration attributes:
+
+* The SME declaration attributes can appear anywhere that a standard
+ ``[[...]]`` declaration attribute can appear.
+
+* The SME type attributes apply only to prototyped functions and can appear
+ anywhere that a standard ``[[...]]`` type attribute can appear. The SME
+ type attributes do not apply to functions having a K&R-style
+ unprototyped function type.
+
+See `Arm C Language Extensions <https://github.com/ARM-software/acle>`_
+for more details about the features related to the SME extension.
+
+See `Procedure Call Standard for the Arm® 64-bit Architecture (AArch64)
+<https://github.com/ARM-software/abi-aa>`_ for more details about
+streaming-interface functions and shared/private-ZA interface functions.
+ }];
+}
+
+def ArmSmeStreamingDocs : Documentation {
+ let Category = DocCatArmSmeAttributes;
+ let Content = [{
+The ``__arm_streaming`` keyword applies to prototyped function types and specifies
+that the function has a "streaming interface". This means that:
+
+* the function requires that the processor implements the Scalable Matrix
+ Extension (SME).
+
+* the function must be entered in streaming mode (that is, with PSTATE.SM
+ set to 1)
+
+* the function must return in streaming mode
+
+Clang manages PSTATE.SM automatically; it is not the source code's
+responsibility to do this. For example, if a non-streaming
+function calls an ``__arm_streaming`` function, Clang generates code
+that switches into streaming mode before calling the function and
+switches back to non-streaming mode on return.
+ }];
+}
+
+def ArmSmeStreamingCompatibleDocs : Documentation {
+ let Category = DocCatArmSmeAttributes;
+ let Content = [{
+The ``__arm_streaming_compatible`` keyword applies to prototyped function types and
+specifies that the function has a "streaming compatible interface". This
+means that:
+
+* the function may be entered in either non-streaming mode (PSTATE.SM=0) or
+ in streaming mode (PSTATE.SM=1).
+
+* the function must return in the same mode as it was entered.
+
+* the code executed in the function is compatible with either mode.
+
+Clang manages PSTATE.SM automatically; it is not the source code's
+responsibility to do this. Clang will ensure that the generated code in
+streaming-compatible functions is valid in either mode (PSTATE.SM=0 or
+PSTATE.SM=1). For example, if an ``__arm_streaming_compatible`` function calls a
+non-streaming function, Clang generates code to temporarily switch out of streaming
+mode before calling the function and switch back to streaming-mode on return if
+``PSTATE.SM`` is ``1`` on entry of the caller. If ``PSTATE.SM`` is ``0`` on
+entry to the ``__arm_streaming_compatible`` function, the call will be executed
+without changing modes.
+ }];
+}
+
+def ArmInDocs : Documentation {
+ let Category = DocCatArmSmeAttributes;
+ let Content = [{
+The ``__arm_in`` keyword applies to prototyped function types and specifies
+that the function shares a given state S with its caller. For ``__arm_in``, the
+function takes the state S as input and returns with the state S unchanged.
+
+The attribute takes string arguments to instruct the compiler which state
+is shared. The supported states for S are:
+
+* ``"za"`` for Matrix Storage (requires SME)
+
+The attributes ``__arm_in(S)``, ``__arm_out(S)``, ``__arm_inout(S)`` and
+``__arm_preserves(S)`` are all mutually exclusive for the same state S.
+ }];
+}
+
+def ArmOutDocs : Documentation {
+ let Category = DocCatArmSmeAttributes;
+ let Content = [{
+The ``__arm_out`` keyword applies to prototyped function types and specifies
+that the function shares a given state S with its caller. For ``__arm_out``,
+the function ignores the incoming state for S and returns new state for S.
+
+The attribute takes string arguments to instruct the compiler which state
+is shared. The supported states for S are:
+
+* ``"za"`` for Matrix Storage (requires SME)
+
+The attributes ``__arm_in(S)``, ``__arm_out(S)``, ``__arm_inout(S)`` and
+``__arm_preserves(S)`` are all mutually exclusive for the same state S.
+ }];
+}
+
+def ArmInOutDocs : Documentation {
+ let Category = DocCatArmSmeAttributes;
+ let Content = [{
+The ``__arm_inout`` keyword applies to prototyped function types and specifies
+that the function shares a given state S with its caller. For ``__arm_inout``,
+the function takes the state S as input and returns new state for S.
+
+The attribute takes string arguments to instruct the compiler which state
+is shared. The supported states for S are:
+
+* ``"za"`` for Matrix Storage (requires SME)
+
+The attributes ``__arm_in(S)``, ``__arm_out(S)``, ``__arm_inout(S)`` and
+``__arm_preserves(S)`` are all mutually exclusive for the same state S.
+ }];
+}
+
+def ArmPreservesDocs : Documentation {
+ let Category = DocCatArmSmeAttributes;
+ let Content = [{
+The ``__arm_preserves`` keyword applies to prototyped function types and
+specifies that the function does not read a given state S and returns
+with state S unchanged.
+
+The attribute takes string arguments to instruct the compiler which state
+is shared. The supported states for S are:
+
+* ``"za"`` for Matrix Storage (requires SME)
+
+The attributes ``__arm_in(S)``, ``__arm_out(S)``, ``__arm_inout(S)`` and
+``__arm_preserves(S)`` are all mutually exclusive for the same state S.
+ }];
+}
+
+def ArmSmeLocallyStreamingDocs : Documentation {
+ let Category = DocCatArmSmeAttributes;
+ let Content = [{
+The ``__arm_locally_streaming`` keyword applies to function declarations
+and specifies that all the statements in the function are executed in
+streaming mode. This means that:
+
+* the function requires that the target processor implements the Scalable Matrix
+ Extension (SME).
+
+* the program automatically puts the machine into streaming mode before
+ executing the statements and automatically restores the previous mode
+ afterwards.
+
+Clang manages PSTATE.SM automatically; it is not the source code's
+responsibility to do this. For example, Clang will emit code to enable
+streaming mode at the start of the function, and disable streaming mode
+at the end of the function.
+ }];
+}
+
+def ArmNewDocs : Documentation {
+ let Category = DocCatArmSmeAttributes;
+ let Content = [{
+The ``__arm_new`` keyword applies to function declarations and specifies
+that the function will create a new scope for state S.
+
+The attribute takes string arguments to instruct the compiler for which state
+to create new scope. The supported states for S are:
+
+* ``"za"`` for Matrix Storage (requires SME)
+
+For state ``"za"``, this means that:
+
+* the function requires that the target processor implements the Scalable Matrix
+ Extension (SME).
+
+* the function will commit any lazily saved ZA data.
+
+* the function will create a new ZA context and enable PSTATE.ZA.
+
+* the function will disable PSTATE.ZA (by setting it to 0) before returning.
+
+For ``__arm_new("za")`` functions Clang will set up the ZA context automatically
+on entry to the function and disable it before returning. For example, if ZA is
+in a dormant state Clang will generate the code to commit a lazy-save and set up
+a new ZA state before executing user code.
+ }];
+}
+
def AlwaysInlineDocs : Documentation {
let Category = DocCatFunction;
let Content = [{
Inlining heuristics are disabled and inlining is always attempted regardless of
optimization level.
-Does not guarantee that inline substitution actually occurs.
+``[[clang::always_inline]]`` spelling can be used as a statement attribute; other
+spellings of the attribute are not supported on statements. If a statement is
+marked ``[[clang::always_inline]]`` and contains calls, the compiler attempts
+to inline those calls.
+
+.. code-block:: c
+
+ int example(void) {
+ int i;
+ [[clang::always_inline]] foo(); // attempts to inline foo
+ [[clang::always_inline]] i = bar(); // attempts to inline bar
+ [[clang::always_inline]] return f(42, baz(bar())); // attempts to inline everything
+ }
+
+A declaration statement, which is a statement, is not a statement that can have an
+attribute associated with it (the attribute applies to the declaration, not the
+statement in that case). So this use case will not work:
+
+.. code-block:: c
+
+ int example(void) {
+ [[clang::always_inline]] int i = bar();
+ return i;
+ }
+
+This attribute does not guarantee that inline substitution actually occurs.
+
+<ins>Note: applying this attribute to a coroutine at the `-O0` optimization level
+has no effect; other optimization levels may only partially inline and result in a
+diagnostic.</ins>
See also `the Microsoft Docs on Inline Functions`_, `the GCC Common Function
Attribute docs`_, and `the GCC Inline docs`_.
@@ -6045,3 +7054,827 @@ def EnforceTCBLeafDocs : Documentation {
- ``enforce_tcb_leaf(Name)`` indicates that this function is a part of the TCB named ``Name``
}];
}
+
+def ErrorAttrDocs : Documentation {
+ let Category = DocCatFunction;
+ let Heading = "error, warning";
+ let Content = [{
+The ``error`` and ``warning`` function attributes can be used to specify a
+custom diagnostic to be emitted when a call to such a function is not
+eliminated via optimizations. This can be used to create compile time
+assertions that depend on optimizations, while providing diagnostics
+pointing to precise locations of the call site in the source.
+
+.. code-block:: c++
+
+ __attribute__((warning("oh no"))) void dontcall();
+ void foo() {
+ if (someCompileTimeAssertionThatsTrue)
+ dontcall(); // Warning
+
+ dontcall(); // Warning
+
+ if (someCompileTimeAssertionThatsFalse)
+ dontcall(); // No Warning
+ sizeof(dontcall()); // No Warning
+ }
+ }];
+}
+
+def ZeroCallUsedRegsDocs : Documentation {
+ let Category = DocCatFunction;
+ let Content = [{
+This attribute, when attached to a function, causes the compiler to zero a
+subset of all call-used registers before the function returns. It's used to
+increase program security by either mitigating `Return-Oriented Programming`_
+(ROP) attacks or preventing information leakage through registers.
+
+The term "call-used" means registers which are not guaranteed to be preserved
+unchanged for the caller by the current calling convention. This could also be
+described as "caller-saved" or "not callee-saved".
+
+The `choice` parameters gives the programmer flexibility to choose the subset
+of the call-used registers to be zeroed:
+
+- ``skip`` doesn't zero any call-used registers. This choice overrides any
+ command-line arguments.
+- ``used`` only zeros call-used registers used in the function. By ``used``, we
+ mean a register whose contents have been set or referenced in the function.
+- ``used-gpr`` only zeros call-used GPR registers used in the function.
+- ``used-arg`` only zeros call-used registers used to pass arguments to the
+ function.
+- ``used-gpr-arg`` only zeros call-used GPR registers used to pass arguments to
+ the function.
+- ``all`` zeros all call-used registers.
+- ``all-gpr`` zeros all call-used GPR registers.
+- ``all-arg`` zeros all call-used registers used to pass arguments to the
+ function.
+- ``all-gpr-arg`` zeros all call-used GPR registers used to pass arguments to
+ the function.
+
+The default for the attribute is controlled by the ``-fzero-call-used-regs``
+flag.
+
+.. _Return-Oriented Programming: https://en.wikipedia.org/wiki/Return-oriented_programming
+ }];
+}
+
+def NumThreadsDocs : Documentation {
+ let Category = DocCatFunction;
+ let Content = [{
+The ``numthreads`` attribute applies to HLSL shaders where explcit thread counts
+are required. The ``X``, ``Y``, and ``Z`` values provided to the attribute
+dictate the thread id. Total number of threads executed is ``X * Y * Z``.
+
+The full documentation is available here: https://docs.microsoft.com/en-us/windows/win32/direct3dhlsl/sm5-attributes-numthreads
+ }];
+}
+
+def HLSLSV_ShaderTypeAttrDocs : Documentation {
+ let Category = DocCatFunction;
+ let Content = [{
+The ``shader`` type attribute applies to HLSL shader entry functions to
+identify the shader type for the entry function.
+The syntax is:
+
+.. code-block:: text
+
+ ``[shader(string-literal)]``
+
+where the string literal is one of: "pixel", "vertex", "geometry", "hull",
+"domain", "compute", "raygeneration", "intersection", "anyhit", "closesthit",
+"miss", "callable", "mesh", "amplification". Normally the shader type is set
+by shader target with the ``-T`` option like ``-Tps_6_1``. When compiling to a
+library target like ``lib_6_3``, the shader type attribute can help the
+compiler to identify the shader type. It is mostly used by Raytracing shaders
+where shaders must be compiled into a library and linked at runtime.
+ }];
+}
+
+def ClangRandomizeLayoutDocs : Documentation {
+ let Category = DocCatDecl;
+ let Heading = "randomize_layout, no_randomize_layout";
+ let Content = [{
+The attribute ``randomize_layout``, when attached to a C structure, selects it
+for structure layout field randomization; a compile-time hardening technique. A
+"seed" value, is specified via the ``-frandomize-layout-seed=`` command line flag.
+For example:
+
+.. code-block:: bash
+
+ SEED=`od -A n -t x8 -N 32 /dev/urandom | tr -d ' \n'`
+ make ... CFLAGS="-frandomize-layout-seed=$SEED" ...
+
+You can also supply the seed in a file with ``-frandomize-layout-seed-file=``.
+For example:
+
+.. code-block:: bash
+
+ od -A n -t x8 -N 32 /dev/urandom | tr -d ' \n' > /tmp/seed_file.txt
+ make ... CFLAGS="-frandomize-layout-seed-file=/tmp/seed_file.txt" ...
+
+The randomization is deterministic based for a given seed, so the entire
+program should be compiled with the same seed, but keep the seed safe
+otherwise.
+
+The attribute ``no_randomize_layout``, when attached to a C structure,
+instructs the compiler that this structure should not have its field layout
+randomized.
+ }];
+}
+
+def HLSLSV_GroupIndexDocs : Documentation {
+ let Category = DocCatFunction;
+ let Content = [{
+The ``SV_GroupIndex`` semantic, when applied to an input parameter, specifies a
+data binding to map the group index to the specified parameter. This attribute
+is only supported in compute shaders.
+
+The full documentation is available here: https://docs.microsoft.com/en-us/windows/win32/direct3dhlsl/sv-groupindex
+ }];
+}
+
+def HLSLResourceBindingDocs : Documentation {
+ let Category = DocCatFunction;
+ let Content = [{
+The resource binding attribute sets the virtual register and logical register space for a resource.
+Attribute spelling in HLSL is: ``register(slot [, space])``.
+``slot`` takes the format ``[type][number]``,
+where ``type`` is a single character specifying the resource type and ``number`` is the virtual register number.
+
+Register types are:
+t for shader resource views (SRV),
+s for samplers,
+u for unordered access views (UAV),
+b for constant buffer views (CBV).
+
+Register space is specified in the format ``space[number]`` and defaults to ``space0`` if omitted.
+Here're resource binding examples with and without space:
+.. code-block:: c++
+
+ RWBuffer<float> Uav : register(u3, space1);
+ Buffer<float> Buf : register(t1);
+
+The full documentation is available here: https://docs.microsoft.com/en-us/windows/win32/direct3d12/resource-binding-in-hlsl
+ }];
+}
+
+def HLSLSV_DispatchThreadIDDocs : Documentation {
+ let Category = DocCatFunction;
+ let Content = [{
+The ``SV_DispatchThreadID`` semantic, when applied to an input parameter,
+specifies a data binding to map the global thread offset within the Dispatch
+call (per dimension of the group) to the specified parameter.
+When applied to a field of a struct, the data binding is specified to the field
+when the struct is used as a parameter type.
+The semantic on the field is ignored when not used as a parameter.
+This attribute is only supported in compute shaders.
+
+The full documentation is available here: https://docs.microsoft.com/en-us/windows/win32/direct3dhlsl/sv-dispatchthreadid
+ }];
+}
+
+def HLSLGroupSharedAddressSpaceDocs : Documentation {
+ let Category = DocCatVariable;
+ let Content = [{
+HLSL enables threads of a compute shader to exchange values via shared memory.
+HLSL provides barrier primitives such as GroupMemoryBarrierWithGroupSync,
+and so on to ensure the correct ordering of reads and writes to shared memory
+in the shader and to avoid data races.
+Here's an example to declare a groupshared variable.
+.. code-block:: c++
+
+ groupshared GSData data[5*5*1];
+
+The full documentation is available here: https://learn.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-variable-syntax#group-shared
+ }];
+}
+
+def HLSLParamQualifierDocs : Documentation {
+ let Category = DocCatVariable;
+ let Heading = "HLSL Parameter Modifiers";
+ let Content = [{
+HLSL function parameters are passed by value. Parameter declarations support
+three qualifiers to denote parameter passing behavior. The three qualifiers are
+`in`, `out` and `inout`.
+
+Parameters annotated with `in` or with no annotation are passed by value from
+the caller to the callee.
+
+Parameters annotated with `out` are written to the argument after the callee
+returns (Note: arguments values passed into `out` parameters *are not* copied
+into the callee).
+
+Parameters annotated with `inout` are copied into the callee via a temporary,
+and copied back to the argument after the callee returns.
+ }];
+}
+
+def AnnotateTypeDocs : Documentation {
+ let Category = DocCatType;
+ let Heading = "annotate_type";
+ let Content = [{
+This attribute is used to add annotations to types, typically for use by static
+analysis tools that are not integrated into the core Clang compiler (e.g.,
+Clang-Tidy checks or out-of-tree Clang-based tools). It is a counterpart to the
+`annotate` attribute, which serves the same purpose, but for declarations.
+
+The attribute takes a mandatory string literal argument specifying the
+annotation category and an arbitrary number of optional arguments that provide
+additional information specific to the annotation category. The optional
+arguments must be constant expressions of arbitrary type.
+
+For example:
+
+.. code-block:: c++
+
+ int* [[clang::annotate_type("category1", "foo", 1)]] f(int[[clang::annotate_type("category2")]] *);
+
+The attribute does not have any effect on the semantics of the type system,
+neither type checking rules, nor runtime semantics. In particular:
+
+- ``std::is_same<T, T [[clang::annotate_type("foo")]]>`` is true for all types
+ ``T``.
+
+- It is not permissible for overloaded functions or template specializations
+ to differ merely by an ``annotate_type`` attribute.
+
+- The presence of an ``annotate_type`` attribute will not affect name
+ mangling.
+ }];
+}
+
+def WeakDocs : Documentation {
+ let Category = DocCatDecl;
+ let Content = [{
+
+In supported output formats the ``weak`` attribute can be used to
+specify that a variable or function should be emitted as a symbol with
+``weak`` (if a definition) or ``extern_weak`` (if a declaration of an
+external symbol) `linkage
+<https://llvm.org/docs/LangRef.html#linkage-types>`_.
+
+If there is a non-weak definition of the symbol the linker will select
+that over the weak. They must have same type and alignment (variables
+must also have the same size), but may have a different value.
+
+If there are multiple weak definitions of same symbol, but no non-weak
+definition, they should have same type, size, alignment and value, the
+linker will select one of them (see also selectany_ attribute).
+
+If the ``weak`` attribute is applied to a ``const`` qualified variable
+definition that variable is no longer consider a compiletime constant
+as its value can change during linking (or dynamic linking). This
+means that it can e.g no longer be part of an initializer expression.
+
+.. code-block:: c
+
+ const int ANSWER __attribute__ ((weak)) = 42;
+
+ /* This function may be replaced link-time */
+ __attribute__ ((weak)) void debug_log(const char *msg)
+ {
+ fprintf(stderr, "DEBUG: %s\n", msg);
+ }
+
+ int main(int argc, const char **argv)
+ {
+ debug_log ("Starting up...");
+
+ /* This may print something else than "6 * 7 = 42",
+ if there is a non-weak definition of "ANSWER" in
+ an object linked in */
+ printf("6 * 7 = %d\n", ANSWER);
+
+ return 0;
+ }
+
+If an external declaration is marked weak and that symbol does not
+exist during linking (possibly dynamic) the address of the symbol will
+evaluate to NULL.
+
+.. code-block:: c
+
+ void may_not_exist(void) __attribute__ ((weak));
+
+ int main(int argc, const char **argv)
+ {
+ if (may_not_exist) {
+ may_not_exist();
+ } else {
+ printf("Function did not exist\n");
+ }
+ return 0;
+ }
+ }];
+}
+
+def FunctionReturnThunksDocs : Documentation {
+ let Category = DocCatFunction;
+ let Content = [{
+The attribute ``function_return`` can replace return instructions with jumps to
+target-specific symbols. This attribute supports 2 possible values,
+corresponding to the values supported by the ``-mfunction-return=`` command
+line flag:
+
+* ``__attribute__((function_return("keep")))`` to disable related transforms.
+ This is useful for undoing global setting from ``-mfunction-return=`` locally
+ for individual functions.
+* ``__attribute__((function_return("thunk-extern")))`` to replace returns with
+ jumps, while NOT emitting the thunk.
+
+The values ``thunk`` and ``thunk-inline`` from GCC are not supported.
+
+The symbol used for ``thunk-extern`` is target specific:
+* X86: ``__x86_return_thunk``
+
+As such, this function attribute is currently only supported on X86 targets.
+ }];
+}
+
+def ReadOnlyPlacementDocs : Documentation {
+ let Category = DocCatType;
+ let Content = [{This attribute is attached to a structure, class or union declaration.
+ When attached to a record declaration/definition, it checks if all instances
+ of this type can be placed in the read-only data segment of the program. If it
+ finds an instance that can not be placed in a read-only segment, the compiler
+ emits a warning at the source location where the type was used.
+
+ Examples:
+ * ``struct __attribute__((enforce_read_only_placement)) Foo;``
+ * ``struct __attribute__((enforce_read_only_placement)) Bar { ... };``
+
+ Both ``Foo`` and ``Bar`` types have the ``enforce_read_only_placement`` attribute.
+
+ The goal of introducing this attribute is to assist developers with writing secure
+ code. A ``const``-qualified global is generally placed in the read-only section
+ of the memory that has additional run time protection from malicious writes. By
+ attaching this attribute to a declaration, the developer can express the intent
+ to place all instances of the annotated type in the read-only program memory.
+
+ Note 1: The attribute doesn't guarantee that the object will be placed in the
+ read-only data segment as it does not instruct the compiler to ensure such
+ a placement. It emits a warning if something in the code can be proven to prevent
+ an instance from being placed in the read-only data segment.
+
+ Note 2: Currently, clang only checks if all global declarations of a given type 'T'
+ are ``const``-qualified. The following conditions would also prevent the data to be
+ put into read only segment, but the corresponding warnings are not yet implemented.
+
+ 1. An instance of type ``T`` is allocated on the heap/stack.
+ 2. Type ``T`` defines/inherits a mutable field.
+ 3. Type ``T`` defines/inherits non-constexpr constructor(s) for initialization.
+ 4. A field of type ``T`` is defined by type ``Q``, which does not bear the
+ ``enforce_read_only_placement`` attribute.
+ 5. A type ``Q`` inherits from type ``T`` and it does not have the
+ ``enforce_read_only_placement`` attribute.
+ }];
+}
+
+def WebAssemblyFuncrefDocs : Documentation {
+ let Category = DocCatType;
+ let Content = [{
+Clang supports the ``__funcref`` attribute for the WebAssembly target.
+This attribute may be attached to a function pointer type, where it modifies
+its underlying representation to be a WebAssembly ``funcref``.
+ }];
+}
+
+def PreferredTypeDocumentation : Documentation {
+ let Category = DocCatField;
+ let Content = [{
+This attribute allows adjusting the type of a bit-field in debug information.
+This can be helpful when a bit-field is intended to store an enumeration value,
+but has to be specified as having the enumeration's underlying type in order to
+facilitate compiler optimizations or bit-field packing behavior. Normally, the
+underlying type is what is emitted in debug information, which can make it hard
+for debuggers to know to map a bit-field's value back to a particular enumeration.
+
+.. code-block:: c++
+
+ enum Colors { Red, Green, Blue };
+
+ struct S {
+ [[clang::preferred_type(Colors)]] unsigned ColorVal : 2;
+ [[clang::preferred_type(bool)]] unsigned UseAlternateColorSpace : 1;
+ } s = { Green, false };
+
+Without the attribute, a debugger is likely to display the value ``1`` for ``ColorVal``
+and ``0`` for ``UseAlternateColorSpace``. With the attribute, the debugger may now
+display ``Green`` and ``false`` instead.
+
+This can be used to map a bit-field to an arbitrary type that isn't integral
+or an enumeration type. For example:
+
+.. code-block:: c++
+
+ struct A {
+ short a1;
+ short a2;
+ };
+
+ struct B {
+ [[clang::preferred_type(A)]] unsigned b1 : 32 = 0x000F'000C;
+ };
+
+will associate the type ``A`` with the ``b1`` bit-field and is intended to display
+something like this in the debugger:
+
+.. code-block:: text
+
+ Process 2755547 stopped
+ * thread #1, name = 'test-preferred-', stop reason = step in
+ frame #0: 0x0000555555555148 test-preferred-type`main at test.cxx:13:14
+ 10 int main()
+ 11 {
+ 12 B b;
+ -> 13 return b.b1;
+ 14 }
+ (lldb) v -T
+ (B) b = {
+ (A:32) b1 = {
+ (short) a1 = 12
+ (short) a2 = 15
+ }
+ }
+
+Note that debuggers may not be able to handle more complex mappings, and so
+this usage is debugger-dependent.
+ }];
+}
+
+def CleanupDocs : Documentation {
+ let Category = DocCatVariable;
+ let Content = [{
+This attribute allows a function to be run when a local variable goes out of
+scope. The attribute takes the identifier of a function with a parameter type
+that is a pointer to the type with the attribute.
+
+.. code-block:: c
+
+ static void foo (int *) { ... }
+ static void bar (int *) { ... }
+ void baz (void) {
+ int x __attribute__((cleanup(foo)));
+ {
+ int y __attribute__((cleanup(bar)));
+ }
+ }
+
+The above example will result in a call to ``bar`` being passed the address of
+`y`` when ``y`` goes out of scope, then a call to ``foo`` being passed the
+address of ``x`` when ``x`` goes out of scope. If two or more variables share
+the same scope, their ``cleanup`` callbacks are invoked in the reverse order
+the variables were declared in. It is not possible to check the return value
+(if any) of these ``cleanup`` callback functions.
+}];
+}
+
+def CtorDtorDocs : Documentation {
+ let Category = DocCatFunction;
+ let Content = [{
+The ``constructor`` attribute causes the function to be called before entering
+``main()``, and the ``destructor`` attribute causes the function to be called
+after returning from ``main()`` or when the ``exit()`` function has been
+called. Note, ``quick_exit()``, ``_Exit()``, and ``abort()`` prevent a function
+marked ``destructor`` from being called.
+
+The constructor or destructor function should not accept any arguments and its
+return type should be ``void``.
+
+The attributes accept an optional argument used to specify the priority order
+in which to execute constructor and destructor functions. The priority is
+given as an integer constant expression between 101 and 65535 (inclusive).
+Priorities outside of that range are reserved for use by the implementation. A
+lower value indicates a higher priority of initialization. Note that only the
+relative ordering of values is important. For example:
+
+.. code-block:: c++
+
+ __attribute__((constructor(200))) void foo(void);
+ __attribute__((constructor(101))) void bar(void);
+
+``bar()`` will be called before ``foo()``, and both will be called before
+``main()``. If no argument is given to the ``constructor`` or ``destructor``
+attribute, they default to the value ``65535``.
+}];
+}
+
+def CoroOnlyDestroyWhenCompleteDocs : Documentation {
+ let Category = DocCatDecl;
+ let Content = [{
+The `coro_only_destroy_when_complete` attribute should be marked on a C++ class. The coroutines
+whose return type is marked with the attribute are assumed to be destroyed only after the coroutine has
+reached the final suspend point.
+
+This is helpful for the optimizers to reduce the size of the destroy function for the coroutines.
+
+For example,
+
+.. code-block:: c++
+
+ A foo() {
+ dtor d;
+ co_await something();
+ dtor d1;
+ co_await something();
+ dtor d2;
+ co_return 43;
+ }
+
+The compiler may generate the following pseudocode:
+
+.. code-block:: c++
+
+ void foo.destroy(foo.Frame *frame) {
+ switch(frame->suspend_index()) {
+ case 1:
+ frame->d.~dtor();
+ break;
+ case 2:
+ frame->d.~dtor();
+ frame->d1.~dtor();
+ break;
+ case 3:
+ frame->d.~dtor();
+ frame->d1.~dtor();
+ frame->d2.~dtor();
+ break;
+ default: // coroutine completed or haven't started
+ break;
+ }
+
+ frame->promise.~promise_type();
+ delete frame;
+ }
+
+The `foo.destroy()` function's purpose is to release all of the resources
+initialized for the coroutine when it is destroyed in a suspended state.
+However, if the coroutine is only ever destroyed at the final suspend state,
+the rest of the conditions are superfluous.
+
+The user can use the `coro_only_destroy_when_complete` attributo suppress
+generation of the other destruction cases, optimizing the above `foo.destroy` to:
+
+.. code-block:: c++
+
+ void foo.destroy(foo.Frame *frame) {
+ frame->promise.~promise_type();
+ delete frame;
+ }
+
+ }];
+}
+
+def CoroReturnTypeAndWrapperDoc : Documentation {
+ let Category = DocCatDecl;
+ let Content = [{
+The ``[[clang::coro_return_type]]`` attribute is used to help static analyzers to recognize
+coroutines from the function signatures.
+
+The ``coro_return_type`` attribute should be marked on a C++ class to mark it as
+a **coroutine return type (CRT)**.
+
+A function ``R func(P1, .., PN)`` has a coroutine return type (CRT) ``R`` if ``R``
+is marked by ``[[clang::coro_return_type]]`` and ``R`` has a promise type associated to it
+(i.e., std::coroutine_traits<R, P1, .., PN>::promise_type is a valid promise type).
+
+If the return type of a function is a ``CRT`` then the function must be a coroutine.
+Otherwise the program is invalid. It is allowed for a non-coroutine to return a ``CRT``
+if the function is marked with ``[[clang::coro_wrapper]]``.
+
+The ``[[clang::coro_wrapper]]`` attribute should be marked on a C++ function to mark it as
+a **coroutine wrapper**. A coroutine wrapper is a function which returns a ``CRT``,
+is not a coroutine itself and is marked with ``[[clang::coro_wrapper]]``.
+
+Clang will enforce that all functions that return a ``CRT`` are either coroutines or marked
+with ``[[clang::coro_wrapper]]``. Clang will enforce this with an error.
+
+From a language perspective, it is not possible to differentiate between a coroutine and a
+function returning a CRT by merely looking at the function signature.
+
+Coroutine wrappers, in particular, are susceptible to capturing
+references to temporaries and other lifetime issues. This allows to avoid such lifetime
+issues with coroutine wrappers.
+
+For example,
+
+.. code-block:: c++
+
+ // This is a CRT.
+ template <typename T> struct [[clang::coro_return_type]] Task {
+ using promise_type = some_promise_type;
+ };
+
+ Task<int> increment(int a) { co_return a + 1; } // Fine. This is a coroutine.
+ Task<int> foo() { return increment(1); } // Error. foo is not a coroutine.
+
+ // Fine for a coroutine wrapper to return a CRT.
+ [[clang::coro_wrapper]] Task<int> foo() { return increment(1); }
+
+ void bar() {
+ // Invalid. This intantiates a function which returns a CRT but is not marked as
+ // a coroutine wrapper.
+ std::function<Task<int>(int)> f = increment;
+ }
+
+Note: ``a_promise_type::get_return_object`` is exempted from this analysis as it is a necessary
+implementation detail of any coroutine library.
+}];
+}
+
+def CodeAlignAttrDocs : Documentation {
+ let Category = DocCatVariable;
+ let Heading = "clang::code_align";
+ let Content = [{
+The ``clang::code_align(N)`` attribute applies to a loop and specifies the byte
+alignment for a loop. The attribute accepts a positive integer constant
+initialization expression indicating the number of bytes for the minimum
+alignment boundary. Its value must be a power of 2, between 1 and 4096
+(inclusive).
+
+.. code-block:: c++
+
+ void foo() {
+ int var = 0;
+ [[clang::code_align(16)]] for (int i = 0; i < 10; ++i) var++;
+ }
+
+ void Array(int *array, size_t n) {
+ [[clang::code_align(64)]] for (int i = 0; i < n; ++i) array[i] = 0;
+ }
+
+ void count () {
+ int a1[10], int i = 0;
+ [[clang::code_align(32)]] while (i < 10) { a1[i] += 3; }
+ }
+
+ void check() {
+ int a = 10;
+ [[clang::code_align(8)]] do {
+ a = a + 1;
+ } while (a < 20);
+ }
+
+ template<int A>
+ void func() {
+ [[clang::code_align(A)]] for(;;) { }
+ }
+
+ }];
+}
+
+def CoroLifetimeBoundDoc : Documentation {
+ let Category = DocCatDecl;
+ let Content = [{
+The ``[[clang::coro_lifetimebound]]`` is a class attribute which can be applied
+to a coroutine return type (`CRT`_) (i.e.
+it should also be annotated with ``[[clang::coro_return_type]]``).
+
+All parameters of a function are considered to be lifetime bound if the function returns a
+coroutine return type (CRT) annotated with ``[[clang::coro_lifetimebound]]``.
+This lifetime bound analysis can be disabled for a coroutine wrapper or a coroutine by annotating the function
+with ``[[clang::coro_disable_lifetimebound]]`` function attribute .
+See `documentation`_ of ``[[clang::lifetimebound]]`` for details about lifetime bound analysis.
+
+
+Reference parameters of a coroutine are susceptible to capturing references to temporaries or local variables.
+
+For example,
+
+.. code-block:: c++
+
+ task<int> coro(const int& a) { co_return a + 1; }
+ task<int> dangling_refs(int a) {
+ // `coro` captures reference to a temporary. `foo` would now contain a dangling reference to `a`.
+ auto foo = coro(1);
+ // `coro` captures reference to local variable `a` which is destroyed after the return.
+ return coro(a);
+ }
+
+Lifetime bound static analysis can be used to detect such instances when coroutines capture references
+which may die earlier than the coroutine frame itself. In the above example, if the CRT `task` is annotated with
+``[[clang::coro_lifetimebound]]``, then lifetime bound analysis would detect capturing reference to
+temporaries or return address of a local variable.
+
+Both coroutines and coroutine wrappers are part of this analysis.
+
+.. code-block:: c++
+
+ template <typename T> struct [[clang::coro_return_type, clang::coro_lifetimebound]] Task {
+ using promise_type = some_promise_type;
+ };
+
+ Task<int> coro(const int& a) { co_return a + 1; }
+ [[clang::coro_wrapper]] Task<int> coro_wrapper(const int& a, const int& b) {
+ return a > b ? coro(a) : coro(b);
+ }
+ Task<int> temporary_reference() {
+ auto foo = coro(1); // warning: capturing reference to a temporary which would die after the expression.
+
+ int a = 1;
+ auto bar = coro_wrapper(a, 0); // warning: `b` captures reference to a temporary.
+
+ co_return co_await coro(1); // fine.
+ }
+ [[clang::coro_wrapper]] Task<int> stack_reference(int a) {
+ return coro(a); // warning: returning address of stack variable `a`.
+ }
+
+This analysis can be disabled for all calls to a particular function by annotating the function
+with function attribute ``[[clang::coro_disable_lifetimebound]]``.
+For example, this could be useful for coroutine wrappers which accept reference parameters
+but do not pass them to the underlying coroutine or pass them by value.
+
+.. code-block:: c++
+
+ Task<int> coro(int a) { co_return a + 1; }
+ [[clang::coro_wrapper, clang::coro_disable_lifetimebound]] Task<int> coro_wrapper(const int& a) {
+ return coro(a + 1);
+ }
+ void use() {
+ auto task = coro_wrapper(1); // use of temporary is fine as the argument is not lifetime bound.
+ }
+
+.. _`documentation`: https://clang.llvm.org/docs/AttributeReference.html#lifetimebound
+.. _`CRT`: https://clang.llvm.org/docs/AttributeReference.html#coro-return-type
+}];
+}
+
+def CountedByDocs : Documentation {
+ let Category = DocCatField;
+ let Content = [{
+Clang supports the ``counted_by`` attribute on the flexible array member of a
+structure in C. The argument for the attribute is the name of a field member
+holding the count of elements in the flexible array. This information can be
+used to improve the results of the array bound sanitizer and the
+``__builtin_dynamic_object_size`` builtin. The ``count`` field member must be
+within the same non-anonymous, enclosing struct as the flexible array member.
+
+This example specifies that the flexible array member ``array`` has the number
+of elements allocated for it in ``count``:
+
+.. code-block:: c
+
+ struct bar;
+
+ struct foo {
+ size_t count;
+ char other;
+ struct bar *array[] __attribute__((counted_by(count)));
+ };
+
+This establishes a relationship between ``array`` and ``count``. Specifically,
+``array`` must have at least ``count`` number of elements available. It's the
+user's responsibility to ensure that this relationship is maintained through
+changes to the structure.
+
+In the following example, the allocated array erroneously has fewer elements
+than what's specified by ``p->count``. This would result in an out-of-bounds
+access not being detected.
+
+.. code-block:: c
+
+ #define SIZE_INCR 42
+
+ struct foo *p;
+
+ void foo_alloc(size_t count) {
+ p = malloc(MAX(sizeof(struct foo),
+ offsetof(struct foo, array[0]) + count * sizeof(struct bar *)));
+ p->count = count + SIZE_INCR;
+ }
+
+The next example updates ``p->count``, but breaks the relationship requirement
+that ``p->array`` must have at least ``p->count`` number of elements available:
+
+.. code-block:: c
+
+ #define SIZE_INCR 42
+
+ struct foo *p;
+
+ void foo_alloc(size_t count) {
+ p = malloc(MAX(sizeof(struct foo),
+ offsetof(struct foo, array[0]) + count * sizeof(struct bar *)));
+ p->count = count;
+ }
+
+ void use_foo(int index, int val) {
+ p->count += SIZE_INCR + 1; /* 'count' is now larger than the number of elements of 'array'. */
+ p->array[index] = val; /* The sanitizer can't properly check this access. */
+ }
+
+In this example, an update to ``p->count`` maintains the relationship
+requirement:
+
+.. code-block:: c
+
+ void use_foo(int index, int val) {
+ if (p->count == 0)
+ return;
+ --p->count;
+ p->array[index] = val;
+ }
+ }];
+}
diff --git a/contrib/llvm-project/clang/include/clang/Basic/AttrSubjectMatchRules.h b/contrib/llvm-project/clang/include/clang/Basic/AttrSubjectMatchRules.h
index 010cefcaf340..bec8122ea930 100644
--- a/contrib/llvm-project/clang/include/clang/Basic/AttrSubjectMatchRules.h
+++ b/contrib/llvm-project/clang/include/clang/Basic/AttrSubjectMatchRules.h
@@ -6,19 +6,24 @@
//
//===----------------------------------------------------------------------===//
-#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"
namespace clang {
+
+class SourceRange;
+
namespace attr {
/// A list of all the recognized kinds of attributes.
enum SubjectMatchRule {
#define ATTR_MATCH_RULE(X, Spelling, IsAbstract) X,
#include "clang/Basic/AttrSubMatchRulesList.inc"
+ SubjectMatchRule_Last = -1
+#define ATTR_MATCH_RULE(X, Spelling, IsAbstract) +1
+#include "clang/Basic/AttrSubMatchRulesList.inc"
};
const char *getSubjectMatchRuleSpelling(SubjectMatchRule Rule);
diff --git a/contrib/llvm-project/clang/include/clang/Basic/AttributeCommonInfo.h b/contrib/llvm-project/clang/include/clang/Basic/AttributeCommonInfo.h
index 4be598e109fd..ef2ddf525c98 100644
--- a/contrib/llvm-project/clang/include/clang/Basic/AttributeCommonInfo.h
+++ b/contrib/llvm-project/clang/include/clang/Basic/AttributeCommonInfo.h
@@ -13,24 +13,27 @@
#ifndef LLVM_CLANG_BASIC_ATTRIBUTECOMMONINFO_H
#define LLVM_CLANG_BASIC_ATTRIBUTECOMMONINFO_H
+
#include "clang/Basic/SourceLocation.h"
+#include "clang/Basic/TokenKinds.h"
namespace clang {
-class IdentifierInfo;
+
class ASTRecordWriter;
+class IdentifierInfo;
class AttributeCommonInfo {
public:
/// The style used to specify an attribute.
enum Syntax {
/// __attribute__((...))
- AS_GNU,
+ AS_GNU = 1,
/// [[...]]
AS_CXX11,
/// [[...]]
- AS_C2x,
+ AS_C23,
/// __declspec(...)
AS_Declspec,
@@ -48,6 +51,13 @@ public:
// without adding related code to TableGen/ClangAttrEmitter.cpp.
/// Context-sensitive version of a keyword attribute.
AS_ContextSensitiveKeyword,
+
+ /// <vardecl> : <semantic>
+ AS_HLSLSemantic,
+
+ /// The attibute has no source code manifestation and is only created
+ /// implicitly.
+ AS_Implicit
};
enum Kind {
#define PARSED_ATTR(NAME) AT_##NAME,
@@ -64,68 +74,110 @@ private:
SourceRange AttrRange;
const SourceLocation ScopeLoc;
// Corresponds to the Kind enum.
+ LLVM_PREFERRED_TYPE(Kind)
unsigned AttrKind : 16;
/// Corresponds to the Syntax enum.
- unsigned SyntaxUsed : 3;
+ LLVM_PREFERRED_TYPE(Syntax)
+ unsigned SyntaxUsed : 4;
+ LLVM_PREFERRED_TYPE(bool)
unsigned SpellingIndex : 4;
+ LLVM_PREFERRED_TYPE(bool)
+ unsigned IsAlignas : 1;
+ LLVM_PREFERRED_TYPE(bool)
+ unsigned IsRegularKeywordAttribute : 1;
protected:
static constexpr unsigned SpellingNotCalculated = 0xf;
public:
- AttributeCommonInfo(SourceRange AttrRange)
- : AttrRange(AttrRange), ScopeLoc(), AttrKind(0), SyntaxUsed(0),
- SpellingIndex(SpellingNotCalculated) {}
-
- AttributeCommonInfo(SourceLocation AttrLoc)
- : AttrRange(AttrLoc), ScopeLoc(), AttrKind(0), SyntaxUsed(0),
- SpellingIndex(SpellingNotCalculated) {}
-
- AttributeCommonInfo(const IdentifierInfo *AttrName,
- const IdentifierInfo *ScopeName, SourceRange AttrRange,
- SourceLocation ScopeLoc, Syntax SyntaxUsed)
- : AttrName(AttrName), ScopeName(ScopeName), AttrRange(AttrRange),
- ScopeLoc(ScopeLoc),
- AttrKind(getParsedKind(AttrName, ScopeName, SyntaxUsed)),
- SyntaxUsed(SyntaxUsed), SpellingIndex(SpellingNotCalculated) {}
+ /// Combines information about the source-code form of an attribute,
+ /// including its syntax and spelling.
+ class Form {
+ public:
+ constexpr Form(Syntax SyntaxUsed, unsigned SpellingIndex, bool IsAlignas,
+ bool IsRegularKeywordAttribute)
+ : SyntaxUsed(SyntaxUsed), SpellingIndex(SpellingIndex),
+ IsAlignas(IsAlignas),
+ IsRegularKeywordAttribute(IsRegularKeywordAttribute) {}
+ constexpr Form(tok::TokenKind Tok)
+ : SyntaxUsed(AS_Keyword), SpellingIndex(SpellingNotCalculated),
+ IsAlignas(Tok == tok::kw_alignas),
+ IsRegularKeywordAttribute(tok::isRegularKeywordAttribute(Tok)) {}
+
+ Syntax getSyntax() const { return Syntax(SyntaxUsed); }
+ unsigned getSpellingIndex() const { return SpellingIndex; }
+ bool isAlignas() const { return IsAlignas; }
+ bool isRegularKeywordAttribute() const { return IsRegularKeywordAttribute; }
+
+ static Form GNU() { return AS_GNU; }
+ static Form CXX11() { return AS_CXX11; }
+ static Form C23() { return AS_C23; }
+ static Form Declspec() { return AS_Declspec; }
+ static Form Microsoft() { return AS_Microsoft; }
+ static Form Keyword(bool IsAlignas, bool IsRegularKeywordAttribute) {
+ return Form(AS_Keyword, SpellingNotCalculated, IsAlignas,
+ IsRegularKeywordAttribute);
+ }
+ static Form Pragma() { return AS_Pragma; }
+ static Form ContextSensitiveKeyword() { return AS_ContextSensitiveKeyword; }
+ static Form HLSLSemantic() { return AS_HLSLSemantic; }
+ static Form Implicit() { return AS_Implicit; }
+
+ private:
+ constexpr Form(Syntax SyntaxUsed)
+ : SyntaxUsed(SyntaxUsed), SpellingIndex(SpellingNotCalculated),
+ IsAlignas(0), IsRegularKeywordAttribute(0) {}
+
+ LLVM_PREFERRED_TYPE(Syntax)
+ unsigned SyntaxUsed : 4;
+ unsigned SpellingIndex : 4;
+ LLVM_PREFERRED_TYPE(bool)
+ unsigned IsAlignas : 1;
+ LLVM_PREFERRED_TYPE(bool)
+ unsigned IsRegularKeywordAttribute : 1;
+ };
AttributeCommonInfo(const IdentifierInfo *AttrName,
const IdentifierInfo *ScopeName, SourceRange AttrRange,
- SourceLocation ScopeLoc, Kind AttrKind, Syntax SyntaxUsed)
+ SourceLocation ScopeLoc, Kind AttrKind, Form FormUsed)
: AttrName(AttrName), ScopeName(ScopeName), AttrRange(AttrRange),
- ScopeLoc(ScopeLoc), AttrKind(AttrKind), SyntaxUsed(SyntaxUsed),
- SpellingIndex(SpellingNotCalculated) {}
+ ScopeLoc(ScopeLoc), AttrKind(AttrKind),
+ SyntaxUsed(FormUsed.getSyntax()),
+ SpellingIndex(FormUsed.getSpellingIndex()),
+ IsAlignas(FormUsed.isAlignas()),
+ IsRegularKeywordAttribute(FormUsed.isRegularKeywordAttribute()) {
+ assert(SyntaxUsed >= AS_GNU && SyntaxUsed <= AS_Implicit &&
+ "Invalid syntax!");
+ }
AttributeCommonInfo(const IdentifierInfo *AttrName,
const IdentifierInfo *ScopeName, SourceRange AttrRange,
- SourceLocation ScopeLoc, Kind AttrKind, Syntax SyntaxUsed,
- unsigned Spelling)
- : AttrName(AttrName), ScopeName(ScopeName), AttrRange(AttrRange),
- ScopeLoc(ScopeLoc), AttrKind(AttrKind), SyntaxUsed(SyntaxUsed),
- SpellingIndex(Spelling) {}
+ SourceLocation ScopeLoc, Form FormUsed)
+ : AttributeCommonInfo(
+ AttrName, ScopeName, AttrRange, ScopeLoc,
+ getParsedKind(AttrName, ScopeName, FormUsed.getSyntax()),
+ FormUsed) {}
AttributeCommonInfo(const IdentifierInfo *AttrName, SourceRange AttrRange,
- Syntax SyntaxUsed)
- : AttrName(AttrName), ScopeName(nullptr), AttrRange(AttrRange),
- ScopeLoc(), AttrKind(getParsedKind(AttrName, ScopeName, SyntaxUsed)),
- SyntaxUsed(SyntaxUsed), SpellingIndex(SpellingNotCalculated) {}
-
- AttributeCommonInfo(SourceRange AttrRange, Kind K, Syntax SyntaxUsed)
- : AttrName(nullptr), ScopeName(nullptr), AttrRange(AttrRange), ScopeLoc(),
- AttrKind(K), SyntaxUsed(SyntaxUsed),
- SpellingIndex(SpellingNotCalculated) {}
+ Form FormUsed)
+ : AttributeCommonInfo(AttrName, nullptr, AttrRange, SourceLocation(),
+ FormUsed) {}
- AttributeCommonInfo(SourceRange AttrRange, Kind K, Syntax SyntaxUsed,
- unsigned Spelling)
- : AttrName(nullptr), ScopeName(nullptr), AttrRange(AttrRange), ScopeLoc(),
- AttrKind(K), SyntaxUsed(SyntaxUsed), SpellingIndex(Spelling) {}
+ AttributeCommonInfo(SourceRange AttrRange, Kind K, Form FormUsed)
+ : AttributeCommonInfo(nullptr, nullptr, AttrRange, SourceLocation(), K,
+ FormUsed) {}
AttributeCommonInfo(AttributeCommonInfo &&) = default;
AttributeCommonInfo(const AttributeCommonInfo &) = default;
Kind getParsedKind() const { return Kind(AttrKind); }
Syntax getSyntax() const { return Syntax(SyntaxUsed); }
+ Form getForm() const {
+ return Form(getSyntax(), SpellingIndex, IsAlignas,
+ IsRegularKeywordAttribute);
+ }
const IdentifierInfo *getAttrName() const { return AttrName; }
+ void setAttrName(const IdentifierInfo *AttrNameII) { AttrName = AttrNameII; }
SourceLocation getLoc() const { return AttrRange.getBegin(); }
SourceRange getRange() const { return AttrRange; }
void setRange(SourceRange R) { AttrRange = R; }
@@ -143,28 +195,35 @@ public:
bool isMicrosoftAttribute() const { return SyntaxUsed == AS_Microsoft; }
bool isGNUScope() const;
+ bool isClangScope() const;
- bool isAlignasAttribute() const {
- // FIXME: Use a better mechanism to determine this.
- return getParsedKind() == AT_Aligned && isKeywordAttribute();
- }
+ bool isCXX11Attribute() const { return SyntaxUsed == AS_CXX11 || IsAlignas; }
- bool isCXX11Attribute() const {
- return SyntaxUsed == AS_CXX11 || isAlignasAttribute();
- }
+ bool isC23Attribute() const { return SyntaxUsed == AS_C23; }
- bool isC2xAttribute() const { return SyntaxUsed == AS_C2x; }
+ bool isAlignas() const {
+ // FIXME: In the current state, the IsAlignas member variable is only true
+ // with the C++ `alignas` keyword but not `_Alignas`. The following
+ // expression works around the otherwise lost information so it will return
+ // true for `alignas` or `_Alignas` while still returning false for things
+ // like `__attribute__((aligned))`.
+ return (getParsedKind() == AT_Aligned && isKeywordAttribute());
+ }
/// The attribute is spelled [[]] in either C or C++ mode, including standard
/// attributes spelled with a keyword, like alignas.
bool isStandardAttributeSyntax() const {
- return isCXX11Attribute() || isC2xAttribute();
+ return isCXX11Attribute() || isC23Attribute();
}
+ bool isGNUAttribute() const { return SyntaxUsed == AS_GNU; }
+
bool isKeywordAttribute() const {
return SyntaxUsed == AS_Keyword || SyntaxUsed == AS_ContextSensitiveKeyword;
}
+ bool isRegularKeywordAttribute() const { return IsRegularKeywordAttribute; }
+
bool isContextSensitiveKeywordAttribute() const {
return SyntaxUsed == AS_ContextSensitiveKeyword;
}
@@ -196,6 +255,19 @@ protected:
return SpellingIndex != SpellingNotCalculated;
}
};
+
+inline bool doesKeywordAttributeTakeArgs(tok::TokenKind Kind) {
+ switch (Kind) {
+ default:
+ return false;
+#define KEYWORD_ATTRIBUTE(NAME, HASARG, ...) \
+ case tok::kw_##NAME: \
+ return HASARG;
+#include "clang/Basic/RegularKeywordAttrInfo.inc"
+#undef KEYWORD_ATTRIBUTE
+ }
+}
+
} // namespace clang
#endif // LLVM_CLANG_BASIC_ATTRIBUTECOMMONINFO_H
diff --git a/contrib/llvm-project/clang/include/clang/Basic/Attributes.h b/contrib/llvm-project/clang/include/clang/Basic/Attributes.h
index c69633decd57..61666a6f4d9a 100644
--- a/contrib/llvm-project/clang/include/clang/Basic/Attributes.h
+++ b/contrib/llvm-project/clang/include/clang/Basic/Attributes.h
@@ -9,33 +9,19 @@
#ifndef LLVM_CLANG_BASIC_ATTRIBUTES_H
#define LLVM_CLANG_BASIC_ATTRIBUTES_H
-#include "clang/Basic/LangOptions.h"
-#include "clang/Basic/TargetInfo.h"
+#include "clang/Basic/AttributeCommonInfo.h"
namespace clang {
class IdentifierInfo;
-
-enum class AttrSyntax {
- /// Is the identifier known as a GNU-style attribute?
- GNU,
- /// Is the identifier known as a __declspec-style attribute?
- Declspec,
- /// Is the identifier known as a [] Microsoft-style attribute?
- Microsoft,
- // Is the identifier known as a C++-style attribute?
- CXX,
- // Is the identifier known as a C-style attribute?
- C,
- // Is the identifier known as a pragma attribute?
- Pragma
-};
+class LangOptions;
+class TargetInfo;
/// Return the version number associated with the attribute if we
/// recognize and implement the attribute specified by the given information.
-int hasAttribute(AttrSyntax Syntax, const IdentifierInfo *Scope,
- const IdentifierInfo *Attr, const TargetInfo &Target,
- const LangOptions &LangOpts);
+int hasAttribute(AttributeCommonInfo::Syntax Syntax,
+ const IdentifierInfo *Scope, const IdentifierInfo *Attr,
+ const TargetInfo &Target, const LangOptions &LangOpts);
} // end namespace clang
diff --git a/contrib/llvm-project/clang/include/clang/Basic/BuiltinHeaders.def b/contrib/llvm-project/clang/include/clang/Basic/BuiltinHeaders.def
new file mode 100644
index 000000000000..8e4a2f9bee9a
--- /dev/null
+++ b/contrib/llvm-project/clang/include/clang/Basic/BuiltinHeaders.def
@@ -0,0 +1,43 @@
+//===--- BuiltinHeaders.def - Builtin header info database ------*- 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 the standard builtin function header locations. Users of
+// this file must define the HEADER macro to make use of this information.
+//
+//===----------------------------------------------------------------------===//
+
+HEADER(NO_HEADER, nullptr)
+HEADER(BLOCKS_H, "Blocks.h")
+HEADER(COMPLEX_H, "complex.h")
+HEADER(CTYPE_H, "ctype.h")
+HEADER(EMMINTRIN_H, "emmintrin.h")
+HEADER(FOUNDATION_NSOBJCRUNTIME_H, "Foundation/NSObjCRuntime.h")
+HEADER(IMMINTRIN_H, "immintrin.h")
+HEADER(INTRIN_H, "intrin.h")
+HEADER(MALLOC_H, "malloc.h")
+HEADER(MATH_H, "math.h")
+HEADER(MEMORY, "memory")
+HEADER(OBJC_MESSAGE_H, "objc/message.h")
+HEADER(OBJC_OBJC_AUTO_H, "objc/objc-auto.h")
+HEADER(OBJC_OBJC_EXCEPTION_H, "objc/objc-exception.h")
+HEADER(OBJC_OBJC_SYNC_H, "objc/objc-sync.h")
+HEADER(OBJC_RUNTIME_H, "objc/runtime.h")
+HEADER(PTHREAD_H, "pthread.h")
+HEADER(SETJMPEX_H, "setjmpex.h")
+HEADER(SETJMP_H, "setjmp.h")
+HEADER(STDARG_H, "stdarg.h")
+HEADER(STDIO_H, "stdio.h")
+HEADER(STDLIB_H, "stdlib.h")
+HEADER(STRINGS_H, "strings.h")
+HEADER(STRING_H, "string.h")
+HEADER(UNISTD_H, "unistd.h")
+HEADER(UTILITY, "utility")
+HEADER(WCHAR_H, "wchar.h")
+HEADER(XMMINTRIN_H, "xmmintrin.h")
+
+#undef HEADER
diff --git a/contrib/llvm-project/clang/include/clang/Basic/Builtins.def b/contrib/llvm-project/clang/include/clang/Basic/Builtins.def
index 0e3898537bcf..4dcbaf8a7bea 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
@@ -38,6 +39,8 @@
// A -> "reference" to __builtin_va_list
// V -> Vector, followed by the number of elements and the base type.
// q -> Scalable vector, followed by the number of elements and the base type.
+// Q -> target builtin type, followed by a character to distinguish the builtin type
+// Qa -> AArch64 svcount_t builtin type.
// E -> ext_vector, followed by the number of elements and the base type.
// X -> _Complex, followed by the base type.
// Y -> ptrdiff_t
@@ -80,9 +83,9 @@
// builtin even if type doesn't match signature, and don't warn if we
// can't be sure the type is right
// F -> this is a libc/libm function with a '__builtin_' prefix added.
-// f -> this is a libc/libm function without the '__builtin_' prefix. It can
-// be followed by ':headername:' to state which header this function
-// comes from.
+// f -> this is a libc/libm function without a '__builtin_' prefix, or with
+// 'z', a C++ standard library function in namespace std::. This builtin
+// is disableable by '-fno-builtin-foo' / '-fno-builtin-std-foo'.
// h -> this function requires a specific header or an explicit declaration.
// i -> this is a runtime library implemented function without the
// '__builtin_' prefix. It will be implemented in compiler-rt or libgcc.
@@ -96,12 +99,15 @@
// S:N: -> similar to the s:N: attribute, but the function is like vscanf
// in that it accepts its arguments as a va_list rather than
// through an ellipsis
-// e -> const, but only when -fno-math-errno
+// e -> const, but only when -fno-math-errno and FP exceptions are ignored
+// g -> const when FP exceptions are ignored
// j -> returns_twice (like setjmp)
// u -> arguments are not evaluated for their side-effects
// V:N: -> requires vectors of at least N bits to be legal
// C<N,M_0,...,M_k> -> callback behavior: argument N is called with argument
// M_0, ..., M_k as payload
+// z -> this is a function in (possibly-versioned) namespace std
+// E -> this function can be constant evaluated by Clang frontend
// FIXME: gcc has nonnull
#if defined(BUILTIN) && !defined(LIBBUILTIN)
@@ -118,16 +124,16 @@ BUILTIN(__builtin_atan2f, "fff" , "Fne")
BUILTIN(__builtin_atan2l, "LdLdLd", "Fne")
BUILTIN(__builtin_atan2f128, "LLdLLdLLd", "Fne")
BUILTIN(__builtin_abs , "ii" , "ncF")
-BUILTIN(__builtin_copysign, "ddd", "ncF")
-BUILTIN(__builtin_copysignf, "fff", "ncF")
+BUILTIN(__builtin_copysign, "ddd", "ncFE")
+BUILTIN(__builtin_copysignf, "fff", "ncFE")
BUILTIN(__builtin_copysignf16, "hhh", "ncF")
-BUILTIN(__builtin_copysignl, "LdLdLd", "ncF")
-BUILTIN(__builtin_copysignf128, "LLdLLdLLd", "ncF")
-BUILTIN(__builtin_fabs , "dd" , "ncF")
-BUILTIN(__builtin_fabsf, "ff" , "ncF")
-BUILTIN(__builtin_fabsl, "LdLd", "ncF")
+BUILTIN(__builtin_copysignl, "LdLdLd", "ncFE")
+BUILTIN(__builtin_copysignf128, "LLdLLdLLd", "ncFE")
+BUILTIN(__builtin_fabs , "dd" , "ncFE")
+BUILTIN(__builtin_fabsf, "ff" , "ncFE")
+BUILTIN(__builtin_fabsl, "LdLd", "ncFE")
BUILTIN(__builtin_fabsf16, "hh" , "ncF")
-BUILTIN(__builtin_fabsf128, "LLdLLd", "ncF")
+BUILTIN(__builtin_fabsf128, "LLdLLd", "ncFE")
BUILTIN(__builtin_fmod , "ddd" , "Fne")
BUILTIN(__builtin_fmodf, "fff" , "Fne")
BUILTIN(__builtin_fmodf16, "hhh" , "Fne")
@@ -137,32 +143,38 @@ BUILTIN(__builtin_frexp , "ddi*" , "Fn")
BUILTIN(__builtin_frexpf, "ffi*" , "Fn")
BUILTIN(__builtin_frexpl, "LdLdi*", "Fn")
BUILTIN(__builtin_frexpf128, "LLdLLdi*", "Fn")
-BUILTIN(__builtin_huge_val, "d", "nc")
-BUILTIN(__builtin_huge_valf, "f", "nc")
-BUILTIN(__builtin_huge_vall, "Ld", "nc")
-BUILTIN(__builtin_huge_valf128, "LLd", "nc")
-BUILTIN(__builtin_inf , "d" , "nc")
-BUILTIN(__builtin_inff , "f" , "nc")
-BUILTIN(__builtin_infl , "Ld" , "nc")
-BUILTIN(__builtin_inff128 , "LLd" , "nc")
+BUILTIN(__builtin_frexpf16, "hhi*" , "Fn")
+BUILTIN(__builtin_huge_val, "d", "ncE")
+BUILTIN(__builtin_huge_valf, "f", "ncE")
+BUILTIN(__builtin_huge_vall, "Ld", "ncE")
+BUILTIN(__builtin_huge_valf16, "x", "ncE")
+BUILTIN(__builtin_huge_valf128, "LLd", "ncE")
+BUILTIN(__builtin_inf , "d" , "ncE")
+BUILTIN(__builtin_inff , "f" , "ncE")
+BUILTIN(__builtin_infl , "Ld" , "ncE")
+BUILTIN(__builtin_inff16 , "x" , "ncE")
+BUILTIN(__builtin_inff128 , "LLd" , "ncE")
BUILTIN(__builtin_labs , "LiLi" , "Fnc")
BUILTIN(__builtin_llabs, "LLiLLi", "Fnc")
BUILTIN(__builtin_ldexp , "ddi" , "Fne")
BUILTIN(__builtin_ldexpf, "ffi" , "Fne")
BUILTIN(__builtin_ldexpl, "LdLdi", "Fne")
BUILTIN(__builtin_ldexpf128, "LLdLLdi", "Fne")
+BUILTIN(__builtin_ldexpf16, "hhi", "Fne")
BUILTIN(__builtin_modf , "ddd*" , "Fn")
BUILTIN(__builtin_modff, "fff*" , "Fn")
BUILTIN(__builtin_modfl, "LdLdLd*", "Fn")
BUILTIN(__builtin_modff128, "LLdLLdLLd*", "Fn")
-BUILTIN(__builtin_nan, "dcC*" , "FnU")
-BUILTIN(__builtin_nanf, "fcC*" , "FnU")
-BUILTIN(__builtin_nanl, "LdcC*", "FnU")
-BUILTIN(__builtin_nanf128, "LLdcC*", "FnU")
-BUILTIN(__builtin_nans, "dcC*" , "FnU")
-BUILTIN(__builtin_nansf, "fcC*" , "FnU")
-BUILTIN(__builtin_nansl, "LdcC*", "FnU")
-BUILTIN(__builtin_nansf128, "LLdcC*", "FnU")
+BUILTIN(__builtin_nan, "dcC*" , "FnUE")
+BUILTIN(__builtin_nanf, "fcC*" , "FnUE")
+BUILTIN(__builtin_nanl, "LdcC*", "FnUE")
+BUILTIN(__builtin_nanf16, "xcC*", "FnUE")
+BUILTIN(__builtin_nanf128, "LLdcC*", "FnUE")
+BUILTIN(__builtin_nans, "dcC*" , "FnUE")
+BUILTIN(__builtin_nansf, "fcC*" , "FnUE")
+BUILTIN(__builtin_nansl, "LdcC*", "FnUE")
+BUILTIN(__builtin_nansf16, "xcC*", "FnUE")
+BUILTIN(__builtin_nansf128, "LLdcC*", "FnUE")
BUILTIN(__builtin_powi , "ddi" , "Fnc")
BUILTIN(__builtin_powif, "ffi" , "Fnc")
BUILTIN(__builtin_powil, "LdLdi", "Fnc")
@@ -233,6 +245,11 @@ BUILTIN(__builtin_exp2f, "ff" , "Fne")
BUILTIN(__builtin_exp2f16, "hh" , "Fne")
BUILTIN(__builtin_exp2l, "LdLd", "Fne")
BUILTIN(__builtin_exp2f128, "LLdLLd" , "Fne")
+BUILTIN(__builtin_exp10 , "dd" , "Fne")
+BUILTIN(__builtin_exp10f, "ff" , "Fne")
+BUILTIN(__builtin_exp10f16, "hh" , "Fne")
+BUILTIN(__builtin_exp10l, "LdLd", "Fne")
+BUILTIN(__builtin_exp10f128, "LLdLLd" , "Fne")
BUILTIN(__builtin_expm1 , "dd", "Fne")
BUILTIN(__builtin_expm1f, "ff", "Fne")
BUILTIN(__builtin_expm1l, "LdLd", "Fne")
@@ -251,16 +268,16 @@ BUILTIN(__builtin_fmaf, "ffff", "Fne")
BUILTIN(__builtin_fmaf16, "hhhh", "Fne")
BUILTIN(__builtin_fmal, "LdLdLdLd", "Fne")
BUILTIN(__builtin_fmaf128, "LLdLLdLLdLLd", "Fne")
-BUILTIN(__builtin_fmax, "ddd", "Fnc")
-BUILTIN(__builtin_fmaxf, "fff", "Fnc")
-BUILTIN(__builtin_fmaxf16, "hhh", "Fnc")
-BUILTIN(__builtin_fmaxl, "LdLdLd", "Fnc")
-BUILTIN(__builtin_fmaxf128, "LLdLLdLLd", "Fnc")
-BUILTIN(__builtin_fmin, "ddd", "Fnc")
-BUILTIN(__builtin_fminf, "fff", "Fnc")
-BUILTIN(__builtin_fminf16, "hhh", "Fnc")
-BUILTIN(__builtin_fminl, "LdLdLd", "Fnc")
-BUILTIN(__builtin_fminf128, "LLdLLdLLd", "Fnc")
+BUILTIN(__builtin_fmax, "ddd", "FncE")
+BUILTIN(__builtin_fmaxf, "fff", "FncE")
+BUILTIN(__builtin_fmaxf16, "hhh", "FncE")
+BUILTIN(__builtin_fmaxl, "LdLdLd", "FncE")
+BUILTIN(__builtin_fmaxf128, "LLdLLdLLd", "FncE")
+BUILTIN(__builtin_fmin, "ddd", "FncE")
+BUILTIN(__builtin_fminf, "fff", "FncE")
+BUILTIN(__builtin_fminf16, "hhh", "FncE")
+BUILTIN(__builtin_fminl, "LdLdLd", "FncE")
+BUILTIN(__builtin_fminf128, "LLdLLdLLd", "FncE")
BUILTIN(__builtin_hypot , "ddd" , "Fne")
BUILTIN(__builtin_hypotf, "fff" , "Fne")
BUILTIN(__builtin_hypotl, "LdLdLd", "Fne")
@@ -342,6 +359,11 @@ BUILTIN(__builtin_roundf, "ff" , "Fnc")
BUILTIN(__builtin_roundf16, "hh" , "Fnc")
BUILTIN(__builtin_roundl, "LdLd" , "Fnc")
BUILTIN(__builtin_roundf128, "LLdLLd" , "Fnc")
+BUILTIN(__builtin_roundeven, "dd" , "Fnc")
+BUILTIN(__builtin_roundevenf, "ff" , "Fnc")
+BUILTIN(__builtin_roundevenf16, "hh" , "Fnc")
+BUILTIN(__builtin_roundevenl, "LdLd" , "Fnc")
+BUILTIN(__builtin_roundevenf128, "LLdLLd" , "Fnc")
BUILTIN(__builtin_scalbln , "ddLi", "Fne")
BUILTIN(__builtin_scalblnf, "ffLi", "Fne")
BUILTIN(__builtin_scalblnl, "LdLdLi", "Fne")
@@ -384,6 +406,7 @@ BUILTIN(__builtin_truncf16, "hh", "Fnc")
// Access to floating point environment
BUILTIN(__builtin_flt_rounds, "i", "n")
+BUILTIN(__builtin_set_flt_rounds, "vi", "n")
// C99 complex builtins
BUILTIN(__builtin_cabs, "dXd", "Fne")
@@ -454,7 +477,7 @@ BUILTIN(__builtin_ctanhf, "XfXf", "Fne")
BUILTIN(__builtin_ctanhl, "XLdXLd", "Fne")
// GCC-compatible C99 CMPLX implementation.
-BUILTIN(__builtin_complex, "v.", "nct")
+BUILTIN(__builtin_complex, "v.", "nctE")
// FP Comparisons.
BUILTIN(__builtin_isgreater , "i.", "Fnct")
@@ -465,12 +488,16 @@ BUILTIN(__builtin_islessgreater , "i.", "Fnct")
BUILTIN(__builtin_isunordered , "i.", "Fnct")
// Unary FP classification
-BUILTIN(__builtin_fpclassify, "iiiiii.", "Fnct")
-BUILTIN(__builtin_isfinite, "i.", "Fnct")
-BUILTIN(__builtin_isinf, "i.", "Fnct")
-BUILTIN(__builtin_isinf_sign, "i.", "Fnct")
-BUILTIN(__builtin_isnan, "i.", "Fnct")
-BUILTIN(__builtin_isnormal, "i.", "Fnct")
+BUILTIN(__builtin_fpclassify, "iiiiii.", "FnctE")
+BUILTIN(__builtin_isfinite, "i.", "FnctE")
+BUILTIN(__builtin_isinf, "i.", "FnctE")
+BUILTIN(__builtin_isinf_sign, "i.", "FnctE")
+BUILTIN(__builtin_isnan, "i.", "FnctE")
+BUILTIN(__builtin_isnormal, "i.", "FnctE")
+BUILTIN(__builtin_issubnormal,"i.", "FnctE")
+BUILTIN(__builtin_iszero, "i.", "FnctE")
+BUILTIN(__builtin_issignaling,"i.", "FnctE")
+BUILTIN(__builtin_isfpclass, "i.", "nctE")
// FP signbit builtins
BUILTIN(__builtin_signbit, "i.", "Fnct")
@@ -484,103 +511,102 @@ BUILTIN(__builtin_canonicalizef16, "hh", "nc")
BUILTIN(__builtin_canonicalizel, "LdLd", "nc")
// Builtins for arithmetic.
-BUILTIN(__builtin_clzs , "iUs" , "nc")
-BUILTIN(__builtin_clz , "iUi" , "nc")
-BUILTIN(__builtin_clzl , "iULi" , "nc")
-BUILTIN(__builtin_clzll, "iULLi", "nc")
+BUILTIN(__builtin_clzs , "iUs" , "ncE")
+BUILTIN(__builtin_clz , "iUi" , "ncE")
+BUILTIN(__builtin_clzl , "iULi" , "ncE")
+BUILTIN(__builtin_clzll, "iULLi", "ncE")
// TODO: int clzimax(uintmax_t)
-BUILTIN(__builtin_ctzs , "iUs" , "nc")
-BUILTIN(__builtin_ctz , "iUi" , "nc")
-BUILTIN(__builtin_ctzl , "iULi" , "nc")
-BUILTIN(__builtin_ctzll, "iULLi", "nc")
+BUILTIN(__builtin_ctzs , "iUs" , "ncE")
+BUILTIN(__builtin_ctz , "iUi" , "ncE")
+BUILTIN(__builtin_ctzl , "iULi" , "ncE")
+BUILTIN(__builtin_ctzll, "iULLi", "ncE")
// TODO: int ctzimax(uintmax_t)
-BUILTIN(__builtin_ffs , "ii" , "Fnc")
-BUILTIN(__builtin_ffsl , "iLi" , "Fnc")
-BUILTIN(__builtin_ffsll, "iLLi", "Fnc")
-BUILTIN(__builtin_parity , "iUi" , "nc")
-BUILTIN(__builtin_parityl , "iULi" , "nc")
-BUILTIN(__builtin_parityll, "iULLi", "nc")
-BUILTIN(__builtin_popcount , "iUi" , "nc")
-BUILTIN(__builtin_popcountl , "iULi" , "nc")
-BUILTIN(__builtin_popcountll, "iULLi", "nc")
-BUILTIN(__builtin_clrsb , "ii" , "nc")
-BUILTIN(__builtin_clrsbl , "iLi" , "nc")
-BUILTIN(__builtin_clrsbll, "iLLi", "nc")
+BUILTIN(__builtin_ffs , "ii" , "FncE")
+BUILTIN(__builtin_ffsl , "iLi" , "FncE")
+BUILTIN(__builtin_ffsll, "iLLi", "FncE")
+BUILTIN(__builtin_parity , "iUi" , "ncE")
+BUILTIN(__builtin_parityl , "iULi" , "ncE")
+BUILTIN(__builtin_parityll, "iULLi", "ncE")
+BUILTIN(__builtin_popcount , "iUi" , "ncE")
+BUILTIN(__builtin_popcountl , "iULi" , "ncE")
+BUILTIN(__builtin_popcountll, "iULLi", "ncE")
+BUILTIN(__builtin_clrsb , "ii" , "ncE")
+BUILTIN(__builtin_clrsbl , "iLi" , "ncE")
+BUILTIN(__builtin_clrsbll, "iLLi", "ncE")
// The following builtins rely on that char == 8 bits, short == 16 bits and that
// there exists native types on the target that are 32- and 64-bits wide, unless
// these conditions are fulfilled these builtins will operate on a not intended
// bitwidth.
-BUILTIN(__builtin_bswap16, "UsUs", "nc")
-BUILTIN(__builtin_bswap32, "UZiUZi", "nc")
-BUILTIN(__builtin_bswap64, "UWiUWi", "nc")
-
-BUILTIN(__builtin_bitreverse8, "UcUc", "nc")
-BUILTIN(__builtin_bitreverse16, "UsUs", "nc")
-BUILTIN(__builtin_bitreverse32, "UZiUZi", "nc")
-BUILTIN(__builtin_bitreverse64, "UWiUWi", "nc")
-
-BUILTIN(__builtin_rotateleft8, "UcUcUc", "nc")
-BUILTIN(__builtin_rotateleft16, "UsUsUs", "nc")
-BUILTIN(__builtin_rotateleft32, "UZiUZiUZi", "nc")
-BUILTIN(__builtin_rotateleft64, "UWiUWiUWi", "nc")
-BUILTIN(__builtin_rotateright8, "UcUcUc", "nc")
-BUILTIN(__builtin_rotateright16, "UsUsUs", "nc")
-BUILTIN(__builtin_rotateright32, "UZiUZiUZi", "nc")
-BUILTIN(__builtin_rotateright64, "UWiUWiUWi", "nc")
+BUILTIN(__builtin_bswap16, "UsUs", "ncE")
+BUILTIN(__builtin_bswap32, "UZiUZi", "ncE")
+BUILTIN(__builtin_bswap64, "UWiUWi", "ncE")
+
+BUILTIN(__builtin_bitreverse8, "UcUc", "ncE")
+BUILTIN(__builtin_bitreverse16, "UsUs", "ncE")
+BUILTIN(__builtin_bitreverse32, "UZiUZi", "ncE")
+BUILTIN(__builtin_bitreverse64, "UWiUWi", "ncE")
+
+BUILTIN(__builtin_rotateleft8, "UcUcUc", "ncE")
+BUILTIN(__builtin_rotateleft16, "UsUsUs", "ncE")
+BUILTIN(__builtin_rotateleft32, "UZiUZiUZi", "ncE")
+BUILTIN(__builtin_rotateleft64, "UWiUWiUWi", "ncE")
+BUILTIN(__builtin_rotateright8, "UcUcUc", "ncE")
+BUILTIN(__builtin_rotateright16, "UsUsUs", "ncE")
+BUILTIN(__builtin_rotateright32, "UZiUZiUZi", "ncE")
+BUILTIN(__builtin_rotateright64, "UWiUWiUWi", "ncE")
// Random GCC builtins
BUILTIN(__builtin_calloc, "v*zz", "nF")
-BUILTIN(__builtin_constant_p, "i.", "nctu")
-BUILTIN(__builtin_classify_type, "i.", "nctu")
-BUILTIN(__builtin___CFStringMakeConstantString, "FC*cC*", "nc")
-BUILTIN(__builtin___NSStringMakeConstantString, "FC*cC*", "nc")
+BUILTIN(__builtin_constant_p, "i.", "nctuE")
+BUILTIN(__builtin_classify_type, "i.", "nctuE")
+BUILTIN(__builtin___CFStringMakeConstantString, "FC*cC*", "ncE")
+BUILTIN(__builtin___NSStringMakeConstantString, "FC*cC*", "ncE")
BUILTIN(__builtin_va_start, "vA.", "nt")
BUILTIN(__builtin_va_end, "vA", "n")
BUILTIN(__builtin_va_copy, "vAA", "n")
BUILTIN(__builtin_stdarg_start, "vA.", "nt")
-BUILTIN(__builtin_assume_aligned, "v*vC*z.", "nc")
-BUILTIN(__builtin_bcmp, "ivC*vC*z", "Fn")
-BUILTIN(__builtin_bcopy, "vv*v*z", "n")
+BUILTIN(__builtin_assume_aligned, "v*vC*z.", "nctE")
+BUILTIN(__builtin_bcmp, "ivC*vC*z", "FnE")
+BUILTIN(__builtin_bcopy, "vvC*v*z", "nF")
BUILTIN(__builtin_bzero, "vv*z", "nF")
-BUILTIN(__builtin_fprintf, "iP*cC*.", "Fp:1:")
BUILTIN(__builtin_free, "vv*", "nF")
BUILTIN(__builtin_malloc, "v*z", "nF")
-BUILTIN(__builtin_memchr, "v*vC*iz", "nF")
-BUILTIN(__builtin_memcmp, "ivC*vC*z", "nF")
-BUILTIN(__builtin_memcpy, "v*v*vC*z", "nF")
-BUILTIN(__builtin_memcpy_inline, "vv*vC*Iz", "nt")
-BUILTIN(__builtin_memmove, "v*v*vC*z", "nF")
+BUILTIN(__builtin_memchr, "v*vC*iz", "nFE")
+BUILTIN(__builtin_memcmp, "ivC*vC*z", "nFE")
+BUILTIN(__builtin_memcpy, "v*v*vC*z", "nFE")
+BUILTIN(__builtin_memcpy_inline, "vv*vC*Iz", "n")
+BUILTIN(__builtin_memmove, "v*v*vC*z", "nFE")
BUILTIN(__builtin_mempcpy, "v*v*vC*z", "nF")
BUILTIN(__builtin_memset, "v*v*iz", "nF")
-BUILTIN(__builtin_printf, "icC*.", "Fp:0:")
+BUILTIN(__builtin_memset_inline, "vv*iIz", "n")
BUILTIN(__builtin_stpcpy, "c*c*cC*", "nF")
BUILTIN(__builtin_stpncpy, "c*c*cC*z", "nF")
BUILTIN(__builtin_strcasecmp, "icC*cC*", "nF")
BUILTIN(__builtin_strcat, "c*c*cC*", "nF")
-BUILTIN(__builtin_strchr, "c*cC*i", "nF")
-BUILTIN(__builtin_strcmp, "icC*cC*", "nF")
+BUILTIN(__builtin_strchr, "c*cC*i", "nFE")
+BUILTIN(__builtin_strcmp, "icC*cC*", "nFE")
BUILTIN(__builtin_strcpy, "c*c*cC*", "nF")
BUILTIN(__builtin_strcspn, "zcC*cC*", "nF")
BUILTIN(__builtin_strdup, "c*cC*", "nF")
-BUILTIN(__builtin_strlen, "zcC*", "nF")
+BUILTIN(__builtin_strlen, "zcC*", "nFE")
BUILTIN(__builtin_strncasecmp, "icC*cC*z", "nF")
BUILTIN(__builtin_strncat, "c*c*cC*z", "nF")
-BUILTIN(__builtin_strncmp, "icC*cC*z", "nF")
+BUILTIN(__builtin_strncmp, "icC*cC*z", "nFE")
BUILTIN(__builtin_strncpy, "c*c*cC*z", "nF")
BUILTIN(__builtin_strndup, "c*cC*z", "nF")
BUILTIN(__builtin_strpbrk, "c*cC*cC*", "nF")
BUILTIN(__builtin_strrchr, "c*cC*i", "nF")
BUILTIN(__builtin_strspn, "zcC*cC*", "nF")
BUILTIN(__builtin_strstr, "c*cC*cC*", "nF")
-BUILTIN(__builtin_wcschr, "w*wC*w", "nF")
-BUILTIN(__builtin_wcscmp, "iwC*wC*", "nF")
-BUILTIN(__builtin_wcslen, "zwC*", "nF")
-BUILTIN(__builtin_wcsncmp, "iwC*wC*z", "nF")
-BUILTIN(__builtin_wmemchr, "w*wC*wz", "nF")
-BUILTIN(__builtin_wmemcmp, "iwC*wC*z", "nF")
-BUILTIN(__builtin_wmemcpy, "w*w*wC*z", "nF")
-BUILTIN(__builtin_wmemmove, "w*w*wC*z", "nF")
+BUILTIN(__builtin_wcschr, "w*wC*w", "nFE")
+BUILTIN(__builtin_wcscmp, "iwC*wC*", "nFE")
+BUILTIN(__builtin_wcslen, "zwC*", "nFE")
+BUILTIN(__builtin_wcsncmp, "iwC*wC*z", "nFE")
+BUILTIN(__builtin_wmemchr, "w*wC*wz", "nFE")
+BUILTIN(__builtin_wmemcmp, "iwC*wC*z", "nFE")
+BUILTIN(__builtin_wmemcpy, "w*w*wC*z", "nFE")
+BUILTIN(__builtin_wmemmove, "w*w*wC*z", "nFE")
BUILTIN(__builtin_realloc, "v*v*z", "nF")
BUILTIN(__builtin_return_address, "v*IUi", "n")
BUILTIN(__builtin_extract_return_addr, "v*v*", "n")
@@ -589,14 +615,24 @@ BUILTIN(__builtin___clear_cache, "vc*c*", "n")
BUILTIN(__builtin_setjmp, "iv**", "j")
BUILTIN(__builtin_longjmp, "vv**i", "r")
BUILTIN(__builtin_unwind_init, "v", "")
-BUILTIN(__builtin_eh_return_data_regno, "iIi", "nc")
-BUILTIN(__builtin_snprintf, "ic*zcC*.", "nFp:2:")
-BUILTIN(__builtin_sprintf, "ic*cC*.", "nFP:1:")
-BUILTIN(__builtin_vsnprintf, "ic*zcC*a", "nFP:2:")
-BUILTIN(__builtin_vsprintf, "ic*cC*a", "nFP:1:")
+BUILTIN(__builtin_eh_return_data_regno, "iIi", "ncE")
+BUILTIN(__builtin_fprintf, "iP*RcC*R.", "nFp:1:")
+BUILTIN(__builtin_printf, "icC*R.", "nFp:0:")
+BUILTIN(__builtin_sprintf, "ic*RcC*R.", "nFp:1:")
+BUILTIN(__builtin_snprintf, "ic*RzcC*R.", "nFp:2:")
+BUILTIN(__builtin_vprintf, "icC*Ra", "nFP:0:")
+BUILTIN(__builtin_vfprintf, "iP*RcC*Ra", "nFP:1:")
+BUILTIN(__builtin_vsprintf, "ic*RcC*Ra", "nFP:1:")
+BUILTIN(__builtin_vsnprintf, "ic*RzcC*Ra", "nFP:2:")
+BUILTIN(__builtin_fscanf, "iP*RcC*R.", "Fs:1:")
+BUILTIN(__builtin_scanf, "icC*R.", "Fs:0:")
+BUILTIN(__builtin_sscanf, "icC*RcC*R.", "Fs:1:")
+BUILTIN(__builtin_vfscanf, "iP*RcC*Ra", "FS:1:")
+BUILTIN(__builtin_vscanf, "icC*Ra", "FS:0:")
+BUILTIN(__builtin_vsscanf, "icC*RcC*Ra", "FS:1:")
BUILTIN(__builtin_thread_pointer, "v*", "nc")
-BUILTIN(__builtin_launder, "v*v*", "nt")
-LANGBUILTIN(__builtin_is_constant_evaluated, "b", "n", CXX_LANG)
+BUILTIN(__builtin_launder, "v*v*", "ntE")
+LANGBUILTIN(__builtin_is_constant_evaluated, "b", "nE", CXX_LANG)
// GCC exception builtins
BUILTIN(__builtin_eh_return, "vzv*", "r") // FIXME: Takes intptr_t, not size_t!
@@ -607,8 +643,8 @@ BUILTIN(__builtin_dwarf_sp_column, "Ui", "n")
BUILTIN(__builtin_extend_pointer, "ULLiv*", "n") // _Unwind_Word == uint64_t
// GCC Object size checking builtins
-BUILTIN(__builtin_object_size, "zvC*i", "nu")
-BUILTIN(__builtin_dynamic_object_size, "zvC*i", "nu") // Clang only.
+BUILTIN(__builtin_object_size, "zvC*i", "nuE")
+BUILTIN(__builtin_dynamic_object_size, "zvC*i", "nuE") // Clang only.
BUILTIN(__builtin___memcpy_chk, "v*v*vC*zz", "nF")
BUILTIN(__builtin___memccpy_chk, "v*v*vC*izz", "nF")
BUILTIN(__builtin___memmove_chk, "v*v*vC*zz", "nF")
@@ -622,18 +658,18 @@ BUILTIN(__builtin___strlcpy_chk, "zc*cC*zz", "nF")
BUILTIN(__builtin___strncat_chk, "c*c*cC*zz", "nF")
BUILTIN(__builtin___strncpy_chk, "c*c*cC*zz", "nF")
BUILTIN(__builtin___stpncpy_chk, "c*c*cC*zz", "nF")
-BUILTIN(__builtin___snprintf_chk, "ic*zizcC*.", "Fp:4:")
-BUILTIN(__builtin___sprintf_chk, "ic*izcC*.", "Fp:3:")
-BUILTIN(__builtin___vsnprintf_chk, "ic*zizcC*a", "FP:4:")
-BUILTIN(__builtin___vsprintf_chk, "ic*izcC*a", "FP:3:")
-BUILTIN(__builtin___fprintf_chk, "iP*icC*.", "Fp:2:")
-BUILTIN(__builtin___printf_chk, "iicC*.", "Fp:1:")
-BUILTIN(__builtin___vfprintf_chk, "iP*icC*a", "FP:2:")
-BUILTIN(__builtin___vprintf_chk, "iicC*a", "FP:1:")
+BUILTIN(__builtin___snprintf_chk, "ic*RzizcC*R.", "Fp:4:")
+BUILTIN(__builtin___sprintf_chk, "ic*RizcC*R.", "Fp:3:")
+BUILTIN(__builtin___vsnprintf_chk, "ic*RzizcC*Ra", "FP:4:")
+BUILTIN(__builtin___vsprintf_chk, "ic*RizcC*Ra", "FP:3:")
+BUILTIN(__builtin___fprintf_chk, "iP*RicC*R.", "Fp:2:")
+BUILTIN(__builtin___printf_chk, "iicC*R.", "Fp:1:")
+BUILTIN(__builtin___vfprintf_chk, "iP*RicC*Ra", "FP:2:")
+BUILTIN(__builtin___vprintf_chk, "iicC*Ra", "FP:1:")
BUILTIN(__builtin_unpredictable, "LiLi" , "nc")
-BUILTIN(__builtin_expect, "LiLiLi" , "nc")
-BUILTIN(__builtin_expect_with_probability, "LiLiLid", "nc")
+BUILTIN(__builtin_expect, "LiLiLi" , "ncE")
+BUILTIN(__builtin_expect_with_probability, "LiLiLid", "ncE")
BUILTIN(__builtin_prefetch, "vvC*.", "nc")
BUILTIN(__builtin_readcyclecounter, "ULLi", "n")
BUILTIN(__builtin_trap, "v", "nr")
@@ -641,9 +677,46 @@ BUILTIN(__builtin_debugtrap, "v", "n")
BUILTIN(__builtin_unreachable, "v", "nr")
BUILTIN(__builtin_shufflevector, "v." , "nct")
BUILTIN(__builtin_convertvector, "v." , "nct")
+BUILTIN(__builtin_vectorelements, "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_nondeterministic_value, "v.", "nt")
+
+BUILTIN(__builtin_elementwise_abs, "v.", "nct")
+BUILTIN(__builtin_elementwise_bitreverse, "v.", "nct")
+BUILTIN(__builtin_elementwise_max, "v.", "nct")
+BUILTIN(__builtin_elementwise_min, "v.", "nct")
+BUILTIN(__builtin_elementwise_ceil, "v.", "nct")
+BUILTIN(__builtin_elementwise_cos, "v.", "nct")
+BUILTIN(__builtin_elementwise_exp, "v.", "nct")
+BUILTIN(__builtin_elementwise_exp2, "v.", "nct")
+BUILTIN(__builtin_elementwise_floor, "v.", "nct")
+BUILTIN(__builtin_elementwise_log, "v.", "nct")
+BUILTIN(__builtin_elementwise_log2, "v.", "nct")
+BUILTIN(__builtin_elementwise_log10, "v.", "nct")
+BUILTIN(__builtin_elementwise_pow, "v.", "nct")
+BUILTIN(__builtin_elementwise_roundeven, "v.", "nct")
+BUILTIN(__builtin_elementwise_round, "v.", "nct")
+BUILTIN(__builtin_elementwise_rint, "v.", "nct")
+BUILTIN(__builtin_elementwise_nearbyint, "v.", "nct")
+BUILTIN(__builtin_elementwise_sin, "v.", "nct")
+BUILTIN(__builtin_elementwise_sqrt, "v.", "nct")
+BUILTIN(__builtin_elementwise_trunc, "v.", "nct")
+BUILTIN(__builtin_elementwise_canonicalize, "v.", "nct")
+BUILTIN(__builtin_elementwise_copysign, "v.", "nct")
+BUILTIN(__builtin_elementwise_fma, "v.", "nct")
+BUILTIN(__builtin_elementwise_add_sat, "v.", "nct")
+BUILTIN(__builtin_elementwise_sub_sat, "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_reduce_add, "v.", "nct")
+BUILTIN(__builtin_reduce_mul, "v.", "nct")
BUILTIN(__builtin_matrix_transpose, "v.", "nFt")
BUILTIN(__builtin_matrix_column_major_load, "v.", "nFt")
@@ -794,11 +867,12 @@ ATOMIC_BUILTIN(__c11_atomic_fetch_sub, "v.", "t")
ATOMIC_BUILTIN(__c11_atomic_fetch_and, "v.", "t")
ATOMIC_BUILTIN(__c11_atomic_fetch_or, "v.", "t")
ATOMIC_BUILTIN(__c11_atomic_fetch_xor, "v.", "t")
+ATOMIC_BUILTIN(__c11_atomic_fetch_nand, "v.", "t")
ATOMIC_BUILTIN(__c11_atomic_fetch_max, "v.", "t")
ATOMIC_BUILTIN(__c11_atomic_fetch_min, "v.", "t")
BUILTIN(__c11_atomic_thread_fence, "vi", "n")
BUILTIN(__c11_atomic_signal_fence, "vi", "n")
-BUILTIN(__c11_atomic_is_lock_free, "bz", "n")
+BUILTIN(__c11_atomic_is_lock_free, "bz", "nE")
// GNU atomic builtins.
ATOMIC_BUILTIN(__atomic_load, "v.", "t")
@@ -827,8 +901,34 @@ BUILTIN(__atomic_test_and_set, "bvD*i", "n")
BUILTIN(__atomic_clear, "vvD*i", "n")
BUILTIN(__atomic_thread_fence, "vi", "n")
BUILTIN(__atomic_signal_fence, "vi", "n")
-BUILTIN(__atomic_always_lock_free, "bzvCD*", "n")
-BUILTIN(__atomic_is_lock_free, "bzvCD*", "n")
+BUILTIN(__atomic_always_lock_free, "bzvCD*", "nE")
+BUILTIN(__atomic_is_lock_free, "bzvCD*", "nE")
+
+// GNU atomic builtins with atomic scopes.
+ATOMIC_BUILTIN(__scoped_atomic_load, "v.", "t")
+ATOMIC_BUILTIN(__scoped_atomic_load_n, "v.", "t")
+ATOMIC_BUILTIN(__scoped_atomic_store, "v.", "t")
+ATOMIC_BUILTIN(__scoped_atomic_store_n, "v.", "t")
+ATOMIC_BUILTIN(__scoped_atomic_exchange, "v.", "t")
+ATOMIC_BUILTIN(__scoped_atomic_exchange_n, "v.", "t")
+ATOMIC_BUILTIN(__scoped_atomic_compare_exchange, "v.", "t")
+ATOMIC_BUILTIN(__scoped_atomic_compare_exchange_n, "v.", "t")
+ATOMIC_BUILTIN(__scoped_atomic_fetch_add, "v.", "t")
+ATOMIC_BUILTIN(__scoped_atomic_fetch_sub, "v.", "t")
+ATOMIC_BUILTIN(__scoped_atomic_fetch_and, "v.", "t")
+ATOMIC_BUILTIN(__scoped_atomic_fetch_or, "v.", "t")
+ATOMIC_BUILTIN(__scoped_atomic_fetch_xor, "v.", "t")
+ATOMIC_BUILTIN(__scoped_atomic_fetch_nand, "v.", "t")
+ATOMIC_BUILTIN(__scoped_atomic_add_fetch, "v.", "t")
+ATOMIC_BUILTIN(__scoped_atomic_sub_fetch, "v.", "t")
+ATOMIC_BUILTIN(__scoped_atomic_and_fetch, "v.", "t")
+ATOMIC_BUILTIN(__scoped_atomic_or_fetch, "v.", "t")
+ATOMIC_BUILTIN(__scoped_atomic_xor_fetch, "v.", "t")
+ATOMIC_BUILTIN(__scoped_atomic_max_fetch, "v.", "t")
+ATOMIC_BUILTIN(__scoped_atomic_min_fetch, "v.", "t")
+ATOMIC_BUILTIN(__scoped_atomic_nand_fetch, "v.", "t")
+ATOMIC_BUILTIN(__scoped_atomic_fetch_min, "v.", "t")
+ATOMIC_BUILTIN(__scoped_atomic_fetch_max, "v.", "t")
// OpenCL 2.0 atomic builtins.
ATOMIC_BUILTIN(__opencl_atomic_init, "v.", "t")
@@ -849,6 +949,20 @@ ATOMIC_BUILTIN(__opencl_atomic_fetch_max, "v.", "t")
ATOMIC_BUILTIN(__atomic_fetch_min, "v.", "t")
ATOMIC_BUILTIN(__atomic_fetch_max, "v.", "t")
+// HIP atomic builtins.
+ATOMIC_BUILTIN(__hip_atomic_load, "v.", "t")
+ATOMIC_BUILTIN(__hip_atomic_store, "v.", "t")
+ATOMIC_BUILTIN(__hip_atomic_compare_exchange_weak, "v.", "t")
+ATOMIC_BUILTIN(__hip_atomic_compare_exchange_strong, "v.", "t")
+ATOMIC_BUILTIN(__hip_atomic_exchange, "v.", "t")
+ATOMIC_BUILTIN(__hip_atomic_fetch_add, "v.", "t")
+ATOMIC_BUILTIN(__hip_atomic_fetch_sub, "v.", "t")
+ATOMIC_BUILTIN(__hip_atomic_fetch_and, "v.", "t")
+ATOMIC_BUILTIN(__hip_atomic_fetch_or, "v.", "t")
+ATOMIC_BUILTIN(__hip_atomic_fetch_xor, "v.", "t")
+ATOMIC_BUILTIN(__hip_atomic_fetch_min, "v.", "t")
+ATOMIC_BUILTIN(__hip_atomic_fetch_max, "v.", "t")
+
#undef ATOMIC_BUILTIN
// Non-overloaded atomic builtins.
@@ -870,7 +984,7 @@ BUILTIN(__warn_memset_zero_len, "v", "nU")
// Microsoft builtins. These are only active with -fms-extensions.
LANGBUILTIN(_alloca, "v*z", "n", ALL_MS_LANGUAGES)
LANGBUILTIN(__annotation, "wC*.","n", ALL_MS_LANGUAGES)
-LANGBUILTIN(__assume, "vb", "n", ALL_MS_LANGUAGES)
+LANGBUILTIN(__assume, "vb", "nE", ALL_MS_LANGUAGES)
LANGBUILTIN(_bittest, "UcNiC*Ni", "n", ALL_MS_LANGUAGES)
LANGBUILTIN(_bittestandcomplement, "UcNi*Ni", "n", ALL_MS_LANGUAGES)
LANGBUILTIN(_bittestandreset, "UcNi*Ni", "n", ALL_MS_LANGUAGES)
@@ -879,9 +993,9 @@ LANGBUILTIN(_bittest64, "UcWiC*Wi", "n", ALL_MS_LANGUAGES)
LANGBUILTIN(_bittestandcomplement64, "UcWi*Wi", "n", ALL_MS_LANGUAGES)
LANGBUILTIN(_bittestandreset64, "UcWi*Wi", "n", ALL_MS_LANGUAGES)
LANGBUILTIN(_bittestandset64, "UcWi*Wi", "n", ALL_MS_LANGUAGES)
-LIBBUILTIN(_byteswap_ushort, "UsUs", "fnc", "stdlib.h", ALL_MS_LANGUAGES)
-LIBBUILTIN(_byteswap_ulong, "UNiUNi", "fnc", "stdlib.h", ALL_MS_LANGUAGES)
-LIBBUILTIN(_byteswap_uint64, "ULLiULLi", "fnc", "stdlib.h", ALL_MS_LANGUAGES)
+LIBBUILTIN(_byteswap_ushort, "UsUs", "fnc", STDLIB_H, ALL_MS_LANGUAGES)
+LIBBUILTIN(_byteswap_ulong, "UNiUNi", "fnc", STDLIB_H, ALL_MS_LANGUAGES)
+LIBBUILTIN(_byteswap_uint64, "ULLiULLi", "fnc", STDLIB_H, ALL_MS_LANGUAGES)
LANGBUILTIN(__debugbreak, "v", "n", ALL_MS_LANGUAGES)
LANGBUILTIN(__exception_code, "UNi", "n", ALL_MS_LANGUAGES)
LANGBUILTIN(_exception_code, "UNi", "n", ALL_MS_LANGUAGES)
@@ -889,7 +1003,7 @@ LANGBUILTIN(__exception_info, "v*", "n", ALL_MS_LANGUAGES)
LANGBUILTIN(_exception_info, "v*", "n", ALL_MS_LANGUAGES)
LANGBUILTIN(__abnormal_termination, "i", "n", ALL_MS_LANGUAGES)
LANGBUILTIN(_abnormal_termination, "i", "n", ALL_MS_LANGUAGES)
-LANGBUILTIN(__GetExceptionInfo, "v*.", "ntu", ALL_MS_LANGUAGES)
+LANGBUILTIN(__GetExceptionInfo, "v*.", "zntu", ALL_MS_LANGUAGES)
LANGBUILTIN(_InterlockedAnd8, "ccD*c", "n", ALL_MS_LANGUAGES)
LANGBUILTIN(_InterlockedAnd16, "ssD*s", "n", ALL_MS_LANGUAGES)
LANGBUILTIN(_InterlockedAnd, "NiNiD*Ni", "n", ALL_MS_LANGUAGES)
@@ -938,586 +1052,602 @@ LANGBUILTIN(__iso_volatile_store16, "vsD*s", "n", ALL_MS_LANGUAGES)
LANGBUILTIN(__iso_volatile_store32, "viD*i", "n", ALL_MS_LANGUAGES)
LANGBUILTIN(__iso_volatile_store64, "vLLiD*LLi", "n", ALL_MS_LANGUAGES)
LANGBUILTIN(__noop, "i.", "n", ALL_MS_LANGUAGES)
-LANGBUILTIN(__lzcnt16, "UsUs", "nc", ALL_MS_LANGUAGES)
-LANGBUILTIN(__lzcnt, "UiUi", "nc", ALL_MS_LANGUAGES)
-LANGBUILTIN(__lzcnt64, "UWiUWi", "nc", ALL_MS_LANGUAGES)
-LANGBUILTIN(__popcnt16, "UsUs", "nc", ALL_MS_LANGUAGES)
-LANGBUILTIN(__popcnt, "UiUi", "nc", ALL_MS_LANGUAGES)
-LANGBUILTIN(__popcnt64, "UWiUWi", "nc", ALL_MS_LANGUAGES)
+LANGBUILTIN(__lzcnt16, "UsUs", "ncE", ALL_MS_LANGUAGES)
+LANGBUILTIN(__lzcnt, "UiUi", "ncE", ALL_MS_LANGUAGES)
+LANGBUILTIN(__lzcnt64, "UWiUWi", "ncE", ALL_MS_LANGUAGES)
+LANGBUILTIN(__popcnt16, "UsUs", "ncE", ALL_MS_LANGUAGES)
+LANGBUILTIN(__popcnt, "UiUi", "ncE", ALL_MS_LANGUAGES)
+LANGBUILTIN(__popcnt64, "UWiUWi", "ncE", ALL_MS_LANGUAGES)
LANGBUILTIN(_ReturnAddress, "v*", "n", ALL_MS_LANGUAGES)
-LANGBUILTIN(_rotl8, "UcUcUc", "n", ALL_MS_LANGUAGES)
-LANGBUILTIN(_rotl16, "UsUsUc", "n", ALL_MS_LANGUAGES)
-LANGBUILTIN(_rotl, "UiUii", "n", ALL_MS_LANGUAGES)
-LANGBUILTIN(_lrotl, "ULiULii", "n", ALL_MS_LANGUAGES)
-LANGBUILTIN(_rotl64, "UWiUWii", "n", ALL_MS_LANGUAGES)
-LANGBUILTIN(_rotr8, "UcUcUc", "n", ALL_MS_LANGUAGES)
-LANGBUILTIN(_rotr16, "UsUsUc", "n", ALL_MS_LANGUAGES)
-LANGBUILTIN(_rotr, "UiUii", "n", ALL_MS_LANGUAGES)
-LANGBUILTIN(_lrotr, "ULiULii", "n", ALL_MS_LANGUAGES)
-LANGBUILTIN(_rotr64, "UWiUWii", "n", ALL_MS_LANGUAGES)
+LANGBUILTIN(_rotl8, "UcUcUc", "nE", ALL_MS_LANGUAGES)
+LANGBUILTIN(_rotl16, "UsUsUc", "nE", ALL_MS_LANGUAGES)
+LANGBUILTIN(_rotl, "UiUii", "nE", ALL_MS_LANGUAGES)
+LANGBUILTIN(_lrotl, "ULiULii", "nE", ALL_MS_LANGUAGES)
+LANGBUILTIN(_rotl64, "UWiUWii", "nE", ALL_MS_LANGUAGES)
+LANGBUILTIN(_rotr8, "UcUcUc", "nE", ALL_MS_LANGUAGES)
+LANGBUILTIN(_rotr16, "UsUsUc", "nE", ALL_MS_LANGUAGES)
+LANGBUILTIN(_rotr, "UiUii", "nE", ALL_MS_LANGUAGES)
+LANGBUILTIN(_lrotr, "ULiULii", "nE", ALL_MS_LANGUAGES)
+LANGBUILTIN(_rotr64, "UWiUWii", "nE", ALL_MS_LANGUAGES)
LANGBUILTIN(__va_start, "vc**.", "nt", ALL_MS_LANGUAGES)
LANGBUILTIN(__fastfail, "vUi", "nr", ALL_MS_LANGUAGES)
// Microsoft library builtins.
-LIBBUILTIN(_setjmpex, "iJ", "fjT", "setjmpex.h", ALL_MS_LANGUAGES)
+LIBBUILTIN(_setjmpex, "iJ", "fjT", SETJMPEX_H, ALL_MS_LANGUAGES)
// C99 library functions
// C99 stdarg.h
-LIBBUILTIN(va_start, "vA.", "fn", "stdarg.h", ALL_LANGUAGES)
-LIBBUILTIN(va_end, "vA", "fn", "stdarg.h", ALL_LANGUAGES)
-LIBBUILTIN(va_copy, "vAA", "fn", "stdarg.h", ALL_LANGUAGES)
+LIBBUILTIN(va_start, "vA.", "fn", STDARG_H, ALL_LANGUAGES)
+LIBBUILTIN(va_end, "vA", "fn", STDARG_H, ALL_LANGUAGES)
+LIBBUILTIN(va_copy, "vAA", "fn", STDARG_H, ALL_LANGUAGES)
// C99 stdlib.h
-LIBBUILTIN(abort, "v", "fr", "stdlib.h", ALL_LANGUAGES)
-LIBBUILTIN(calloc, "v*zz", "f", "stdlib.h", ALL_LANGUAGES)
-LIBBUILTIN(exit, "vi", "fr", "stdlib.h", ALL_LANGUAGES)
-LIBBUILTIN(_Exit, "vi", "fr", "stdlib.h", ALL_LANGUAGES)
-LIBBUILTIN(malloc, "v*z", "f", "stdlib.h", ALL_LANGUAGES)
-LIBBUILTIN(realloc, "v*v*z", "f", "stdlib.h", ALL_LANGUAGES)
-LIBBUILTIN(free, "vv*", "f", "stdlib.h", ALL_LANGUAGES)
-LIBBUILTIN(strtod, "dcC*c**", "f", "stdlib.h", ALL_LANGUAGES)
-LIBBUILTIN(strtof, "fcC*c**", "f", "stdlib.h", ALL_LANGUAGES)
-LIBBUILTIN(strtold, "LdcC*c**", "f", "stdlib.h", ALL_LANGUAGES)
-LIBBUILTIN(strtol, "LicC*c**i", "f", "stdlib.h", ALL_LANGUAGES)
-LIBBUILTIN(strtoll, "LLicC*c**i", "f", "stdlib.h", ALL_LANGUAGES)
-LIBBUILTIN(strtoul, "ULicC*c**i", "f", "stdlib.h", ALL_LANGUAGES)
-LIBBUILTIN(strtoull, "ULLicC*c**i", "f", "stdlib.h", ALL_LANGUAGES)
+LIBBUILTIN(abort, "v", "fr", STDLIB_H, ALL_LANGUAGES)
+LIBBUILTIN(calloc, "v*zz", "f", STDLIB_H, ALL_LANGUAGES)
+LIBBUILTIN(exit, "vi", "fr", STDLIB_H, ALL_LANGUAGES)
+LIBBUILTIN(_Exit, "vi", "fr", STDLIB_H, ALL_LANGUAGES)
+LIBBUILTIN(malloc, "v*z", "f", STDLIB_H, ALL_LANGUAGES)
+LIBBUILTIN(realloc, "v*v*z", "f", STDLIB_H, ALL_LANGUAGES)
+LIBBUILTIN(free, "vv*", "f", STDLIB_H, ALL_LANGUAGES)
+LIBBUILTIN(strtod, "dcC*c**", "f", STDLIB_H, ALL_LANGUAGES)
+LIBBUILTIN(strtof, "fcC*c**", "f", STDLIB_H, ALL_LANGUAGES)
+LIBBUILTIN(strtold, "LdcC*c**", "f", STDLIB_H, ALL_LANGUAGES)
+LIBBUILTIN(strtol, "LicC*c**i", "f", STDLIB_H, ALL_LANGUAGES)
+LIBBUILTIN(strtoll, "LLicC*c**i", "f", STDLIB_H, ALL_LANGUAGES)
+LIBBUILTIN(strtoul, "ULicC*c**i", "f", STDLIB_H, ALL_LANGUAGES)
+LIBBUILTIN(strtoull, "ULLicC*c**i", "f", STDLIB_H, ALL_LANGUAGES)
// C11 stdlib.h
-LIBBUILTIN(aligned_alloc, "v*zz", "f", "stdlib.h", ALL_LANGUAGES)
+LIBBUILTIN(aligned_alloc, "v*zz", "f", STDLIB_H, ALL_LANGUAGES)
// C99 string.h
-LIBBUILTIN(memcpy, "v*v*vC*z", "f", "string.h", ALL_LANGUAGES)
-LIBBUILTIN(memcmp, "ivC*vC*z", "f", "string.h", ALL_LANGUAGES)
-LIBBUILTIN(memmove, "v*v*vC*z", "f", "string.h", ALL_LANGUAGES)
-LIBBUILTIN(strcpy, "c*c*cC*", "f", "string.h", ALL_LANGUAGES)
-LIBBUILTIN(strncpy, "c*c*cC*z", "f", "string.h", ALL_LANGUAGES)
-LIBBUILTIN(strcmp, "icC*cC*", "f", "string.h", ALL_LANGUAGES)
-LIBBUILTIN(strncmp, "icC*cC*z", "f", "string.h", ALL_LANGUAGES)
-LIBBUILTIN(strcat, "c*c*cC*", "f", "string.h", ALL_LANGUAGES)
-LIBBUILTIN(strncat, "c*c*cC*z", "f", "string.h", ALL_LANGUAGES)
-LIBBUILTIN(strxfrm, "zc*cC*z", "f", "string.h", ALL_LANGUAGES)
-LIBBUILTIN(memchr, "v*vC*iz", "f", "string.h", ALL_LANGUAGES)
-LIBBUILTIN(strchr, "c*cC*i", "f", "string.h", ALL_LANGUAGES)
-LIBBUILTIN(strcspn, "zcC*cC*", "f", "string.h", ALL_LANGUAGES)
-LIBBUILTIN(strpbrk, "c*cC*cC*", "f", "string.h", ALL_LANGUAGES)
-LIBBUILTIN(strrchr, "c*cC*i", "f", "string.h", ALL_LANGUAGES)
-LIBBUILTIN(strspn, "zcC*cC*", "f", "string.h", ALL_LANGUAGES)
-LIBBUILTIN(strstr, "c*cC*cC*", "f", "string.h", ALL_LANGUAGES)
-LIBBUILTIN(strtok, "c*c*cC*", "f", "string.h", ALL_LANGUAGES)
-LIBBUILTIN(memset, "v*v*iz", "f", "string.h", ALL_LANGUAGES)
-LIBBUILTIN(strerror, "c*i", "f", "string.h", ALL_LANGUAGES)
-LIBBUILTIN(strlen, "zcC*", "f", "string.h", ALL_LANGUAGES)
+LIBBUILTIN(memcpy, "v*v*vC*z", "fE", STRING_H, ALL_LANGUAGES)
+LIBBUILTIN(memcmp, "ivC*vC*z", "fE", STRING_H, ALL_LANGUAGES)
+LIBBUILTIN(memmove, "v*v*vC*z", "fE", STRING_H, ALL_LANGUAGES)
+LIBBUILTIN(strcpy, "c*c*cC*", "f", STRING_H, ALL_LANGUAGES)
+LIBBUILTIN(strncpy, "c*c*cC*z", "f", STRING_H, ALL_LANGUAGES)
+LIBBUILTIN(strcmp, "icC*cC*", "fE", STRING_H, ALL_LANGUAGES)
+LIBBUILTIN(strncmp, "icC*cC*z", "fE", STRING_H, ALL_LANGUAGES)
+LIBBUILTIN(strcat, "c*c*cC*", "f", STRING_H, ALL_LANGUAGES)
+LIBBUILTIN(strncat, "c*c*cC*z", "f", STRING_H, ALL_LANGUAGES)
+LIBBUILTIN(strxfrm, "zc*cC*z", "f", STRING_H, ALL_LANGUAGES)
+LIBBUILTIN(memchr, "v*vC*iz", "fE", STRING_H, ALL_LANGUAGES)
+LIBBUILTIN(strchr, "c*cC*i", "fE", STRING_H, ALL_LANGUAGES)
+LIBBUILTIN(strcspn, "zcC*cC*", "f", STRING_H, ALL_LANGUAGES)
+LIBBUILTIN(strpbrk, "c*cC*cC*", "f", STRING_H, ALL_LANGUAGES)
+LIBBUILTIN(strrchr, "c*cC*i", "f", STRING_H, ALL_LANGUAGES)
+LIBBUILTIN(strspn, "zcC*cC*", "f", STRING_H, ALL_LANGUAGES)
+LIBBUILTIN(strstr, "c*cC*cC*", "f", STRING_H, ALL_LANGUAGES)
+LIBBUILTIN(strtok, "c*c*cC*", "f", STRING_H, ALL_LANGUAGES)
+LIBBUILTIN(memset, "v*v*iz", "f", STRING_H, ALL_LANGUAGES)
+LIBBUILTIN(strerror, "c*i", "f", STRING_H, ALL_LANGUAGES)
+LIBBUILTIN(strlen, "zcC*", "fE", STRING_H, ALL_LANGUAGES)
// C99 stdio.h
// FIXME: This list is incomplete.
-LIBBUILTIN(printf, "icC*.", "fp:0:", "stdio.h", ALL_LANGUAGES)
-LIBBUILTIN(fprintf, "iP*cC*.", "fp:1:", "stdio.h", ALL_LANGUAGES)
-LIBBUILTIN(snprintf, "ic*zcC*.", "fp:2:", "stdio.h", ALL_LANGUAGES)
-LIBBUILTIN(sprintf, "ic*cC*.", "fp:1:", "stdio.h", ALL_LANGUAGES)
-LIBBUILTIN(vprintf, "icC*a", "fP:0:", "stdio.h", ALL_LANGUAGES)
-LIBBUILTIN(vfprintf, "iP*cC*a", "fP:1:", "stdio.h", ALL_LANGUAGES)
-LIBBUILTIN(vsnprintf, "ic*zcC*a", "fP:2:", "stdio.h", ALL_LANGUAGES)
-LIBBUILTIN(vsprintf, "ic*cC*a", "fP:1:", "stdio.h", ALL_LANGUAGES)
-LIBBUILTIN(scanf, "icC*R.", "fs:0:", "stdio.h", ALL_LANGUAGES)
-LIBBUILTIN(fscanf, "iP*RcC*R.", "fs:1:", "stdio.h", ALL_LANGUAGES)
-LIBBUILTIN(sscanf, "icC*RcC*R.", "fs:1:", "stdio.h", ALL_LANGUAGES)
-LIBBUILTIN(vscanf, "icC*Ra", "fS:0:", "stdio.h", ALL_LANGUAGES)
-LIBBUILTIN(vfscanf, "iP*RcC*Ra", "fS:1:", "stdio.h", ALL_LANGUAGES)
-LIBBUILTIN(vsscanf, "icC*RcC*Ra", "fS:1:", "stdio.h", ALL_LANGUAGES)
-LIBBUILTIN(fopen, "P*cC*cC*", "f", "stdio.h", ALL_LANGUAGES)
-LIBBUILTIN(fread, "zv*zzP*", "f", "stdio.h", ALL_LANGUAGES)
-LIBBUILTIN(fwrite, "zvC*zzP*", "f", "stdio.h", ALL_LANGUAGES)
+LIBBUILTIN(printf, "icC*.", "fp:0:", STDIO_H, ALL_LANGUAGES)
+LIBBUILTIN(fprintf, "iP*cC*.", "fp:1:", STDIO_H, ALL_LANGUAGES)
+LIBBUILTIN(snprintf, "ic*zcC*.", "fp:2:", STDIO_H, ALL_LANGUAGES)
+LIBBUILTIN(sprintf, "ic*cC*.", "fp:1:", STDIO_H, ALL_LANGUAGES)
+LIBBUILTIN(vprintf, "icC*a", "fP:0:", STDIO_H, ALL_LANGUAGES)
+LIBBUILTIN(vfprintf, "iP*cC*a", "fP:1:", STDIO_H, ALL_LANGUAGES)
+LIBBUILTIN(vsnprintf, "ic*zcC*a", "fP:2:", STDIO_H, ALL_LANGUAGES)
+LIBBUILTIN(vsprintf, "ic*cC*a", "fP:1:", STDIO_H, ALL_LANGUAGES)
+LIBBUILTIN(scanf, "icC*R.", "fs:0:", STDIO_H, ALL_LANGUAGES)
+LIBBUILTIN(fscanf, "iP*RcC*R.", "fs:1:", STDIO_H, ALL_LANGUAGES)
+LIBBUILTIN(sscanf, "icC*RcC*R.", "fs:1:", STDIO_H, ALL_LANGUAGES)
+LIBBUILTIN(vscanf, "icC*Ra", "fS:0:", STDIO_H, ALL_LANGUAGES)
+LIBBUILTIN(vfscanf, "iP*RcC*Ra", "fS:1:", STDIO_H, ALL_LANGUAGES)
+LIBBUILTIN(vsscanf, "icC*RcC*Ra", "fS:1:", STDIO_H, ALL_LANGUAGES)
+LIBBUILTIN(fopen, "P*cC*cC*", "f", STDIO_H, ALL_LANGUAGES)
+LIBBUILTIN(fread, "zv*zzP*", "f", STDIO_H, ALL_LANGUAGES)
+LIBBUILTIN(fwrite, "zvC*zzP*", "f", STDIO_H, ALL_LANGUAGES)
// C99 ctype.h
-LIBBUILTIN(isalnum, "ii", "fnU", "ctype.h", ALL_LANGUAGES)
-LIBBUILTIN(isalpha, "ii", "fnU", "ctype.h", ALL_LANGUAGES)
-LIBBUILTIN(isblank, "ii", "fnU", "ctype.h", ALL_LANGUAGES)
-LIBBUILTIN(iscntrl, "ii", "fnU", "ctype.h", ALL_LANGUAGES)
-LIBBUILTIN(isdigit, "ii", "fnU", "ctype.h", ALL_LANGUAGES)
-LIBBUILTIN(isgraph, "ii", "fnU", "ctype.h", ALL_LANGUAGES)
-LIBBUILTIN(islower, "ii", "fnU", "ctype.h", ALL_LANGUAGES)
-LIBBUILTIN(isprint, "ii", "fnU", "ctype.h", ALL_LANGUAGES)
-LIBBUILTIN(ispunct, "ii", "fnU", "ctype.h", ALL_LANGUAGES)
-LIBBUILTIN(isspace, "ii", "fnU", "ctype.h", ALL_LANGUAGES)
-LIBBUILTIN(isupper, "ii", "fnU", "ctype.h", ALL_LANGUAGES)
-LIBBUILTIN(isxdigit, "ii", "fnU", "ctype.h", ALL_LANGUAGES)
-LIBBUILTIN(tolower, "ii", "fnU", "ctype.h", ALL_LANGUAGES)
-LIBBUILTIN(toupper, "ii", "fnU", "ctype.h", ALL_LANGUAGES)
+LIBBUILTIN(isalnum, "ii", "fnU", CTYPE_H, ALL_LANGUAGES)
+LIBBUILTIN(isalpha, "ii", "fnU", CTYPE_H, ALL_LANGUAGES)
+LIBBUILTIN(isblank, "ii", "fnU", CTYPE_H, ALL_LANGUAGES)
+LIBBUILTIN(iscntrl, "ii", "fnU", CTYPE_H, ALL_LANGUAGES)
+LIBBUILTIN(isdigit, "ii", "fnU", CTYPE_H, ALL_LANGUAGES)
+LIBBUILTIN(isgraph, "ii", "fnU", CTYPE_H, ALL_LANGUAGES)
+LIBBUILTIN(islower, "ii", "fnU", CTYPE_H, ALL_LANGUAGES)
+LIBBUILTIN(isprint, "ii", "fnU", CTYPE_H, ALL_LANGUAGES)
+LIBBUILTIN(ispunct, "ii", "fnU", CTYPE_H, ALL_LANGUAGES)
+LIBBUILTIN(isspace, "ii", "fnU", CTYPE_H, ALL_LANGUAGES)
+LIBBUILTIN(isupper, "ii", "fnU", CTYPE_H, ALL_LANGUAGES)
+LIBBUILTIN(isxdigit, "ii", "fnU", CTYPE_H, ALL_LANGUAGES)
+LIBBUILTIN(tolower, "ii", "fnU", CTYPE_H, ALL_LANGUAGES)
+LIBBUILTIN(toupper, "ii", "fnU", CTYPE_H, ALL_LANGUAGES)
// C99 wchar.h
// FIXME: This list is incomplete. We should cover at least the functions that
// take format strings.
-LIBBUILTIN(wcschr, "w*wC*w", "f", "wchar.h", ALL_LANGUAGES)
-LIBBUILTIN(wcscmp, "iwC*wC*", "f", "wchar.h", ALL_LANGUAGES)
-LIBBUILTIN(wcslen, "zwC*", "f", "wchar.h", ALL_LANGUAGES)
-LIBBUILTIN(wcsncmp, "iwC*wC*z", "f", "wchar.h", ALL_LANGUAGES)
-LIBBUILTIN(wmemchr, "w*wC*wz", "f", "wchar.h", ALL_LANGUAGES)
-LIBBUILTIN(wmemcmp, "iwC*wC*z", "f", "wchar.h", ALL_LANGUAGES)
-LIBBUILTIN(wmemcpy, "w*w*wC*z", "f", "wchar.h", ALL_LANGUAGES)
-LIBBUILTIN(wmemmove,"w*w*wC*z", "f", "wchar.h", ALL_LANGUAGES)
+LIBBUILTIN(wcschr, "w*wC*w", "fE", WCHAR_H, ALL_LANGUAGES)
+LIBBUILTIN(wcscmp, "iwC*wC*", "fE", WCHAR_H, ALL_LANGUAGES)
+LIBBUILTIN(wcslen, "zwC*", "fE", WCHAR_H, ALL_LANGUAGES)
+LIBBUILTIN(wcsncmp, "iwC*wC*z", "fE", WCHAR_H, ALL_LANGUAGES)
+LIBBUILTIN(wmemchr, "w*wC*wz", "fE", WCHAR_H, ALL_LANGUAGES)
+LIBBUILTIN(wmemcmp, "iwC*wC*z", "fE", WCHAR_H, ALL_LANGUAGES)
+LIBBUILTIN(wmemcpy, "w*w*wC*z", "fE", WCHAR_H, ALL_LANGUAGES)
+LIBBUILTIN(wmemmove,"w*w*wC*z", "fE", WCHAR_H, ALL_LANGUAGES)
// C99
// In some systems setjmp is a macro that expands to _setjmp. We undefine
// it here to avoid having two identical LIBBUILTIN entries.
#undef setjmp
-LIBBUILTIN(setjmp, "iJ", "fjT", "setjmp.h", ALL_LANGUAGES)
-LIBBUILTIN(longjmp, "vJi", "frT", "setjmp.h", ALL_LANGUAGES)
+LIBBUILTIN(setjmp, "iJ", "fjT", SETJMP_H, ALL_LANGUAGES)
+LIBBUILTIN(longjmp, "vJi", "frT", SETJMP_H, ALL_LANGUAGES)
// Non-C library functions, active in GNU mode only.
// Functions with (returns_twice) attribute (marked as "j") are still active in
// all languages, because losing this attribute would result in miscompilation
// when these functions are used in non-GNU mode. PR16138.
-LIBBUILTIN(alloca, "v*z", "f", "stdlib.h", ALL_GNU_LANGUAGES)
+LIBBUILTIN(alloca, "v*z", "f", STDLIB_H, ALL_GNU_LANGUAGES)
// POSIX malloc.h
-LIBBUILTIN(memalign, "v*zz", "f", "malloc.h", ALL_GNU_LANGUAGES)
+LIBBUILTIN(memalign, "v*zz", "f", MALLOC_H, ALL_GNU_LANGUAGES)
// POSIX string.h
-LIBBUILTIN(memccpy, "v*v*vC*iz", "f", "string.h", ALL_GNU_LANGUAGES)
-LIBBUILTIN(mempcpy, "v*v*vC*z", "f", "string.h", ALL_GNU_LANGUAGES)
-LIBBUILTIN(stpcpy, "c*c*cC*", "f", "string.h", ALL_GNU_LANGUAGES)
-LIBBUILTIN(stpncpy, "c*c*cC*z", "f", "string.h", ALL_GNU_LANGUAGES)
-LIBBUILTIN(strdup, "c*cC*", "f", "string.h", ALL_GNU_LANGUAGES)
-LIBBUILTIN(strndup, "c*cC*z", "f", "string.h", ALL_GNU_LANGUAGES)
+LIBBUILTIN(memccpy, "v*v*vC*iz", "f", STRING_H, ALL_GNU_LANGUAGES)
+LIBBUILTIN(mempcpy, "v*v*vC*z", "f", STRING_H, ALL_GNU_LANGUAGES)
+LIBBUILTIN(stpcpy, "c*c*cC*", "f", STRING_H, ALL_GNU_LANGUAGES)
+LIBBUILTIN(stpncpy, "c*c*cC*z", "f", STRING_H, ALL_GNU_LANGUAGES)
+LIBBUILTIN(strdup, "c*cC*", "f", STRING_H, ALL_GNU_LANGUAGES)
+LIBBUILTIN(strndup, "c*cC*z", "f", STRING_H, ALL_GNU_LANGUAGES)
// POSIX strings.h
-LIBBUILTIN(index, "c*cC*i", "f", "strings.h", ALL_GNU_LANGUAGES)
-LIBBUILTIN(rindex, "c*cC*i", "f", "strings.h", ALL_GNU_LANGUAGES)
-LIBBUILTIN(bzero, "vv*z", "f", "strings.h", ALL_GNU_LANGUAGES)
-LIBBUILTIN(bcmp, "ivC*vC*z", "f", "strings.h", ALL_GNU_LANGUAGES)
+LIBBUILTIN(index, "c*cC*i", "f", STRINGS_H, ALL_GNU_LANGUAGES)
+LIBBUILTIN(rindex, "c*cC*i", "f", STRINGS_H, ALL_GNU_LANGUAGES)
+LIBBUILTIN(bzero, "vv*z", "f", STRINGS_H, ALL_GNU_LANGUAGES)
+LIBBUILTIN(bcopy, "vvC*v*z", "f", STRINGS_H, ALL_GNU_LANGUAGES)
+LIBBUILTIN(bcmp, "ivC*vC*z", "fE", STRINGS_H, ALL_GNU_LANGUAGES)
// In some systems str[n]casejmp is a macro that expands to _str[n]icmp.
// We undefine then here to avoid wrong name.
#undef strcasecmp
#undef strncasecmp
-LIBBUILTIN(strcasecmp, "icC*cC*", "f", "strings.h", ALL_GNU_LANGUAGES)
-LIBBUILTIN(strncasecmp, "icC*cC*z", "f", "strings.h", ALL_GNU_LANGUAGES)
+LIBBUILTIN(strcasecmp, "icC*cC*", "f", STRINGS_H, ALL_GNU_LANGUAGES)
+LIBBUILTIN(strncasecmp, "icC*cC*z", "f", STRINGS_H, ALL_GNU_LANGUAGES)
// POSIX unistd.h
-LIBBUILTIN(_exit, "vi", "fr", "unistd.h", ALL_GNU_LANGUAGES)
-LIBBUILTIN(vfork, "p", "fjT", "unistd.h", ALL_LANGUAGES)
+LIBBUILTIN(_exit, "vi", "fr", UNISTD_H, ALL_GNU_LANGUAGES)
+LIBBUILTIN(vfork, "p", "fjT", UNISTD_H, ALL_LANGUAGES)
// POSIX pthread.h
// FIXME: Should specify argument types.
-LIBBUILTIN(pthread_create, "", "fC<2,3>", "pthread.h", ALL_GNU_LANGUAGES)
+LIBBUILTIN(pthread_create, "", "fC<2,3>", PTHREAD_H, ALL_GNU_LANGUAGES)
// POSIX setjmp.h
// FIXME: MinGW _setjmp has an additional void* parameter.
-LIBBUILTIN(_setjmp, "iJ", "fjT", "setjmp.h", ALL_LANGUAGES)
-LIBBUILTIN(__sigsetjmp, "iSJi", "fjT", "setjmp.h", ALL_LANGUAGES)
-LIBBUILTIN(sigsetjmp, "iSJi", "fjT", "setjmp.h", ALL_LANGUAGES)
-LIBBUILTIN(savectx, "iJ", "fjT", "setjmp.h", ALL_LANGUAGES)
-LIBBUILTIN(getcontext, "iK*", "fjT", "setjmp.h", ALL_LANGUAGES)
-
-LIBBUILTIN(_longjmp, "vJi", "frT", "setjmp.h", ALL_GNU_LANGUAGES)
-LIBBUILTIN(siglongjmp, "vSJi", "frT", "setjmp.h", ALL_GNU_LANGUAGES)
+LIBBUILTIN(_setjmp, "iJ", "fjT", SETJMP_H, ALL_LANGUAGES)
+LIBBUILTIN(__sigsetjmp, "iSJi", "fjT", SETJMP_H, ALL_LANGUAGES)
+LIBBUILTIN(sigsetjmp, "iSJi", "fjT", SETJMP_H, ALL_LANGUAGES)
+LIBBUILTIN(savectx, "iJ", "fjT", SETJMP_H, ALL_LANGUAGES)
+LIBBUILTIN(getcontext, "iK*", "fjT", SETJMP_H, ALL_LANGUAGES)
+
+LIBBUILTIN(_longjmp, "vJi", "frT", SETJMP_H, ALL_GNU_LANGUAGES)
+LIBBUILTIN(siglongjmp, "vSJi", "frT", SETJMP_H, ALL_GNU_LANGUAGES)
// non-standard but very common
-LIBBUILTIN(strlcpy, "zc*cC*z", "f", "string.h", ALL_GNU_LANGUAGES)
-LIBBUILTIN(strlcat, "zc*cC*z", "f", "string.h", ALL_GNU_LANGUAGES)
+LIBBUILTIN(strlcpy, "zc*cC*z", "f", STRING_H, ALL_GNU_LANGUAGES)
+LIBBUILTIN(strlcat, "zc*cC*z", "f", STRING_H, ALL_GNU_LANGUAGES)
// id objc_msgSend(id, SEL, ...)
-LIBBUILTIN(objc_msgSend, "GGH.", "f", "objc/message.h", OBJC_LANG)
+LIBBUILTIN(objc_msgSend, "GGH.", "f", OBJC_MESSAGE_H, OBJC_LANG)
// long double objc_msgSend_fpret(id self, SEL op, ...)
-LIBBUILTIN(objc_msgSend_fpret, "LdGH.", "f", "objc/message.h", OBJC_LANG)
+LIBBUILTIN(objc_msgSend_fpret, "LdGH.", "f", OBJC_MESSAGE_H, OBJC_LANG)
// _Complex long double objc_msgSend_fp2ret(id self, SEL op, ...)
-LIBBUILTIN(objc_msgSend_fp2ret, "XLdGH.", "f", "objc/message.h", OBJC_LANG)
+LIBBUILTIN(objc_msgSend_fp2ret, "XLdGH.", "f", OBJC_MESSAGE_H, OBJC_LANG)
// void objc_msgSend_stret (id, SEL, ...)
-LIBBUILTIN(objc_msgSend_stret, "vGH.", "f", "objc/message.h", OBJC_LANG)
+LIBBUILTIN(objc_msgSend_stret, "vGH.", "f", OBJC_MESSAGE_H, OBJC_LANG)
// id objc_msgSendSuper(struct objc_super *super, SEL op, ...)
-LIBBUILTIN(objc_msgSendSuper, "GM*H.", "f", "objc/message.h", OBJC_LANG)
+LIBBUILTIN(objc_msgSendSuper, "GM*H.", "f", OBJC_MESSAGE_H, OBJC_LANG)
// void objc_msgSendSuper_stret(struct objc_super *super, SEL op, ...)
-LIBBUILTIN(objc_msgSendSuper_stret, "vM*H.", "f", "objc/message.h", OBJC_LANG)
+LIBBUILTIN(objc_msgSendSuper_stret, "vM*H.", "f", OBJC_MESSAGE_H, OBJC_LANG)
// id objc_getClass(const char *name)
-LIBBUILTIN(objc_getClass, "GcC*", "f", "objc/runtime.h", OBJC_LANG)
+LIBBUILTIN(objc_getClass, "GcC*", "f", OBJC_RUNTIME_H, OBJC_LANG)
// id objc_getMetaClass(const char *name)
-LIBBUILTIN(objc_getMetaClass, "GcC*", "f", "objc/runtime.h", OBJC_LANG)
+LIBBUILTIN(objc_getMetaClass, "GcC*", "f", OBJC_RUNTIME_H, OBJC_LANG)
// void objc_enumerationMutation(id)
-LIBBUILTIN(objc_enumerationMutation, "vG", "f", "objc/runtime.h", OBJC_LANG)
+LIBBUILTIN(objc_enumerationMutation, "vG", "f", OBJC_RUNTIME_H, OBJC_LANG)
// id objc_read_weak(id *location)
-LIBBUILTIN(objc_read_weak, "GG*", "f", "objc/objc-auto.h", OBJC_LANG)
+LIBBUILTIN(objc_read_weak, "GG*", "f", OBJC_OBJC_AUTO_H, OBJC_LANG)
// id objc_assign_weak(id value, id *location)
-LIBBUILTIN(objc_assign_weak, "GGG*", "f", "objc/objc-auto.h", OBJC_LANG)
+LIBBUILTIN(objc_assign_weak, "GGG*", "f", OBJC_OBJC_AUTO_H, OBJC_LANG)
// id objc_assign_ivar(id value, id dest, ptrdiff_t offset)
-LIBBUILTIN(objc_assign_ivar, "GGGY", "f", "objc/objc-auto.h", OBJC_LANG)
+LIBBUILTIN(objc_assign_ivar, "GGGY", "f", OBJC_OBJC_AUTO_H, OBJC_LANG)
// id objc_assign_global(id val, id *dest)
-LIBBUILTIN(objc_assign_global, "GGG*", "f", "objc/objc-auto.h", OBJC_LANG)
+LIBBUILTIN(objc_assign_global, "GGG*", "f", OBJC_OBJC_AUTO_H, OBJC_LANG)
// id objc_assign_strongCast(id val, id *dest
-LIBBUILTIN(objc_assign_strongCast, "GGG*", "f", "objc/objc-auto.h", OBJC_LANG)
+LIBBUILTIN(objc_assign_strongCast, "GGG*", "f", OBJC_OBJC_AUTO_H, OBJC_LANG)
// id objc_exception_extract(void *localExceptionData)
-LIBBUILTIN(objc_exception_extract, "Gv*", "f", "objc/objc-exception.h", OBJC_LANG)
+LIBBUILTIN(objc_exception_extract, "Gv*", "f", OBJC_OBJC_EXCEPTION_H, OBJC_LANG)
// void objc_exception_try_enter(void *localExceptionData)
-LIBBUILTIN(objc_exception_try_enter, "vv*", "f", "objc/objc-exception.h", OBJC_LANG)
+LIBBUILTIN(objc_exception_try_enter, "vv*", "f", OBJC_OBJC_EXCEPTION_H, OBJC_LANG)
// void objc_exception_try_exit(void *localExceptionData)
-LIBBUILTIN(objc_exception_try_exit, "vv*", "f", "objc/objc-exception.h", OBJC_LANG)
+LIBBUILTIN(objc_exception_try_exit, "vv*", "f", OBJC_OBJC_EXCEPTION_H, OBJC_LANG)
// int objc_exception_match(Class exceptionClass, id exception)
-LIBBUILTIN(objc_exception_match, "iGG", "f", "objc/objc-exception.h", OBJC_LANG)
+LIBBUILTIN(objc_exception_match, "iGG", "f", OBJC_OBJC_EXCEPTION_H, OBJC_LANG)
// void objc_exception_throw(id exception)
-LIBBUILTIN(objc_exception_throw, "vG", "f", "objc/objc-exception.h", OBJC_LANG)
+LIBBUILTIN(objc_exception_throw, "vG", "f", OBJC_OBJC_EXCEPTION_H, OBJC_LANG)
// int objc_sync_enter(id obj)
-LIBBUILTIN(objc_sync_enter, "iG", "f", "objc/objc-sync.h", OBJC_LANG)
+LIBBUILTIN(objc_sync_enter, "iG", "f", OBJC_OBJC_SYNC_H, OBJC_LANG)
// int objc_sync_exit(id obj)
-LIBBUILTIN(objc_sync_exit, "iG", "f", "objc/objc-sync.h", OBJC_LANG)
+LIBBUILTIN(objc_sync_exit, "iG", "f", OBJC_OBJC_SYNC_H, OBJC_LANG)
BUILTIN(__builtin_objc_memmove_collectable, "v*v*vC*z", "nF")
// void NSLog(NSString *fmt, ...)
-LIBBUILTIN(NSLog, "vG.", "fp:0:", "Foundation/NSObjCRuntime.h", OBJC_LANG)
+LIBBUILTIN(NSLog, "vG.", "fp:0:", FOUNDATION_NSOBJCRUNTIME_H, OBJC_LANG)
// void NSLogv(NSString *fmt, va_list args)
-LIBBUILTIN(NSLogv, "vGa", "fP:0:", "Foundation/NSObjCRuntime.h", OBJC_LANG)
+LIBBUILTIN(NSLogv, "vGa", "fP:0:", FOUNDATION_NSOBJCRUNTIME_H, OBJC_LANG)
// Builtin math library functions
-LIBBUILTIN(atan2, "ddd", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(atan2f, "fff", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(atan2l, "LdLdLd", "fne", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(atan2, "ddd", "fne", MATH_H, ALL_LANGUAGES)
+LIBBUILTIN(atan2f, "fff", "fne", MATH_H, ALL_LANGUAGES)
+LIBBUILTIN(atan2l, "LdLdLd", "fne", MATH_H, ALL_LANGUAGES)
-LIBBUILTIN(abs, "ii", "fnc", "stdlib.h", ALL_LANGUAGES)
-LIBBUILTIN(labs, "LiLi", "fnc", "stdlib.h", ALL_LANGUAGES)
-LIBBUILTIN(llabs, "LLiLLi", "fnc", "stdlib.h", ALL_LANGUAGES)
+LIBBUILTIN(abs, "ii", "fnc", STDLIB_H, ALL_LANGUAGES)
+LIBBUILTIN(labs, "LiLi", "fnc", STDLIB_H, ALL_LANGUAGES)
+LIBBUILTIN(llabs, "LLiLLi", "fnc", STDLIB_H, ALL_LANGUAGES)
-LIBBUILTIN(copysign, "ddd", "fnc", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(copysignf, "fff", "fnc", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(copysignl, "LdLdLd", "fnc", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(copysign, "ddd", "fnc", MATH_H, ALL_LANGUAGES)
+LIBBUILTIN(copysignf, "fff", "fnc", MATH_H, ALL_LANGUAGES)
+LIBBUILTIN(copysignl, "LdLdLd", "fnc", MATH_H, ALL_LANGUAGES)
-LIBBUILTIN(fabs, "dd", "fnc", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(fabsf, "ff", "fnc", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(fabsl, "LdLd", "fnc", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(fabs, "dd", "fnc", MATH_H, ALL_LANGUAGES)
+LIBBUILTIN(fabsf, "ff", "fnc", MATH_H, ALL_LANGUAGES)
+LIBBUILTIN(fabsl, "LdLd", "fnc", MATH_H, ALL_LANGUAGES)
// Some systems define finitef as alias of _finitef.
#if defined (finitef)
#undef finitef
#endif
-LIBBUILTIN(finite, "id", "fnc", "math.h", GNU_LANG)
-LIBBUILTIN(finitef, "if", "fnc", "math.h", GNU_LANG)
-LIBBUILTIN(finitel, "iLd", "fnc", "math.h", GNU_LANG)
+LIBBUILTIN(finite, "id", "fnc", MATH_H, GNU_LANG)
+LIBBUILTIN(finitef, "if", "fnc", MATH_H, GNU_LANG)
+LIBBUILTIN(finitel, "iLd", "fnc", MATH_H, GNU_LANG)
// glibc's math.h generates calls to __finite
-LIBBUILTIN(__finite, "id", "fnc", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(__finitef, "if", "fnc", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(__finitel, "iLd", "fnc", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(__finite, "id", "fnc", MATH_H, ALL_LANGUAGES)
+LIBBUILTIN(__finitef, "if", "fnc", MATH_H, ALL_LANGUAGES)
+LIBBUILTIN(__finitel, "iLd", "fnc", MATH_H, ALL_LANGUAGES)
-LIBBUILTIN(fmod, "ddd", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(fmodf, "fff", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(fmodl, "LdLdLd", "fne", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(fmod, "ddd", "fne", MATH_H, ALL_LANGUAGES)
+LIBBUILTIN(fmodf, "fff", "fne", MATH_H, ALL_LANGUAGES)
+LIBBUILTIN(fmodl, "LdLdLd", "fne", MATH_H, ALL_LANGUAGES)
-LIBBUILTIN(frexp, "ddi*", "fn", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(frexpf, "ffi*", "fn", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(frexpl, "LdLdi*", "fn", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(frexp, "ddi*", "fn", MATH_H, ALL_LANGUAGES)
+LIBBUILTIN(frexpf, "ffi*", "fn", MATH_H, ALL_LANGUAGES)
+LIBBUILTIN(frexpl, "LdLdi*", "fn", MATH_H, ALL_LANGUAGES)
-LIBBUILTIN(ldexp, "ddi", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(ldexpf, "ffi", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(ldexpl, "LdLdi", "fne", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(ldexp, "ddi", "fne", MATH_H, ALL_LANGUAGES)
+LIBBUILTIN(ldexpf, "ffi", "fne", MATH_H, ALL_LANGUAGES)
+LIBBUILTIN(ldexpl, "LdLdi", "fne", MATH_H, ALL_LANGUAGES)
-LIBBUILTIN(modf, "ddd*", "fn", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(modff, "fff*", "fn", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(modfl, "LdLdLd*", "fn", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(modf, "ddd*", "fn", MATH_H, ALL_LANGUAGES)
+LIBBUILTIN(modff, "fff*", "fn", MATH_H, ALL_LANGUAGES)
+LIBBUILTIN(modfl, "LdLdLd*", "fn", MATH_H, ALL_LANGUAGES)
-LIBBUILTIN(nan, "dcC*", "fUn", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(nanf, "fcC*", "fUn", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(nanl, "LdcC*", "fUn", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(nan, "dcC*", "fUn", MATH_H, ALL_LANGUAGES)
+LIBBUILTIN(nanf, "fcC*", "fUn", MATH_H, ALL_LANGUAGES)
+LIBBUILTIN(nanl, "LdcC*", "fUn", MATH_H, ALL_LANGUAGES)
-LIBBUILTIN(pow, "ddd", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(powf, "fff", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(powl, "LdLdLd", "fne", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(pow, "ddd", "fne", MATH_H, ALL_LANGUAGES)
+LIBBUILTIN(powf, "fff", "fne", MATH_H, ALL_LANGUAGES)
+LIBBUILTIN(powl, "LdLdLd", "fne", MATH_H, ALL_LANGUAGES)
-LIBBUILTIN(acos, "dd", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(acosf, "ff", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(acosl, "LdLd", "fne", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(acos, "dd", "fne", MATH_H, ALL_LANGUAGES)
+LIBBUILTIN(acosf, "ff", "fne", MATH_H, ALL_LANGUAGES)
+LIBBUILTIN(acosl, "LdLd", "fne", MATH_H, ALL_LANGUAGES)
-LIBBUILTIN(acosh, "dd", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(acoshf, "ff", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(acoshl, "LdLd", "fne", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(acosh, "dd", "fne", MATH_H, ALL_LANGUAGES)
+LIBBUILTIN(acoshf, "ff", "fne", MATH_H, ALL_LANGUAGES)
+LIBBUILTIN(acoshl, "LdLd", "fne", MATH_H, ALL_LANGUAGES)
-LIBBUILTIN(asin, "dd", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(asinf, "ff", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(asinl, "LdLd", "fne", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(asin, "dd", "fne", MATH_H, ALL_LANGUAGES)
+LIBBUILTIN(asinf, "ff", "fne", MATH_H, ALL_LANGUAGES)
+LIBBUILTIN(asinl, "LdLd", "fne", MATH_H, ALL_LANGUAGES)
-LIBBUILTIN(asinh, "dd", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(asinhf, "ff", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(asinhl, "LdLd", "fne", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(asinh, "dd", "fne", MATH_H, ALL_LANGUAGES)
+LIBBUILTIN(asinhf, "ff", "fne", MATH_H, ALL_LANGUAGES)
+LIBBUILTIN(asinhl, "LdLd", "fne", MATH_H, ALL_LANGUAGES)
-LIBBUILTIN(atan, "dd", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(atanf, "ff", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(atanl, "LdLd", "fne", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(atan, "dd", "fne", MATH_H, ALL_LANGUAGES)
+LIBBUILTIN(atanf, "ff", "fne", MATH_H, ALL_LANGUAGES)
+LIBBUILTIN(atanl, "LdLd", "fne", MATH_H, ALL_LANGUAGES)
-LIBBUILTIN(atanh, "dd", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(atanhf, "ff", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(atanhl, "LdLd", "fne", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(atanh, "dd", "fne", MATH_H, ALL_LANGUAGES)
+LIBBUILTIN(atanhf, "ff", "fne", MATH_H, ALL_LANGUAGES)
+LIBBUILTIN(atanhl, "LdLd", "fne", MATH_H, ALL_LANGUAGES)
-LIBBUILTIN(cbrt, "dd", "fnc", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(cbrtf, "ff", "fnc", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(cbrtl, "LdLd", "fnc", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(cbrt, "dd", "fnc", MATH_H, ALL_LANGUAGES)
+LIBBUILTIN(cbrtf, "ff", "fnc", MATH_H, ALL_LANGUAGES)
+LIBBUILTIN(cbrtl, "LdLd", "fnc", MATH_H, ALL_LANGUAGES)
-LIBBUILTIN(ceil, "dd", "fnc", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(ceilf, "ff", "fnc", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(ceill, "LdLd", "fnc", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(ceil, "dd", "fnc", MATH_H, ALL_LANGUAGES)
+LIBBUILTIN(ceilf, "ff", "fnc", MATH_H, ALL_LANGUAGES)
+LIBBUILTIN(ceill, "LdLd", "fnc", MATH_H, ALL_LANGUAGES)
-LIBBUILTIN(cos, "dd", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(cosf, "ff", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(cosl, "LdLd", "fne", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(cos, "dd", "fne", MATH_H, ALL_LANGUAGES)
+LIBBUILTIN(cosf, "ff", "fne", MATH_H, ALL_LANGUAGES)
+LIBBUILTIN(cosl, "LdLd", "fne", MATH_H, ALL_LANGUAGES)
-LIBBUILTIN(cosh, "dd", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(coshf, "ff", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(coshl, "LdLd", "fne", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(cosh, "dd", "fne", MATH_H, ALL_LANGUAGES)
+LIBBUILTIN(coshf, "ff", "fne", MATH_H, ALL_LANGUAGES)
+LIBBUILTIN(coshl, "LdLd", "fne", MATH_H, ALL_LANGUAGES)
-LIBBUILTIN(erf, "dd", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(erff, "ff", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(erfl, "LdLd", "fne", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(erf, "dd", "fne", MATH_H, ALL_LANGUAGES)
+LIBBUILTIN(erff, "ff", "fne", MATH_H, ALL_LANGUAGES)
+LIBBUILTIN(erfl, "LdLd", "fne", MATH_H, ALL_LANGUAGES)
-LIBBUILTIN(erfc, "dd", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(erfcf, "ff", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(erfcl, "LdLd", "fne", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(erfc, "dd", "fne", MATH_H, ALL_LANGUAGES)
+LIBBUILTIN(erfcf, "ff", "fne", MATH_H, ALL_LANGUAGES)
+LIBBUILTIN(erfcl, "LdLd", "fne", MATH_H, ALL_LANGUAGES)
-LIBBUILTIN(exp, "dd", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(expf, "ff", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(expl, "LdLd", "fne", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(exp, "dd", "fne", MATH_H, ALL_LANGUAGES)
+LIBBUILTIN(expf, "ff", "fne", MATH_H, ALL_LANGUAGES)
+LIBBUILTIN(expl, "LdLd", "fne", MATH_H, ALL_LANGUAGES)
-LIBBUILTIN(exp2, "dd", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(exp2f, "ff", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(exp2l, "LdLd", "fne", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(exp2, "dd", "fne", MATH_H, ALL_LANGUAGES)
+LIBBUILTIN(exp2f, "ff", "fne", MATH_H, ALL_LANGUAGES)
+LIBBUILTIN(exp2l, "LdLd", "fne", MATH_H, ALL_LANGUAGES)
-LIBBUILTIN(expm1, "dd", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(expm1f, "ff", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(expm1l, "LdLd", "fne", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(expm1, "dd", "fne", MATH_H, ALL_LANGUAGES)
+LIBBUILTIN(expm1f, "ff", "fne", MATH_H, ALL_LANGUAGES)
+LIBBUILTIN(expm1l, "LdLd", "fne", MATH_H, ALL_LANGUAGES)
-LIBBUILTIN(fdim, "ddd", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(fdimf, "fff", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(fdiml, "LdLdLd", "fne", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(fdim, "ddd", "fne", MATH_H, ALL_LANGUAGES)
+LIBBUILTIN(fdimf, "fff", "fne", MATH_H, ALL_LANGUAGES)
+LIBBUILTIN(fdiml, "LdLdLd", "fne", MATH_H, ALL_LANGUAGES)
-LIBBUILTIN(floor, "dd", "fnc", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(floorf, "ff", "fnc", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(floorl, "LdLd", "fnc", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(floor, "dd", "fnc", MATH_H, ALL_LANGUAGES)
+LIBBUILTIN(floorf, "ff", "fnc", MATH_H, ALL_LANGUAGES)
+LIBBUILTIN(floorl, "LdLd", "fnc", MATH_H, ALL_LANGUAGES)
-LIBBUILTIN(fma, "dddd", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(fmaf, "ffff", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(fmal, "LdLdLdLd", "fne", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(fma, "dddd", "fne", MATH_H, ALL_LANGUAGES)
+LIBBUILTIN(fmaf, "ffff", "fne", MATH_H, ALL_LANGUAGES)
+LIBBUILTIN(fmal, "LdLdLdLd", "fne", MATH_H, ALL_LANGUAGES)
-LIBBUILTIN(fmax, "ddd", "fnc", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(fmaxf, "fff", "fnc", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(fmaxl, "LdLdLd", "fnc", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(fmax, "ddd", "fnc", MATH_H, ALL_LANGUAGES)
+LIBBUILTIN(fmaxf, "fff", "fnc", MATH_H, ALL_LANGUAGES)
+LIBBUILTIN(fmaxl, "LdLdLd", "fnc", MATH_H, ALL_LANGUAGES)
-LIBBUILTIN(fmin, "ddd", "fnc", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(fminf, "fff", "fnc", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(fminl, "LdLdLd", "fnc", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(fmin, "ddd", "fnc", MATH_H, ALL_LANGUAGES)
+LIBBUILTIN(fminf, "fff", "fnc", MATH_H, ALL_LANGUAGES)
+LIBBUILTIN(fminl, "LdLdLd", "fnc", MATH_H, ALL_LANGUAGES)
-LIBBUILTIN(hypot, "ddd", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(hypotf, "fff", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(hypotl, "LdLdLd", "fne", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(hypot, "ddd", "fne", MATH_H, ALL_LANGUAGES)
+LIBBUILTIN(hypotf, "fff", "fne", MATH_H, ALL_LANGUAGES)
+LIBBUILTIN(hypotl, "LdLdLd", "fne", MATH_H, ALL_LANGUAGES)
-LIBBUILTIN(ilogb, "id", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(ilogbf, "if", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(ilogbl, "iLd", "fne", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(ilogb, "id", "fne", MATH_H, ALL_LANGUAGES)
+LIBBUILTIN(ilogbf, "if", "fne", MATH_H, ALL_LANGUAGES)
+LIBBUILTIN(ilogbl, "iLd", "fne", MATH_H, ALL_LANGUAGES)
// POSIX math.h declares a global, signgam, that lgamma writes to, so these
-// shouldn't have "e" or "c" attributes
-LIBBUILTIN(lgamma, "dd", "fn", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(lgammaf, "ff", "fn", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(lgammal, "LdLd", "fn", "math.h", ALL_LANGUAGES)
+// shouldn't have "e", "c" or "g" attributes
+LIBBUILTIN(lgamma, "dd", "fn", MATH_H, ALL_LANGUAGES)
+LIBBUILTIN(lgammaf, "ff", "fn", MATH_H, ALL_LANGUAGES)
+LIBBUILTIN(lgammal, "LdLd", "fn", MATH_H, ALL_LANGUAGES)
+
+LIBBUILTIN(llrint, "LLid", "fne", MATH_H, ALL_LANGUAGES)
+LIBBUILTIN(llrintf, "LLif", "fne", MATH_H, ALL_LANGUAGES)
+LIBBUILTIN(llrintl, "LLiLd", "fne", MATH_H, ALL_LANGUAGES)
-LIBBUILTIN(llrint, "LLid", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(llrintf, "LLif", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(llrintl, "LLiLd", "fne", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(llround, "LLid", "fne", MATH_H, ALL_LANGUAGES)
+LIBBUILTIN(llroundf, "LLif", "fne", MATH_H, ALL_LANGUAGES)
+LIBBUILTIN(llroundl, "LLiLd", "fne", MATH_H, ALL_LANGUAGES)
-LIBBUILTIN(llround, "LLid", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(llroundf, "LLif", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(llroundl, "LLiLd", "fne", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(log, "dd", "fne", MATH_H, ALL_LANGUAGES)
+LIBBUILTIN(logf, "ff", "fne", MATH_H, ALL_LANGUAGES)
+LIBBUILTIN(logl, "LdLd", "fne", MATH_H, ALL_LANGUAGES)
-LIBBUILTIN(log, "dd", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(logf, "ff", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(logl, "LdLd", "fne", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(log10, "dd", "fne", MATH_H, ALL_LANGUAGES)
+LIBBUILTIN(log10f, "ff", "fne", MATH_H, ALL_LANGUAGES)
+LIBBUILTIN(log10l, "LdLd", "fne", MATH_H, ALL_LANGUAGES)
-LIBBUILTIN(log10, "dd", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(log10f, "ff", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(log10l, "LdLd", "fne", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(log1p, "dd", "fne", MATH_H, ALL_LANGUAGES)
+LIBBUILTIN(log1pf, "ff", "fne", MATH_H, ALL_LANGUAGES)
+LIBBUILTIN(log1pl, "LdLd", "fne", MATH_H, ALL_LANGUAGES)
-LIBBUILTIN(log1p, "dd", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(log1pf, "ff", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(log1pl, "LdLd", "fne", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(log2, "dd", "fne", MATH_H, ALL_LANGUAGES)
+LIBBUILTIN(log2f, "ff", "fne", MATH_H, ALL_LANGUAGES)
+LIBBUILTIN(log2l, "LdLd", "fne", MATH_H, ALL_LANGUAGES)
-LIBBUILTIN(log2, "dd", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(log2f, "ff", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(log2l, "LdLd", "fne", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(logb, "dd", "fne", MATH_H, ALL_LANGUAGES)
+LIBBUILTIN(logbf, "ff", "fne", MATH_H, ALL_LANGUAGES)
+LIBBUILTIN(logbl, "LdLd", "fne", MATH_H, ALL_LANGUAGES)
-LIBBUILTIN(logb, "dd", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(logbf, "ff", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(logbl, "LdLd", "fne", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(lrint, "Lid", "fne", MATH_H, ALL_LANGUAGES)
+LIBBUILTIN(lrintf, "Lif", "fne", MATH_H, ALL_LANGUAGES)
+LIBBUILTIN(lrintl, "LiLd", "fne", MATH_H, ALL_LANGUAGES)
-LIBBUILTIN(lrint, "Lid", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(lrintf, "Lif", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(lrintl, "LiLd", "fne", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(lround, "Lid", "fne", MATH_H, ALL_LANGUAGES)
+LIBBUILTIN(lroundf, "Lif", "fne", MATH_H, ALL_LANGUAGES)
+LIBBUILTIN(lroundl, "LiLd", "fne", MATH_H, ALL_LANGUAGES)
-LIBBUILTIN(lround, "Lid", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(lroundf, "Lif", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(lroundl, "LiLd", "fne", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(nearbyint, "dd", "fnc", MATH_H, ALL_LANGUAGES)
+LIBBUILTIN(nearbyintf, "ff", "fnc", MATH_H, ALL_LANGUAGES)
+LIBBUILTIN(nearbyintl, "LdLd", "fnc", MATH_H, ALL_LANGUAGES)
-LIBBUILTIN(nearbyint, "dd", "fnc", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(nearbyintf, "ff", "fnc", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(nearbyintl, "LdLd", "fnc", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(nextafter, "ddd", "fne", MATH_H, ALL_LANGUAGES)
+LIBBUILTIN(nextafterf, "fff", "fne", MATH_H, ALL_LANGUAGES)
+LIBBUILTIN(nextafterl, "LdLdLd", "fne", MATH_H, ALL_LANGUAGES)
-LIBBUILTIN(nextafter, "ddd", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(nextafterf, "fff", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(nextafterl, "LdLdLd", "fne", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(nexttoward, "ddLd", "fne", MATH_H, ALL_LANGUAGES)
+LIBBUILTIN(nexttowardf, "ffLd", "fne", MATH_H, ALL_LANGUAGES)
+LIBBUILTIN(nexttowardl, "LdLdLd", "fne", MATH_H, ALL_LANGUAGES)
-LIBBUILTIN(nexttoward, "ddLd", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(nexttowardf, "ffLd", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(nexttowardl, "LdLdLd", "fne", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(remainder, "ddd", "fne", MATH_H, ALL_LANGUAGES)
+LIBBUILTIN(remainderf, "fff", "fne", MATH_H, ALL_LANGUAGES)
+LIBBUILTIN(remainderl, "LdLdLd", "fne", MATH_H, ALL_LANGUAGES)
-LIBBUILTIN(remainder, "ddd", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(remainderf, "fff", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(remainderl, "LdLdLd", "fne", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(remquo, "dddi*", "fn", MATH_H, ALL_LANGUAGES)
+LIBBUILTIN(remquof, "fffi*", "fn", MATH_H, ALL_LANGUAGES)
+LIBBUILTIN(remquol, "LdLdLdi*", "fn", MATH_H, ALL_LANGUAGES)
-LIBBUILTIN(remquo, "dddi*", "fn", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(remquof, "fffi*", "fn", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(remquol, "LdLdLdi*", "fn", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(rint, "dd", "fng", MATH_H, ALL_LANGUAGES)
+LIBBUILTIN(rintf, "ff", "fng", MATH_H, ALL_LANGUAGES)
+LIBBUILTIN(rintl, "LdLd", "fng", MATH_H, ALL_LANGUAGES)
-LIBBUILTIN(rint, "dd", "fnc", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(rintf, "ff", "fnc", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(rintl, "LdLd", "fnc", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(round, "dd", "fnc", MATH_H, ALL_LANGUAGES)
+LIBBUILTIN(roundf, "ff", "fnc", MATH_H, ALL_LANGUAGES)
+LIBBUILTIN(roundl, "LdLd", "fnc", MATH_H, ALL_LANGUAGES)
-LIBBUILTIN(round, "dd", "fnc", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(roundf, "ff", "fnc", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(roundl, "LdLd", "fnc", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(roundeven, "dd", "fnc", MATH_H, ALL_LANGUAGES)
+LIBBUILTIN(roundevenf, "ff", "fnc", MATH_H, ALL_LANGUAGES)
+LIBBUILTIN(roundevenl, "LdLd", "fnc", MATH_H, ALL_LANGUAGES)
-LIBBUILTIN(scalbln, "ddLi", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(scalblnf, "ffLi", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(scalblnl, "LdLdLi", "fne", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(scalbln, "ddLi", "fne", MATH_H, ALL_LANGUAGES)
+LIBBUILTIN(scalblnf, "ffLi", "fne", MATH_H, ALL_LANGUAGES)
+LIBBUILTIN(scalblnl, "LdLdLi", "fne", MATH_H, ALL_LANGUAGES)
-LIBBUILTIN(scalbn, "ddi", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(scalbnf, "ffi", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(scalbnl, "LdLdi", "fne", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(scalbn, "ddi", "fne", MATH_H, ALL_LANGUAGES)
+LIBBUILTIN(scalbnf, "ffi", "fne", MATH_H, ALL_LANGUAGES)
+LIBBUILTIN(scalbnl, "LdLdi", "fne", MATH_H, ALL_LANGUAGES)
-LIBBUILTIN(sin, "dd", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(sinf, "ff", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(sinl, "LdLd", "fne", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(sin, "dd", "fne", MATH_H, ALL_LANGUAGES)
+LIBBUILTIN(sinf, "ff", "fne", MATH_H, ALL_LANGUAGES)
+LIBBUILTIN(sinl, "LdLd", "fne", MATH_H, ALL_LANGUAGES)
-LIBBUILTIN(sinh, "dd", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(sinhf, "ff", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(sinhl, "LdLd", "fne", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(sinh, "dd", "fne", MATH_H, ALL_LANGUAGES)
+LIBBUILTIN(sinhf, "ff", "fne", MATH_H, ALL_LANGUAGES)
+LIBBUILTIN(sinhl, "LdLd", "fne", MATH_H, ALL_LANGUAGES)
-LIBBUILTIN(sqrt, "dd", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(sqrtf, "ff", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(sqrtl, "LdLd", "fne", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(sqrt, "dd", "fne", MATH_H, ALL_LANGUAGES)
+LIBBUILTIN(sqrtf, "ff", "fne", MATH_H, ALL_LANGUAGES)
+LIBBUILTIN(sqrtl, "LdLd", "fne", MATH_H, ALL_LANGUAGES)
-LIBBUILTIN(tan, "dd", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(tanf, "ff", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(tanl, "LdLd", "fne", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(tan, "dd", "fne", MATH_H, ALL_LANGUAGES)
+LIBBUILTIN(tanf, "ff", "fne", MATH_H, ALL_LANGUAGES)
+LIBBUILTIN(tanl, "LdLd", "fne", MATH_H, ALL_LANGUAGES)
-LIBBUILTIN(tanh, "dd", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(tanhf, "ff", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(tanhl, "LdLd", "fne", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(tanh, "dd", "fne", MATH_H, ALL_LANGUAGES)
+LIBBUILTIN(tanhf, "ff", "fne", MATH_H, ALL_LANGUAGES)
+LIBBUILTIN(tanhl, "LdLd", "fne", MATH_H, ALL_LANGUAGES)
-LIBBUILTIN(tgamma, "dd", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(tgammaf, "ff", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(tgammal, "LdLd", "fne", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(tgamma, "dd", "fne", MATH_H, ALL_LANGUAGES)
+LIBBUILTIN(tgammaf, "ff", "fne", MATH_H, ALL_LANGUAGES)
+LIBBUILTIN(tgammal, "LdLd", "fne", MATH_H, ALL_LANGUAGES)
-LIBBUILTIN(trunc, "dd", "fnc", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(truncf, "ff", "fnc", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(truncl, "LdLd", "fnc", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(trunc, "dd", "fnc", MATH_H, ALL_LANGUAGES)
+LIBBUILTIN(truncf, "ff", "fnc", MATH_H, ALL_LANGUAGES)
+LIBBUILTIN(truncl, "LdLd", "fnc", MATH_H, ALL_LANGUAGES)
-LIBBUILTIN(cabs, "dXd", "fne", "complex.h", ALL_LANGUAGES)
-LIBBUILTIN(cabsf, "fXf", "fne", "complex.h", ALL_LANGUAGES)
-LIBBUILTIN(cabsl, "LdXLd", "fne", "complex.h", ALL_LANGUAGES)
+LIBBUILTIN(cabs, "dXd", "fne", COMPLEX_H, ALL_LANGUAGES)
+LIBBUILTIN(cabsf, "fXf", "fne", COMPLEX_H, ALL_LANGUAGES)
+LIBBUILTIN(cabsl, "LdXLd", "fne", COMPLEX_H, ALL_LANGUAGES)
-LIBBUILTIN(cacos, "XdXd", "fne", "complex.h", ALL_LANGUAGES)
-LIBBUILTIN(cacosf, "XfXf", "fne", "complex.h", ALL_LANGUAGES)
-LIBBUILTIN(cacosl, "XLdXLd", "fne", "complex.h", ALL_LANGUAGES)
+LIBBUILTIN(cacos, "XdXd", "fne", COMPLEX_H, ALL_LANGUAGES)
+LIBBUILTIN(cacosf, "XfXf", "fne", COMPLEX_H, ALL_LANGUAGES)
+LIBBUILTIN(cacosl, "XLdXLd", "fne", COMPLEX_H, ALL_LANGUAGES)
-LIBBUILTIN(cacosh, "XdXd", "fne", "complex.h", ALL_LANGUAGES)
-LIBBUILTIN(cacoshf, "XfXf", "fne", "complex.h", ALL_LANGUAGES)
-LIBBUILTIN(cacoshl, "XLdXLd", "fne", "complex.h", ALL_LANGUAGES)
+LIBBUILTIN(cacosh, "XdXd", "fne", COMPLEX_H, ALL_LANGUAGES)
+LIBBUILTIN(cacoshf, "XfXf", "fne", COMPLEX_H, ALL_LANGUAGES)
+LIBBUILTIN(cacoshl, "XLdXLd", "fne", COMPLEX_H, ALL_LANGUAGES)
-LIBBUILTIN(carg, "dXd", "fne", "complex.h", ALL_LANGUAGES)
-LIBBUILTIN(cargf, "fXf", "fne", "complex.h", ALL_LANGUAGES)
-LIBBUILTIN(cargl, "LdXLd", "fne", "complex.h", ALL_LANGUAGES)
+LIBBUILTIN(carg, "dXd", "fne", COMPLEX_H, ALL_LANGUAGES)
+LIBBUILTIN(cargf, "fXf", "fne", COMPLEX_H, ALL_LANGUAGES)
+LIBBUILTIN(cargl, "LdXLd", "fne", COMPLEX_H, ALL_LANGUAGES)
-LIBBUILTIN(casin, "XdXd", "fne", "complex.h", ALL_LANGUAGES)
-LIBBUILTIN(casinf, "XfXf", "fne", "complex.h", ALL_LANGUAGES)
-LIBBUILTIN(casinl, "XLdXLd", "fne", "complex.h", ALL_LANGUAGES)
+LIBBUILTIN(casin, "XdXd", "fne", COMPLEX_H, ALL_LANGUAGES)
+LIBBUILTIN(casinf, "XfXf", "fne", COMPLEX_H, ALL_LANGUAGES)
+LIBBUILTIN(casinl, "XLdXLd", "fne", COMPLEX_H, ALL_LANGUAGES)
-LIBBUILTIN(casinh, "XdXd", "fne", "complex.h", ALL_LANGUAGES)
-LIBBUILTIN(casinhf, "XfXf", "fne", "complex.h", ALL_LANGUAGES)
-LIBBUILTIN(casinhl, "XLdXLd", "fne", "complex.h", ALL_LANGUAGES)
+LIBBUILTIN(casinh, "XdXd", "fne", COMPLEX_H, ALL_LANGUAGES)
+LIBBUILTIN(casinhf, "XfXf", "fne", COMPLEX_H, ALL_LANGUAGES)
+LIBBUILTIN(casinhl, "XLdXLd", "fne", COMPLEX_H, ALL_LANGUAGES)
-LIBBUILTIN(catan, "XdXd", "fne", "complex.h", ALL_LANGUAGES)
-LIBBUILTIN(catanf, "XfXf", "fne", "complex.h", ALL_LANGUAGES)
-LIBBUILTIN(catanl, "XLdXLd", "fne", "complex.h", ALL_LANGUAGES)
+LIBBUILTIN(catan, "XdXd", "fne", COMPLEX_H, ALL_LANGUAGES)
+LIBBUILTIN(catanf, "XfXf", "fne", COMPLEX_H, ALL_LANGUAGES)
+LIBBUILTIN(catanl, "XLdXLd", "fne", COMPLEX_H, ALL_LANGUAGES)
-LIBBUILTIN(catanh, "XdXd", "fne", "complex.h", ALL_LANGUAGES)
-LIBBUILTIN(catanhf, "XfXf", "fne", "complex.h", ALL_LANGUAGES)
-LIBBUILTIN(catanhl, "XLdXLd", "fne", "complex.h", ALL_LANGUAGES)
+LIBBUILTIN(catanh, "XdXd", "fne", COMPLEX_H, ALL_LANGUAGES)
+LIBBUILTIN(catanhf, "XfXf", "fne", COMPLEX_H, ALL_LANGUAGES)
+LIBBUILTIN(catanhl, "XLdXLd", "fne", COMPLEX_H, ALL_LANGUAGES)
-LIBBUILTIN(ccos, "XdXd", "fne", "complex.h", ALL_LANGUAGES)
-LIBBUILTIN(ccosf, "XfXf", "fne", "complex.h", ALL_LANGUAGES)
-LIBBUILTIN(ccosl, "XLdXLd", "fne", "complex.h", ALL_LANGUAGES)
+LIBBUILTIN(ccos, "XdXd", "fne", COMPLEX_H, ALL_LANGUAGES)
+LIBBUILTIN(ccosf, "XfXf", "fne", COMPLEX_H, ALL_LANGUAGES)
+LIBBUILTIN(ccosl, "XLdXLd", "fne", COMPLEX_H, ALL_LANGUAGES)
-LIBBUILTIN(ccosh, "XdXd", "fne", "complex.h", ALL_LANGUAGES)
-LIBBUILTIN(ccoshf, "XfXf", "fne", "complex.h", ALL_LANGUAGES)
-LIBBUILTIN(ccoshl, "XLdXLd", "fne", "complex.h", ALL_LANGUAGES)
+LIBBUILTIN(ccosh, "XdXd", "fne", COMPLEX_H, ALL_LANGUAGES)
+LIBBUILTIN(ccoshf, "XfXf", "fne", COMPLEX_H, ALL_LANGUAGES)
+LIBBUILTIN(ccoshl, "XLdXLd", "fne", COMPLEX_H, ALL_LANGUAGES)
-LIBBUILTIN(cexp, "XdXd", "fne", "complex.h", ALL_LANGUAGES)
-LIBBUILTIN(cexpf, "XfXf", "fne", "complex.h", ALL_LANGUAGES)
-LIBBUILTIN(cexpl, "XLdXLd", "fne", "complex.h", ALL_LANGUAGES)
+LIBBUILTIN(cexp, "XdXd", "fne", COMPLEX_H, ALL_LANGUAGES)
+LIBBUILTIN(cexpf, "XfXf", "fne", COMPLEX_H, ALL_LANGUAGES)
+LIBBUILTIN(cexpl, "XLdXLd", "fne", COMPLEX_H, ALL_LANGUAGES)
-LIBBUILTIN(cimag, "dXd", "fnc", "complex.h", ALL_LANGUAGES)
-LIBBUILTIN(cimagf, "fXf", "fnc", "complex.h", ALL_LANGUAGES)
-LIBBUILTIN(cimagl, "LdXLd", "fnc", "complex.h", ALL_LANGUAGES)
+LIBBUILTIN(cimag, "dXd", "fnc", COMPLEX_H, ALL_LANGUAGES)
+LIBBUILTIN(cimagf, "fXf", "fnc", COMPLEX_H, ALL_LANGUAGES)
+LIBBUILTIN(cimagl, "LdXLd", "fnc", COMPLEX_H, ALL_LANGUAGES)
-LIBBUILTIN(conj, "XdXd", "fnc", "complex.h", ALL_LANGUAGES)
-LIBBUILTIN(conjf, "XfXf", "fnc", "complex.h", ALL_LANGUAGES)
-LIBBUILTIN(conjl, "XLdXLd", "fnc", "complex.h", ALL_LANGUAGES)
+LIBBUILTIN(conj, "XdXd", "fnc", COMPLEX_H, ALL_LANGUAGES)
+LIBBUILTIN(conjf, "XfXf", "fnc", COMPLEX_H, ALL_LANGUAGES)
+LIBBUILTIN(conjl, "XLdXLd", "fnc", COMPLEX_H, ALL_LANGUAGES)
-LIBBUILTIN(clog, "XdXd", "fne", "complex.h", ALL_LANGUAGES)
-LIBBUILTIN(clogf, "XfXf", "fne", "complex.h", ALL_LANGUAGES)
-LIBBUILTIN(clogl, "XLdXLd", "fne", "complex.h", ALL_LANGUAGES)
+LIBBUILTIN(clog, "XdXd", "fne", COMPLEX_H, ALL_LANGUAGES)
+LIBBUILTIN(clogf, "XfXf", "fne", COMPLEX_H, ALL_LANGUAGES)
+LIBBUILTIN(clogl, "XLdXLd", "fne", COMPLEX_H, ALL_LANGUAGES)
-LIBBUILTIN(cproj, "XdXd", "fnc", "complex.h", ALL_LANGUAGES)
-LIBBUILTIN(cprojf, "XfXf", "fnc", "complex.h", ALL_LANGUAGES)
-LIBBUILTIN(cprojl, "XLdXLd", "fnc", "complex.h", ALL_LANGUAGES)
+LIBBUILTIN(cproj, "XdXd", "fnc", COMPLEX_H, ALL_LANGUAGES)
+LIBBUILTIN(cprojf, "XfXf", "fnc", COMPLEX_H, ALL_LANGUAGES)
+LIBBUILTIN(cprojl, "XLdXLd", "fnc", COMPLEX_H, ALL_LANGUAGES)
-LIBBUILTIN(cpow, "XdXdXd", "fne", "complex.h", ALL_LANGUAGES)
-LIBBUILTIN(cpowf, "XfXfXf", "fne", "complex.h", ALL_LANGUAGES)
-LIBBUILTIN(cpowl, "XLdXLdXLd", "fne", "complex.h", ALL_LANGUAGES)
+LIBBUILTIN(cpow, "XdXdXd", "fne", COMPLEX_H, ALL_LANGUAGES)
+LIBBUILTIN(cpowf, "XfXfXf", "fne", COMPLEX_H, ALL_LANGUAGES)
+LIBBUILTIN(cpowl, "XLdXLdXLd", "fne", COMPLEX_H, ALL_LANGUAGES)
-LIBBUILTIN(creal, "dXd", "fnc", "complex.h", ALL_LANGUAGES)
-LIBBUILTIN(crealf, "fXf", "fnc", "complex.h", ALL_LANGUAGES)
-LIBBUILTIN(creall, "LdXLd", "fnc", "complex.h", ALL_LANGUAGES)
+LIBBUILTIN(creal, "dXd", "fnc", COMPLEX_H, ALL_LANGUAGES)
+LIBBUILTIN(crealf, "fXf", "fnc", COMPLEX_H, ALL_LANGUAGES)
+LIBBUILTIN(creall, "LdXLd", "fnc", COMPLEX_H, ALL_LANGUAGES)
-LIBBUILTIN(csin, "XdXd", "fne", "complex.h", ALL_LANGUAGES)
-LIBBUILTIN(csinf, "XfXf", "fne", "complex.h", ALL_LANGUAGES)
-LIBBUILTIN(csinl, "XLdXLd", "fne", "complex.h", ALL_LANGUAGES)
+LIBBUILTIN(csin, "XdXd", "fne", COMPLEX_H, ALL_LANGUAGES)
+LIBBUILTIN(csinf, "XfXf", "fne", COMPLEX_H, ALL_LANGUAGES)
+LIBBUILTIN(csinl, "XLdXLd", "fne", COMPLEX_H, ALL_LANGUAGES)
-LIBBUILTIN(csinh, "XdXd", "fne", "complex.h", ALL_LANGUAGES)
-LIBBUILTIN(csinhf, "XfXf", "fne", "complex.h", ALL_LANGUAGES)
-LIBBUILTIN(csinhl, "XLdXLd", "fne", "complex.h", ALL_LANGUAGES)
+LIBBUILTIN(csinh, "XdXd", "fne", COMPLEX_H, ALL_LANGUAGES)
+LIBBUILTIN(csinhf, "XfXf", "fne", COMPLEX_H, ALL_LANGUAGES)
+LIBBUILTIN(csinhl, "XLdXLd", "fne", COMPLEX_H, ALL_LANGUAGES)
-LIBBUILTIN(csqrt, "XdXd", "fne", "complex.h", ALL_LANGUAGES)
-LIBBUILTIN(csqrtf, "XfXf", "fne", "complex.h", ALL_LANGUAGES)
-LIBBUILTIN(csqrtl, "XLdXLd", "fne", "complex.h", ALL_LANGUAGES)
+LIBBUILTIN(csqrt, "XdXd", "fne", COMPLEX_H, ALL_LANGUAGES)
+LIBBUILTIN(csqrtf, "XfXf", "fne", COMPLEX_H, ALL_LANGUAGES)
+LIBBUILTIN(csqrtl, "XLdXLd", "fne", COMPLEX_H, ALL_LANGUAGES)
-LIBBUILTIN(ctan, "XdXd", "fne", "complex.h", ALL_LANGUAGES)
-LIBBUILTIN(ctanf, "XfXf", "fne", "complex.h", ALL_LANGUAGES)
-LIBBUILTIN(ctanl, "XLdXLd", "fne", "complex.h", ALL_LANGUAGES)
+LIBBUILTIN(ctan, "XdXd", "fne", COMPLEX_H, ALL_LANGUAGES)
+LIBBUILTIN(ctanf, "XfXf", "fne", COMPLEX_H, ALL_LANGUAGES)
+LIBBUILTIN(ctanl, "XLdXLd", "fne", COMPLEX_H, ALL_LANGUAGES)
-LIBBUILTIN(ctanh, "XdXd", "fne", "complex.h", ALL_LANGUAGES)
-LIBBUILTIN(ctanhf, "XfXf", "fne", "complex.h", ALL_LANGUAGES)
-LIBBUILTIN(ctanhl, "XLdXLd", "fne", "complex.h", ALL_LANGUAGES)
+LIBBUILTIN(ctanh, "XdXd", "fne", COMPLEX_H, ALL_LANGUAGES)
+LIBBUILTIN(ctanhf, "XfXf", "fne", COMPLEX_H, ALL_LANGUAGES)
+LIBBUILTIN(ctanhl, "XLdXLd", "fne", COMPLEX_H, ALL_LANGUAGES)
// __sinpi and friends are OS X specific library functions, but otherwise much
// like the standard (non-complex) sin (etc).
-LIBBUILTIN(__sinpi, "dd", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(__sinpif, "ff", "fne", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(__sinpi, "dd", "fne", MATH_H, ALL_LANGUAGES)
+LIBBUILTIN(__sinpif, "ff", "fne", MATH_H, ALL_LANGUAGES)
-LIBBUILTIN(__cospi, "dd", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(__cospif, "ff", "fne", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(__cospi, "dd", "fne", MATH_H, ALL_LANGUAGES)
+LIBBUILTIN(__cospif, "ff", "fne", MATH_H, ALL_LANGUAGES)
-LIBBUILTIN(__tanpi, "dd", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(__tanpif, "ff", "fne", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(__tanpi, "dd", "fne", MATH_H, ALL_LANGUAGES)
+LIBBUILTIN(__tanpif, "ff", "fne", MATH_H, ALL_LANGUAGES)
// Similarly, __exp10 is OS X only
-LIBBUILTIN(__exp10, "dd", "fne", "math.h", ALL_LANGUAGES)
-LIBBUILTIN(__exp10f, "ff", "fne", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(__exp10, "dd", "fne", MATH_H, ALL_LANGUAGES)
+LIBBUILTIN(__exp10f, "ff", "fne", MATH_H, ALL_LANGUAGES)
// Blocks runtime Builtin math library functions
-LIBBUILTIN(_Block_object_assign, "vv*vC*iC", "f", "Blocks.h", ALL_LANGUAGES)
-LIBBUILTIN(_Block_object_dispose, "vvC*iC", "f", "Blocks.h", ALL_LANGUAGES)
+LIBBUILTIN(_Block_object_assign, "vv*vC*iC", "f", BLOCKS_H, ALL_LANGUAGES)
+LIBBUILTIN(_Block_object_dispose, "vvC*iC", "f", BLOCKS_H, ALL_LANGUAGES)
// FIXME: Also declare NSConcreteGlobalBlock and NSConcreteStackBlock.
+// C++ standard library builtins in namespace 'std'.
+LIBBUILTIN(addressof, "v*v&", "zfncThE", MEMORY, CXX_LANG)
+// Synonym for addressof used internally by libstdc++.
+LANGBUILTIN(__addressof, "v*v&", "zfncTE", CXX_LANG)
+LIBBUILTIN(as_const, "v&v&", "zfncThE", UTILITY, CXX_LANG)
+LIBBUILTIN(forward, "v&v&", "zfncThE", UTILITY, CXX_LANG)
+LIBBUILTIN(forward_like, "v&v&", "zfncThE", UTILITY, CXX_LANG)
+LIBBUILTIN(move, "v&v&", "zfncThE", UTILITY, CXX_LANG)
+LIBBUILTIN(move_if_noexcept, "v&v&", "zfncThE", UTILITY, CXX_LANG)
+
// Annotation function
BUILTIN(__builtin_annotation, "v.", "tn")
// Invariants
-BUILTIN(__builtin_assume, "vb", "n")
+BUILTIN(__builtin_assume, "vb", "nE")
+BUILTIN(__builtin_assume_separate_storage, "vvCD*vCD*", "nE")
// Multiprecision Arithmetic Builtins.
BUILTIN(__builtin_addcb, "UcUcCUcCUcCUc*", "n")
@@ -1532,40 +1662,41 @@ BUILTIN(__builtin_subcl, "ULiULiCULiCULiCULi*", "n")
BUILTIN(__builtin_subcll, "ULLiULLiCULLiCULLiCULLi*", "n")
// Checked Arithmetic Builtins for Security.
-BUILTIN(__builtin_add_overflow, "b.", "nt")
-BUILTIN(__builtin_sub_overflow, "b.", "nt")
-BUILTIN(__builtin_mul_overflow, "b.", "nt")
-BUILTIN(__builtin_uadd_overflow, "bUiCUiCUi*", "n")
-BUILTIN(__builtin_uaddl_overflow, "bULiCULiCULi*", "n")
-BUILTIN(__builtin_uaddll_overflow, "bULLiCULLiCULLi*", "n")
-BUILTIN(__builtin_usub_overflow, "bUiCUiCUi*", "n")
-BUILTIN(__builtin_usubl_overflow, "bULiCULiCULi*", "n")
-BUILTIN(__builtin_usubll_overflow, "bULLiCULLiCULLi*", "n")
-BUILTIN(__builtin_umul_overflow, "bUiCUiCUi*", "n")
-BUILTIN(__builtin_umull_overflow, "bULiCULiCULi*", "n")
-BUILTIN(__builtin_umulll_overflow, "bULLiCULLiCULLi*", "n")
-BUILTIN(__builtin_sadd_overflow, "bSiCSiCSi*", "n")
-BUILTIN(__builtin_saddl_overflow, "bSLiCSLiCSLi*", "n")
-BUILTIN(__builtin_saddll_overflow, "bSLLiCSLLiCSLLi*", "n")
-BUILTIN(__builtin_ssub_overflow, "bSiCSiCSi*", "n")
-BUILTIN(__builtin_ssubl_overflow, "bSLiCSLiCSLi*", "n")
-BUILTIN(__builtin_ssubll_overflow, "bSLLiCSLLiCSLLi*", "n")
-BUILTIN(__builtin_smul_overflow, "bSiCSiCSi*", "n")
-BUILTIN(__builtin_smull_overflow, "bSLiCSLiCSLi*", "n")
-BUILTIN(__builtin_smulll_overflow, "bSLLiCSLLiCSLLi*", "n")
+BUILTIN(__builtin_add_overflow, "b.", "ntE")
+BUILTIN(__builtin_sub_overflow, "b.", "ntE")
+BUILTIN(__builtin_mul_overflow, "b.", "ntE")
+BUILTIN(__builtin_uadd_overflow, "bUiCUiCUi*", "nE")
+BUILTIN(__builtin_uaddl_overflow, "bULiCULiCULi*", "nE")
+BUILTIN(__builtin_uaddll_overflow, "bULLiCULLiCULLi*", "nE")
+BUILTIN(__builtin_usub_overflow, "bUiCUiCUi*", "nE")
+BUILTIN(__builtin_usubl_overflow, "bULiCULiCULi*", "nE")
+BUILTIN(__builtin_usubll_overflow, "bULLiCULLiCULLi*", "nE")
+BUILTIN(__builtin_umul_overflow, "bUiCUiCUi*", "nE")
+BUILTIN(__builtin_umull_overflow, "bULiCULiCULi*", "nE")
+BUILTIN(__builtin_umulll_overflow, "bULLiCULLiCULLi*", "nE")
+BUILTIN(__builtin_sadd_overflow, "bSiCSiCSi*", "nE")
+BUILTIN(__builtin_saddl_overflow, "bSLiCSLiCSLi*", "nE")
+BUILTIN(__builtin_saddll_overflow, "bSLLiCSLLiCSLLi*", "nE")
+BUILTIN(__builtin_ssub_overflow, "bSiCSiCSi*", "nE")
+BUILTIN(__builtin_ssubl_overflow, "bSLiCSLiCSLi*", "nE")
+BUILTIN(__builtin_ssubll_overflow, "bSLLiCSLLiCSLLi*", "nE")
+BUILTIN(__builtin_smul_overflow, "bSiCSiCSi*", "nE")
+BUILTIN(__builtin_smull_overflow, "bSLiCSLiCSLi*", "nE")
+BUILTIN(__builtin_smulll_overflow, "bSLLiCSLLiCSLLi*", "nE")
// Clang builtins (not available in GCC).
-BUILTIN(__builtin_addressof, "v*v&", "nct")
-BUILTIN(__builtin_operator_new, "v*z", "tc")
-BUILTIN(__builtin_operator_delete, "vv*", "tn")
-BUILTIN(__builtin_char_memchr, "c*cC*iz", "n")
-BUILTIN(__builtin_dump_struct, "ivC*v*", "tn")
+BUILTIN(__builtin_addressof, "v*v&", "nctE")
+BUILTIN(__builtin_function_start, "v*v&", "nctE")
+BUILTIN(__builtin_operator_new, "v*z", "tcE")
+BUILTIN(__builtin_operator_delete, "vv*", "tnE")
+BUILTIN(__builtin_char_memchr, "c*cC*iz", "nE")
+BUILTIN(__builtin_dump_struct, "v.", "t")
BUILTIN(__builtin_preserve_access_index, "v.", "t")
// Alignment builtins (uses custom parsing to support pointers and integers)
-BUILTIN(__builtin_is_aligned, "bvC*z", "nct")
-BUILTIN(__builtin_align_up, "v*vC*z", "nct")
-BUILTIN(__builtin_align_down, "v*vC*z", "nct")
+BUILTIN(__builtin_is_aligned, "bvC*z", "nctE")
+BUILTIN(__builtin_align_up, "v*vC*z", "nctE")
+BUILTIN(__builtin_align_down, "v*vC*z", "nctE")
// Safestack builtins
BUILTIN(__builtin___get_unsafe_stack_start, "v*", "Fn")
@@ -1584,6 +1715,7 @@ LANGBUILTIN(__builtin_coro_done, "bv*", "n", COR_LANG)
LANGBUILTIN(__builtin_coro_promise, "v*v*IiIb", "n", COR_LANG)
LANGBUILTIN(__builtin_coro_size, "z", "n", COR_LANG)
+LANGBUILTIN(__builtin_coro_align, "z", "n", COR_LANG)
LANGBUILTIN(__builtin_coro_frame, "v*", "n", COR_LANG)
LANGBUILTIN(__builtin_coro_noop, "v*", "n", COR_LANG)
LANGBUILTIN(__builtin_coro_free, "v*v*", "n", COR_LANG)
@@ -1593,62 +1725,65 @@ LANGBUILTIN(__builtin_coro_alloc, "b", "n", COR_LANG)
LANGBUILTIN(__builtin_coro_begin, "v*v*", "n", COR_LANG)
LANGBUILTIN(__builtin_coro_end, "bv*Ib", "n", COR_LANG)
LANGBUILTIN(__builtin_coro_suspend, "cIb", "n", COR_LANG)
-LANGBUILTIN(__builtin_coro_param, "bv*v*", "n", COR_LANG)
// OpenCL v2.0 s6.13.16, s9.17.3.5 - Pipe functions.
// We need the generic prototype, since the packet type could be anything.
-LANGBUILTIN(read_pipe, "i.", "tn", OCLC20_LANG)
-LANGBUILTIN(write_pipe, "i.", "tn", OCLC20_LANG)
+LANGBUILTIN(read_pipe, "i.", "tn", OCL_PIPE)
+LANGBUILTIN(write_pipe, "i.", "tn", OCL_PIPE)
-LANGBUILTIN(reserve_read_pipe, "i.", "tn", OCLC20_LANG)
-LANGBUILTIN(reserve_write_pipe, "i.", "tn", OCLC20_LANG)
+LANGBUILTIN(reserve_read_pipe, "i.", "tn", OCL_PIPE)
+LANGBUILTIN(reserve_write_pipe, "i.", "tn", OCL_PIPE)
-LANGBUILTIN(commit_write_pipe, "v.", "tn", OCLC20_LANG)
-LANGBUILTIN(commit_read_pipe, "v.", "tn", OCLC20_LANG)
+LANGBUILTIN(commit_write_pipe, "v.", "tn", OCL_PIPE)
+LANGBUILTIN(commit_read_pipe, "v.", "tn", OCL_PIPE)
-LANGBUILTIN(sub_group_reserve_read_pipe, "i.", "tn", OCLC20_LANG)
-LANGBUILTIN(sub_group_reserve_write_pipe, "i.", "tn", OCLC20_LANG)
+LANGBUILTIN(sub_group_reserve_read_pipe, "i.", "tn", OCL_PIPE)
+LANGBUILTIN(sub_group_reserve_write_pipe, "i.", "tn", OCL_PIPE)
-LANGBUILTIN(sub_group_commit_read_pipe, "v.", "tn", OCLC20_LANG)
-LANGBUILTIN(sub_group_commit_write_pipe, "v.", "tn", OCLC20_LANG)
+LANGBUILTIN(sub_group_commit_read_pipe, "v.", "tn", OCL_PIPE)
+LANGBUILTIN(sub_group_commit_write_pipe, "v.", "tn", OCL_PIPE)
-LANGBUILTIN(work_group_reserve_read_pipe, "i.", "tn", OCLC20_LANG)
-LANGBUILTIN(work_group_reserve_write_pipe, "i.", "tn", OCLC20_LANG)
+LANGBUILTIN(work_group_reserve_read_pipe, "i.", "tn", OCL_PIPE)
+LANGBUILTIN(work_group_reserve_write_pipe, "i.", "tn", OCL_PIPE)
-LANGBUILTIN(work_group_commit_read_pipe, "v.", "tn", OCLC20_LANG)
-LANGBUILTIN(work_group_commit_write_pipe, "v.", "tn", OCLC20_LANG)
+LANGBUILTIN(work_group_commit_read_pipe, "v.", "tn", OCL_PIPE)
+LANGBUILTIN(work_group_commit_write_pipe, "v.", "tn", OCL_PIPE)
-LANGBUILTIN(get_pipe_num_packets, "Ui.", "tn", OCLC20_LANG)
-LANGBUILTIN(get_pipe_max_packets, "Ui.", "tn", OCLC20_LANG)
+LANGBUILTIN(get_pipe_num_packets, "Ui.", "tn", OCL_PIPE)
+LANGBUILTIN(get_pipe_max_packets, "Ui.", "tn", OCL_PIPE)
// OpenCL v2.0 s6.13.17 - Enqueue kernel functions.
// Custom builtin check allows to perform special check of passed block arguments.
-LANGBUILTIN(enqueue_kernel, "i.", "tn", OCLC20_LANG)
-LANGBUILTIN(get_kernel_work_group_size, "Ui.", "tn", OCLC20_LANG)
-LANGBUILTIN(get_kernel_preferred_work_group_size_multiple, "Ui.", "tn", OCLC20_LANG)
-LANGBUILTIN(get_kernel_max_sub_group_size_for_ndrange, "Ui.", "tn", OCLC20_LANG)
-LANGBUILTIN(get_kernel_sub_group_count_for_ndrange, "Ui.", "tn", OCLC20_LANG)
+LANGBUILTIN(enqueue_kernel, "i.", "tn", OCL_DSE)
+LANGBUILTIN(get_kernel_work_group_size, "Ui.", "tn", OCL_DSE)
+LANGBUILTIN(get_kernel_preferred_work_group_size_multiple, "Ui.", "tn", OCL_DSE)
+LANGBUILTIN(get_kernel_max_sub_group_size_for_ndrange, "Ui.", "tn", OCL_DSE)
+LANGBUILTIN(get_kernel_sub_group_count_for_ndrange, "Ui.", "tn", OCL_DSE)
// OpenCL v2.0 s6.13.9 - Address space qualifier functions.
// FIXME: Pointer parameters of OpenCL builtins should have their address space
// requirement defined.
-LANGBUILTIN(to_global, "v*v*", "tn", OCLC20_LANG)
-LANGBUILTIN(to_local, "v*v*", "tn", OCLC20_LANG)
-LANGBUILTIN(to_private, "v*v*", "tn", OCLC20_LANG)
+LANGBUILTIN(to_global, "v*v*", "tn", OCL_GAS)
+LANGBUILTIN(to_local, "v*v*", "tn", OCL_GAS)
+LANGBUILTIN(to_private, "v*v*", "tn", OCL_GAS)
// OpenCL half load/store builtin
-LANGBUILTIN(__builtin_store_half, "vdh*", "n", ALL_OCLC_LANGUAGES)
-LANGBUILTIN(__builtin_store_halff, "vfh*", "n", ALL_OCLC_LANGUAGES)
-LANGBUILTIN(__builtin_load_half, "dhC*", "nc", ALL_OCLC_LANGUAGES)
-LANGBUILTIN(__builtin_load_halff, "fhC*", "nc", ALL_OCLC_LANGUAGES)
+LANGBUILTIN(__builtin_store_half, "vdh*", "n", ALL_OCL_LANGUAGES)
+LANGBUILTIN(__builtin_store_halff, "vfh*", "n", ALL_OCL_LANGUAGES)
+LANGBUILTIN(__builtin_load_half, "dhC*", "nc", ALL_OCL_LANGUAGES)
+LANGBUILTIN(__builtin_load_halff, "fhC*", "nc", ALL_OCL_LANGUAGES)
// Builtins for os_log/os_trace
-BUILTIN(__builtin_os_log_format_buffer_size, "zcC*.", "p:0:nut")
+BUILTIN(__builtin_os_log_format_buffer_size, "zcC*.", "p:0:nutE")
BUILTIN(__builtin_os_log_format, "v*v*cC*.", "p:0:nt")
// CUDA/HIP
LANGBUILTIN(__builtin_get_device_side_mangled_name, "cC*.", "ncT", CUDA_LANG)
+// HLSL
+LANGBUILTIN(__builtin_hlsl_wave_active_count_bits, "Uib", "nc", HLSL_LANG)
+LANGBUILTIN(__builtin_hlsl_create_handle, "v*Uc", "nc", HLSL_LANG)
+
// Builtins for XRay
BUILTIN(__xray_customevent, "vcC*z", "")
BUILTIN(__xray_typedevent, "vzcC*z", "")
@@ -1659,7 +1794,7 @@ BUILTIN(__builtin_ms_va_end, "vc*&", "n")
BUILTIN(__builtin_ms_va_copy, "vc*&c*&", "n")
// Arithmetic Fence: to prevent FP reordering and reassociation optimizations
-LANGBUILTIN(__arithmetic_fence, "v.", "t", ALL_LANGUAGES)
+LANGBUILTIN(__arithmetic_fence, "v.", "tE", ALL_LANGUAGES)
#undef BUILTIN
#undef LIBBUILTIN
diff --git a/contrib/llvm-project/clang/include/clang/Basic/Builtins.h b/contrib/llvm-project/clang/include/clang/Basic/Builtins.h
index cdaaee48c32d..3fd5b02b5aa5 100644
--- a/contrib/llvm-project/clang/include/clang/Basic/Builtins.h
+++ b/contrib/llvm-project/clang/include/clang/Basic/Builtins.h
@@ -16,6 +16,8 @@
#define LLVM_CLANG_BASIC_BUILTINS_H
#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/StringRef.h"
#include <cstring>
// VC++ defines 'alloca' as an object-like macro, which interferes with our
@@ -27,21 +29,35 @@ class TargetInfo;
class IdentifierTable;
class LangOptions;
-enum LanguageID {
- GNU_LANG = 0x1, // builtin requires GNU mode.
- C_LANG = 0x2, // builtin for c only.
- CXX_LANG = 0x4, // builtin for cplusplus only.
- OBJC_LANG = 0x8, // builtin for objective-c and objective-c++
- MS_LANG = 0x10, // builtin requires MS mode.
- OCLC20_LANG = 0x20, // builtin for OpenCL C 2.0 only.
- OCLC1X_LANG = 0x40, // builtin for OpenCL C 1.x only.
- OMP_LANG = 0x80, // builtin requires OpenMP.
- CUDA_LANG = 0x100, // builtin requires CUDA.
- COR_LANG = 0x200, // builtin requires use of 'fcoroutine-ts' option.
+enum LanguageID : uint16_t {
+ GNU_LANG = 0x1, // builtin requires GNU mode.
+ C_LANG = 0x2, // builtin for c only.
+ CXX_LANG = 0x4, // builtin for cplusplus only.
+ OBJC_LANG = 0x8, // builtin for objective-c and objective-c++
+ MS_LANG = 0x10, // builtin requires MS mode.
+ OMP_LANG = 0x20, // builtin requires OpenMP.
+ CUDA_LANG = 0x40, // builtin requires CUDA.
+ COR_LANG = 0x80, // builtin requires use of 'fcoroutine-ts' option.
+ OCL_GAS = 0x100, // builtin requires OpenCL generic address space.
+ OCL_PIPE = 0x200, // builtin requires OpenCL pipe.
+ OCL_DSE = 0x400, // builtin requires OpenCL device side enqueue.
+ ALL_OCL_LANGUAGES = 0x800, // builtin for OCL languages.
+ HLSL_LANG = 0x1000, // builtin requires HLSL.
ALL_LANGUAGES = C_LANG | CXX_LANG | OBJC_LANG, // builtin for all languages.
ALL_GNU_LANGUAGES = ALL_LANGUAGES | GNU_LANG, // builtin requires GNU mode.
- ALL_MS_LANGUAGES = ALL_LANGUAGES | MS_LANG, // builtin requires MS mode.
- ALL_OCLC_LANGUAGES = OCLC1X_LANG | OCLC20_LANG // builtin for OCLC languages.
+ ALL_MS_LANGUAGES = ALL_LANGUAGES | MS_LANG // builtin requires MS mode.
+};
+
+struct HeaderDesc {
+ enum HeaderID : uint16_t {
+#define HEADER(ID, NAME) ID,
+#include "clang/Basic/BuiltinHeaders.def"
+#undef HEADER
+ } ID;
+
+ constexpr HeaderDesc(HeaderID ID) : ID(ID) {}
+
+ const char *getName() const;
};
namespace Builtin {
@@ -53,9 +69,11 @@ enum ID {
};
struct Info {
- const char *Name, *Type, *Attributes, *HeaderName;
- LanguageID Langs;
+ llvm::StringLiteral Name;
+ const char *Type, *Attributes;
const char *Features;
+ HeaderDesc Header;
+ LanguageID Langs;
};
/// Holds information about both target-independent and
@@ -69,7 +87,7 @@ class Context {
llvm::ArrayRef<Info> AuxTSRecords;
public:
- Context() {}
+ Context() = default;
/// Perform target-specific initialization
/// \param AuxTarget Target info to incorporate builtins from. May be nullptr.
@@ -82,9 +100,7 @@ public:
/// Return the identifier name for the specified builtin,
/// e.g. "__builtin_abs".
- const char *getName(unsigned ID) const {
- return getRecord(ID).Name;
- }
+ llvm::StringRef getName(unsigned ID) const { return getRecord(ID).Name; }
/// Get the type descriptor string for the specified builtin.
const char *getTypeString(unsigned ID) const {
@@ -137,6 +153,10 @@ public:
/// Determines whether this builtin is a predefined libc/libm
/// function, such as "malloc", where we know the signature a
/// priori.
+ /// In C, such functions behave as if they are predeclared,
+ /// possibly with a warning on first use. In Objective-C and C++,
+ /// they do not, but they are recognized as builtins once we see
+ /// a declaration.
bool isPredefinedLibFunction(unsigned ID) const {
return strchr(getRecord(ID).Attributes, 'f') != nullptr;
}
@@ -155,6 +175,23 @@ public:
return strchr(getRecord(ID).Attributes, 'i') != nullptr;
}
+ /// Determines whether this builtin is a C++ standard library function
+ /// that lives in (possibly-versioned) namespace std, possibly a template
+ /// specialization, where the signature is determined by the standard library
+ /// declaration.
+ bool isInStdNamespace(unsigned ID) const {
+ return strchr(getRecord(ID).Attributes, 'z') != nullptr;
+ }
+
+ /// Determines whether this builtin can have its address taken with no
+ /// special action required.
+ bool isDirectlyAddressable(unsigned ID) const {
+ // Most standard library functions can have their addresses taken. C++
+ // standard library functions formally cannot in C++20 onwards, and when
+ // we allow it, we need to ensure we instantiate a definition.
+ return isPredefinedLibFunction(ID) && !isInStdNamespace(ID);
+ }
+
/// Determines whether this builtin has custom typechecking.
bool hasCustomTypechecking(unsigned ID) const {
return strchr(getRecord(ID).Attributes, 't') != nullptr;
@@ -183,7 +220,7 @@ public:
/// If this is a library function that comes from a specific
/// header, retrieve that header name.
const char *getHeaderName(unsigned ID) const {
- return getRecord(ID).HeaderName;
+ return getRecord(ID).Header.getName();
}
/// Determine whether this builtin is like printf in its
@@ -203,13 +240,18 @@ public:
llvm::SmallVectorImpl<int> &Encoding) const;
/// Return true if this function has no side effects and doesn't
- /// read memory, except for possibly errno.
+ /// read memory, except for possibly errno or raising FP exceptions.
///
- /// Such functions can be const when the MathErrno lang option is disabled.
- bool isConstWithoutErrno(unsigned ID) const {
+ /// Such functions can be const when the MathErrno lang option and FP
+ /// exceptions are disabled.
+ bool isConstWithoutErrnoAndExceptions(unsigned ID) const {
return strchr(getRecord(ID).Attributes, 'e') != nullptr;
}
+ bool isConstWithoutExceptions(unsigned ID) const {
+ return strchr(getRecord(ID).Attributes, 'g') != nullptr;
+ }
+
const char *getRequiredFeatures(unsigned ID) const {
return getRecord(ID).Features;
}
@@ -233,19 +275,28 @@ public:
/// for non-builtins.
bool canBeRedeclared(unsigned ID) const;
+ /// Return true if this function can be constant evaluated by Clang frontend.
+ bool isConstantEvaluated(unsigned ID) const {
+ return strchr(getRecord(ID).Attributes, 'E') != nullptr;
+ }
+
private:
const Info &getRecord(unsigned ID) const;
- /// Is this builtin supported according to the given language options?
- bool builtinIsSupported(const Builtin::Info &BuiltinInfo,
- const LangOptions &LangOpts);
-
/// Helper function for isPrintfLike and isScanfLike.
bool isLike(unsigned ID, unsigned &FormatIdx, bool &HasVAListArg,
const char *Fmt) const;
};
-}
+/// Returns true if the required target features of a builtin function are
+/// enabled.
+/// \p TargetFeatureMap maps a target feature to true if it is enabled and
+/// false if it is disabled.
+bool evaluateRequiredTargetFeatures(
+ llvm::StringRef RequiredFatures,
+ const llvm::StringMap<bool> &TargetFetureMap);
+
+} // namespace Builtin
/// Kinds of BuiltinTemplateDecl.
enum BuiltinTemplateKind : int {
diff --git a/contrib/llvm-project/clang/include/clang/Basic/BuiltinsAArch64.def b/contrib/llvm-project/clang/include/clang/Basic/BuiltinsAArch64.def
index 634bcaed20a6..31ec84143f65 100644
--- a/contrib/llvm-project/clang/include/clang/Basic/BuiltinsAArch64.def
+++ b/contrib/llvm-project/clang/include/clang/Basic/BuiltinsAArch64.def
@@ -17,6 +17,10 @@
# define LANGBUILTIN(ID, TYPE, ATTRS, BUILTIN_LANG) BUILTIN(ID, TYPE, ATTRS)
#endif
+#if defined(BUILTIN) && !defined(TARGET_BUILTIN)
+# define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) BUILTIN(ID, TYPE, ATTRS)
+#endif
+
#if defined(BUILTIN) && !defined(TARGET_HEADER_BUILTIN)
# define TARGET_HEADER_BUILTIN(ID, TYPE, ATTRS, HEADER, LANG, FEATURE) BUILTIN(ID, TYPE, ATTRS)
#endif
@@ -35,6 +39,8 @@ BUILTIN(__builtin_arm_rbit, "UiUi", "nc")
BUILTIN(__builtin_arm_rbit64, "WUiWUi", "nc")
BUILTIN(__builtin_arm_cls, "UiZUi", "nc")
BUILTIN(__builtin_arm_cls64, "UiWUi", "nc")
+BUILTIN(__builtin_arm_clz, "UiZUi", "nc")
+BUILTIN(__builtin_arm_clz64, "UiWUi", "nc")
// HINT
BUILTIN(__builtin_arm_nop, "v", "")
@@ -45,29 +51,35 @@ BUILTIN(__builtin_arm_sev, "v", "")
BUILTIN(__builtin_arm_sevl, "v", "")
// CRC32
-BUILTIN(__builtin_arm_crc32b, "UiUiUc", "nc")
-BUILTIN(__builtin_arm_crc32cb, "UiUiUc", "nc")
-BUILTIN(__builtin_arm_crc32h, "UiUiUs", "nc")
-BUILTIN(__builtin_arm_crc32ch, "UiUiUs", "nc")
-BUILTIN(__builtin_arm_crc32w, "UiUiUi", "nc")
-BUILTIN(__builtin_arm_crc32cw, "UiUiUi", "nc")
-BUILTIN(__builtin_arm_crc32d, "UiUiWUi", "nc")
-BUILTIN(__builtin_arm_crc32cd, "UiUiWUi", "nc")
+TARGET_BUILTIN(__builtin_arm_crc32b, "UiUiUc", "nc", "crc")
+TARGET_BUILTIN(__builtin_arm_crc32cb, "UiUiUc", "nc", "crc")
+TARGET_BUILTIN(__builtin_arm_crc32h, "UiUiUs", "nc", "crc")
+TARGET_BUILTIN(__builtin_arm_crc32ch, "UiUiUs", "nc", "crc")
+TARGET_BUILTIN(__builtin_arm_crc32w, "UiUiUi", "nc", "crc")
+TARGET_BUILTIN(__builtin_arm_crc32cw, "UiUiUi", "nc", "crc")
+TARGET_BUILTIN(__builtin_arm_crc32d, "UiUiWUi", "nc", "crc")
+TARGET_BUILTIN(__builtin_arm_crc32cd, "UiUiWUi", "nc", "crc")
// Memory Tagging Extensions (MTE)
-BUILTIN(__builtin_arm_irg, "v*v*Ui", "t")
-BUILTIN(__builtin_arm_addg, "v*v*Ui", "t")
-BUILTIN(__builtin_arm_gmi, "Uiv*Ui", "t")
-BUILTIN(__builtin_arm_ldg, "v*v*", "t")
-BUILTIN(__builtin_arm_stg, "vv*", "t")
-BUILTIN(__builtin_arm_subp, "Uiv*v*", "t")
+TARGET_BUILTIN(__builtin_arm_irg, "v*v*Ui", "t", "mte")
+TARGET_BUILTIN(__builtin_arm_addg, "v*v*Ui", "t", "mte")
+TARGET_BUILTIN(__builtin_arm_gmi, "Uiv*Ui", "t", "mte")
+TARGET_BUILTIN(__builtin_arm_ldg, "v*v*", "t", "mte")
+TARGET_BUILTIN(__builtin_arm_stg, "vv*", "t", "mte")
+TARGET_BUILTIN(__builtin_arm_subp, "Uiv*v*", "t", "mte")
+
+// SME state function
+BUILTIN(__builtin_arm_get_sme_state, "vULi*ULi*", "n")
+
+// Memory Operations
+TARGET_BUILTIN(__builtin_arm_mops_memset_tag, "v*v*iz", "", "mte,mops")
// Memory barrier
BUILTIN(__builtin_arm_dmb, "vUi", "nc")
BUILTIN(__builtin_arm_dsb, "vUi", "nc")
BUILTIN(__builtin_arm_isb, "vUi", "nc")
-BUILTIN(__builtin_arm_jcvt, "Zid", "nc")
+TARGET_BUILTIN(__builtin_arm_jcvt, "Zid", "nc", "v8.3a")
// Prefetch
BUILTIN(__builtin_arm_prefetch, "vvC*UiUiUiUi", "nc")
@@ -75,9 +87,11 @@ BUILTIN(__builtin_arm_prefetch, "vvC*UiUiUiUi", "nc")
// System Registers
BUILTIN(__builtin_arm_rsr, "UicC*", "nc")
BUILTIN(__builtin_arm_rsr64, "WUicC*", "nc")
+TARGET_BUILTIN(__builtin_arm_rsr128, "LLLUicC*", "nc", "d128")
BUILTIN(__builtin_arm_rsrp, "v*cC*", "nc")
BUILTIN(__builtin_arm_wsr, "vcC*Ui", "nc")
BUILTIN(__builtin_arm_wsr64, "vcC*WUi", "nc")
+TARGET_BUILTIN(__builtin_arm_wsr128, "vcC*LLLUi", "nc", "d128")
BUILTIN(__builtin_arm_wsrp, "vcC*vC*", "nc")
// MSVC
@@ -100,152 +114,181 @@ BUILTIN(__builtin_arm_tcancel, "vWUIi", "n")
BUILTIN(__builtin_arm_ttest, "WUi", "nc")
// Armv8.5-A FP rounding intrinsics
-BUILTIN(__builtin_arm_frint32zf, "ff", "")
-BUILTIN(__builtin_arm_frint32z, "dd", "")
-BUILTIN(__builtin_arm_frint64zf, "ff", "")
-BUILTIN(__builtin_arm_frint64z, "dd", "")
-BUILTIN(__builtin_arm_frint32xf, "ff", "")
-BUILTIN(__builtin_arm_frint32x, "dd", "")
-BUILTIN(__builtin_arm_frint64xf, "ff", "")
-BUILTIN(__builtin_arm_frint64x, "dd", "")
+TARGET_BUILTIN(__builtin_arm_rint32zf, "ff", "", "v8.5a")
+TARGET_BUILTIN(__builtin_arm_rint32z, "dd", "", "v8.5a")
+TARGET_BUILTIN(__builtin_arm_rint64zf, "ff", "", "v8.5a")
+TARGET_BUILTIN(__builtin_arm_rint64z, "dd", "", "v8.5a")
+TARGET_BUILTIN(__builtin_arm_rint32xf, "ff", "", "v8.5a")
+TARGET_BUILTIN(__builtin_arm_rint32x, "dd", "", "v8.5a")
+TARGET_BUILTIN(__builtin_arm_rint64xf, "ff", "", "v8.5a")
+TARGET_BUILTIN(__builtin_arm_rint64x, "dd", "", "v8.5a")
// Armv8.5-A Random number generation intrinsics
-BUILTIN(__builtin_arm_rndr, "iWUi*", "n")
-BUILTIN(__builtin_arm_rndrrs, "iWUi*", "n")
+TARGET_BUILTIN(__builtin_arm_rndr, "iWUi*", "n", "rand")
+TARGET_BUILTIN(__builtin_arm_rndrrs, "iWUi*", "n", "rand")
// Armv8.7-A load/store 64-byte intrinsics
-BUILTIN(__builtin_arm_ld64b, "vvC*WUi*", "n")
-BUILTIN(__builtin_arm_st64b, "vv*WUiC*", "n")
-BUILTIN(__builtin_arm_st64bv, "WUiv*WUiC*", "n")
-BUILTIN(__builtin_arm_st64bv0, "WUiv*WUiC*", "n")
-
-TARGET_HEADER_BUILTIN(_BitScanForward, "UcUNi*UNi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_BitScanReverse, "UcUNi*UNi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_BitScanForward64, "UcUNi*ULLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_BitScanReverse64, "UcUNi*ULLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-
-TARGET_HEADER_BUILTIN(_InterlockedAdd, "NiNiD*Ni", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedAnd64, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedDecrement64, "LLiLLiD*", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedExchange64, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedExchangeAdd64, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedExchangeSub64, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedIncrement64, "LLiLLiD*", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedOr64, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedXor64, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-
-TARGET_HEADER_BUILTIN(_InterlockedExchangeAdd_acq, "NiNiD*Ni", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedExchangeAdd_rel, "NiNiD*Ni", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedExchangeAdd_nf, "NiNiD*Ni", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedExchangeAdd8_acq, "ccD*c", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedExchangeAdd8_rel, "ccD*c", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedExchangeAdd8_nf, "ccD*c", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedExchangeAdd16_acq, "ssD*s", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedExchangeAdd16_rel, "ssD*s", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedExchangeAdd16_nf, "ssD*s", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedExchangeAdd64_acq, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedExchangeAdd64_rel, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedExchangeAdd64_nf, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-
-TARGET_HEADER_BUILTIN(_InterlockedExchange8_acq, "ccD*c", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedExchange8_nf, "ccD*c", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedExchange8_rel, "ccD*c", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedExchange16_acq, "ssD*s", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedExchange16_nf, "ssD*s", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedExchange16_rel, "ssD*s", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedExchange_acq, "NiNiD*Ni", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedExchange_nf, "NiNiD*Ni", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedExchange_rel, "NiNiD*Ni", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedExchange64_acq, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedExchange64_nf, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedExchange64_rel, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-
-TARGET_HEADER_BUILTIN(_InterlockedCompareExchange8_acq, "ccD*cc", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedCompareExchange8_nf, "ccD*cc", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedCompareExchange8_rel, "ccD*cc", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedCompareExchange16_acq, "ssD*ss", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedCompareExchange16_nf, "ssD*ss", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedCompareExchange16_rel, "ssD*ss", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedCompareExchange_acq, "NiNiD*NiNi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedCompareExchange_nf, "NiNiD*NiNi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedCompareExchange_rel, "NiNiD*NiNi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedCompareExchange64_acq, "LLiLLiD*LLiLLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedCompareExchange64_nf, "LLiLLiD*LLiLLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedCompareExchange64_rel, "LLiLLiD*LLiLLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-
-TARGET_HEADER_BUILTIN(_InterlockedCompareExchange128, "UcLLiD*LLiLLiLLi*", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedCompareExchange128_acq,"UcLLiD*LLiLLiLLi*", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedCompareExchange128_nf ,"UcLLiD*LLiLLiLLi*", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedCompareExchange128_rel,"UcLLiD*LLiLLiLLi*", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-
-TARGET_HEADER_BUILTIN(_InterlockedOr8_acq, "ccD*c", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedOr8_nf, "ccD*c", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedOr8_rel, "ccD*c", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedOr16_acq, "ssD*s", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedOr16_nf, "ssD*s", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedOr16_rel, "ssD*s", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedOr_acq, "NiNiD*Ni", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedOr_nf, "NiNiD*Ni", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedOr_rel, "NiNiD*Ni", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedOr64_acq, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedOr64_nf, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedOr64_rel, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-
-TARGET_HEADER_BUILTIN(_InterlockedXor8_acq, "ccD*c", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedXor8_nf, "ccD*c", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedXor8_rel, "ccD*c", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedXor16_acq, "ssD*s", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedXor16_nf, "ssD*s", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedXor16_rel, "ssD*s", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedXor_acq, "NiNiD*Ni", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedXor_nf, "NiNiD*Ni", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedXor_rel, "NiNiD*Ni", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedXor64_acq, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedXor64_nf, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedXor64_rel, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-
-TARGET_HEADER_BUILTIN(_InterlockedAnd8_acq, "ccD*c", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedAnd8_nf, "ccD*c", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedAnd8_rel, "ccD*c", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedAnd16_acq, "ssD*s", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedAnd16_nf, "ssD*s", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedAnd16_rel, "ssD*s", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedAnd_acq, "NiNiD*Ni", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedAnd_nf, "NiNiD*Ni", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedAnd_rel, "NiNiD*Ni", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedAnd64_acq, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedAnd64_nf, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedAnd64_rel, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-
-TARGET_HEADER_BUILTIN(_InterlockedIncrement16_acq, "ssD*", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedIncrement16_nf, "ssD*", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedIncrement16_rel, "ssD*", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedIncrement_acq, "NiNiD*", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedIncrement_nf, "NiNiD*", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedIncrement_rel, "NiNiD*", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedIncrement64_acq, "LLiLLiD*", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedIncrement64_nf, "LLiLLiD*", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedIncrement64_rel, "LLiLLiD*", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-
-TARGET_HEADER_BUILTIN(_InterlockedDecrement16_acq, "ssD*", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedDecrement16_nf, "ssD*", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedDecrement16_rel, "ssD*", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedDecrement_acq, "NiNiD*", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedDecrement_nf, "NiNiD*", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedDecrement_rel, "NiNiD*", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedDecrement64_acq, "LLiLLiD*", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedDecrement64_nf, "LLiLLiD*", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedDecrement64_rel, "LLiLLiD*", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-
-TARGET_HEADER_BUILTIN(_ReadWriteBarrier, "v", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(__getReg, "ULLii", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_ReadStatusReg, "LLii", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_WriteStatusReg, "viLLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_AddressOfReturnAddress, "v*", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-
-TARGET_HEADER_BUILTIN(__mulh, "SLLiSLLiSLLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(__umulh, "ULLiULLiULLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_BUILTIN(__builtin_arm_ld64b, "vvC*WUi*", "n", "ls64")
+TARGET_BUILTIN(__builtin_arm_st64b, "vv*WUiC*", "n", "ls64")
+TARGET_BUILTIN(__builtin_arm_st64bv, "WUiv*WUiC*", "n", "ls64")
+TARGET_BUILTIN(__builtin_arm_st64bv0, "WUiv*WUiC*", "n", "ls64")
+
+TARGET_HEADER_BUILTIN(_BitScanForward, "UcUNi*UNi", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_BitScanReverse, "UcUNi*UNi", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_BitScanForward64, "UcUNi*ULLi", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_BitScanReverse64, "UcUNi*ULLi", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+
+TARGET_HEADER_BUILTIN(_InterlockedAdd, "NiNiD*Ni", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedAnd64, "LLiLLiD*LLi", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedDecrement64, "LLiLLiD*", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedExchange64, "LLiLLiD*LLi", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedExchangeAdd64, "LLiLLiD*LLi", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedExchangeSub64, "LLiLLiD*LLi", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedIncrement64, "LLiLLiD*", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedOr64, "LLiLLiD*LLi", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedXor64, "LLiLLiD*LLi", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+
+TARGET_HEADER_BUILTIN(_InterlockedExchangeAdd_acq, "NiNiD*Ni", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedExchangeAdd_rel, "NiNiD*Ni", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedExchangeAdd_nf, "NiNiD*Ni", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedExchangeAdd8_acq, "ccD*c", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedExchangeAdd8_rel, "ccD*c", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedExchangeAdd8_nf, "ccD*c", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedExchangeAdd16_acq, "ssD*s", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedExchangeAdd16_rel, "ssD*s", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedExchangeAdd16_nf, "ssD*s", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedExchangeAdd64_acq, "LLiLLiD*LLi", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedExchangeAdd64_rel, "LLiLLiD*LLi", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedExchangeAdd64_nf, "LLiLLiD*LLi", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+
+TARGET_HEADER_BUILTIN(_InterlockedExchange8_acq, "ccD*c", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedExchange8_nf, "ccD*c", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedExchange8_rel, "ccD*c", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedExchange16_acq, "ssD*s", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedExchange16_nf, "ssD*s", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedExchange16_rel, "ssD*s", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedExchange_acq, "NiNiD*Ni", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedExchange_nf, "NiNiD*Ni", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedExchange_rel, "NiNiD*Ni", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedExchange64_acq, "LLiLLiD*LLi", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedExchange64_nf, "LLiLLiD*LLi", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedExchange64_rel, "LLiLLiD*LLi", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+
+TARGET_HEADER_BUILTIN(_InterlockedCompareExchange8_acq, "ccD*cc", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedCompareExchange8_nf, "ccD*cc", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedCompareExchange8_rel, "ccD*cc", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedCompareExchange16_acq, "ssD*ss", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedCompareExchange16_nf, "ssD*ss", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedCompareExchange16_rel, "ssD*ss", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedCompareExchange_acq, "NiNiD*NiNi", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedCompareExchange_nf, "NiNiD*NiNi", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedCompareExchange_rel, "NiNiD*NiNi", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedCompareExchange64_acq, "LLiLLiD*LLiLLi", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedCompareExchange64_nf, "LLiLLiD*LLiLLi", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedCompareExchange64_rel, "LLiLLiD*LLiLLi", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+
+TARGET_HEADER_BUILTIN(_InterlockedCompareExchange128, "UcLLiD*LLiLLiLLi*", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedCompareExchange128_acq,"UcLLiD*LLiLLiLLi*", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedCompareExchange128_nf ,"UcLLiD*LLiLLiLLi*", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedCompareExchange128_rel,"UcLLiD*LLiLLiLLi*", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+
+TARGET_HEADER_BUILTIN(_InterlockedOr8_acq, "ccD*c", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedOr8_nf, "ccD*c", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedOr8_rel, "ccD*c", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedOr16_acq, "ssD*s", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedOr16_nf, "ssD*s", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedOr16_rel, "ssD*s", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedOr_acq, "NiNiD*Ni", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedOr_nf, "NiNiD*Ni", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedOr_rel, "NiNiD*Ni", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedOr64_acq, "LLiLLiD*LLi", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedOr64_nf, "LLiLLiD*LLi", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedOr64_rel, "LLiLLiD*LLi", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+
+TARGET_HEADER_BUILTIN(_InterlockedXor8_acq, "ccD*c", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedXor8_nf, "ccD*c", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedXor8_rel, "ccD*c", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedXor16_acq, "ssD*s", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedXor16_nf, "ssD*s", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedXor16_rel, "ssD*s", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedXor_acq, "NiNiD*Ni", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedXor_nf, "NiNiD*Ni", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedXor_rel, "NiNiD*Ni", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedXor64_acq, "LLiLLiD*LLi", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedXor64_nf, "LLiLLiD*LLi", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedXor64_rel, "LLiLLiD*LLi", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+
+TARGET_HEADER_BUILTIN(_InterlockedAnd8_acq, "ccD*c", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedAnd8_nf, "ccD*c", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedAnd8_rel, "ccD*c", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedAnd16_acq, "ssD*s", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedAnd16_nf, "ssD*s", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedAnd16_rel, "ssD*s", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedAnd_acq, "NiNiD*Ni", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedAnd_nf, "NiNiD*Ni", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedAnd_rel, "NiNiD*Ni", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedAnd64_acq, "LLiLLiD*LLi", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedAnd64_nf, "LLiLLiD*LLi", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedAnd64_rel, "LLiLLiD*LLi", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+
+TARGET_HEADER_BUILTIN(_InterlockedIncrement16_acq, "ssD*", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedIncrement16_nf, "ssD*", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedIncrement16_rel, "ssD*", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedIncrement_acq, "NiNiD*", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedIncrement_nf, "NiNiD*", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedIncrement_rel, "NiNiD*", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedIncrement64_acq, "LLiLLiD*", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedIncrement64_nf, "LLiLLiD*", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedIncrement64_rel, "LLiLLiD*", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+
+TARGET_HEADER_BUILTIN(_InterlockedDecrement16_acq, "ssD*", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedDecrement16_nf, "ssD*", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedDecrement16_rel, "ssD*", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedDecrement_acq, "NiNiD*", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedDecrement_nf, "NiNiD*", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedDecrement_rel, "NiNiD*", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedDecrement64_acq, "LLiLLiD*", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedDecrement64_nf, "LLiLLiD*", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedDecrement64_rel, "LLiLLiD*", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+
+TARGET_HEADER_BUILTIN(_ReadWriteBarrier, "v", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(__getReg, "ULLii", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_ReadStatusReg, "LLii", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_WriteStatusReg, "viLLi", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_AddressOfReturnAddress, "v*", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+
+TARGET_HEADER_BUILTIN(__mulh, "SLLiSLLiSLLi", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(__umulh, "ULLiULLiULLi", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+
+TARGET_HEADER_BUILTIN(__break, "vi", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+
+TARGET_HEADER_BUILTIN(__writex18byte, "vUNiUc", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(__writex18word, "vUNiUs", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(__writex18dword, "vUNiUNi", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(__writex18qword, "vUNiULLi", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+
+TARGET_HEADER_BUILTIN(__readx18byte, "UcUNi", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(__readx18word, "UsUNi", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(__readx18dword, "UNiUNi", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(__readx18qword, "ULLiUNi", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+
+TARGET_HEADER_BUILTIN(_CopyDoubleFromInt64, "dSLLi", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_CopyFloatFromInt32, "fSi", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_CopyInt32FromFloat, "Sif", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_CopyInt64FromDouble, "SLLid", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+
+TARGET_HEADER_BUILTIN(_CountLeadingOnes, "UiUNi", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_CountLeadingOnes64, "UiULLi", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_CountLeadingSigns, "UiSNi", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_CountLeadingSigns64, "UiSLLi", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_CountLeadingZeros, "UiUNi", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_CountLeadingZeros64, "UiULLi", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_CountOneBits, "UiUNi", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_CountOneBits64, "UiULLi", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+
+TARGET_HEADER_BUILTIN(__prefetch, "vv*", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
#undef BUILTIN
#undef LANGBUILTIN
+#undef TARGET_BUILTIN
#undef TARGET_HEADER_BUILTIN
diff --git a/contrib/llvm-project/clang/include/clang/Basic/BuiltinsAArch64NeonSVEBridge.def b/contrib/llvm-project/clang/include/clang/Basic/BuiltinsAArch64NeonSVEBridge.def
new file mode 100644
index 000000000000..b8bb054d4cce
--- /dev/null
+++ b/contrib/llvm-project/clang/include/clang/Basic/BuiltinsAArch64NeonSVEBridge.def
@@ -0,0 +1,39 @@
+#ifdef GET_SVE_BUILTINS
+TARGET_BUILTIN(__builtin_sve_svget_neonq_s8, "V16Scq16Sc", "n", "sve")
+TARGET_BUILTIN(__builtin_sve_svget_neonq_s16, "V8sq8s", "n", "sve")
+TARGET_BUILTIN(__builtin_sve_svget_neonq_s32, "V4iq4i", "n", "sve")
+TARGET_BUILTIN(__builtin_sve_svget_neonq_s64, "V2Wiq2Wi", "n", "sve")
+TARGET_BUILTIN(__builtin_sve_svget_neonq_u8, "V16Ucq16Uc", "n", "sve")
+TARGET_BUILTIN(__builtin_sve_svget_neonq_u16, "V16Usq16Us", "n", "sve")
+TARGET_BUILTIN(__builtin_sve_svget_neonq_u32, "V4Uiq4Ui", "n", "sve")
+TARGET_BUILTIN(__builtin_sve_svget_neonq_u64, "V2UWiq2UWi", "n", "sve")
+TARGET_BUILTIN(__builtin_sve_svget_neonq_f16, "V8hq8h", "n", "sve")
+TARGET_BUILTIN(__builtin_sve_svget_neonq_f32, "V4fq4f", "n", "sve")
+TARGET_BUILTIN(__builtin_sve_svget_neonq_f64, "V2dq2d", "n", "sve")
+TARGET_BUILTIN(__builtin_sve_svget_neonq_bf16, "V8yq8y", "n", "sve,bf16")
+TARGET_BUILTIN(__builtin_sve_svset_neonq_s8, "q16Scq16ScV16Sc", "n", "sve")
+TARGET_BUILTIN(__builtin_sve_svset_neonq_s16, "q8sq8sV8s", "n", "sve")
+TARGET_BUILTIN(__builtin_sve_svset_neonq_s32, "q4iq4iV4i", "n", "sve")
+TARGET_BUILTIN(__builtin_sve_svset_neonq_s64, "q2Wiq2WiV2Wi", "n", "sve")
+TARGET_BUILTIN(__builtin_sve_svset_neonq_u8, "q16Ucq16UcV16Uc", "n", "sve")
+TARGET_BUILTIN(__builtin_sve_svset_neonq_u16, "q8Usq8UsV8s", "n", "sve")
+TARGET_BUILTIN(__builtin_sve_svset_neonq_u32, "q4Uiq4UiV4Ui", "n", "sve")
+TARGET_BUILTIN(__builtin_sve_svset_neonq_u64, "q2UWiq2UWiV2UWi", "n", "sve")
+TARGET_BUILTIN(__builtin_sve_svset_neonq_f16, "q8hq8hV8h", "n", "sve")
+TARGET_BUILTIN(__builtin_sve_svset_neonq_f32, "q4fq4fV4f", "n", "sve")
+TARGET_BUILTIN(__builtin_sve_svset_neonq_f64, "q2dq2dV2d", "n", "sve")
+TARGET_BUILTIN(__builtin_sve_svset_neonq_bf16, "q8yq8yV8y", "n", "sve,bf16")
+TARGET_BUILTIN(__builtin_sve_svdup_neonq_s8, "q16ScV16Sc", "n", "sve")
+TARGET_BUILTIN(__builtin_sve_svdup_neonq_s16, "q8sV8s", "n", "sve")
+TARGET_BUILTIN(__builtin_sve_svdup_neonq_s32, "q4iV4i", "n", "sve")
+TARGET_BUILTIN(__builtin_sve_svdup_neonq_s64, "q4iV4i", "n", "sve")
+TARGET_BUILTIN(__builtin_sve_svdup_neonq_u8, "q16UcV16Uc", "n", "sve")
+TARGET_BUILTIN(__builtin_sve_svdup_neonq_u16, "q8UsV8Us", "n", "sve")
+TARGET_BUILTIN(__builtin_sve_svdup_neonq_u32, "q4UiV4Ui", "n", "sve")
+TARGET_BUILTIN(__builtin_sve_svdup_neonq_u64, "q2UWiV2UWi", "n", "sve")
+TARGET_BUILTIN(__builtin_sve_svdup_neonq_f16, "q8hV8h", "n", "sve")
+TARGET_BUILTIN(__builtin_sve_svdup_neonq_f32, "q4fV4f", "n", "sve")
+TARGET_BUILTIN(__builtin_sve_svdup_neonq_f64, "q2dV2d", "n", "sve")
+TARGET_BUILTIN(__builtin_sve_svdup_neonq_bf16, "q8yV8y", "n", "sve,bf16")
+#endif
+
diff --git a/contrib/llvm-project/clang/include/clang/Basic/BuiltinsAArch64NeonSVEBridge_cg.def b/contrib/llvm-project/clang/include/clang/Basic/BuiltinsAArch64NeonSVEBridge_cg.def
new file mode 100644
index 000000000000..7717ba67b427
--- /dev/null
+++ b/contrib/llvm-project/clang/include/clang/Basic/BuiltinsAArch64NeonSVEBridge_cg.def
@@ -0,0 +1,39 @@
+#ifdef GET_SVE_LLVM_INTRINSIC_MAP
+SVEMAP2(svget_neonq_s8, SVETypeFlags::EltTyInt8),
+SVEMAP2(svget_neonq_s16, SVETypeFlags::EltTyInt16),
+SVEMAP2(svget_neonq_s32, SVETypeFlags::EltTyInt32),
+SVEMAP2(svget_neonq_s64, SVETypeFlags::EltTyInt64),
+SVEMAP2(svget_neonq_u8, SVETypeFlags::EltTyInt8),
+SVEMAP2(svget_neonq_u16, SVETypeFlags::EltTyInt16),
+SVEMAP2(svget_neonq_u32, SVETypeFlags::EltTyInt32),
+SVEMAP2(svget_neonq_u64, SVETypeFlags::EltTyInt64),
+SVEMAP2(svget_neonq_f16, SVETypeFlags::EltTyFloat16),
+SVEMAP2(svget_neonq_f32, SVETypeFlags::EltTyFloat32),
+SVEMAP2(svget_neonq_f64, SVETypeFlags::EltTyFloat64),
+SVEMAP2(svget_neonq_bf16, SVETypeFlags::EltTyBFloat16),
+SVEMAP2(svset_neonq_s8, SVETypeFlags::EltTyInt8),
+SVEMAP2(svset_neonq_s16, SVETypeFlags::EltTyInt16),
+SVEMAP2(svset_neonq_s32, SVETypeFlags::EltTyInt32),
+SVEMAP2(svset_neonq_s64, SVETypeFlags::EltTyInt64),
+SVEMAP2(svset_neonq_u8, SVETypeFlags::EltTyInt8),
+SVEMAP2(svset_neonq_u16, SVETypeFlags::EltTyInt16),
+SVEMAP2(svset_neonq_u32, SVETypeFlags::EltTyInt32),
+SVEMAP2(svset_neonq_u64, SVETypeFlags::EltTyInt64),
+SVEMAP2(svset_neonq_f16, SVETypeFlags::EltTyFloat16),
+SVEMAP2(svset_neonq_f32, SVETypeFlags::EltTyFloat32),
+SVEMAP2(svset_neonq_f64, SVETypeFlags::EltTyFloat64),
+SVEMAP2(svset_neonq_bf16, SVETypeFlags::EltTyBFloat16),
+SVEMAP2(svdup_neonq_s8, SVETypeFlags::EltTyInt8),
+SVEMAP2(svdup_neonq_s16, SVETypeFlags::EltTyInt16),
+SVEMAP2(svdup_neonq_s32, SVETypeFlags::EltTyInt32),
+SVEMAP2(svdup_neonq_s64, SVETypeFlags::EltTyInt64),
+SVEMAP2(svdup_neonq_u8, SVETypeFlags::EltTyInt8),
+SVEMAP2(svdup_neonq_u16, SVETypeFlags::EltTyInt16),
+SVEMAP2(svdup_neonq_u32, SVETypeFlags::EltTyInt32),
+SVEMAP2(svdup_neonq_u64, SVETypeFlags::EltTyInt64),
+SVEMAP2(svdup_neonq_f16, SVETypeFlags::EltTyFloat16),
+SVEMAP2(svdup_neonq_f32, SVETypeFlags::EltTyFloat32),
+SVEMAP2(svdup_neonq_f64, SVETypeFlags::EltTyFloat64),
+SVEMAP2(svdup_neonq_bf16, SVETypeFlags::EltTyBFloat16),
+#endif
+
diff --git a/contrib/llvm-project/clang/include/clang/Basic/BuiltinsAMDGPU.def b/contrib/llvm-project/clang/include/clang/Basic/BuiltinsAMDGPU.def
index 3570431d952c..74dfd1d214e8 100644
--- a/contrib/llvm-project/clang/include/clang/Basic/BuiltinsAMDGPU.def
+++ b/contrib/llvm-project/clang/include/clang/Basic/BuiltinsAMDGPU.def
@@ -62,13 +62,11 @@ BUILTIN(__builtin_amdgcn_s_sendmsg, "vIiUi", "n")
BUILTIN(__builtin_amdgcn_s_sendmsghalt, "vIiUi", "n")
BUILTIN(__builtin_amdgcn_s_barrier, "v", "n")
BUILTIN(__builtin_amdgcn_wave_barrier, "v", "n")
+BUILTIN(__builtin_amdgcn_sched_barrier, "vIi", "n")
+BUILTIN(__builtin_amdgcn_sched_group_barrier, "vIiIiIi", "n")
+BUILTIN(__builtin_amdgcn_iglp_opt, "vIi", "n")
BUILTIN(__builtin_amdgcn_s_dcache_inv, "v", "n")
BUILTIN(__builtin_amdgcn_buffer_wbinvl1, "v", "n")
-BUILTIN(__builtin_amdgcn_ds_gws_init, "vUiUi", "n")
-BUILTIN(__builtin_amdgcn_ds_gws_barrier, "vUiUi", "n")
-BUILTIN(__builtin_amdgcn_ds_gws_sema_v, "vUi", "n")
-BUILTIN(__builtin_amdgcn_ds_gws_sema_br, "vUiUi", "n")
-BUILTIN(__builtin_amdgcn_ds_gws_sema_p, "vUi", "n")
BUILTIN(__builtin_amdgcn_fence, "vUicC*", "n")
BUILTIN(__builtin_amdgcn_groupstaticsize, "Ui", "n")
@@ -97,6 +95,8 @@ BUILTIN(__builtin_amdgcn_rsq_clamp, "dd", "nc")
BUILTIN(__builtin_amdgcn_rsq_clampf, "ff", "nc")
BUILTIN(__builtin_amdgcn_sinf, "ff", "nc")
BUILTIN(__builtin_amdgcn_cosf, "ff", "nc")
+BUILTIN(__builtin_amdgcn_logf, "ff", "nc")
+BUILTIN(__builtin_amdgcn_exp2f, "ff", "nc")
BUILTIN(__builtin_amdgcn_log_clampf, "ff", "nc")
BUILTIN(__builtin_amdgcn_ldexp, "ddi", "nc")
BUILTIN(__builtin_amdgcn_ldexpf, "ffi", "nc")
@@ -116,12 +116,7 @@ BUILTIN(__builtin_amdgcn_cubema, "ffff", "nc")
BUILTIN(__builtin_amdgcn_s_sleep, "vIi", "n")
BUILTIN(__builtin_amdgcn_s_incperflevel, "vIi", "n")
BUILTIN(__builtin_amdgcn_s_decperflevel, "vIi", "n")
-BUILTIN(__builtin_amdgcn_uicmp, "WUiUiUiIi", "nc")
-BUILTIN(__builtin_amdgcn_uicmpl, "WUiWUiWUiIi", "nc")
-BUILTIN(__builtin_amdgcn_sicmp, "WUiiiIi", "nc")
-BUILTIN(__builtin_amdgcn_sicmpl, "WUiWiWiIi", "nc")
-BUILTIN(__builtin_amdgcn_fcmp, "WUiddIi", "nc")
-BUILTIN(__builtin_amdgcn_fcmpf, "WUiffIi", "nc")
+BUILTIN(__builtin_amdgcn_s_setprio, "vIs", "n")
BUILTIN(__builtin_amdgcn_ds_swizzle, "iiIi", "nc")
BUILTIN(__builtin_amdgcn_ds_permute, "iii", "nc")
BUILTIN(__builtin_amdgcn_ds_bpermute, "iii", "nc")
@@ -152,13 +147,41 @@ BUILTIN(__builtin_amdgcn_mqsad_pk_u16_u8, "WUiWUiUiWUi", "nc")
BUILTIN(__builtin_amdgcn_mqsad_u32_u8, "V4UiWUiUiV4Ui", "nc")
//===----------------------------------------------------------------------===//
+// Ballot builtins.
+//===----------------------------------------------------------------------===//
+
+TARGET_BUILTIN(__builtin_amdgcn_ballot_w32, "ZUib", "nc", "wavefrontsize32")
+TARGET_BUILTIN(__builtin_amdgcn_ballot_w64, "WUib", "nc", "wavefrontsize64")
+
+// Deprecated intrinsics in favor of __builtin_amdgn_ballot_{w32|w64}
+BUILTIN(__builtin_amdgcn_uicmp, "WUiUiUiIi", "nc")
+BUILTIN(__builtin_amdgcn_uicmpl, "WUiWUiWUiIi", "nc")
+BUILTIN(__builtin_amdgcn_sicmp, "WUiiiIi", "nc")
+BUILTIN(__builtin_amdgcn_sicmpl, "WUiWiWiIi", "nc")
+BUILTIN(__builtin_amdgcn_fcmp, "WUiddIi", "nc")
+BUILTIN(__builtin_amdgcn_fcmpf, "WUiffIi", "nc")
+
+//===----------------------------------------------------------------------===//
+// Flat addressing builtins.
+//===----------------------------------------------------------------------===//
+BUILTIN(__builtin_amdgcn_is_shared, "bvC*0", "nc")
+BUILTIN(__builtin_amdgcn_is_private, "bvC*0", "nc")
+
+//===----------------------------------------------------------------------===//
+// GWS builtins.
+//===----------------------------------------------------------------------===//
+TARGET_BUILTIN(__builtin_amdgcn_ds_gws_init, "vUiUi", "n", "gws")
+TARGET_BUILTIN(__builtin_amdgcn_ds_gws_barrier, "vUiUi", "n", "gws")
+TARGET_BUILTIN(__builtin_amdgcn_ds_gws_sema_v, "vUi", "n", "gws")
+TARGET_BUILTIN(__builtin_amdgcn_ds_gws_sema_br, "vUiUi", "n", "gws")
+TARGET_BUILTIN(__builtin_amdgcn_ds_gws_sema_p, "vUi", "n", "gws")
+
+//===----------------------------------------------------------------------===//
// CI+ only builtins.
//===----------------------------------------------------------------------===//
TARGET_BUILTIN(__builtin_amdgcn_s_dcache_inv_vol, "v", "n", "ci-insts")
TARGET_BUILTIN(__builtin_amdgcn_buffer_wbinvl1_vol, "v", "n", "ci-insts")
TARGET_BUILTIN(__builtin_amdgcn_ds_gws_sema_release_all, "vUi", "n", "ci-insts")
-TARGET_BUILTIN(__builtin_amdgcn_is_shared, "bvC*0", "nc", "flat-address-space")
-TARGET_BUILTIN(__builtin_amdgcn_is_private, "bvC*0", "nc", "flat-address-space")
//===----------------------------------------------------------------------===//
// Interpolation builtins.
@@ -196,17 +219,46 @@ TARGET_BUILTIN(__builtin_amdgcn_perm, "UiUiUiUi", "nc", "gfx8-insts")
TARGET_BUILTIN(__builtin_amdgcn_fmed3h, "hhhh", "nc", "gfx9-insts")
+TARGET_BUILTIN(__builtin_amdgcn_global_atomic_fadd_f64, "dd*1d", "t", "gfx90a-insts")
+TARGET_BUILTIN(__builtin_amdgcn_global_atomic_fadd_f32, "ff*1f", "t", "atomic-fadd-rtn-insts")
+TARGET_BUILTIN(__builtin_amdgcn_global_atomic_fadd_v2f16, "V2hV2h*1V2h", "t", "atomic-buffer-global-pk-add-f16-insts")
+TARGET_BUILTIN(__builtin_amdgcn_global_atomic_fmin_f64, "dd*1d", "t", "gfx90a-insts")
+TARGET_BUILTIN(__builtin_amdgcn_global_atomic_fmax_f64, "dd*1d", "t", "gfx90a-insts")
+
+TARGET_BUILTIN(__builtin_amdgcn_flat_atomic_fadd_f64, "dd*0d", "t", "gfx90a-insts")
+TARGET_BUILTIN(__builtin_amdgcn_flat_atomic_fmin_f64, "dd*0d", "t", "gfx90a-insts")
+TARGET_BUILTIN(__builtin_amdgcn_flat_atomic_fmax_f64, "dd*0d", "t", "gfx90a-insts")
+
+TARGET_BUILTIN(__builtin_amdgcn_ds_atomic_fadd_f64, "dd*3d", "t", "gfx90a-insts")
+TARGET_BUILTIN(__builtin_amdgcn_ds_atomic_fadd_f32, "ff*3f", "t", "gfx8-insts")
+
+TARGET_BUILTIN(__builtin_amdgcn_flat_atomic_fadd_f32, "ff*0f", "t", "gfx940-insts")
+TARGET_BUILTIN(__builtin_amdgcn_flat_atomic_fadd_v2f16, "V2hV2h*0V2h", "t", "atomic-flat-pk-add-16-insts")
+TARGET_BUILTIN(__builtin_amdgcn_flat_atomic_fadd_v2bf16, "V2sV2s*0V2s", "t", "atomic-flat-pk-add-16-insts")
+TARGET_BUILTIN(__builtin_amdgcn_global_atomic_fadd_v2bf16, "V2sV2s*1V2s", "t", "atomic-global-pk-add-bf16-inst")
+TARGET_BUILTIN(__builtin_amdgcn_ds_atomic_fadd_v2bf16, "V2sV2s*3V2s", "t", "atomic-ds-pk-add-16-insts")
+TARGET_BUILTIN(__builtin_amdgcn_ds_atomic_fadd_v2f16, "V2hV2h*3V2h", "t", "atomic-ds-pk-add-16-insts")
+
//===----------------------------------------------------------------------===//
// Deep learning builtins.
//===----------------------------------------------------------------------===//
-TARGET_BUILTIN(__builtin_amdgcn_fdot2, "fV2hV2hfIb", "nc", "dot7-insts")
+TARGET_BUILTIN(__builtin_amdgcn_fdot2, "fV2hV2hfIb", "nc", "dot10-insts")
+TARGET_BUILTIN(__builtin_amdgcn_fdot2_f16_f16, "hV2hV2hh", "nc", "dot9-insts")
+TARGET_BUILTIN(__builtin_amdgcn_fdot2_bf16_bf16, "sV2sV2ss", "nc", "dot9-insts")
+TARGET_BUILTIN(__builtin_amdgcn_fdot2_f32_bf16, "fV2sV2sfIb", "nc", "dot9-insts")
TARGET_BUILTIN(__builtin_amdgcn_sdot2, "SiV2SsV2SsSiIb", "nc", "dot2-insts")
TARGET_BUILTIN(__builtin_amdgcn_udot2, "UiV2UsV2UsUiIb", "nc", "dot2-insts")
TARGET_BUILTIN(__builtin_amdgcn_sdot4, "SiSiSiSiIb", "nc", "dot1-insts")
TARGET_BUILTIN(__builtin_amdgcn_udot4, "UiUiUiUiIb", "nc", "dot7-insts")
+TARGET_BUILTIN(__builtin_amdgcn_sudot4, "iIbiIbiiIb", "nc", "dot8-insts")
TARGET_BUILTIN(__builtin_amdgcn_sdot8, "SiSiSiSiIb", "nc", "dot1-insts")
TARGET_BUILTIN(__builtin_amdgcn_udot8, "UiUiUiUiIb", "nc", "dot7-insts")
+TARGET_BUILTIN(__builtin_amdgcn_sudot8, "iIbiIbiiIb", "nc", "dot8-insts")
+TARGET_BUILTIN(__builtin_amdgcn_dot4_f32_fp8_bf8, "fUiUif", "nc", "gfx12-insts")
+TARGET_BUILTIN(__builtin_amdgcn_dot4_f32_bf8_fp8, "fUiUif", "nc", "gfx12-insts")
+TARGET_BUILTIN(__builtin_amdgcn_dot4_f32_fp8_fp8, "fUiUif", "nc", "gfx12-insts")
+TARGET_BUILTIN(__builtin_amdgcn_dot4_f32_bf8_bf8, "fUiUif", "nc", "gfx12-insts")
//===----------------------------------------------------------------------===//
// GFX10+ only builtins.
@@ -226,6 +278,43 @@ TARGET_BUILTIN(__builtin_amdgcn_image_bvh_intersect_ray_h, "V4UiUifV4fV4hV4hV4Ui
TARGET_BUILTIN(__builtin_amdgcn_image_bvh_intersect_ray_l, "V4UiWUifV4fV4fV4fV4Ui", "nc", "gfx10-insts")
TARGET_BUILTIN(__builtin_amdgcn_image_bvh_intersect_ray_lh, "V4UiWUifV4fV4hV4hV4Ui", "nc", "gfx10-insts")
+
+//===----------------------------------------------------------------------===//
+// GFX11+ only builtins.
+//===----------------------------------------------------------------------===//
+
+// TODO: This is a no-op in wave32. Should the builtin require wavefrontsize64?
+TARGET_BUILTIN(__builtin_amdgcn_permlane64, "UiUi", "nc", "gfx11-insts")
+TARGET_BUILTIN(__builtin_amdgcn_s_wait_event_export_ready, "v", "n", "gfx11-insts")
+
+//===----------------------------------------------------------------------===//
+// WMMA builtins.
+// Postfix w32 indicates the builtin requires wavefront size of 32.
+// Postfix w64 indicates the builtin requires wavefront size of 64.
+//===----------------------------------------------------------------------===//
+TARGET_BUILTIN(__builtin_amdgcn_wmma_f32_16x16x16_f16_w32, "V8fV16hV16hV8f", "nc", "gfx11-insts")
+TARGET_BUILTIN(__builtin_amdgcn_wmma_f32_16x16x16_bf16_w32, "V8fV16sV16sV8f", "nc", "gfx11-insts")
+TARGET_BUILTIN(__builtin_amdgcn_wmma_f16_16x16x16_f16_w32, "V16hV16hV16hV16hIb", "nc", "gfx11-insts")
+TARGET_BUILTIN(__builtin_amdgcn_wmma_bf16_16x16x16_bf16_w32, "V16sV16sV16sV16sIb", "nc", "gfx11-insts")
+TARGET_BUILTIN(__builtin_amdgcn_wmma_f16_16x16x16_f16_tied_w32, "V16hV16hV16hV16hIb", "nc", "gfx11-insts")
+TARGET_BUILTIN(__builtin_amdgcn_wmma_bf16_16x16x16_bf16_tied_w32, "V16sV16sV16sV16sIb", "nc", "gfx11-insts")
+TARGET_BUILTIN(__builtin_amdgcn_wmma_i32_16x16x16_iu8_w32, "V8iIbV4iIbV4iV8iIb", "nc", "gfx11-insts")
+TARGET_BUILTIN(__builtin_amdgcn_wmma_i32_16x16x16_iu4_w32, "V8iIbV2iIbV2iV8iIb", "nc", "gfx11-insts")
+
+TARGET_BUILTIN(__builtin_amdgcn_wmma_f32_16x16x16_f16_w64, "V4fV16hV16hV4f", "nc", "gfx11-insts")
+TARGET_BUILTIN(__builtin_amdgcn_wmma_f32_16x16x16_bf16_w64, "V4fV16sV16sV4f", "nc", "gfx11-insts")
+TARGET_BUILTIN(__builtin_amdgcn_wmma_f16_16x16x16_f16_w64, "V8hV16hV16hV8hIb", "nc", "gfx11-insts")
+TARGET_BUILTIN(__builtin_amdgcn_wmma_bf16_16x16x16_bf16_w64, "V8sV16sV16sV8sIb", "nc", "gfx11-insts")
+TARGET_BUILTIN(__builtin_amdgcn_wmma_f16_16x16x16_f16_tied_w64, "V8hV16hV16hV8hIb", "nc", "gfx11-insts")
+TARGET_BUILTIN(__builtin_amdgcn_wmma_bf16_16x16x16_bf16_tied_w64, "V8sV16sV16sV8sIb", "nc", "gfx11-insts")
+TARGET_BUILTIN(__builtin_amdgcn_wmma_i32_16x16x16_iu8_w64, "V4iIbV4iIbV4iV4iIb", "nc", "gfx11-insts")
+TARGET_BUILTIN(__builtin_amdgcn_wmma_i32_16x16x16_iu4_w64, "V4iIbV2iIbV2iV4iIb", "nc", "gfx11-insts")
+
+TARGET_BUILTIN(__builtin_amdgcn_s_sendmsg_rtn, "UiUIi", "n", "gfx11-insts")
+TARGET_BUILTIN(__builtin_amdgcn_s_sendmsg_rtnl, "UWiUIi", "n", "gfx11-insts")
+
+TARGET_BUILTIN(__builtin_amdgcn_ds_bvh_stack_rtn, "V2UiUiUiV4UiIi", "n", "gfx11-insts")
+
//===----------------------------------------------------------------------===//
// Special builtins.
//===----------------------------------------------------------------------===//
@@ -285,5 +374,129 @@ TARGET_BUILTIN(__builtin_amdgcn_mfma_f32_16x16x16bf16_1k, "V4fV4sV4sV4fIiIiIi",
TARGET_BUILTIN(__builtin_amdgcn_mfma_f64_16x16x4f64, "V4dddV4dIiIiIi", "nc", "mai-insts")
TARGET_BUILTIN(__builtin_amdgcn_mfma_f64_4x4x4f64, "ddddIiIiIi", "nc", "mai-insts")
+TARGET_BUILTIN(__builtin_amdgcn_mfma_i32_16x16x32_i8, "V4iWiWiV4iIiIiIi", "nc", "mai-insts")
+TARGET_BUILTIN(__builtin_amdgcn_mfma_i32_32x32x16_i8, "V16iWiWiV16iIiIiIi", "nc", "mai-insts")
+TARGET_BUILTIN(__builtin_amdgcn_mfma_f32_16x16x8_xf32, "V4fV2fV2fV4fIiIiIi", "nc", "mai-insts")
+TARGET_BUILTIN(__builtin_amdgcn_mfma_f32_32x32x4_xf32, "V16fV2fV2fV16fIiIiIi", "nc", "mai-insts")
+TARGET_BUILTIN(__builtin_amdgcn_mfma_f32_16x16x32_bf8_bf8, "V4fWiWiV4fIiIiIi", "nc", "fp8-insts")
+TARGET_BUILTIN(__builtin_amdgcn_mfma_f32_16x16x32_bf8_fp8, "V4fWiWiV4fIiIiIi", "nc", "fp8-insts")
+TARGET_BUILTIN(__builtin_amdgcn_mfma_f32_16x16x32_fp8_bf8, "V4fWiWiV4fIiIiIi", "nc", "fp8-insts")
+TARGET_BUILTIN(__builtin_amdgcn_mfma_f32_16x16x32_fp8_fp8, "V4fWiWiV4fIiIiIi", "nc", "fp8-insts")
+TARGET_BUILTIN(__builtin_amdgcn_mfma_f32_32x32x16_bf8_bf8, "V16fWiWiV16fIiIiIi", "nc", "fp8-insts")
+TARGET_BUILTIN(__builtin_amdgcn_mfma_f32_32x32x16_bf8_fp8, "V16fWiWiV16fIiIiIi", "nc", "fp8-insts")
+TARGET_BUILTIN(__builtin_amdgcn_mfma_f32_32x32x16_fp8_bf8, "V16fWiWiV16fIiIiIi", "nc", "fp8-insts")
+TARGET_BUILTIN(__builtin_amdgcn_mfma_f32_32x32x16_fp8_fp8, "V16fWiWiV16fIiIiIi", "nc", "fp8-insts")
+TARGET_BUILTIN(__builtin_amdgcn_smfmac_f32_16x16x32_f16, "V4fV4hV8hV4fiIiIi", "nc", "mai-insts")
+TARGET_BUILTIN(__builtin_amdgcn_smfmac_f32_32x32x16_f16, "V16fV4hV8hV16fiIiIi", "nc", "mai-insts")
+TARGET_BUILTIN(__builtin_amdgcn_smfmac_f32_16x16x32_bf16, "V4fV4sV8sV4fiIiIi", "nc", "mai-insts")
+TARGET_BUILTIN(__builtin_amdgcn_smfmac_f32_32x32x16_bf16, "V16fV4sV8sV16fiIiIi", "nc", "mai-insts")
+TARGET_BUILTIN(__builtin_amdgcn_smfmac_i32_16x16x64_i8, "V4iV2iV4iV4iiIiIi", "nc", "mai-insts")
+TARGET_BUILTIN(__builtin_amdgcn_smfmac_i32_32x32x32_i8, "V16iV2iV4iV16iiIiIi", "nc", "mai-insts")
+TARGET_BUILTIN(__builtin_amdgcn_smfmac_f32_16x16x64_bf8_bf8, "V4fV2iV4iV4fiIiIi", "nc", "fp8-insts")
+TARGET_BUILTIN(__builtin_amdgcn_smfmac_f32_16x16x64_bf8_fp8, "V4fV2iV4iV4fiIiIi", "nc", "fp8-insts")
+TARGET_BUILTIN(__builtin_amdgcn_smfmac_f32_16x16x64_fp8_bf8, "V4fV2iV4iV4fiIiIi", "nc", "fp8-insts")
+TARGET_BUILTIN(__builtin_amdgcn_smfmac_f32_16x16x64_fp8_fp8, "V4fV2iV4iV4fiIiIi", "nc", "fp8-insts")
+TARGET_BUILTIN(__builtin_amdgcn_smfmac_f32_32x32x32_bf8_bf8, "V16fV2iV4iV16fiIiIi", "nc", "fp8-insts")
+TARGET_BUILTIN(__builtin_amdgcn_smfmac_f32_32x32x32_bf8_fp8, "V16fV2iV4iV16fiIiIi", "nc", "fp8-insts")
+TARGET_BUILTIN(__builtin_amdgcn_smfmac_f32_32x32x32_fp8_bf8, "V16fV2iV4iV16fiIiIi", "nc", "fp8-insts")
+TARGET_BUILTIN(__builtin_amdgcn_smfmac_f32_32x32x32_fp8_fp8, "V16fV2iV4iV16fiIiIi", "nc", "fp8-insts")
+
+TARGET_BUILTIN(__builtin_amdgcn_cvt_f32_bf8, "fiIi", "nc", "fp8-conversion-insts")
+TARGET_BUILTIN(__builtin_amdgcn_cvt_f32_fp8, "fiIi", "nc", "fp8-conversion-insts")
+TARGET_BUILTIN(__builtin_amdgcn_cvt_pk_f32_bf8, "V2fiIb", "nc", "fp8-conversion-insts")
+TARGET_BUILTIN(__builtin_amdgcn_cvt_pk_f32_fp8, "V2fiIb", "nc", "fp8-conversion-insts")
+TARGET_BUILTIN(__builtin_amdgcn_cvt_pk_bf8_f32, "iffiIb", "nc", "fp8-conversion-insts")
+TARGET_BUILTIN(__builtin_amdgcn_cvt_pk_fp8_f32, "iffiIb", "nc", "fp8-conversion-insts")
+TARGET_BUILTIN(__builtin_amdgcn_cvt_sr_bf8_f32, "ifiiIi", "nc", "fp8-conversion-insts")
+TARGET_BUILTIN(__builtin_amdgcn_cvt_sr_fp8_f32, "ifiiIi", "nc", "fp8-conversion-insts")
+
+//===----------------------------------------------------------------------===//
+// GFX12+ only builtins.
+//===----------------------------------------------------------------------===//
+
+TARGET_BUILTIN(__builtin_amdgcn_s_sleep_var, "vUi", "n", "gfx12-insts")
+TARGET_BUILTIN(__builtin_amdgcn_permlane16_var, "UiUiUiUiIbIb", "nc", "gfx12-insts")
+TARGET_BUILTIN(__builtin_amdgcn_permlanex16_var, "UiUiUiUiIbIb", "nc", "gfx12-insts")
+TARGET_BUILTIN(__builtin_amdgcn_s_barrier_signal, "vIi", "n", "gfx12-insts")
+TARGET_BUILTIN(__builtin_amdgcn_s_barrier_signal_var, "vi", "n", "gfx12-insts")
+TARGET_BUILTIN(__builtin_amdgcn_s_barrier_wait, "vIs", "n", "gfx12-insts")
+TARGET_BUILTIN(__builtin_amdgcn_s_barrier_signal_isfirst, "bIi", "n", "gfx12-insts")
+TARGET_BUILTIN(__builtin_amdgcn_s_barrier_signal_isfirst_var, "bi", "n", "gfx12-insts")
+TARGET_BUILTIN(__builtin_amdgcn_s_barrier_init, "vii", "n", "gfx12-insts")
+TARGET_BUILTIN(__builtin_amdgcn_s_barrier_join, "vi", "n", "gfx12-insts")
+TARGET_BUILTIN(__builtin_amdgcn_s_wakeup_barrier, "vi", "n", "gfx12-insts")
+TARGET_BUILTIN(__builtin_amdgcn_s_barrier_leave, "b", "n", "gfx12-insts")
+TARGET_BUILTIN(__builtin_amdgcn_s_get_barrier_state, "Uii", "n", "gfx12-insts")
+
+TARGET_BUILTIN(__builtin_amdgcn_global_load_tr_v2i32, "V2iV2i*1", "nc", "gfx12-insts,wavefrontsize32")
+TARGET_BUILTIN(__builtin_amdgcn_global_load_tr_v8i16, "V8sV8s*1", "nc", "gfx12-insts,wavefrontsize32")
+TARGET_BUILTIN(__builtin_amdgcn_global_load_tr_v8f16, "V8hV8h*1", "nc", "gfx12-insts,wavefrontsize32")
+
+TARGET_BUILTIN(__builtin_amdgcn_global_load_tr_i32, "ii*1", "nc", "gfx12-insts,wavefrontsize64")
+TARGET_BUILTIN(__builtin_amdgcn_global_load_tr_v4i16, "V4sV4s*1", "nc", "gfx12-insts,wavefrontsize64")
+TARGET_BUILTIN(__builtin_amdgcn_global_load_tr_v4f16, "V4hV4h*1", "nc", "gfx12-insts,wavefrontsize64")
+
+//===----------------------------------------------------------------------===//
+// WMMA builtins.
+// Postfix w32 indicates the builtin requires wavefront size of 32.
+// Postfix w64 indicates the builtin requires wavefront size of 64.
+//
+// Some of these are very similar to their GFX11 counterparts, but they don't
+// require replication of the A,B matrices, so they use fewer vector elements.
+// Therefore, we add an "_gfx12" suffix to distinguish them from the existing
+// builtins.
+//===----------------------------------------------------------------------===//
+TARGET_BUILTIN(__builtin_amdgcn_wmma_f32_16x16x16_f16_w32_gfx12, "V8fV8hV8hV8f", "nc", "gfx12-insts,wavefrontsize32")
+TARGET_BUILTIN(__builtin_amdgcn_wmma_f32_16x16x16_bf16_w32_gfx12, "V8fV8sV8sV8f", "nc", "gfx12-insts,wavefrontsize32")
+TARGET_BUILTIN(__builtin_amdgcn_wmma_f16_16x16x16_f16_w32_gfx12, "V8hV8hV8hV8h", "nc", "gfx12-insts,wavefrontsize32")
+TARGET_BUILTIN(__builtin_amdgcn_wmma_bf16_16x16x16_bf16_w32_gfx12, "V8sV8sV8sV8s", "nc", "gfx12-insts,wavefrontsize32")
+TARGET_BUILTIN(__builtin_amdgcn_wmma_i32_16x16x16_iu8_w32_gfx12, "V8iIbV2iIbV2iV8iIb", "nc", "gfx12-insts,wavefrontsize32")
+TARGET_BUILTIN(__builtin_amdgcn_wmma_i32_16x16x16_iu4_w32_gfx12, "V8iIbiIbiV8iIb", "nc", "gfx12-insts,wavefrontsize32")
+// These are gfx12-only, but for consistency with the other WMMA variants we're
+// keeping the "_gfx12" suffix.
+TARGET_BUILTIN(__builtin_amdgcn_wmma_f32_16x16x16_fp8_fp8_w32_gfx12, "V8fV2iV2iV8f", "nc", "gfx12-insts,wavefrontsize32")
+TARGET_BUILTIN(__builtin_amdgcn_wmma_f32_16x16x16_fp8_bf8_w32_gfx12, "V8fV2iV2iV8f", "nc", "gfx12-insts,wavefrontsize32")
+TARGET_BUILTIN(__builtin_amdgcn_wmma_f32_16x16x16_bf8_fp8_w32_gfx12, "V8fV2iV2iV8f", "nc", "gfx12-insts,wavefrontsize32")
+TARGET_BUILTIN(__builtin_amdgcn_wmma_f32_16x16x16_bf8_bf8_w32_gfx12, "V8fV2iV2iV8f", "nc", "gfx12-insts,wavefrontsize32")
+TARGET_BUILTIN(__builtin_amdgcn_wmma_i32_16x16x32_iu4_w32_gfx12, "V8iIbV2iIbV2iV8iIb", "nc", "gfx12-insts,wavefrontsize32")
+
+TARGET_BUILTIN(__builtin_amdgcn_wmma_f32_16x16x16_f16_w64_gfx12, "V4fV4hV4hV4f", "nc", "gfx12-insts,wavefrontsize64")
+TARGET_BUILTIN(__builtin_amdgcn_wmma_f32_16x16x16_bf16_w64_gfx12, "V4fV4sV4sV4f", "nc", "gfx12-insts,wavefrontsize64")
+TARGET_BUILTIN(__builtin_amdgcn_wmma_f16_16x16x16_f16_w64_gfx12, "V4hV4hV4hV4h", "nc", "gfx12-insts,wavefrontsize64")
+TARGET_BUILTIN(__builtin_amdgcn_wmma_bf16_16x16x16_bf16_w64_gfx12, "V4sV4sV4sV4s", "nc", "gfx12-insts,wavefrontsize64")
+TARGET_BUILTIN(__builtin_amdgcn_wmma_i32_16x16x16_iu8_w64_gfx12, "V4iIbiIbiV4iIb", "nc", "gfx12-insts,wavefrontsize64")
+TARGET_BUILTIN(__builtin_amdgcn_wmma_i32_16x16x16_iu4_w64_gfx12, "V4iIbiIbiV4iIb", "nc", "gfx12-insts,wavefrontsize64")
+// These are gfx12-only, but for consistency with the other WMMA variants we're
+// keeping the "_gfx12" suffix.
+TARGET_BUILTIN(__builtin_amdgcn_wmma_f32_16x16x16_fp8_fp8_w64_gfx12, "V4fiiV4f", "nc", "gfx12-insts,wavefrontsize64")
+TARGET_BUILTIN(__builtin_amdgcn_wmma_f32_16x16x16_fp8_bf8_w64_gfx12, "V4fiiV4f", "nc", "gfx12-insts,wavefrontsize64")
+TARGET_BUILTIN(__builtin_amdgcn_wmma_f32_16x16x16_bf8_fp8_w64_gfx12, "V4fiiV4f", "nc", "gfx12-insts,wavefrontsize64")
+TARGET_BUILTIN(__builtin_amdgcn_wmma_f32_16x16x16_bf8_bf8_w64_gfx12, "V4fiiV4f", "nc", "gfx12-insts,wavefrontsize64")
+TARGET_BUILTIN(__builtin_amdgcn_wmma_i32_16x16x32_iu4_w64_gfx12, "V4iIbiIbiV4iIb", "nc", "gfx12-insts,wavefrontsize64")
+
+TARGET_BUILTIN(__builtin_amdgcn_swmmac_f32_16x16x32_f16_w32, "V8fV8hV16hV8fs", "nc", "gfx12-insts,wavefrontsize32")
+TARGET_BUILTIN(__builtin_amdgcn_swmmac_f32_16x16x32_bf16_w32, "V8fV8sV16sV8fs", "nc", "gfx12-insts,wavefrontsize32")
+TARGET_BUILTIN(__builtin_amdgcn_swmmac_f16_16x16x32_f16_w32, "V8hV8hV16hV8hs", "nc", "gfx12-insts,wavefrontsize32")
+TARGET_BUILTIN(__builtin_amdgcn_swmmac_bf16_16x16x32_bf16_w32, "V8sV8sV16sV8ss", "nc", "gfx12-insts,wavefrontsize32")
+TARGET_BUILTIN(__builtin_amdgcn_swmmac_i32_16x16x32_iu8_w32, "V8iIbV2iIbV4iV8isIb", "nc", "gfx12-insts,wavefrontsize32")
+TARGET_BUILTIN(__builtin_amdgcn_swmmac_i32_16x16x32_iu4_w32, "V8iIbiIbV2iV8isIb", "nc", "gfx12-insts,wavefrontsize32")
+TARGET_BUILTIN(__builtin_amdgcn_swmmac_i32_16x16x64_iu4_w32, "V8iIbV2iIbV4iV8isIb", "nc", "gfx12-insts,wavefrontsize32")
+TARGET_BUILTIN(__builtin_amdgcn_swmmac_f32_16x16x32_fp8_fp8_w32, "V8fV2iV4iV8fs", "nc", "gfx12-insts,wavefrontsize32")
+TARGET_BUILTIN(__builtin_amdgcn_swmmac_f32_16x16x32_fp8_bf8_w32, "V8fV2iV4iV8fs", "nc", "gfx12-insts,wavefrontsize32")
+TARGET_BUILTIN(__builtin_amdgcn_swmmac_f32_16x16x32_bf8_fp8_w32, "V8fV2iV4iV8fs", "nc", "gfx12-insts,wavefrontsize32")
+TARGET_BUILTIN(__builtin_amdgcn_swmmac_f32_16x16x32_bf8_bf8_w32, "V8fV2iV4iV8fs", "nc", "gfx12-insts,wavefrontsize32")
+
+TARGET_BUILTIN(__builtin_amdgcn_swmmac_f32_16x16x32_f16_w64, "V4fV4hV8hV4fs", "nc", "gfx12-insts,wavefrontsize64")
+TARGET_BUILTIN(__builtin_amdgcn_swmmac_f32_16x16x32_bf16_w64, "V4fV4sV8sV4fs", "nc", "gfx12-insts,wavefrontsize64")
+TARGET_BUILTIN(__builtin_amdgcn_swmmac_f16_16x16x32_f16_w64, "V4hV4hV8hV4hs", "nc", "gfx12-insts,wavefrontsize64")
+TARGET_BUILTIN(__builtin_amdgcn_swmmac_bf16_16x16x32_bf16_w64, "V4sV4sV8sV4ss", "nc", "gfx12-insts,wavefrontsize64")
+TARGET_BUILTIN(__builtin_amdgcn_swmmac_i32_16x16x32_iu8_w64, "V4iIbiIbV2iV4isIb", "nc", "gfx12-insts,wavefrontsize64")
+TARGET_BUILTIN(__builtin_amdgcn_swmmac_i32_16x16x32_iu4_w64, "V4iIbiIbiV4isIb", "nc", "gfx12-insts,wavefrontsize64")
+TARGET_BUILTIN(__builtin_amdgcn_swmmac_i32_16x16x64_iu4_w64, "V4iIbiIbV2iV4isIb", "nc", "gfx12-insts,wavefrontsize64")
+TARGET_BUILTIN(__builtin_amdgcn_swmmac_f32_16x16x32_fp8_fp8_w64, "V4fiV2iV4fs", "nc", "gfx12-insts,wavefrontsize64")
+TARGET_BUILTIN(__builtin_amdgcn_swmmac_f32_16x16x32_fp8_bf8_w64, "V4fiV2iV4fs", "nc", "gfx12-insts,wavefrontsize64")
+TARGET_BUILTIN(__builtin_amdgcn_swmmac_f32_16x16x32_bf8_fp8_w64, "V4fiV2iV4fs", "nc", "gfx12-insts,wavefrontsize64")
+TARGET_BUILTIN(__builtin_amdgcn_swmmac_f32_16x16x32_bf8_bf8_w64, "V4fiV2iV4fs", "nc", "gfx12-insts,wavefrontsize64")
+
#undef BUILTIN
#undef TARGET_BUILTIN
diff --git a/contrib/llvm-project/clang/include/clang/Basic/BuiltinsARM.def b/contrib/llvm-project/clang/include/clang/Basic/BuiltinsARM.def
index be20c24aa28a..9ee918cb2147 100644
--- a/contrib/llvm-project/clang/include/clang/Basic/BuiltinsARM.def
+++ b/contrib/llvm-project/clang/include/clang/Basic/BuiltinsARM.def
@@ -17,6 +17,10 @@
# define LANGBUILTIN(ID, TYPE, ATTRS, BUILTIN_LANG) BUILTIN(ID, TYPE, ATTRS)
#endif
+#if defined(BUILTIN) && !defined(TARGET_BUILTIN)
+# define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) BUILTIN(ID, TYPE, ATTRS)
+#endif
+
#if defined(BUILTIN) && !defined(TARGET_HEADER_BUILTIN)
# define TARGET_HEADER_BUILTIN(ID, TYPE, ATTRS, HEADER, LANG, FEATURE) BUILTIN(ID, TYPE, ATTRS)
#endif
@@ -115,6 +119,8 @@ BUILTIN(__builtin_arm_smusdx, "iii", "nc")
// Bit manipulation
BUILTIN(__builtin_arm_rbit, "UiUi", "nc")
+BUILTIN(__builtin_arm_clz, "UiZUi", "nc")
+BUILTIN(__builtin_arm_clz64, "UiWUi", "nc")
BUILTIN(__builtin_arm_cls, "UiZUi", "nc")
BUILTIN(__builtin_arm_cls64, "UiWUi", "nc")
@@ -157,14 +163,14 @@ BUILTIN(__builtin_arm_mrrc, "LLUiUIiUIiUIi", "")
BUILTIN(__builtin_arm_mrrc2, "LLUiUIiUIiUIi", "")
// CRC32
-BUILTIN(__builtin_arm_crc32b, "UiUiUc", "nc")
-BUILTIN(__builtin_arm_crc32cb, "UiUiUc", "nc")
-BUILTIN(__builtin_arm_crc32h, "UiUiUs", "nc")
-BUILTIN(__builtin_arm_crc32ch, "UiUiUs", "nc")
-BUILTIN(__builtin_arm_crc32w, "UiUiUi", "nc")
-BUILTIN(__builtin_arm_crc32cw, "UiUiUi", "nc")
-BUILTIN(__builtin_arm_crc32d, "UiUiLLUi", "nc")
-BUILTIN(__builtin_arm_crc32cd, "UiUiLLUi", "nc")
+TARGET_BUILTIN(__builtin_arm_crc32b, "UiUiUc", "nc", "crc")
+TARGET_BUILTIN(__builtin_arm_crc32cb, "UiUiUc", "nc", "crc")
+TARGET_BUILTIN(__builtin_arm_crc32h, "UiUiUs", "nc", "crc")
+TARGET_BUILTIN(__builtin_arm_crc32ch, "UiUiUs", "nc", "crc")
+TARGET_BUILTIN(__builtin_arm_crc32w, "UiUiUi", "nc", "crc")
+TARGET_BUILTIN(__builtin_arm_crc32cw, "UiUiUi", "nc", "crc")
+TARGET_BUILTIN(__builtin_arm_crc32d, "UiUiLLUi", "nc", "crc")
+TARGET_BUILTIN(__builtin_arm_crc32cd, "UiUiLLUi", "nc", "crc")
// ARMv8-M Security Extensions a.k.a CMSE
BUILTIN(__builtin_arm_cmse_TT, "Uiv*", "n")
@@ -197,6 +203,9 @@ BUILTIN(__builtin_arm_wsr, "vcC*Ui", "nc")
BUILTIN(__builtin_arm_wsr64, "vcC*LLUi", "nc")
BUILTIN(__builtin_arm_wsrp, "vcC*vC*", "nc")
+// Misc
+BUILTIN(__builtin_sponentry, "v*", "c")
+
// Builtins for implementing ACLE MVE intrinsics. (Unlike NEON, these
// don't need to live in a separate BuiltinsMVE.def, because they
// aren't included from both here and BuiltinsAArch64.def.)
@@ -222,118 +231,119 @@ LANGBUILTIN(_MoveFromCoprocessor2, "UiIUiIUiIUiIUiIUi", "", ALL_MS_LANGUAGES)
LANGBUILTIN(_MoveToCoprocessor, "vUiIUiIUiIUiIUiIUi", "", ALL_MS_LANGUAGES)
LANGBUILTIN(_MoveToCoprocessor2, "vUiIUiIUiIUiIUiIUi", "", ALL_MS_LANGUAGES)
-TARGET_HEADER_BUILTIN(_BitScanForward, "UcUNi*UNi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_BitScanReverse, "UcUNi*UNi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_BitScanForward64, "UcUNi*ULLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_BitScanReverse64, "UcUNi*ULLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-
-TARGET_HEADER_BUILTIN(_InterlockedAnd64, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedDecrement64, "LLiLLiD*", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedExchange64, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedExchangeAdd64, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedExchangeSub64, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedIncrement64, "LLiLLiD*", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedOr64, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedXor64, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-
-TARGET_HEADER_BUILTIN(_InterlockedExchangeAdd_acq, "NiNiD*Ni", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedExchangeAdd_rel, "NiNiD*Ni", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedExchangeAdd_nf, "NiNiD*Ni", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedExchangeAdd8_acq, "ccD*c", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedExchangeAdd8_rel, "ccD*c", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedExchangeAdd8_nf, "ccD*c", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedExchangeAdd16_acq, "ssD*s", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedExchangeAdd16_rel, "ssD*s", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedExchangeAdd16_nf, "ssD*s", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedExchangeAdd64_acq, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedExchangeAdd64_rel, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedExchangeAdd64_nf, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-
-TARGET_HEADER_BUILTIN(_InterlockedExchange8_acq, "ccD*c", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedExchange8_nf, "ccD*c", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedExchange8_rel, "ccD*c", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedExchange16_acq, "ssD*s", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedExchange16_nf, "ssD*s", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedExchange16_rel, "ssD*s", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedExchange_acq, "NiNiD*Ni", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedExchange_nf, "NiNiD*Ni", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedExchange_rel, "NiNiD*Ni", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedExchange64_acq, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedExchange64_nf, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedExchange64_rel, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-
-TARGET_HEADER_BUILTIN(_InterlockedCompareExchange8_acq, "ccD*cc", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedCompareExchange8_nf, "ccD*cc", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedCompareExchange8_rel, "ccD*cc", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedCompareExchange16_acq, "ssD*ss", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedCompareExchange16_nf, "ssD*ss", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedCompareExchange16_rel, "ssD*ss", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedCompareExchange_acq, "NiNiD*NiNi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedCompareExchange_nf, "NiNiD*NiNi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedCompareExchange_rel, "NiNiD*NiNi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedCompareExchange64_acq, "LLiLLiD*LLiLLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedCompareExchange64_nf, "LLiLLiD*LLiLLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedCompareExchange64_rel, "LLiLLiD*LLiLLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-
-TARGET_HEADER_BUILTIN(_InterlockedOr8_acq, "ccD*c", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedOr8_nf, "ccD*c", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedOr8_rel, "ccD*c", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedOr16_acq, "ssD*s", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedOr16_nf, "ssD*s", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedOr16_rel, "ssD*s", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedOr_acq, "NiNiD*Ni", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedOr_nf, "NiNiD*Ni", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedOr_rel, "NiNiD*Ni", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedOr64_acq, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedOr64_nf, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedOr64_rel, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-
-TARGET_HEADER_BUILTIN(_InterlockedXor8_acq, "ccD*c", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedXor8_nf, "ccD*c", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedXor8_rel, "ccD*c", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedXor16_acq, "ssD*s", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedXor16_nf, "ssD*s", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedXor16_rel, "ssD*s", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedXor_acq, "NiNiD*Ni", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedXor_nf, "NiNiD*Ni", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedXor_rel, "NiNiD*Ni", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedXor64_acq, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedXor64_nf, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedXor64_rel, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-
-TARGET_HEADER_BUILTIN(_InterlockedAnd8_acq, "ccD*c", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedAnd8_nf, "ccD*c", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedAnd8_rel, "ccD*c", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedAnd16_acq, "ssD*s", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedAnd16_nf, "ssD*s", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedAnd16_rel, "ssD*s", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedAnd_acq, "NiNiD*Ni", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedAnd_nf, "NiNiD*Ni", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedAnd_rel, "NiNiD*Ni", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedAnd64_acq, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedAnd64_nf, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedAnd64_rel, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-
-TARGET_HEADER_BUILTIN(_InterlockedIncrement16_acq, "ssD*", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedIncrement16_nf, "ssD*", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedIncrement16_rel, "ssD*", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedIncrement_acq, "NiNiD*", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedIncrement_nf, "NiNiD*", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedIncrement_rel, "NiNiD*", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedIncrement64_acq, "LLiLLiD*", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedIncrement64_nf, "LLiLLiD*", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedIncrement64_rel, "LLiLLiD*", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-
-TARGET_HEADER_BUILTIN(_InterlockedDecrement16_acq, "ssD*", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedDecrement16_nf, "ssD*", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedDecrement16_rel, "ssD*", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedDecrement_acq, "NiNiD*", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedDecrement_nf, "NiNiD*", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedDecrement_rel, "NiNiD*", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedDecrement64_acq, "LLiLLiD*", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedDecrement64_nf, "LLiLLiD*", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedDecrement64_rel, "LLiLLiD*", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_BitScanForward, "UcUNi*UNi", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_BitScanReverse, "UcUNi*UNi", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_BitScanForward64, "UcUNi*ULLi", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_BitScanReverse64, "UcUNi*ULLi", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+
+TARGET_HEADER_BUILTIN(_InterlockedAnd64, "LLiLLiD*LLi", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedDecrement64, "LLiLLiD*", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedExchange64, "LLiLLiD*LLi", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedExchangeAdd64, "LLiLLiD*LLi", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedExchangeSub64, "LLiLLiD*LLi", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedIncrement64, "LLiLLiD*", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedOr64, "LLiLLiD*LLi", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedXor64, "LLiLLiD*LLi", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+
+TARGET_HEADER_BUILTIN(_InterlockedExchangeAdd_acq, "NiNiD*Ni", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedExchangeAdd_rel, "NiNiD*Ni", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedExchangeAdd_nf, "NiNiD*Ni", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedExchangeAdd8_acq, "ccD*c", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedExchangeAdd8_rel, "ccD*c", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedExchangeAdd8_nf, "ccD*c", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedExchangeAdd16_acq, "ssD*s", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedExchangeAdd16_rel, "ssD*s", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedExchangeAdd16_nf, "ssD*s", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedExchangeAdd64_acq, "LLiLLiD*LLi", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedExchangeAdd64_rel, "LLiLLiD*LLi", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedExchangeAdd64_nf, "LLiLLiD*LLi", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+
+TARGET_HEADER_BUILTIN(_InterlockedExchange8_acq, "ccD*c", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedExchange8_nf, "ccD*c", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedExchange8_rel, "ccD*c", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedExchange16_acq, "ssD*s", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedExchange16_nf, "ssD*s", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedExchange16_rel, "ssD*s", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedExchange_acq, "NiNiD*Ni", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedExchange_nf, "NiNiD*Ni", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedExchange_rel, "NiNiD*Ni", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedExchange64_acq, "LLiLLiD*LLi", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedExchange64_nf, "LLiLLiD*LLi", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedExchange64_rel, "LLiLLiD*LLi", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+
+TARGET_HEADER_BUILTIN(_InterlockedCompareExchange8_acq, "ccD*cc", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedCompareExchange8_nf, "ccD*cc", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedCompareExchange8_rel, "ccD*cc", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedCompareExchange16_acq, "ssD*ss", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedCompareExchange16_nf, "ssD*ss", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedCompareExchange16_rel, "ssD*ss", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedCompareExchange_acq, "NiNiD*NiNi", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedCompareExchange_nf, "NiNiD*NiNi", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedCompareExchange_rel, "NiNiD*NiNi", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedCompareExchange64_acq, "LLiLLiD*LLiLLi", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedCompareExchange64_nf, "LLiLLiD*LLiLLi", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedCompareExchange64_rel, "LLiLLiD*LLiLLi", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+
+TARGET_HEADER_BUILTIN(_InterlockedOr8_acq, "ccD*c", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedOr8_nf, "ccD*c", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedOr8_rel, "ccD*c", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedOr16_acq, "ssD*s", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedOr16_nf, "ssD*s", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedOr16_rel, "ssD*s", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedOr_acq, "NiNiD*Ni", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedOr_nf, "NiNiD*Ni", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedOr_rel, "NiNiD*Ni", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedOr64_acq, "LLiLLiD*LLi", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedOr64_nf, "LLiLLiD*LLi", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedOr64_rel, "LLiLLiD*LLi", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+
+TARGET_HEADER_BUILTIN(_InterlockedXor8_acq, "ccD*c", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedXor8_nf, "ccD*c", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedXor8_rel, "ccD*c", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedXor16_acq, "ssD*s", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedXor16_nf, "ssD*s", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedXor16_rel, "ssD*s", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedXor_acq, "NiNiD*Ni", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedXor_nf, "NiNiD*Ni", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedXor_rel, "NiNiD*Ni", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedXor64_acq, "LLiLLiD*LLi", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedXor64_nf, "LLiLLiD*LLi", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedXor64_rel, "LLiLLiD*LLi", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+
+TARGET_HEADER_BUILTIN(_InterlockedAnd8_acq, "ccD*c", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedAnd8_nf, "ccD*c", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedAnd8_rel, "ccD*c", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedAnd16_acq, "ssD*s", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedAnd16_nf, "ssD*s", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedAnd16_rel, "ssD*s", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedAnd_acq, "NiNiD*Ni", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedAnd_nf, "NiNiD*Ni", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedAnd_rel, "NiNiD*Ni", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedAnd64_acq, "LLiLLiD*LLi", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedAnd64_nf, "LLiLLiD*LLi", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedAnd64_rel, "LLiLLiD*LLi", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+
+TARGET_HEADER_BUILTIN(_InterlockedIncrement16_acq, "ssD*", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedIncrement16_nf, "ssD*", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedIncrement16_rel, "ssD*", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedIncrement_acq, "NiNiD*", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedIncrement_nf, "NiNiD*", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedIncrement_rel, "NiNiD*", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedIncrement64_acq, "LLiLLiD*", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedIncrement64_nf, "LLiLLiD*", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedIncrement64_rel, "LLiLLiD*", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+
+TARGET_HEADER_BUILTIN(_InterlockedDecrement16_acq, "ssD*", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedDecrement16_nf, "ssD*", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedDecrement16_rel, "ssD*", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedDecrement_acq, "NiNiD*", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedDecrement_nf, "NiNiD*", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedDecrement_rel, "NiNiD*", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedDecrement64_acq, "LLiLLiD*", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedDecrement64_nf, "LLiLLiD*", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedDecrement64_rel, "LLiLLiD*", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
#undef BUILTIN
#undef LANGBUILTIN
+#undef TARGET_BUILTIN
#undef TARGET_HEADER_BUILTIN
diff --git a/contrib/llvm-project/clang/include/clang/Basic/BuiltinsHexagon.def b/contrib/llvm-project/clang/include/clang/Basic/BuiltinsHexagon.def
index 0001bd556117..0dc0f4567dd4 100644
--- a/contrib/llvm-project/clang/include/clang/Basic/BuiltinsHexagon.def
+++ b/contrib/llvm-project/clang/include/clang/Basic/BuiltinsHexagon.def
@@ -17,8 +17,14 @@
# define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) BUILTIN(ID, TYPE, ATTRS)
#endif
+#pragma push_macro("V73")
+#define V73 "v73"
+#pragma push_macro("V71")
+#define V71 "v71|" V73
+#pragma push_macro("V69")
+#define V69 "v69|" V71
#pragma push_macro("V68")
-#define V68 "v68"
+#define V68 "v68|" V69
#pragma push_macro("V67")
#define V67 "v67|" V68
#pragma push_macro("V66")
@@ -34,8 +40,14 @@
#pragma push_macro("V5")
#define V5 "v5|" V55
+#pragma push_macro("HVXV73")
+#define HVXV73 "hvxv73"
+#pragma push_macro("HVXV71")
+#define HVXV71 "hvxv71|" HVXV73
+#pragma push_macro("HVXV69")
+#define HVXV69 "hvxv69|" HVXV71
#pragma push_macro("HVXV68")
-#define HVXV68 "hvxv68"
+#define HVXV68 "hvxv68|" HVXV69
#pragma push_macro("HVXV67")
#define HVXV67 "hvxv67|" HVXV68
#pragma push_macro("HVXV66")
@@ -128,6 +140,9 @@ TARGET_BUILTIN(__builtin_HEXAGON_V6_vrmpyub_rtt_acc_128B,"V64iV64iV32iLLi","", "
#pragma pop_macro("HVXV66")
#pragma pop_macro("HVXV67")
#pragma pop_macro("HVXV68")
+#pragma pop_macro("HVXV69")
+#pragma pop_macro("HVXV71")
+#pragma pop_macro("HVXV73")
#pragma pop_macro("V5")
#pragma pop_macro("V55")
@@ -137,6 +152,9 @@ TARGET_BUILTIN(__builtin_HEXAGON_V6_vrmpyub_rtt_acc_128B,"V64iV64iV32iLLi","", "
#pragma pop_macro("V66")
#pragma pop_macro("V67")
#pragma pop_macro("V68")
+#pragma pop_macro("V69")
+#pragma pop_macro("V71")
+#pragma pop_macro("V73")
#undef BUILTIN
#undef TARGET_BUILTIN
diff --git a/contrib/llvm-project/clang/include/clang/Basic/BuiltinsHexagonDep.def b/contrib/llvm-project/clang/include/clang/Basic/BuiltinsHexagonDep.def
index 152c9c4dd8ad..6f1ae69037e3 100644
--- a/contrib/llvm-project/clang/include/clang/Basic/BuiltinsHexagonDep.def
+++ b/contrib/llvm-project/clang/include/clang/Basic/BuiltinsHexagonDep.def
@@ -1720,6 +1720,8 @@ TARGET_BUILTIN(__builtin_HEXAGON_V6_vscattermwq_128B, "vV128biiV32iV32i", "", HV
// V66 HVX Instructions.
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vaddcarryo, "V16iV16iV16iv*", "", HVXV66)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vaddcarryo_128B, "V32iV32iV32iv*", "", HVXV66)
TARGET_BUILTIN(__builtin_HEXAGON_V6_vaddcarrysat, "V16iV16iV16iV64b", "", HVXV66)
TARGET_BUILTIN(__builtin_HEXAGON_V6_vaddcarrysat_128B, "V32iV32iV32iV128b", "", HVXV66)
TARGET_BUILTIN(__builtin_HEXAGON_V6_vasr_into, "V32iV32iV16iV16i", "", HVXV66)
@@ -1728,6 +1730,8 @@ TARGET_BUILTIN(__builtin_HEXAGON_V6_vrotr, "V16iV16iV16i", "", HVXV66)
TARGET_BUILTIN(__builtin_HEXAGON_V6_vrotr_128B, "V32iV32iV32i", "", HVXV66)
TARGET_BUILTIN(__builtin_HEXAGON_V6_vsatdw, "V16iV16iV16i", "", HVXV66)
TARGET_BUILTIN(__builtin_HEXAGON_V6_vsatdw_128B, "V32iV32iV32i", "", HVXV66)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vsubcarryo, "V16iV16iV16iv*", "", HVXV66)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vsubcarryo_128B, "V32iV32iV32iv*", "", HVXV66)
// V68 HVX Instructions.
@@ -1739,3 +1743,183 @@ TARGET_BUILTIN(__builtin_HEXAGON_V6_v6mpyvubs10, "V32iV32iV32iUIi", "", HVXV68)
TARGET_BUILTIN(__builtin_HEXAGON_V6_v6mpyvubs10_128B, "V64iV64iV64iUIi", "", HVXV68)
TARGET_BUILTIN(__builtin_HEXAGON_V6_v6mpyvubs10_vxx, "V32iV32iV32iV32iUIi", "", HVXV68)
TARGET_BUILTIN(__builtin_HEXAGON_V6_v6mpyvubs10_vxx_128B, "V64iV64iV64iV64iUIi", "", HVXV68)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vabs_hf, "V16iV16i", "", HVXV68)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vabs_hf_128B, "V32iV32i", "", HVXV68)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vabs_sf, "V16iV16i", "", HVXV68)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vabs_sf_128B, "V32iV32i", "", HVXV68)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vadd_hf, "V16iV16iV16i", "", HVXV68)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vadd_hf_128B, "V32iV32iV32i", "", HVXV68)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vadd_hf_hf, "V16iV16iV16i", "", HVXV68)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vadd_hf_hf_128B, "V32iV32iV32i", "", HVXV68)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vadd_qf16, "V16iV16iV16i", "", HVXV68)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vadd_qf16_128B, "V32iV32iV32i", "", HVXV68)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vadd_qf16_mix, "V16iV16iV16i", "", HVXV68)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vadd_qf16_mix_128B, "V32iV32iV32i", "", HVXV68)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vadd_qf32, "V16iV16iV16i", "", HVXV68)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vadd_qf32_128B, "V32iV32iV32i", "", HVXV68)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vadd_qf32_mix, "V16iV16iV16i", "", HVXV68)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vadd_qf32_mix_128B, "V32iV32iV32i", "", HVXV68)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vadd_sf, "V16iV16iV16i", "", HVXV68)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vadd_sf_128B, "V32iV32iV32i", "", HVXV68)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vadd_sf_hf, "V32iV16iV16i", "", HVXV68)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vadd_sf_hf_128B, "V64iV32iV32i", "", HVXV68)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vadd_sf_sf, "V16iV16iV16i", "", HVXV68)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vadd_sf_sf_128B, "V32iV32iV32i", "", HVXV68)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vassign_fp, "V16iV16i", "", HVXV68)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vassign_fp_128B, "V32iV32i", "", HVXV68)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vconv_hf_qf16, "V16iV16i", "", HVXV68)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vconv_hf_qf16_128B, "V32iV32i", "", HVXV68)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vconv_hf_qf32, "V16iV32i", "", HVXV68)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vconv_hf_qf32_128B, "V32iV64i", "", HVXV68)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vconv_sf_qf32, "V16iV16i", "", HVXV68)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vconv_sf_qf32_128B, "V32iV32i", "", HVXV68)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vcvt_b_hf, "V16iV16iV16i", "", HVXV68)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vcvt_b_hf_128B, "V32iV32iV32i", "", HVXV68)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vcvt_h_hf, "V16iV16i", "", HVXV68)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vcvt_h_hf_128B, "V32iV32i", "", HVXV68)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vcvt_hf_b, "V32iV16i", "", HVXV68)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vcvt_hf_b_128B, "V64iV32i", "", HVXV68)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vcvt_hf_h, "V16iV16i", "", HVXV68)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vcvt_hf_h_128B, "V32iV32i", "", HVXV68)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vcvt_hf_sf, "V16iV16iV16i", "", HVXV68)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vcvt_hf_sf_128B, "V32iV32iV32i", "", HVXV68)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vcvt_hf_ub, "V32iV16i", "", HVXV68)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vcvt_hf_ub_128B, "V64iV32i", "", HVXV68)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vcvt_hf_uh, "V16iV16i", "", HVXV68)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vcvt_hf_uh_128B, "V32iV32i", "", HVXV68)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vcvt_sf_hf, "V32iV16i", "", HVXV68)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vcvt_sf_hf_128B, "V64iV32i", "", HVXV68)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vcvt_ub_hf, "V16iV16iV16i", "", HVXV68)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vcvt_ub_hf_128B, "V32iV32iV32i", "", HVXV68)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vcvt_uh_hf, "V16iV16i", "", HVXV68)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vcvt_uh_hf_128B, "V32iV32i", "", HVXV68)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vdmpy_sf_hf, "V16iV16iV16i", "", HVXV68)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vdmpy_sf_hf_128B, "V32iV32iV32i", "", HVXV68)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vdmpy_sf_hf_acc, "V16iV16iV16iV16i", "", HVXV68)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vdmpy_sf_hf_acc_128B, "V32iV32iV32iV32i", "", HVXV68)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vfmax_hf, "V16iV16iV16i", "", HVXV68)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vfmax_hf_128B, "V32iV32iV32i", "", HVXV68)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vfmax_sf, "V16iV16iV16i", "", HVXV68)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vfmax_sf_128B, "V32iV32iV32i", "", HVXV68)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vfmin_hf, "V16iV16iV16i", "", HVXV68)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vfmin_hf_128B, "V32iV32iV32i", "", HVXV68)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vfmin_sf, "V16iV16iV16i", "", HVXV68)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vfmin_sf_128B, "V32iV32iV32i", "", HVXV68)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vfneg_hf, "V16iV16i", "", HVXV68)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vfneg_hf_128B, "V32iV32i", "", HVXV68)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vfneg_sf, "V16iV16i", "", HVXV68)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vfneg_sf_128B, "V32iV32i", "", HVXV68)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vgthf, "V64bV16iV16i", "", HVXV68)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vgthf_128B, "V128bV32iV32i", "", HVXV68)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vgthf_and, "V64bV64bV16iV16i", "", HVXV68)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vgthf_and_128B, "V128bV128bV32iV32i", "", HVXV68)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vgthf_or, "V64bV64bV16iV16i", "", HVXV68)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vgthf_or_128B, "V128bV128bV32iV32i", "", HVXV68)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vgthf_xor, "V64bV64bV16iV16i", "", HVXV68)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vgthf_xor_128B, "V128bV128bV32iV32i", "", HVXV68)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vgtsf, "V64bV16iV16i", "", HVXV68)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vgtsf_128B, "V128bV32iV32i", "", HVXV68)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vgtsf_and, "V64bV64bV16iV16i", "", HVXV68)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vgtsf_and_128B, "V128bV128bV32iV32i", "", HVXV68)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vgtsf_or, "V64bV64bV16iV16i", "", HVXV68)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vgtsf_or_128B, "V128bV128bV32iV32i", "", HVXV68)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vgtsf_xor, "V64bV64bV16iV16i", "", HVXV68)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vgtsf_xor_128B, "V128bV128bV32iV32i", "", HVXV68)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vmax_hf, "V16iV16iV16i", "", HVXV68)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vmax_hf_128B, "V32iV32iV32i", "", HVXV68)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vmax_sf, "V16iV16iV16i", "", HVXV68)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vmax_sf_128B, "V32iV32iV32i", "", HVXV68)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vmin_hf, "V16iV16iV16i", "", HVXV68)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vmin_hf_128B, "V32iV32iV32i", "", HVXV68)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vmin_sf, "V16iV16iV16i", "", HVXV68)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vmin_sf_128B, "V32iV32iV32i", "", HVXV68)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpy_hf_hf, "V16iV16iV16i", "", HVXV68)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpy_hf_hf_128B, "V32iV32iV32i", "", HVXV68)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpy_hf_hf_acc, "V16iV16iV16iV16i", "", HVXV68)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpy_hf_hf_acc_128B, "V32iV32iV32iV32i", "", HVXV68)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpy_qf16, "V16iV16iV16i", "", HVXV68)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpy_qf16_128B, "V32iV32iV32i", "", HVXV68)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpy_qf16_hf, "V16iV16iV16i", "", HVXV68)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpy_qf16_hf_128B, "V32iV32iV32i", "", HVXV68)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpy_qf16_mix_hf, "V16iV16iV16i", "", HVXV68)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpy_qf16_mix_hf_128B, "V32iV32iV32i", "", HVXV68)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpy_qf32, "V16iV16iV16i", "", HVXV68)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpy_qf32_128B, "V32iV32iV32i", "", HVXV68)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpy_qf32_hf, "V32iV16iV16i", "", HVXV68)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpy_qf32_hf_128B, "V64iV32iV32i", "", HVXV68)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpy_qf32_mix_hf, "V32iV16iV16i", "", HVXV68)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpy_qf32_mix_hf_128B, "V64iV32iV32i", "", HVXV68)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpy_qf32_qf16, "V32iV16iV16i", "", HVXV68)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpy_qf32_qf16_128B, "V64iV32iV32i", "", HVXV68)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpy_qf32_sf, "V16iV16iV16i", "", HVXV68)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpy_qf32_sf_128B, "V32iV32iV32i", "", HVXV68)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpy_sf_hf, "V32iV16iV16i", "", HVXV68)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpy_sf_hf_128B, "V64iV32iV32i", "", HVXV68)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpy_sf_hf_acc, "V32iV32iV16iV16i", "", HVXV68)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpy_sf_hf_acc_128B, "V64iV64iV32iV32i", "", HVXV68)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpy_sf_sf, "V16iV16iV16i", "", HVXV68)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpy_sf_sf_128B, "V32iV32iV32i", "", HVXV68)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vsub_hf, "V16iV16iV16i", "", HVXV68)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vsub_hf_128B, "V32iV32iV32i", "", HVXV68)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vsub_hf_hf, "V16iV16iV16i", "", HVXV68)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vsub_hf_hf_128B, "V32iV32iV32i", "", HVXV68)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vsub_qf16, "V16iV16iV16i", "", HVXV68)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vsub_qf16_128B, "V32iV32iV32i", "", HVXV68)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vsub_qf16_mix, "V16iV16iV16i", "", HVXV68)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vsub_qf16_mix_128B, "V32iV32iV32i", "", HVXV68)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vsub_qf32, "V16iV16iV16i", "", HVXV68)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vsub_qf32_128B, "V32iV32iV32i", "", HVXV68)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vsub_qf32_mix, "V16iV16iV16i", "", HVXV68)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vsub_qf32_mix_128B, "V32iV32iV32i", "", HVXV68)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vsub_sf, "V16iV16iV16i", "", HVXV68)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vsub_sf_128B, "V32iV32iV32i", "", HVXV68)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vsub_sf_hf, "V32iV16iV16i", "", HVXV68)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vsub_sf_hf_128B, "V64iV32iV32i", "", HVXV68)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vsub_sf_sf, "V16iV16iV16i", "", HVXV68)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vsub_sf_sf_128B, "V32iV32iV32i", "", HVXV68)
+
+// V69 HVX Instructions.
+
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vasrvuhubrndsat, "V16iV32iV16i", "", HVXV69)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vasrvuhubrndsat_128B, "V32iV64iV32i", "", HVXV69)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vasrvuhubsat, "V16iV32iV16i", "", HVXV69)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vasrvuhubsat_128B, "V32iV64iV32i", "", HVXV69)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vasrvwuhrndsat, "V16iV32iV16i", "", HVXV69)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vasrvwuhrndsat_128B, "V32iV64iV32i", "", HVXV69)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vasrvwuhsat, "V16iV32iV16i", "", HVXV69)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vasrvwuhsat_128B, "V32iV64iV32i", "", HVXV69)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyuhvs, "V16iV16iV16i", "", HVXV69)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyuhvs_128B, "V32iV32iV32i", "", HVXV69)
+
+// V73 HVX Instructions.
+
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vadd_sf_bf, "V32iV16iV16i", "", HVXV73)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vadd_sf_bf_128B, "V64iV32iV32i", "", HVXV73)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vconv_h_hf, "V16iV16i", "", HVXV73)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vconv_h_hf_128B, "V32iV32i", "", HVXV73)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vconv_hf_h, "V16iV16i", "", HVXV73)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vconv_hf_h_128B, "V32iV32i", "", HVXV73)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vconv_sf_w, "V16iV16i", "", HVXV73)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vconv_sf_w_128B, "V32iV32i", "", HVXV73)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vconv_w_sf, "V16iV16i", "", HVXV73)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vconv_w_sf_128B, "V32iV32i", "", HVXV73)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vcvt_bf_sf, "V16iV16iV16i", "", HVXV73)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vcvt_bf_sf_128B, "V32iV32iV32i", "", HVXV73)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vgtbf, "V64bV16iV16i", "", HVXV73)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vgtbf_128B, "V128bV32iV32i", "", HVXV73)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vgtbf_and, "V64bV64bV16iV16i", "", HVXV73)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vgtbf_and_128B, "V128bV128bV32iV32i", "", HVXV73)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vgtbf_or, "V64bV64bV16iV16i", "", HVXV73)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vgtbf_or_128B, "V128bV128bV32iV32i", "", HVXV73)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vgtbf_xor, "V64bV64bV16iV16i", "", HVXV73)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vgtbf_xor_128B, "V128bV128bV32iV32i", "", HVXV73)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vmax_bf, "V16iV16iV16i", "", HVXV73)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vmax_bf_128B, "V32iV32iV32i", "", HVXV73)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vmin_bf, "V16iV16iV16i", "", HVXV73)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vmin_bf_128B, "V32iV32iV32i", "", HVXV73)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpy_sf_bf, "V32iV16iV16i", "", HVXV73)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpy_sf_bf_128B, "V64iV32iV32i", "", HVXV73)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpy_sf_bf_acc, "V32iV32iV16iV16i", "", HVXV73)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpy_sf_bf_acc_128B, "V64iV64iV32iV32i", "", HVXV73)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vsub_sf_bf, "V32iV16iV16i", "", HVXV73)
+TARGET_BUILTIN(__builtin_HEXAGON_V6_vsub_sf_bf_128B, "V64iV32iV32i", "", HVXV73)
diff --git a/contrib/llvm-project/clang/include/clang/Basic/BuiltinsHexagonMapCustomDep.def b/contrib/llvm-project/clang/include/clang/Basic/BuiltinsHexagonMapCustomDep.def
index 93f560fc5adc..9390d54e0847 100644
--- a/contrib/llvm-project/clang/include/clang/Basic/BuiltinsHexagonMapCustomDep.def
+++ b/contrib/llvm-project/clang/include/clang/Basic/BuiltinsHexagonMapCustomDep.def
@@ -8,199 +8,11 @@
// Automatically generated file, do not edit!
//===----------------------------------------------------------------------===//
-CUSTOM_BUILTIN_MAPPING(A2_add, 0)
-CUSTOM_BUILTIN_MAPPING(A2_addi, 0)
-CUSTOM_BUILTIN_MAPPING(A2_addp, 0)
-CUSTOM_BUILTIN_MAPPING(A2_and, 0)
-CUSTOM_BUILTIN_MAPPING(A2_andir, 0)
-CUSTOM_BUILTIN_MAPPING(A2_neg, 0)
-CUSTOM_BUILTIN_MAPPING(A2_not, 0)
-CUSTOM_BUILTIN_MAPPING(A2_or, 0)
-CUSTOM_BUILTIN_MAPPING(A2_orir, 0)
-CUSTOM_BUILTIN_MAPPING(A2_sub, 0)
-CUSTOM_BUILTIN_MAPPING(A2_subp, 0)
-CUSTOM_BUILTIN_MAPPING(A2_subri, 0)
-CUSTOM_BUILTIN_MAPPING(A2_sxtb, 0)
-CUSTOM_BUILTIN_MAPPING(A2_sxth, 0)
-CUSTOM_BUILTIN_MAPPING(A2_xor, 0)
-CUSTOM_BUILTIN_MAPPING(A2_zxtb, 0)
-CUSTOM_BUILTIN_MAPPING(A2_zxth, 0)
-CUSTOM_BUILTIN_MAPPING(M2_dpmpyss_s0, 0)
-CUSTOM_BUILTIN_MAPPING(M2_dpmpyuu_s0, 0)
-CUSTOM_BUILTIN_MAPPING(M2_mpyi, 0)
-CUSTOM_BUILTIN_MAPPING(M2_mpysmi, 0)
-CUSTOM_BUILTIN_MAPPING(M2_mpyui, 0)
-CUSTOM_BUILTIN_MAPPING(S2_asl_i_p, 0)
-CUSTOM_BUILTIN_MAPPING(S2_asl_i_r, 0)
-CUSTOM_BUILTIN_MAPPING(S2_asr_i_p, 0)
-CUSTOM_BUILTIN_MAPPING(S2_asr_i_r, 0)
-CUSTOM_BUILTIN_MAPPING(S2_lsr_i_p, 0)
-CUSTOM_BUILTIN_MAPPING(S2_lsr_i_r, 0)
-CUSTOM_BUILTIN_MAPPING(V6_pred_and, 64)
-CUSTOM_BUILTIN_MAPPING(V6_pred_and_128B, 128)
-CUSTOM_BUILTIN_MAPPING(V6_pred_and_n, 64)
-CUSTOM_BUILTIN_MAPPING(V6_pred_and_n_128B, 128)
-CUSTOM_BUILTIN_MAPPING(V6_pred_not, 64)
-CUSTOM_BUILTIN_MAPPING(V6_pred_not_128B, 128)
-CUSTOM_BUILTIN_MAPPING(V6_pred_or, 64)
-CUSTOM_BUILTIN_MAPPING(V6_pred_or_128B, 128)
-CUSTOM_BUILTIN_MAPPING(V6_pred_or_n, 64)
-CUSTOM_BUILTIN_MAPPING(V6_pred_or_n_128B, 128)
-CUSTOM_BUILTIN_MAPPING(V6_pred_scalar2, 64)
-CUSTOM_BUILTIN_MAPPING(V6_pred_scalar2_128B, 128)
-CUSTOM_BUILTIN_MAPPING(V6_pred_xor, 64)
-CUSTOM_BUILTIN_MAPPING(V6_pred_xor_128B, 128)
-CUSTOM_BUILTIN_MAPPING(V6_vS32b_nqpred_ai, 64)
-CUSTOM_BUILTIN_MAPPING(V6_vS32b_nqpred_ai_128B, 128)
-CUSTOM_BUILTIN_MAPPING(V6_vS32b_nt_nqpred_ai, 64)
-CUSTOM_BUILTIN_MAPPING(V6_vS32b_nt_nqpred_ai_128B, 128)
-CUSTOM_BUILTIN_MAPPING(V6_vS32b_nt_qpred_ai, 64)
-CUSTOM_BUILTIN_MAPPING(V6_vS32b_nt_qpred_ai_128B, 128)
-CUSTOM_BUILTIN_MAPPING(V6_vS32b_qpred_ai, 64)
-CUSTOM_BUILTIN_MAPPING(V6_vS32b_qpred_ai_128B, 128)
-CUSTOM_BUILTIN_MAPPING(V6_vaddbnq, 64)
-CUSTOM_BUILTIN_MAPPING(V6_vaddbnq_128B, 128)
-CUSTOM_BUILTIN_MAPPING(V6_vaddbq, 64)
-CUSTOM_BUILTIN_MAPPING(V6_vaddbq_128B, 128)
-CUSTOM_BUILTIN_MAPPING(V6_vaddhnq, 64)
-CUSTOM_BUILTIN_MAPPING(V6_vaddhnq_128B, 128)
-CUSTOM_BUILTIN_MAPPING(V6_vaddhq, 64)
-CUSTOM_BUILTIN_MAPPING(V6_vaddhq_128B, 128)
-CUSTOM_BUILTIN_MAPPING(V6_vaddwnq, 64)
-CUSTOM_BUILTIN_MAPPING(V6_vaddwnq_128B, 128)
-CUSTOM_BUILTIN_MAPPING(V6_vaddwq, 64)
-CUSTOM_BUILTIN_MAPPING(V6_vaddwq_128B, 128)
-CUSTOM_BUILTIN_MAPPING(V6_vandqrt, 64)
-CUSTOM_BUILTIN_MAPPING(V6_vandqrt_128B, 128)
-CUSTOM_BUILTIN_MAPPING(V6_vandqrt_acc, 64)
-CUSTOM_BUILTIN_MAPPING(V6_vandqrt_acc_128B, 128)
-CUSTOM_BUILTIN_MAPPING(V6_vandvrt, 64)
-CUSTOM_BUILTIN_MAPPING(V6_vandvrt_128B, 128)
-CUSTOM_BUILTIN_MAPPING(V6_vandvrt_acc, 64)
-CUSTOM_BUILTIN_MAPPING(V6_vandvrt_acc_128B, 128)
-CUSTOM_BUILTIN_MAPPING(V6_veqb, 64)
-CUSTOM_BUILTIN_MAPPING(V6_veqb_128B, 128)
-CUSTOM_BUILTIN_MAPPING(V6_veqb_and, 64)
-CUSTOM_BUILTIN_MAPPING(V6_veqb_and_128B, 128)
-CUSTOM_BUILTIN_MAPPING(V6_veqb_or, 64)
-CUSTOM_BUILTIN_MAPPING(V6_veqb_or_128B, 128)
-CUSTOM_BUILTIN_MAPPING(V6_veqb_xor, 64)
-CUSTOM_BUILTIN_MAPPING(V6_veqb_xor_128B, 128)
-CUSTOM_BUILTIN_MAPPING(V6_veqh, 64)
-CUSTOM_BUILTIN_MAPPING(V6_veqh_128B, 128)
-CUSTOM_BUILTIN_MAPPING(V6_veqh_and, 64)
-CUSTOM_BUILTIN_MAPPING(V6_veqh_and_128B, 128)
-CUSTOM_BUILTIN_MAPPING(V6_veqh_or, 64)
-CUSTOM_BUILTIN_MAPPING(V6_veqh_or_128B, 128)
-CUSTOM_BUILTIN_MAPPING(V6_veqh_xor, 64)
-CUSTOM_BUILTIN_MAPPING(V6_veqh_xor_128B, 128)
-CUSTOM_BUILTIN_MAPPING(V6_veqw, 64)
-CUSTOM_BUILTIN_MAPPING(V6_veqw_128B, 128)
-CUSTOM_BUILTIN_MAPPING(V6_veqw_and, 64)
-CUSTOM_BUILTIN_MAPPING(V6_veqw_and_128B, 128)
-CUSTOM_BUILTIN_MAPPING(V6_veqw_or, 64)
-CUSTOM_BUILTIN_MAPPING(V6_veqw_or_128B, 128)
-CUSTOM_BUILTIN_MAPPING(V6_veqw_xor, 64)
-CUSTOM_BUILTIN_MAPPING(V6_veqw_xor_128B, 128)
-CUSTOM_BUILTIN_MAPPING(V6_vgtb, 64)
-CUSTOM_BUILTIN_MAPPING(V6_vgtb_128B, 128)
-CUSTOM_BUILTIN_MAPPING(V6_vgtb_and, 64)
-CUSTOM_BUILTIN_MAPPING(V6_vgtb_and_128B, 128)
-CUSTOM_BUILTIN_MAPPING(V6_vgtb_or, 64)
-CUSTOM_BUILTIN_MAPPING(V6_vgtb_or_128B, 128)
-CUSTOM_BUILTIN_MAPPING(V6_vgtb_xor, 64)
-CUSTOM_BUILTIN_MAPPING(V6_vgtb_xor_128B, 128)
-CUSTOM_BUILTIN_MAPPING(V6_vgth, 64)
-CUSTOM_BUILTIN_MAPPING(V6_vgth_128B, 128)
-CUSTOM_BUILTIN_MAPPING(V6_vgth_and, 64)
-CUSTOM_BUILTIN_MAPPING(V6_vgth_and_128B, 128)
-CUSTOM_BUILTIN_MAPPING(V6_vgth_or, 64)
-CUSTOM_BUILTIN_MAPPING(V6_vgth_or_128B, 128)
-CUSTOM_BUILTIN_MAPPING(V6_vgth_xor, 64)
-CUSTOM_BUILTIN_MAPPING(V6_vgth_xor_128B, 128)
-CUSTOM_BUILTIN_MAPPING(V6_vgtub, 64)
-CUSTOM_BUILTIN_MAPPING(V6_vgtub_128B, 128)
-CUSTOM_BUILTIN_MAPPING(V6_vgtub_and, 64)
-CUSTOM_BUILTIN_MAPPING(V6_vgtub_and_128B, 128)
-CUSTOM_BUILTIN_MAPPING(V6_vgtub_or, 64)
-CUSTOM_BUILTIN_MAPPING(V6_vgtub_or_128B, 128)
-CUSTOM_BUILTIN_MAPPING(V6_vgtub_xor, 64)
-CUSTOM_BUILTIN_MAPPING(V6_vgtub_xor_128B, 128)
-CUSTOM_BUILTIN_MAPPING(V6_vgtuh, 64)
-CUSTOM_BUILTIN_MAPPING(V6_vgtuh_128B, 128)
-CUSTOM_BUILTIN_MAPPING(V6_vgtuh_and, 64)
-CUSTOM_BUILTIN_MAPPING(V6_vgtuh_and_128B, 128)
-CUSTOM_BUILTIN_MAPPING(V6_vgtuh_or, 64)
-CUSTOM_BUILTIN_MAPPING(V6_vgtuh_or_128B, 128)
-CUSTOM_BUILTIN_MAPPING(V6_vgtuh_xor, 64)
-CUSTOM_BUILTIN_MAPPING(V6_vgtuh_xor_128B, 128)
-CUSTOM_BUILTIN_MAPPING(V6_vgtuw, 64)
-CUSTOM_BUILTIN_MAPPING(V6_vgtuw_128B, 128)
-CUSTOM_BUILTIN_MAPPING(V6_vgtuw_and, 64)
-CUSTOM_BUILTIN_MAPPING(V6_vgtuw_and_128B, 128)
-CUSTOM_BUILTIN_MAPPING(V6_vgtuw_or, 64)
-CUSTOM_BUILTIN_MAPPING(V6_vgtuw_or_128B, 128)
-CUSTOM_BUILTIN_MAPPING(V6_vgtuw_xor, 64)
-CUSTOM_BUILTIN_MAPPING(V6_vgtuw_xor_128B, 128)
-CUSTOM_BUILTIN_MAPPING(V6_vgtw, 64)
-CUSTOM_BUILTIN_MAPPING(V6_vgtw_128B, 128)
-CUSTOM_BUILTIN_MAPPING(V6_vgtw_and, 64)
-CUSTOM_BUILTIN_MAPPING(V6_vgtw_and_128B, 128)
-CUSTOM_BUILTIN_MAPPING(V6_vgtw_or, 64)
-CUSTOM_BUILTIN_MAPPING(V6_vgtw_or_128B, 128)
-CUSTOM_BUILTIN_MAPPING(V6_vgtw_xor, 64)
-CUSTOM_BUILTIN_MAPPING(V6_vgtw_xor_128B, 128)
-CUSTOM_BUILTIN_MAPPING(V6_vmux, 64)
-CUSTOM_BUILTIN_MAPPING(V6_vmux_128B, 128)
-CUSTOM_BUILTIN_MAPPING(V6_vsubbnq, 64)
-CUSTOM_BUILTIN_MAPPING(V6_vsubbnq_128B, 128)
-CUSTOM_BUILTIN_MAPPING(V6_vsubbq, 64)
-CUSTOM_BUILTIN_MAPPING(V6_vsubbq_128B, 128)
-CUSTOM_BUILTIN_MAPPING(V6_vsubhnq, 64)
-CUSTOM_BUILTIN_MAPPING(V6_vsubhnq_128B, 128)
-CUSTOM_BUILTIN_MAPPING(V6_vsubhq, 64)
-CUSTOM_BUILTIN_MAPPING(V6_vsubhq_128B, 128)
-CUSTOM_BUILTIN_MAPPING(V6_vsubwnq, 64)
-CUSTOM_BUILTIN_MAPPING(V6_vsubwnq_128B, 128)
-CUSTOM_BUILTIN_MAPPING(V6_vsubwq, 64)
-CUSTOM_BUILTIN_MAPPING(V6_vsubwq_128B, 128)
-CUSTOM_BUILTIN_MAPPING(V6_vswap, 64)
-CUSTOM_BUILTIN_MAPPING(V6_vswap_128B, 128)
-CUSTOM_BUILTIN_MAPPING(V6_pred_scalar2v2, 64)
-CUSTOM_BUILTIN_MAPPING(V6_pred_scalar2v2_128B, 128)
-CUSTOM_BUILTIN_MAPPING(V6_shuffeqh, 64)
-CUSTOM_BUILTIN_MAPPING(V6_shuffeqh_128B, 128)
-CUSTOM_BUILTIN_MAPPING(V6_shuffeqw, 64)
-CUSTOM_BUILTIN_MAPPING(V6_shuffeqw_128B, 128)
CUSTOM_BUILTIN_MAPPING(V6_vaddcarry, 64)
CUSTOM_BUILTIN_MAPPING(V6_vaddcarry_128B, 128)
-CUSTOM_BUILTIN_MAPPING(V6_vandnqrt, 64)
-CUSTOM_BUILTIN_MAPPING(V6_vandnqrt_128B, 128)
-CUSTOM_BUILTIN_MAPPING(V6_vandnqrt_acc, 64)
-CUSTOM_BUILTIN_MAPPING(V6_vandnqrt_acc_128B, 128)
-CUSTOM_BUILTIN_MAPPING(V6_vandvnqv, 64)
-CUSTOM_BUILTIN_MAPPING(V6_vandvnqv_128B, 128)
-CUSTOM_BUILTIN_MAPPING(V6_vandvqv, 64)
-CUSTOM_BUILTIN_MAPPING(V6_vandvqv_128B, 128)
CUSTOM_BUILTIN_MAPPING(V6_vsubcarry, 64)
CUSTOM_BUILTIN_MAPPING(V6_vsubcarry_128B, 128)
-CUSTOM_BUILTIN_MAPPING(V6_vgathermhq, 64)
-CUSTOM_BUILTIN_MAPPING(V6_vgathermhq_128B, 128)
-CUSTOM_BUILTIN_MAPPING(V6_vgathermhwq, 64)
-CUSTOM_BUILTIN_MAPPING(V6_vgathermhwq_128B, 128)
-CUSTOM_BUILTIN_MAPPING(V6_vgathermwq, 64)
-CUSTOM_BUILTIN_MAPPING(V6_vgathermwq_128B, 128)
-CUSTOM_BUILTIN_MAPPING(V6_vprefixqb, 64)
-CUSTOM_BUILTIN_MAPPING(V6_vprefixqb_128B, 128)
-CUSTOM_BUILTIN_MAPPING(V6_vprefixqh, 64)
-CUSTOM_BUILTIN_MAPPING(V6_vprefixqh_128B, 128)
-CUSTOM_BUILTIN_MAPPING(V6_vprefixqw, 64)
-CUSTOM_BUILTIN_MAPPING(V6_vprefixqw_128B, 128)
-CUSTOM_BUILTIN_MAPPING(V6_vscattermhq, 64)
-CUSTOM_BUILTIN_MAPPING(V6_vscattermhq_128B, 128)
-CUSTOM_BUILTIN_MAPPING(V6_vscattermhwq, 64)
-CUSTOM_BUILTIN_MAPPING(V6_vscattermhwq_128B, 128)
-CUSTOM_BUILTIN_MAPPING(V6_vscattermwq, 64)
-CUSTOM_BUILTIN_MAPPING(V6_vscattermwq_128B, 128)
-CUSTOM_BUILTIN_MAPPING(V6_vaddcarrysat, 64)
-CUSTOM_BUILTIN_MAPPING(V6_vaddcarrysat_128B, 128)
+CUSTOM_BUILTIN_MAPPING(V6_vaddcarryo, 64)
+CUSTOM_BUILTIN_MAPPING(V6_vaddcarryo_128B, 128)
+CUSTOM_BUILTIN_MAPPING(V6_vsubcarryo, 64)
+CUSTOM_BUILTIN_MAPPING(V6_vsubcarryo_128B, 128)
diff --git a/contrib/llvm-project/clang/include/clang/Basic/BuiltinsLoongArch.def b/contrib/llvm-project/clang/include/clang/Basic/BuiltinsLoongArch.def
new file mode 100644
index 000000000000..95359a3fdc71
--- /dev/null
+++ b/contrib/llvm-project/clang/include/clang/Basic/BuiltinsLoongArch.def
@@ -0,0 +1,28 @@
+//==- BuiltinsLoongArch.def - LoongArch Builtin function database -- 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 the LoongArch-specific builtin function database. Users of
+// this file must define the BUILTIN macro to make use of this information.
+//
+//===----------------------------------------------------------------------===//
+
+#if defined(BUILTIN) && !defined(TARGET_BUILTIN)
+# define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) BUILTIN(ID, TYPE, ATTRS)
+#endif
+
+// Definition of LoongArch basic builtins.
+#include "clang/Basic/BuiltinsLoongArchBase.def"
+
+// Definition of LSX builtins.
+#include "clang/Basic/BuiltinsLoongArchLSX.def"
+
+// Definition of LASX builtins.
+#include "clang/Basic/BuiltinsLoongArchLASX.def"
+
+#undef BUILTIN
+#undef TARGET_BUILTIN
diff --git a/contrib/llvm-project/clang/include/clang/Basic/BuiltinsLoongArchBase.def b/contrib/llvm-project/clang/include/clang/Basic/BuiltinsLoongArchBase.def
new file mode 100644
index 000000000000..a5a07c167908
--- /dev/null
+++ b/contrib/llvm-project/clang/include/clang/Basic/BuiltinsLoongArchBase.def
@@ -0,0 +1,58 @@
+//============------------ BuiltinsLoongArchBase.def -------------*- 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 the LoongArch-specific basic builtin function database.
+// Users of this file must define the BUILTIN macro to make use of this
+// information.
+//
+//===----------------------------------------------------------------------===//
+
+TARGET_BUILTIN(__builtin_loongarch_cacop_d, "vWiUWiWi", "nc", "64bit")
+TARGET_BUILTIN(__builtin_loongarch_cacop_w, "viUii", "nc", "32bit")
+TARGET_BUILTIN(__builtin_loongarch_dbar, "vIUi", "nc", "")
+TARGET_BUILTIN(__builtin_loongarch_ibar, "vIUi", "nc", "")
+TARGET_BUILTIN(__builtin_loongarch_movfcsr2gr, "UiIUi", "nc", "f")
+TARGET_BUILTIN(__builtin_loongarch_movgr2fcsr, "vIUiUi", "nc", "f")
+TARGET_BUILTIN(__builtin_loongarch_break, "vIUi", "nc", "")
+TARGET_BUILTIN(__builtin_loongarch_syscall, "vIUi", "nc", "")
+TARGET_BUILTIN(__builtin_loongarch_cpucfg, "UiUi", "nc", "")
+TARGET_BUILTIN(__builtin_loongarch_asrtle_d, "vWiWi", "nc", "64bit")
+TARGET_BUILTIN(__builtin_loongarch_asrtgt_d, "vWiWi", "nc", "64bit")
+
+TARGET_BUILTIN(__builtin_loongarch_crc_w_b_w, "iii", "nc", "64bit")
+TARGET_BUILTIN(__builtin_loongarch_crc_w_h_w, "iii", "nc", "64bit")
+TARGET_BUILTIN(__builtin_loongarch_crc_w_w_w, "iii", "nc", "64bit")
+TARGET_BUILTIN(__builtin_loongarch_crc_w_d_w, "iWii", "nc", "64bit")
+TARGET_BUILTIN(__builtin_loongarch_crcc_w_b_w, "iii", "nc", "64bit")
+TARGET_BUILTIN(__builtin_loongarch_crcc_w_h_w, "iii", "nc", "64bit")
+TARGET_BUILTIN(__builtin_loongarch_crcc_w_w_w, "iii", "nc", "64bit")
+TARGET_BUILTIN(__builtin_loongarch_crcc_w_d_w, "iWii", "nc", "64bit")
+
+TARGET_BUILTIN(__builtin_loongarch_csrrd_w, "UiIUi", "nc", "")
+TARGET_BUILTIN(__builtin_loongarch_csrrd_d, "UWiIUi", "nc", "64bit")
+TARGET_BUILTIN(__builtin_loongarch_csrwr_w, "UiUiIUi", "nc", "")
+TARGET_BUILTIN(__builtin_loongarch_csrwr_d, "UWiUWiIUi", "nc", "64bit")
+TARGET_BUILTIN(__builtin_loongarch_csrxchg_w, "UiUiUiIUi", "nc", "")
+TARGET_BUILTIN(__builtin_loongarch_csrxchg_d, "UWiUWiUWiIUi", "nc", "64bit")
+
+TARGET_BUILTIN(__builtin_loongarch_iocsrrd_b, "UiUi", "nc", "")
+TARGET_BUILTIN(__builtin_loongarch_iocsrrd_h, "UiUi", "nc", "")
+TARGET_BUILTIN(__builtin_loongarch_iocsrrd_w, "UiUi", "nc", "")
+TARGET_BUILTIN(__builtin_loongarch_iocsrrd_d, "UWiUi", "nc", "64bit")
+TARGET_BUILTIN(__builtin_loongarch_iocsrwr_b, "vUiUi", "nc", "")
+TARGET_BUILTIN(__builtin_loongarch_iocsrwr_h, "vUiUi", "nc", "")
+TARGET_BUILTIN(__builtin_loongarch_iocsrwr_w, "vUiUi", "nc", "")
+TARGET_BUILTIN(__builtin_loongarch_iocsrwr_d, "vUWiUi", "nc", "64bit")
+
+TARGET_BUILTIN(__builtin_loongarch_lddir_d, "WiWiIUWi", "nc", "64bit")
+TARGET_BUILTIN(__builtin_loongarch_ldpte_d, "vWiIUWi", "nc", "64bit")
+
+TARGET_BUILTIN(__builtin_loongarch_frecipe_s, "ff", "nc", "f,frecipe")
+TARGET_BUILTIN(__builtin_loongarch_frecipe_d, "dd", "nc", "d,frecipe")
+TARGET_BUILTIN(__builtin_loongarch_frsqrte_s, "ff", "nc", "f,frecipe")
+TARGET_BUILTIN(__builtin_loongarch_frsqrte_d, "dd", "nc", "d,frecipe")
diff --git a/contrib/llvm-project/clang/include/clang/Basic/BuiltinsLoongArchLASX.def b/contrib/llvm-project/clang/include/clang/Basic/BuiltinsLoongArchLASX.def
new file mode 100644
index 000000000000..4cf51cc000f6
--- /dev/null
+++ b/contrib/llvm-project/clang/include/clang/Basic/BuiltinsLoongArchLASX.def
@@ -0,0 +1,988 @@
+//=BuiltinsLoongArchLASX.def - LoongArch Builtin function database -- 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 the LoongArch-specific LASX builtin function database.
+// Users of this file must define the BUILTIN macro to make use of this
+// information.
+//
+//===----------------------------------------------------------------------===//
+
+TARGET_BUILTIN(__builtin_lasx_xvadd_b, "V32cV32cV32c", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvadd_h, "V16sV16sV16s", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvadd_w, "V8iV8iV8i", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvadd_d, "V4LLiV4LLiV4LLi", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvadd_q, "V4LLiV4LLiV4LLi", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvsub_b, "V32cV32cV32c", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvsub_h, "V16sV16sV16s", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvsub_w, "V8iV8iV8i", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvsub_d, "V4LLiV4LLiV4LLi", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvsub_q, "V4LLiV4LLiV4LLi", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvaddi_bu, "V32cV32cIUi", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvaddi_hu, "V16sV16sIUi", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvaddi_wu, "V8iV8iIUi", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvaddi_du, "V4LLiV4LLiIUi", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvsubi_bu, "V32cV32cIUi", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvsubi_hu, "V16sV16sIUi", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvsubi_wu, "V8iV8iIUi", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvsubi_du, "V4LLiV4LLiIUi", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvneg_b, "V32cV32c", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvneg_h, "V16sV16s", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvneg_w, "V8iV8i", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvneg_d, "V4LLiV4LLi", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvsadd_b, "V32ScV32ScV32Sc", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvsadd_h, "V16SsV16SsV16Ss", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvsadd_w, "V8SiV8SiV8Si", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvsadd_d, "V4SLLiV4SLLiV4SLLi", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvsadd_bu, "V32UcV32UcV32Uc", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvsadd_hu, "V16UsV16UsV16Us", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvsadd_wu, "V8UiV8UiV8Ui", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvsadd_du, "V4ULLiV4ULLiV4ULLi", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvssub_b, "V32ScV32ScV32Sc", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvssub_h, "V16SsV16SsV16Ss", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvssub_w, "V8SiV8SiV8Si", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvssub_d, "V4SLLiV4SLLiV4SLLi", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvssub_bu, "V32UcV32UcV32Uc", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvssub_hu, "V16UsV16UsV16Us", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvssub_wu, "V8UiV8UiV8Ui", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvssub_du, "V4ULLiV4ULLiV4ULLi", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvhaddw_h_b, "V16SsV32ScV32Sc", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvhaddw_w_h, "V8SiV16SsV16Ss", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvhaddw_d_w, "V4SLLiV8SiV8Si", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvhaddw_q_d, "V4LLiV4LLiV4LLi", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvhaddw_hu_bu, "V16UsV32UcV32Uc", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvhaddw_wu_hu, "V8UiV16UsV16Us", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvhaddw_du_wu, "V4ULLiV8UiV8Ui", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvhaddw_qu_du, "V4ULLiV4ULLiV4ULLi", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvhsubw_h_b, "V16SsV32ScV32Sc", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvhsubw_w_h, "V8SiV16SsV16Ss", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvhsubw_d_w, "V4SLLiV8SiV8Si", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvhsubw_q_d, "V4LLiV4LLiV4LLi", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvhsubw_hu_bu, "V16UsV32UcV32Uc", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvhsubw_wu_hu, "V8UiV16UsV16Us", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvhsubw_du_wu, "V4ULLiV8UiV8Ui", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvhsubw_qu_du, "V4ULLiV4ULLiV4ULLi", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvaddwev_h_b, "V16sV32cV32c", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvaddwev_w_h, "V8SiV16sV16s", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvaddwev_d_w, "V4LLiV8SiV8Si", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvaddwev_q_d, "V4LLiV4LLiV4LLi", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvaddwod_h_b, "V16sV32cV32c", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvaddwod_w_h, "V8SiV16sV16s", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvaddwod_d_w, "V4LLiV8SiV8Si", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvaddwod_q_d, "V4LLiV4LLiV4LLi", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvsubwev_h_b, "V16sV32cV32c", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvsubwev_w_h, "V8SiV16sV16s", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvsubwev_d_w, "V4LLiV8SiV8Si", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvsubwev_q_d, "V4LLiV4LLiV4LLi", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvsubwod_h_b, "V16sV32cV32c", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvsubwod_w_h, "V8SiV16sV16s", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvsubwod_d_w, "V4LLiV8SiV8Si", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvsubwod_q_d, "V4LLiV4LLiV4LLi", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvaddwev_h_bu, "V16sV32UcV32Uc", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvaddwev_w_hu, "V8SiV16UsV16Us", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvaddwev_d_wu, "V4LLiV8UiV8Ui", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvaddwev_q_du, "V4LLiV4ULLiV4ULLi", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvaddwod_h_bu, "V16sV32UcV32Uc", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvaddwod_w_hu, "V8SiV16UsV16Us", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvaddwod_d_wu, "V4LLiV8UiV8Ui", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvaddwod_q_du, "V4LLiV4ULLiV4ULLi", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvsubwev_h_bu, "V16sV32UcV32Uc", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvsubwev_w_hu, "V8SiV16UsV16Us", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvsubwev_d_wu, "V4LLiV8UiV8Ui", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvsubwev_q_du, "V4LLiV4ULLiV4ULLi", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvsubwod_h_bu, "V16sV32UcV32Uc", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvsubwod_w_hu, "V8SiV16UsV16Us", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvsubwod_d_wu, "V4LLiV8UiV8Ui", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvsubwod_q_du, "V4LLiV4ULLiV4ULLi", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvaddwev_h_bu_b, "V16sV32UcV32c", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvaddwev_w_hu_h, "V8SiV16UsV16s", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvaddwev_d_wu_w, "V4LLiV8UiV8Si", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvaddwev_q_du_d, "V4LLiV4ULLiV4LLi", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvaddwod_h_bu_b, "V16sV32UcV32c", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvaddwod_w_hu_h, "V8SiV16UsV16s", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvaddwod_d_wu_w, "V4LLiV8UiV8Si", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvaddwod_q_du_d, "V4LLiV4ULLiV4LLi", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvavg_b, "V32ScV32ScV32Sc", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvavg_h, "V16SsV16SsV16Ss", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvavg_w, "V8SiV8SiV8Si", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvavg_d, "V4SLLiV4SLLiV4SLLi", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvavg_bu, "V32UcV32UcV32Uc", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvavg_hu, "V16UsV16UsV16Us", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvavg_wu, "V8UiV8UiV8Ui", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvavg_du, "V4ULLiV4ULLiV4ULLi", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvavgr_b, "V32ScV32ScV32Sc", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvavgr_h, "V16SsV16SsV16Ss", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvavgr_w, "V8SiV8SiV8Si", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvavgr_d, "V4SLLiV4SLLiV4SLLi", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvavgr_bu, "V32UcV32UcV32Uc", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvavgr_hu, "V16UsV16UsV16Us", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvavgr_wu, "V8UiV8UiV8Ui", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvavgr_du, "V4ULLiV4ULLiV4ULLi", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvabsd_b, "V32ScV32ScV32Sc", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvabsd_h, "V16SsV16SsV16Ss", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvabsd_w, "V8SiV8SiV8Si", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvabsd_d, "V4SLLiV4SLLiV4SLLi", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvabsd_bu, "V32UcV32UcV32Uc", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvabsd_hu, "V16UsV16UsV16Us", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvabsd_wu, "V8UiV8UiV8Ui", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvabsd_du, "V4ULLiV4ULLiV4ULLi", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvadda_b, "V32ScV32ScV32Sc", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvadda_h, "V16SsV16SsV16Ss", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvadda_w, "V8SiV8SiV8Si", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvadda_d, "V4SLLiV4SLLiV4SLLi", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvmax_b, "V32ScV32ScV32Sc", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvmax_h, "V16SsV16SsV16Ss", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvmax_w, "V8SiV8SiV8Si", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvmax_d, "V4SLLiV4SLLiV4SLLi", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvmaxi_b, "V32ScV32ScIi", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvmaxi_h, "V16SsV16SsIi", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvmaxi_w, "V8SiV8SiIi", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvmaxi_d, "V4SLLiV4SLLiIi", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvmax_bu, "V32UcV32UcV32Uc", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvmax_hu, "V16UsV16UsV16Us", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvmax_wu, "V8UiV8UiV8Ui", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvmax_du, "V4ULLiV4ULLiV4ULLi", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvmaxi_bu, "V32UcV32UcIUi", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvmaxi_hu, "V16UsV16UsIUi", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvmaxi_wu, "V8UiV8UiIUi", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvmaxi_du, "V4ULLiV4ULLiIUi", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvmin_b, "V32ScV32ScV32Sc", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvmin_h, "V16SsV16SsV16Ss", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvmin_w, "V8SiV8SiV8Si", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvmin_d, "V4SLLiV4SLLiV4SLLi", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvmini_b, "V32ScV32ScIi", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvmini_h, "V16SsV16SsIi", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvmini_w, "V8SiV8SiIi", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvmini_d, "V4SLLiV4SLLiIi", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvmin_bu, "V32UcV32UcV32Uc", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvmin_hu, "V16UsV16UsV16Us", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvmin_wu, "V8UiV8UiV8Ui", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvmin_du, "V4ULLiV4ULLiV4ULLi", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvmini_bu, "V32UcV32UcIUi", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvmini_hu, "V16UsV16UsIUi", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvmini_wu, "V8UiV8UiIUi", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvmini_du, "V4ULLiV4ULLiIUi", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvmul_b, "V32ScV32ScV32Sc", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvmul_h, "V16SsV16SsV16Ss", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvmul_w, "V8SiV8SiV8Si", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvmul_d, "V4SLLiV4SLLiV4SLLi", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvmuh_b, "V32cV32cV32c", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvmuh_h, "V16sV16sV16s", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvmuh_w, "V8iV8iV8i", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvmuh_d, "V4LLiV4LLiV4LLi", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvmuh_bu, "V32UcV32UcV32Uc", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvmuh_hu, "V16UsV16UsV16Us", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvmuh_wu, "V8UiV8UiV8Ui", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvmuh_du, "V4ULLiV4ULLiV4ULLi", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvmulwev_h_b, "V16sV32cV32c", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvmulwev_w_h, "V8SiV16sV16s", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvmulwev_d_w, "V4LLiV8SiV8Si", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvmulwev_q_d, "V4LLiV4LLiV4LLi", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvmulwod_h_b, "V16sV32cV32c", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvmulwod_w_h, "V8SiV16sV16s", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvmulwod_d_w, "V4LLiV8SiV8Si", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvmulwod_q_d, "V4LLiV4LLiV4LLi", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvmulwev_h_bu, "V16sV32UcV32Uc", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvmulwev_w_hu, "V8SiV16UsV16Us", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvmulwev_d_wu, "V4LLiV8UiV8Ui", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvmulwev_q_du, "V4LLiV4ULLiV4ULLi", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvmulwod_h_bu, "V16sV32UcV32Uc", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvmulwod_w_hu, "V8SiV16UsV16Us", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvmulwod_d_wu, "V4LLiV8UiV8Ui", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvmulwod_q_du, "V4LLiV4ULLiV4ULLi", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvmulwev_h_bu_b, "V16sV32UcV32c", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvmulwev_w_hu_h, "V8SiV16UsV16s", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvmulwev_d_wu_w, "V4LLiV8UiV8Si", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvmulwev_q_du_d, "V4LLiV4ULLiV4LLi", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvmulwod_h_bu_b, "V16sV32UcV32c", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvmulwod_w_hu_h, "V8SiV16UsV16s", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvmulwod_d_wu_w, "V4LLiV8UiV8Si", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvmulwod_q_du_d, "V4LLiV4ULLiV4LLi", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvmadd_b, "V32ScV32ScV32ScV32Sc", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvmadd_h, "V16SsV16SsV16SsV16Ss", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvmadd_w, "V8SiV8SiV8SiV8Si", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvmadd_d, "V4SLLiV4SLLiV4SLLiV4SLLi", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvmsub_b, "V32ScV32ScV32ScV32Sc", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvmsub_h, "V16SsV16SsV16SsV16Ss", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvmsub_w, "V8SiV8SiV8SiV8Si", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvmsub_d, "V4SLLiV4SLLiV4SLLiV4SLLi", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvmaddwev_h_b, "V16sV16sV32cV32c", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvmaddwev_w_h, "V8SiV8SiV16sV16s", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvmaddwev_d_w, "V4LLiV4LLiV8SiV8Si", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvmaddwev_q_d, "V4LLiV4LLiV4LLiV4LLi", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvmaddwod_h_b, "V16sV16sV32cV32c", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvmaddwod_w_h, "V8SiV8SiV16sV16s", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvmaddwod_d_w, "V4LLiV4LLiV8SiV8Si", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvmaddwod_q_d, "V4LLiV4LLiV4LLiV4LLi", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvmaddwev_h_bu, "V16UsV16UsV32UcV32Uc", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvmaddwev_w_hu, "V8UiV8UiV16UsV16Us", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvmaddwev_d_wu, "V4ULLiV4ULLiV8UiV8Ui", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvmaddwev_q_du, "V4ULLiV4ULLiV4ULLiV4ULLi", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvmaddwod_h_bu, "V16UsV16UsV32UcV32Uc", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvmaddwod_w_hu, "V8UiV8UiV16UsV16Us", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvmaddwod_d_wu, "V4ULLiV4ULLiV8UiV8Ui", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvmaddwod_q_du, "V4ULLiV4ULLiV4ULLiV4ULLi", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvmaddwev_h_bu_b, "V16sV16sV32UcV32c", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvmaddwev_w_hu_h, "V8SiV8SiV16UsV16s", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvmaddwev_d_wu_w, "V4LLiV4LLiV8UiV8Si", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvmaddwev_q_du_d, "V4LLiV4LLiV4ULLiV4LLi", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvmaddwod_h_bu_b, "V16sV16sV32UcV32c", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvmaddwod_w_hu_h, "V8SiV8SiV16UsV16s", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvmaddwod_d_wu_w, "V4LLiV4LLiV8UiV8Si", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvmaddwod_q_du_d, "V4LLiV4LLiV4ULLiV4LLi", "nc", "lasx")
+
+
+TARGET_BUILTIN(__builtin_lasx_xvdiv_b, "V32ScV32ScV32Sc", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvdiv_h, "V16SsV16SsV16Ss", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvdiv_w, "V8SiV8SiV8Si", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvdiv_d, "V4SLLiV4SLLiV4SLLi", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvdiv_bu, "V32UcV32UcV32Uc", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvdiv_hu, "V16UsV16UsV16Us", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvdiv_wu, "V8UiV8UiV8Ui", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvdiv_du, "V4ULLiV4ULLiV4ULLi", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvmod_b, "V32ScV32ScV32Sc", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvmod_h, "V16SsV16SsV16Ss", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvmod_w, "V8SiV8SiV8Si", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvmod_d, "V4SLLiV4SLLiV4SLLi", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvmod_bu, "V32UcV32UcV32Uc", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvmod_hu, "V16UsV16UsV16Us", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvmod_wu, "V8UiV8UiV8Ui", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvmod_du, "V4ULLiV4ULLiV4ULLi", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvsat_b, "V32ScV32ScIUi", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvsat_h, "V16SsV16SsIUi", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvsat_w, "V8SiV8SiIUi", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvsat_d, "V4SLLiV4SLLiIUi", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvsat_bu, "V32UcV32UcIUi", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvsat_hu, "V16UsV16UsIUi", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvsat_wu, "V8UiV8UiIUi", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvsat_du, "V4ULLiV4ULLiIUi", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvexth_h_b, "V16sV32c", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvexth_w_h, "V8SiV16s", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvexth_d_w, "V4LLiV8Si", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvexth_q_d, "V4LLiV4LLi", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvexth_hu_bu, "V16UsV32Uc", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvexth_wu_hu, "V8UiV16Us", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvexth_du_wu, "V4ULLiV8Ui", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvexth_qu_du, "V4ULLiV4ULLi", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_vext2xv_h_b, "V16sV32c", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_vext2xv_w_b, "V8SiV32c", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_vext2xv_d_b, "V4LLiV32c", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_vext2xv_w_h, "V8SiV16s", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_vext2xv_d_h, "V4LLiV16s", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_vext2xv_d_w, "V4LLiV8Si", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_vext2xv_hu_bu, "V16sV32c", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_vext2xv_wu_bu, "V8SiV32c", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_vext2xv_du_bu, "V4LLiV32c", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_vext2xv_wu_hu, "V8SiV16s", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_vext2xv_du_hu, "V4LLiV16s", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_vext2xv_du_wu, "V4LLiV8Si", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvsigncov_b, "V32ScV32ScV32Sc", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvsigncov_h, "V16SsV16SsV16Ss", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvsigncov_w, "V8SiV8SiV8Si", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvsigncov_d, "V4SLLiV4SLLiV4SLLi", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvmskltz_b, "V32cV32c", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvmskltz_h, "V16sV16s", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvmskltz_w, "V8iV8i", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvmskltz_d, "V4LLiV4LLi", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvmskgez_b, "V32cV32c", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvmsknz_b, "V16sV16s", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvldi, "V4LLiIi", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvrepli_b, "V32cIi", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvrepli_h, "V16sIi", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvrepli_w, "V8iIi", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvrepli_d, "V4LLiIi", "nc", "lasx")
+
+
+TARGET_BUILTIN(__builtin_lasx_xvand_v, "V32UcV32UcV32Uc", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvor_v, "V32UcV32UcV32Uc", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvxor_v, "V32cV32cV32c", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvnor_v, "V32UcV32UcV32Uc", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvandn_v, "V32UcV32UcV32Uc", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvorn_v, "V32ScV32ScV32Sc", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvandi_b, "V32UcV32UcIUi", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvori_b, "V32UcV32UcIUi", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvxori_b, "V32UcV32UcIUi", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvnori_b, "V32UcV32UcIUi", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvsll_b, "V32cV32cV32c", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvsll_h, "V16sV16sV16s", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvsll_w, "V8iV8iV8i", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvsll_d, "V4LLiV4LLiV4LLi", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvslli_b, "V32cV32cIUi", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvslli_h, "V16sV16sIUi", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvslli_w, "V8iV8iIUi", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvslli_d, "V4LLiV4LLiIUi", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvsrl_b, "V32cV32cV32c", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvsrl_h, "V16sV16sV16s", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvsrl_w, "V8iV8iV8i", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvsrl_d, "V4LLiV4LLiV4LLi", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvsrli_b, "V32cV32cIUi", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvsrli_h, "V16sV16sIUi", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvsrli_w, "V8iV8iIUi", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvsrli_d, "V4LLiV4LLiIUi", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvsra_b, "V32cV32cV32c", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvsra_h, "V16sV16sV16s", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvsra_w, "V8iV8iV8i", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvsra_d, "V4LLiV4LLiV4LLi", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvsrai_b, "V32cV32cIUi", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvsrai_h, "V16sV16sIUi", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvsrai_w, "V8iV8iIUi", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvsrai_d, "V4LLiV4LLiIUi", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvrotr_b, "V32cV32cV32c", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvrotr_h, "V16sV16sV16s", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvrotr_w, "V8iV8iV8i", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvrotr_d, "V4LLiV4LLiV4LLi", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvrotri_b, "V32cV32cIUi", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvrotri_h, "V16sV16sIUi", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvrotri_w, "V8iV8iIUi", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvrotri_d, "V4LLiV4LLiIUi", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvsllwil_h_b, "V16sV32cIUi", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvsllwil_w_h, "V8SiV16sIUi", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvsllwil_d_w, "V4LLiV8SiIUi", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvextl_q_d, "V4LLiV4LLi", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvsllwil_hu_bu, "V16UsV32UcIUi", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvsllwil_wu_hu, "V8UiV16UsIUi", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvsllwil_du_wu, "V4ULLiV8UiIUi", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvextl_qu_du, "V4LLiV4ULLi", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvsrlr_b, "V32cV32cV32c", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvsrlr_h, "V16sV16sV16s", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvsrlr_w, "V8iV8iV8i", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvsrlr_d, "V4LLiV4LLiV4LLi", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvsrlri_b, "V32cV32cIUi", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvsrlri_h, "V16sV16sIUi", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvsrlri_w, "V8iV8iIUi", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvsrlri_d, "V4LLiV4LLiIUi", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvsrar_b, "V32cV32cV32c", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvsrar_h, "V16sV16sV16s", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvsrar_w, "V8iV8iV8i", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvsrar_d, "V4LLiV4LLiV4LLi", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvsrari_b, "V32cV32cIUi", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvsrari_h, "V16sV16sIUi", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvsrari_w, "V8iV8iIUi", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvsrari_d, "V4LLiV4LLiIUi", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvsrln_b_h, "V32ScV16sV16s", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvsrln_h_w, "V16sV8SiV8Si", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvsrln_w_d, "V8SiV4LLiV4LLi", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvsran_b_h, "V32ScV16sV16s", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvsran_h_w, "V16sV8SiV8Si", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvsran_w_d, "V8SiV4LLiV4LLi", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvsrlni_b_h, "V32cV32cV32cIUi", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvsrlni_h_w, "V16sV16sV16sIUi", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvsrlni_w_d, "V8iV8iV8iIUi", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvsrlni_d_q, "V4LLiV4LLiV4LLiIUi", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvsrani_b_h, "V32cV32cV32cIUi", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvsrani_h_w, "V16sV16sV16sIUi", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvsrani_w_d, "V8iV8iV8iIUi", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvsrani_d_q, "V4LLiV4LLiV4LLiIUi", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvsrlrn_b_h, "V32ScV16sV16s", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvsrlrn_h_w, "V16sV8SiV8Si", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvsrlrn_w_d, "V8SiV4LLiV4LLi", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvsrarn_b_h, "V32ScV16sV16s", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvsrarn_h_w, "V16sV8SiV8Si", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvsrarn_w_d, "V8SiV4LLiV4LLi", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvsrlrni_b_h, "V32cV32cV32cIUi", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvsrlrni_h_w, "V16sV16sV16sIUi", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvsrlrni_w_d, "V8iV8iV8iIUi", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvsrlrni_d_q, "V4LLiV4LLiV4LLiIUi", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvsrarni_b_h, "V32cV32cV32cIUi", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvsrarni_h_w, "V16sV16sV16sIUi", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvsrarni_w_d, "V8iV8iV8iIUi", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvsrarni_d_q, "V4LLiV4LLiV4LLiIUi", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvssrln_b_h, "V32ScV16sV16s", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvssrln_h_w, "V16sV8SiV8Si", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvssrln_w_d, "V8SiV4LLiV4LLi", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvssran_b_h, "V32ScV16sV16s", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvssran_h_w, "V16sV8SiV8Si", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvssran_w_d, "V8SiV4LLiV4LLi", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvssrln_bu_h, "V32UcV16UsV16Us", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvssrln_hu_w, "V16UsV8UiV8Ui", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvssrln_wu_d, "V8UiV4ULLiV4ULLi", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvssran_bu_h, "V32UcV16UsV16Us", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvssran_hu_w, "V16UsV8UiV8Ui", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvssran_wu_d, "V8UiV4ULLiV4ULLi", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvssrlni_b_h, "V32cV32cV32cIUi", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvssrlni_h_w, "V16sV16sV16sIUi", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvssrlni_w_d, "V8iV8iV8iIUi", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvssrlni_d_q, "V4LLiV4LLiV4LLiIUi", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvssrani_b_h, "V32cV32cV32cIUi", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvssrani_h_w, "V16sV16sV16sIUi", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvssrani_w_d, "V8iV8iV8iIUi", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvssrani_d_q, "V4LLiV4LLiV4LLiIUi", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvssrlrni_bu_h, "V32cV32cV32cIUi", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvssrlrni_hu_w, "V16sV16sV16sIUi", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvssrlrni_wu_d, "V8iV8iV8iIUi", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvssrlrni_du_q, "V4LLiV4LLiV4LLiIUi", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvssrani_bu_h, "V32cV32cV32cIUi", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvssrani_hu_w, "V16sV16sV16sIUi", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvssrani_wu_d, "V8iV8iV8iIUi", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvssrani_du_q, "V4LLiV4LLiV4LLiIUi", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvssrlrn_b_h, "V32ScV16sV16s", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvssrlrn_h_w, "V16sV8SiV8Si", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvssrlrn_w_d, "V8SiV4LLiV4LLi", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvssrarn_b_h, "V32ScV16sV16s", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvssrarn_h_w, "V16sV8SiV8Si", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvssrarn_w_d, "V8SiV4LLiV4LLi", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvssrlrn_bu_h, "V32UcV16UsV16Us", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvssrlrn_hu_w, "V16UsV8UiV8Ui", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvssrlrn_wu_d, "V8UiV4ULLiV4ULLi", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvssrarn_bu_h, "V32UcV16UsV16Us", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvssrarn_hu_w, "V16UsV8UiV8Ui", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvssrarn_wu_d, "V8UiV4ULLiV4ULLi", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvssrlrni_b_h, "V32cV32cV32cIUi", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvssrlrni_h_w, "V16sV16sV16sIUi", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvssrlrni_w_d, "V8iV8iV8iIUi", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvssrlrni_d_q, "V4LLiV4LLiV4LLiIUi", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvssrarni_b_h, "V32cV32cV32cIUi", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvssrarni_h_w, "V16sV16sV16sIUi", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvssrarni_w_d, "V8iV8iV8iIUi", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvssrarni_d_q, "V4LLiV4LLiV4LLiIUi", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvssrlni_bu_h, "V32cV32cV32cIUi", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvssrlni_hu_w, "V16sV16sV16sIUi", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvssrlni_wu_d, "V8iV8iV8iIUi", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvssrlni_du_q, "V4LLiV4LLiV4LLiIUi", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvssrarni_bu_h, "V32cV32cV32cIUi", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvssrarni_hu_w, "V16sV16sV16sIUi", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvssrarni_wu_d, "V8iV8iV8iIUi", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvssrarni_du_q, "V4LLiV4LLiV4LLiIUi", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvclo_b, "V32ScV32Sc", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvclo_h, "V16SsV16Ss", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvclo_w, "V8SiV8Si", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvclo_d, "V4SLLiV4SLLi", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvclz_b, "V32ScV32Sc", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvclz_h, "V16SsV16Ss", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvclz_w, "V8SiV8Si", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvclz_d, "V4SLLiV4SLLi", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvpcnt_b, "V32ScV32Sc", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvpcnt_h, "V16SsV16Ss", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvpcnt_w, "V8SiV8Si", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvpcnt_d, "V4SLLiV4SLLi", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvbitclr_b, "V32UcV32UcV32Uc", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvbitclr_h, "V16UsV16UsV16Us", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvbitclr_w, "V8UiV8UiV8Ui", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvbitclr_d, "V4ULLiV4ULLiV4ULLi", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvbitclri_b, "V32UcV32UcIUi", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvbitclri_h, "V16UsV16UsIUi", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvbitclri_w, "V8UiV8UiIUi", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvbitclri_d, "V4ULLiV4ULLiIUi", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvbitset_b, "V32UcV32UcV32Uc", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvbitset_h, "V16UsV16UsV16Us", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvbitset_w, "V8UiV8UiV8Ui", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvbitset_d, "V4ULLiV4ULLiV4ULLi", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvbitseti_b, "V32UcV32UcIUi", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvbitseti_h, "V16UsV16UsIUi", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvbitseti_w, "V8UiV8UiIUi", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvbitseti_d, "V4ULLiV4ULLiIUi", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvbitrev_b, "V32UcV32UcV32Uc", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvbitrev_h, "V16UsV16UsV16Us", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvbitrev_w, "V8UiV8UiV8Ui", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvbitrev_d, "V4ULLiV4ULLiV4ULLi", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvbitrevi_b, "V32UcV32UcIUi", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvbitrevi_h, "V16UsV16UsIUi", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvbitrevi_w, "V8UiV8UiIUi", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvbitrevi_d, "V4ULLiV4ULLiIUi", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvfrstp_b, "V32ScV32ScV32ScV32Sc", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvfrstp_h, "V16SsV16SsV16SsV16Ss", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvfrstpi_b, "V32cV32cV32cIUi", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvfrstpi_h, "V16sV16sV16sIUi", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvfadd_s, "V8fV8fV8f", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvfadd_d, "V4dV4dV4d", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvfsub_s, "V8fV8fV8f", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvfsub_d, "V4dV4dV4d", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvfmul_s, "V8fV8fV8f", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvfmul_d, "V4dV4dV4d", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvfdiv_s, "V8fV8fV8f", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvfdiv_d, "V4dV4dV4d", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvfmadd_s, "V8fV8fV8fV8f", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvfmadd_d, "V4dV4dV4dV4d", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvfmsub_s, "V8fV8fV8fV8f", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvfmsub_d, "V4dV4dV4dV4d", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvfnmadd_s, "V8fV8fV8fV8f", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvfnmadd_d, "V4dV4dV4dV4d", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvfnmsub_s, "V8fV8fV8fV8f", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvfnmsub_d, "V4dV4dV4dV4d", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvfmax_s, "V8fV8fV8f", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvfmax_d, "V4dV4dV4d", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvfmin_s, "V8fV8fV8f", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvfmin_d, "V4dV4dV4d", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvfmaxa_s, "V8fV8fV8f", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvfmaxa_d, "V4dV4dV4d", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvfmina_s, "V8fV8fV8f", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvfmina_d, "V4dV4dV4d", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvflogb_s, "V8fV8f", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvflogb_d, "V4dV4d", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvfclass_s, "V8iV8f", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvfclass_d, "V4LLiV4d", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvfsqrt_s, "V8fV8f", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvfsqrt_d, "V4dV4d", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvfrecip_s, "V8fV8f", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvfrecip_d, "V4dV4d", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvfrecipe_s, "V8fV8f", "nc", "lasx,frecipe")
+TARGET_BUILTIN(__builtin_lasx_xvfrecipe_d, "V4dV4d", "nc", "lasx,frecipe")
+
+TARGET_BUILTIN(__builtin_lasx_xvfrsqrt_s, "V8fV8f", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvfrsqrt_d, "V4dV4d", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvfrsqrte_s, "V8fV8f", "nc", "lasx,frecipe")
+TARGET_BUILTIN(__builtin_lasx_xvfrsqrte_d, "V4dV4d", "nc", "lasx,frecipe")
+
+TARGET_BUILTIN(__builtin_lasx_xvfcvtl_s_h, "V8fV16s", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvfcvth_s_h, "V8fV16s", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvfcvtl_d_s, "V4dV8f", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvfcvth_d_s, "V4dV8f", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvfcvt_h_s, "V16sV8fV8f", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvfcvt_s_d, "V8fV4dV4d", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvfrintrne_s, "V8SiV8f", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvfrintrne_d, "V4LLiV4d", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvfrintrz_s, "V8SiV8f", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvfrintrz_d, "V4LLiV4d", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvfrintrp_s, "V8SiV8f", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvfrintrp_d, "V4LLiV4d", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvfrintrm_s, "V8SiV8f", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvfrintrm_d, "V4LLiV4d", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvfrint_s, "V8fV8f", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvfrint_d, "V4dV4d", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvftintrne_w_s, "V8SiV8f", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvftintrne_l_d, "V4LLiV4d", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvftintrz_w_s, "V8SiV8f", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvftintrz_l_d, "V4LLiV4d", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvftintrp_w_s, "V8SiV8f", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvftintrp_l_d, "V4LLiV4d", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvftintrm_w_s, "V8SiV8f", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvftintrm_l_d, "V4LLiV4d", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvftint_w_s, "V8SiV8f", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvftint_l_d, "V4SLLiV4d", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvftintrz_wu_s, "V8UiV8f", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvftintrz_lu_d, "V4ULLiV4d", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvftint_wu_s, "V8UiV8f", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvftint_lu_d, "V4ULLiV4d", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvftintrne_w_d, "V8SiV4dV4d", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvftintrz_w_d, "V8SiV4dV4d", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvftintrp_w_d, "V8SiV4dV4d", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvftintrm_w_d, "V8SiV4dV4d", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvftint_w_d, "V8SiV4dV4d", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvftintrnel_l_s, "V4LLiV8f", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvftintrneh_l_s, "V4LLiV8f", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvftintrzl_l_s, "V4LLiV8f", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvftintrzh_l_s, "V4LLiV8f", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvftintrpl_l_s, "V4LLiV8f", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvftintrph_l_s, "V4LLiV8f", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvftintrml_l_s, "V4LLiV8f", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvftintrmh_l_s, "V4LLiV8f", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvftintl_l_s, "V4LLiV8f", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvftinth_l_s, "V4LLiV8f", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvffint_s_w, "V8fV8Si", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvffint_d_l, "V4dV4SLLi", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvffint_s_wu, "V8fV8Ui", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvffint_d_lu, "V4dV4ULLi", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvffintl_d_w, "V4dV8Si", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvffinth_d_w, "V4dV8Si", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvffint_s_l, "V8fV4LLiV4LLi", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvseq_b, "V32ScV32ScV32Sc", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvseq_h, "V16SsV16SsV16Ss", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvseq_w, "V8SiV8SiV8Si", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvseq_d, "V4SLLiV4SLLiV4SLLi", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvseqi_b, "V32ScV32ScISi", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvseqi_h, "V16SsV16SsISi", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvseqi_w, "V8SiV8SiISi", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvseqi_d, "V4SLLiV4SLLiISi", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvsle_b, "V32ScV32ScV32Sc", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvsle_h, "V16SsV16SsV16Ss", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvsle_w, "V8SiV8SiV8Si", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvsle_d, "V4SLLiV4SLLiV4SLLi", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvslei_b, "V32ScV32ScISi", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvslei_h, "V16SsV16SsISi", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvslei_w, "V8SiV8SiISi", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvslei_d, "V4SLLiV4SLLiISi", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvsle_bu, "V32ScV32UcV32Uc", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvsle_hu, "V16SsV16UsV16Us", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvsle_wu, "V8SiV8UiV8Ui", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvsle_du, "V4SLLiV4ULLiV4ULLi", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvslei_bu, "V32ScV32UcIUi", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvslei_hu, "V16SsV16UsIUi", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvslei_wu, "V8SiV8UiIUi", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvslei_du, "V4SLLiV4ULLiIUi", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvslt_b, "V32ScV32ScV32Sc", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvslt_h, "V16SsV16SsV16Ss", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvslt_w, "V8SiV8SiV8Si", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvslt_d, "V4SLLiV4SLLiV4SLLi", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvslti_b, "V32ScV32ScISi", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvslti_h, "V16SsV16SsISi", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvslti_w, "V8SiV8SiISi", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvslti_d, "V4SLLiV4SLLiISi", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvslt_bu, "V32ScV32UcV32Uc", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvslt_hu, "V16SsV16UsV16Us", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvslt_wu, "V8SiV8UiV8Ui", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvslt_du, "V4SLLiV4ULLiV4ULLi", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvslti_bu, "V32ScV32UcIUi", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvslti_hu, "V16SsV16UsIUi", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvslti_wu, "V8SiV8UiIUi", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvslti_du, "V4SLLiV4ULLiIUi", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvfcmp_caf_s, "V8SiV8fV8f", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvfcmp_caf_d, "V4SLLiV4dV4d", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvfcmp_cun_s, "V8SiV8fV8f", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvfcmp_cun_d, "V4SLLiV4dV4d", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvfcmp_ceq_s, "V8SiV8fV8f", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvfcmp_ceq_d, "V4SLLiV4dV4d", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvfcmp_cueq_s, "V8SiV8fV8f", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvfcmp_cueq_d, "V4SLLiV4dV4d", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvfcmp_clt_s, "V8SiV8fV8f", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvfcmp_clt_d, "V4SLLiV4dV4d", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvfcmp_cult_s, "V8SiV8fV8f", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvfcmp_cult_d, "V4SLLiV4dV4d", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvfcmp_cle_s, "V8SiV8fV8f", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvfcmp_cle_d, "V4SLLiV4dV4d", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvfcmp_cule_s, "V8SiV8fV8f", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvfcmp_cule_d, "V4SLLiV4dV4d", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvfcmp_cne_s, "V8SiV8fV8f", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvfcmp_cne_d, "V4SLLiV4dV4d", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvfcmp_cor_s, "V8SiV8fV8f", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvfcmp_cor_d, "V4SLLiV4dV4d", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvfcmp_cune_s, "V8SiV8fV8f", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvfcmp_cune_d, "V4SLLiV4dV4d", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvfcmp_saf_s, "V8SiV8fV8f", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvfcmp_saf_d, "V4SLLiV4dV4d", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvfcmp_sun_s, "V8SiV8fV8f", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvfcmp_sun_d, "V4SLLiV4dV4d", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvfcmp_seq_s, "V8SiV8fV8f", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvfcmp_seq_d, "V4SLLiV4dV4d", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvfcmp_sueq_s, "V8SiV8fV8f", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvfcmp_sueq_d, "V4SLLiV4dV4d", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvfcmp_slt_s, "V8SiV8fV8f", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvfcmp_slt_d, "V4SLLiV4dV4d", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvfcmp_sult_s, "V8SiV8fV8f", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvfcmp_sult_d, "V4SLLiV4dV4d", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvfcmp_sle_s, "V8SiV8fV8f", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvfcmp_sle_d, "V4SLLiV4dV4d", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvfcmp_sule_s, "V8SiV8fV8f", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvfcmp_sule_d, "V4SLLiV4dV4d", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvfcmp_sne_s, "V8SiV8fV8f", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvfcmp_sne_d, "V4SLLiV4dV4d", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvfcmp_sor_s, "V8SiV8fV8f", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvfcmp_sor_d, "V4SLLiV4dV4d", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvfcmp_sune_s, "V8SiV8fV8f", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvfcmp_sune_d, "V4SLLiV4dV4d", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvbitsel_v, "V32UcV32UcV32UcV32Uc", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvbitseli_b, "V32UcV32UcV32UcIUi", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvreplgr2vr_b, "V32Sci", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvreplgr2vr_h, "V16Ssi", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvreplgr2vr_w, "V8Sii", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvreplgr2vr_d, "V4SLLiLLi", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvinsgr2vr_w, "V8SiV8SiiIUi", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvinsgr2vr_d, "V4SLLiV4SLLiLLiIUi", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvpickve2gr_w, "iV8SiIUi", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvpickve2gr_d, "LLiV4SLLiIUi", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvpickve2gr_wu, "iV8UiIUi", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvpickve2gr_du, "LLiV4ULLiIUi", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvreplve_b, "V32cV32cUi", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvreplve_h, "V16sV16sUi", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvreplve_w, "V8iV8iUi", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvreplve_d, "V4LLiV4LLiUi", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvrepl128vei_b, "V32cV32cIUi", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvrepl128vei_h, "V16sV16sIUi", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvrepl128vei_w, "V8iV8iIUi", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvrepl128vei_d, "V4LLiV4LLiIUi", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvreplve0_b, "V32ScV32Sc", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvreplve0_h, "V16SsV16Ss", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvreplve0_w, "V8SiV8Si", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvreplve0_d, "V4SLLiV4SLLi", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvreplve0_q, "V32ScV32Sc", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvinsve0_w, "V8iV8iV8iIUi", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvinsve0_d, "V4LLiV4LLiV4LLiIUi", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvpickve_w, "V8iV8iIUi", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvpickve_d, "V4LLiV4LLiIUi", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvpickve_w_f, "V8fV8fIUi", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvpickve_d_f, "V4dV4dIUi", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvbsll_v, "V32cV32cIUi", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvbsrl_v, "V32cV32cIUi", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvpackev_b, "V32cV32cV32c", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvpackev_h, "V16sV16sV16s", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvpackev_w, "V8iV8iV8i", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvpackev_d, "V4LLiV4LLiV4LLi", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvpackod_b, "V32cV32cV32c", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvpackod_h, "V16sV16sV16s", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvpackod_w, "V8iV8iV8i", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvpackod_d, "V4LLiV4LLiV4LLi", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvpickev_b, "V32cV32cV32c", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvpickev_h, "V16sV16sV16s", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvpickev_w, "V8iV8iV8i", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvpickev_d, "V4LLiV4LLiV4LLi", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvpickod_b, "V32cV32cV32c", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvpickod_h, "V16sV16sV16s", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvpickod_w, "V8iV8iV8i", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvpickod_d, "V4LLiV4LLiV4LLi", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvilvl_b, "V32cV32cV32c", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvilvl_h, "V16sV16sV16s", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvilvl_w, "V8iV8iV8i", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvilvl_d, "V4LLiV4LLiV4LLi", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvilvh_b, "V32cV32cV32c", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvilvh_h, "V16sV16sV16s", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvilvh_w, "V8iV8iV8i", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvilvh_d, "V4LLiV4LLiV4LLi", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvshuf_b, "V32UcV32UcV32UcV32Uc", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvshuf_h, "V16sV16sV16sV16s", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvshuf_w, "V8iV8iV8iV8i", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvshuf_d, "V4LLiV4LLiV4LLiV4LLi", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvperm_w, "V8iV8iV8i", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvshuf4i_b, "V32cV32cIUi", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvshuf4i_h, "V16sV16sIUi", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvshuf4i_w, "V8iV8iIUi", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvshuf4i_d, "V4LLiV4LLiV4LLiIUi", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvpermi_w, "V8iV8iV8iIUi", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvpermi_d, "V4LLiV4LLiIUi", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvpermi_q, "V32cV32cV32cIUi", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvextrins_b, "V32cV32cV32cIUi", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvextrins_h, "V16sV16sV16sIUi", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvextrins_w, "V8iV8iV8iIUi", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvextrins_d, "V4LLiV4LLiV4LLiIUi", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvld, "V32ScvC*Ii", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvst, "vV32Scv*Ii", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvldx, "V32ScvC*LLi", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvstx, "vV32Scv*LLi", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvldrepl_b, "V32cvC*Ii", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvldrepl_h, "V16svC*Ii", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvldrepl_w, "V8ivC*Ii", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvldrepl_d, "V4LLivC*Ii", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xvstelm_b, "vV32Scv*IiUi", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvstelm_h, "vV16Ssv*IiUi", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvstelm_w, "vV8Siv*IiUi", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xvstelm_d, "vV4SLLiv*IiUi", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xbz_v, "iV32Uc", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xbnz_v, "iV32Uc", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xbz_b, "iV32Uc", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xbz_h, "iV16Us", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xbz_w, "iV8Ui", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xbz_d, "iV4ULLi", "nc", "lasx")
+
+TARGET_BUILTIN(__builtin_lasx_xbnz_b, "iV32Uc", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xbnz_h, "iV16Us", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xbnz_w, "iV8Ui", "nc", "lasx")
+TARGET_BUILTIN(__builtin_lasx_xbnz_d, "iV4ULLi", "nc", "lasx")
diff --git a/contrib/llvm-project/clang/include/clang/Basic/BuiltinsLoongArchLSX.def b/contrib/llvm-project/clang/include/clang/Basic/BuiltinsLoongArchLSX.def
new file mode 100644
index 000000000000..c90f4dc5458f
--- /dev/null
+++ b/contrib/llvm-project/clang/include/clang/Basic/BuiltinsLoongArchLSX.def
@@ -0,0 +1,959 @@
+//=============------------- BuiltinsLoongArchLSX.def --------------- 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 the LoongArch-specific LSX builtin function database.
+// Users of this file must define the BUILTIN macro to make use of this
+// information.
+//
+//===----------------------------------------------------------------------===//
+
+TARGET_BUILTIN(__builtin_lsx_vadd_b, "V16cV16cV16c", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vadd_h, "V8sV8sV8s", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vadd_w, "V4iV4iV4i", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vadd_d, "V2LLiV2LLiV2LLi", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vadd_q, "V2LLiV2LLiV2LLi", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vsub_b, "V16cV16cV16c", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vsub_h, "V8sV8sV8s", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vsub_w, "V4iV4iV4i", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vsub_d, "V2LLiV2LLiV2LLi", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vsub_q, "V2LLiV2LLiV2LLi", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vaddi_bu, "V16cV16cIUi", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vaddi_hu, "V8sV8sIUi", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vaddi_wu, "V4iV4iIUi", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vaddi_du, "V2LLiV2LLiIUi", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vsubi_bu, "V16cV16cIUi", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vsubi_hu, "V8sV8sIUi", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vsubi_wu, "V4iV4iIUi", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vsubi_du, "V2LLiV2LLiIUi", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vneg_b, "V16cV16c", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vneg_h, "V8sV8s", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vneg_w, "V4iV4i", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vneg_d, "V2LLiV2LLi", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vsadd_b, "V16ScV16ScV16Sc", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vsadd_h, "V8SsV8SsV8Ss", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vsadd_w, "V4SiV4SiV4Si", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vsadd_d, "V2SLLiV2SLLiV2SLLi", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vsadd_bu, "V16UcV16UcV16Uc", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vsadd_hu, "V8UsV8UsV8Us", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vsadd_wu, "V4UiV4UiV4Ui", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vsadd_du, "V2ULLiV2ULLiV2ULLi", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vssub_b, "V16ScV16ScV16Sc", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vssub_h, "V8SsV8SsV8Ss", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vssub_w, "V4SiV4SiV4Si", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vssub_d, "V2SLLiV2SLLiV2SLLi", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vssub_bu, "V16UcV16UcV16Uc", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vssub_hu, "V8UsV8UsV8Us", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vssub_wu, "V4UiV4UiV4Ui", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vssub_du, "V2ULLiV2ULLiV2ULLi", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vhaddw_h_b, "V8SsV16ScV16Sc", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vhaddw_w_h, "V4SiV8SsV8Ss", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vhaddw_d_w, "V2SLLiV4SiV4Si", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vhaddw_q_d, "V2LLiV2LLiV2LLi", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vhaddw_hu_bu, "V8UsV16UcV16Uc", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vhaddw_wu_hu, "V4UiV8UsV8Us", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vhaddw_du_wu, "V2ULLiV4UiV4Ui", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vhaddw_qu_du, "V2ULLiV2ULLiV2ULLi", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vhsubw_h_b, "V8SsV16ScV16Sc", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vhsubw_w_h, "V4SiV8SsV8Ss", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vhsubw_d_w, "V2SLLiV4SiV4Si", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vhsubw_q_d, "V2LLiV2LLiV2LLi", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vhsubw_hu_bu, "V8UsV16UcV16Uc", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vhsubw_wu_hu, "V4UiV8UsV8Us", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vhsubw_du_wu, "V2ULLiV4UiV4Ui", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vhsubw_qu_du, "V2ULLiV2ULLiV2ULLi", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vaddwev_h_b, "V8sV16cV16c", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vaddwev_w_h, "V4SiV8sV8s", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vaddwev_d_w, "V2LLiV4SiV4Si", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vaddwev_q_d, "V2LLiV2LLiV2LLi", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vaddwod_h_b, "V8sV16cV16c", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vaddwod_w_h, "V4SiV8sV8s", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vaddwod_d_w, "V2LLiV4SiV4Si", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vaddwod_q_d, "V2LLiV2LLiV2LLi", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vsubwev_h_b, "V8sV16cV16c", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vsubwev_w_h, "V4SiV8sV8s", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vsubwev_d_w, "V2LLiV4SiV4Si", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vsubwev_q_d, "V2LLiV2LLiV2LLi", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vsubwod_h_b, "V8sV16cV16c", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vsubwod_w_h, "V4SiV8sV8s", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vsubwod_d_w, "V2LLiV4SiV4Si", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vsubwod_q_d, "V2LLiV2LLiV2LLi", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vaddwev_h_bu, "V8sV16UcV16Uc", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vaddwev_w_hu, "V4SiV8UsV8Us", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vaddwev_d_wu, "V2LLiV4UiV4Ui", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vaddwev_q_du, "V2LLiV2ULLiV2ULLi", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vaddwod_h_bu, "V8sV16UcV16Uc", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vaddwod_w_hu, "V4SiV8UsV8Us", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vaddwod_d_wu, "V2LLiV4UiV4Ui", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vaddwod_q_du, "V2LLiV2ULLiV2ULLi", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vsubwev_h_bu, "V8sV16UcV16Uc", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vsubwev_w_hu, "V4SiV8UsV8Us", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vsubwev_d_wu, "V2LLiV4UiV4Ui", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vsubwev_q_du, "V2LLiV2ULLiV2ULLi", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vsubwod_h_bu, "V8sV16UcV16Uc", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vsubwod_w_hu, "V4SiV8UsV8Us", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vsubwod_d_wu, "V2LLiV4UiV4Ui", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vsubwod_q_du, "V2LLiV2ULLiV2ULLi", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vaddwev_h_bu_b, "V8sV16UcV16c", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vaddwev_w_hu_h, "V4SiV8UsV8s", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vaddwev_d_wu_w, "V2LLiV4UiV4Si", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vaddwev_q_du_d, "V2LLiV2ULLiV2LLi", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vaddwod_h_bu_b, "V8sV16UcV16c", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vaddwod_w_hu_h, "V4SiV8UsV8s", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vaddwod_d_wu_w, "V2LLiV4UiV4Si", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vaddwod_q_du_d, "V2LLiV2ULLiV2LLi", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vavg_b, "V16ScV16ScV16Sc", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vavg_h, "V8SsV8SsV8Ss", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vavg_w, "V4SiV4SiV4Si", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vavg_d, "V2SLLiV2SLLiV2SLLi", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vavg_bu, "V16UcV16UcV16Uc", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vavg_hu, "V8UsV8UsV8Us", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vavg_wu, "V4UiV4UiV4Ui", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vavg_du, "V2ULLiV2ULLiV2ULLi", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vavgr_b, "V16ScV16ScV16Sc", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vavgr_h, "V8SsV8SsV8Ss", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vavgr_w, "V4SiV4SiV4Si", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vavgr_d, "V2SLLiV2SLLiV2SLLi", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vavgr_bu, "V16UcV16UcV16Uc", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vavgr_hu, "V8UsV8UsV8Us", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vavgr_wu, "V4UiV4UiV4Ui", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vavgr_du, "V2ULLiV2ULLiV2ULLi", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vabsd_b, "V16ScV16ScV16Sc", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vabsd_h, "V8SsV8SsV8Ss", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vabsd_w, "V4SiV4SiV4Si", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vabsd_d, "V2SLLiV2SLLiV2SLLi", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vabsd_bu, "V16UcV16UcV16Uc", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vabsd_hu, "V8UsV8UsV8Us", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vabsd_wu, "V4UiV4UiV4Ui", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vabsd_du, "V2ULLiV2ULLiV2ULLi", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vadda_b, "V16ScV16ScV16Sc", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vadda_h, "V8SsV8SsV8Ss", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vadda_w, "V4SiV4SiV4Si", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vadda_d, "V2SLLiV2SLLiV2SLLi", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vmax_b, "V16ScV16ScV16Sc", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vmax_h, "V8SsV8SsV8Ss", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vmax_w, "V4SiV4SiV4Si", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vmax_d, "V2SLLiV2SLLiV2SLLi", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vmaxi_b, "V16ScV16ScIi", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vmaxi_h, "V8SsV8SsIi", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vmaxi_w, "V4SiV4SiIi", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vmaxi_d, "V2SLLiV2SLLiIi", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vmax_bu, "V16UcV16UcV16Uc", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vmax_hu, "V8UsV8UsV8Us", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vmax_wu, "V4UiV4UiV4Ui", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vmax_du, "V2ULLiV2ULLiV2ULLi", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vmaxi_bu, "V16UcV16UcIUi", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vmaxi_hu, "V8UsV8UsIUi", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vmaxi_wu, "V4UiV4UiIUi", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vmaxi_du, "V2ULLiV2ULLiIUi", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vmin_b, "V16ScV16ScV16Sc", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vmin_h, "V8SsV8SsV8Ss", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vmin_w, "V4SiV4SiV4Si", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vmin_d, "V2SLLiV2SLLiV2SLLi", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vmini_b, "V16ScV16ScIi", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vmini_h, "V8SsV8SsIi", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vmini_w, "V4SiV4SiIi", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vmini_d, "V2SLLiV2SLLiIi", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vmin_bu, "V16UcV16UcV16Uc", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vmin_hu, "V8UsV8UsV8Us", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vmin_wu, "V4UiV4UiV4Ui", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vmin_du, "V2ULLiV2ULLiV2ULLi", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vmini_bu, "V16UcV16UcIUi", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vmini_hu, "V8UsV8UsIUi", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vmini_wu, "V4UiV4UiIUi", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vmini_du, "V2ULLiV2ULLiIUi", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vmul_b, "V16ScV16ScV16Sc", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vmul_h, "V8SsV8SsV8Ss", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vmul_w, "V4SiV4SiV4Si", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vmul_d, "V2SLLiV2SLLiV2SLLi", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vmuh_b, "V16cV16cV16c", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vmuh_h, "V8sV8sV8s", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vmuh_w, "V4iV4iV4i", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vmuh_d, "V2LLiV2LLiV2LLi", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vmuh_bu, "V16UcV16UcV16Uc", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vmuh_hu, "V8UsV8UsV8Us", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vmuh_wu, "V4UiV4UiV4Ui", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vmuh_du, "V2ULLiV2ULLiV2ULLi", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vmulwev_h_b, "V8sV16cV16c", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vmulwev_w_h, "V4SiV8sV8s", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vmulwev_d_w, "V2LLiV4SiV4Si", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vmulwev_q_d, "V2LLiV2LLiV2LLi", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vmulwod_h_b, "V8sV16cV16c", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vmulwod_w_h, "V4SiV8sV8s", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vmulwod_d_w, "V2LLiV4SiV4Si", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vmulwod_q_d, "V2LLiV2LLiV2LLi", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vmulwev_h_bu, "V8sV16UcV16Uc", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vmulwev_w_hu, "V4SiV8UsV8Us", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vmulwev_d_wu, "V2LLiV4UiV4Ui", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vmulwev_q_du, "V2LLiV2ULLiV2ULLi", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vmulwod_h_bu, "V8sV16UcV16Uc", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vmulwod_w_hu, "V4SiV8UsV8Us", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vmulwod_d_wu, "V2LLiV4UiV4Ui", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vmulwod_q_du, "V2LLiV2ULLiV2ULLi", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vmulwev_h_bu_b, "V8sV16UcV16c", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vmulwev_w_hu_h, "V4SiV8UsV8s", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vmulwev_d_wu_w, "V2LLiV4UiV4Si", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vmulwev_q_du_d, "V2LLiV2ULLiV2LLi", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vmulwod_h_bu_b, "V8sV16UcV16c", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vmulwod_w_hu_h, "V4SiV8UsV8s", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vmulwod_d_wu_w, "V2LLiV4UiV4Si", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vmulwod_q_du_d, "V2LLiV2ULLiV2LLi", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vmadd_b, "V16ScV16ScV16ScV16Sc", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vmadd_h, "V8SsV8SsV8SsV8Ss", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vmadd_w, "V4SiV4SiV4SiV4Si", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vmadd_d, "V2SLLiV2SLLiV2SLLiV2SLLi", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vmsub_b, "V16ScV16ScV16ScV16Sc", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vmsub_h, "V8SsV8SsV8SsV8Ss", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vmsub_w, "V4SiV4SiV4SiV4Si", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vmsub_d, "V2SLLiV2SLLiV2SLLiV2SLLi", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vmaddwev_h_b, "V8sV8sV16cV16c", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vmaddwev_w_h, "V4SiV4SiV8sV8s", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vmaddwev_d_w, "V2LLiV2LLiV4SiV4Si", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vmaddwev_q_d, "V2LLiV2LLiV2LLiV2LLi", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vmaddwod_h_b, "V8sV8sV16cV16c", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vmaddwod_w_h, "V4SiV4SiV8sV8s", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vmaddwod_d_w, "V2LLiV2LLiV4SiV4Si", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vmaddwod_q_d, "V2LLiV2LLiV2LLiV2LLi", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vmaddwev_h_bu, "V8UsV8UsV16UcV16Uc", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vmaddwev_w_hu, "V4UiV4UiV8UsV8Us", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vmaddwev_d_wu, "V2ULLiV2ULLiV4UiV4Ui", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vmaddwev_q_du, "V2ULLiV2ULLiV2ULLiV2ULLi", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vmaddwod_h_bu, "V8UsV8UsV16UcV16Uc", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vmaddwod_w_hu, "V4UiV4UiV8UsV8Us", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vmaddwod_d_wu, "V2ULLiV2ULLiV4UiV4Ui", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vmaddwod_q_du, "V2ULLiV2ULLiV2ULLiV2ULLi", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vmaddwev_h_bu_b, "V8sV8sV16UcV16c", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vmaddwev_w_hu_h, "V4SiV4SiV8UsV8s", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vmaddwev_d_wu_w, "V2LLiV2LLiV4UiV4Si", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vmaddwev_q_du_d, "V2LLiV2LLiV2ULLiV2LLi", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vmaddwod_h_bu_b, "V8sV8sV16UcV16c", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vmaddwod_w_hu_h, "V4SiV4SiV8UsV8s", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vmaddwod_d_wu_w, "V2LLiV2LLiV4UiV4Si", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vmaddwod_q_du_d, "V2LLiV2LLiV2ULLiV2LLi", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vdiv_b, "V16ScV16ScV16Sc", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vdiv_h, "V8SsV8SsV8Ss", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vdiv_w, "V4SiV4SiV4Si", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vdiv_d, "V2SLLiV2SLLiV2SLLi", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vdiv_bu, "V16UcV16UcV16Uc", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vdiv_hu, "V8UsV8UsV8Us", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vdiv_wu, "V4UiV4UiV4Ui", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vdiv_du, "V2ULLiV2ULLiV2ULLi", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vmod_b, "V16ScV16ScV16Sc", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vmod_h, "V8SsV8SsV8Ss", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vmod_w, "V4SiV4SiV4Si", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vmod_d, "V2SLLiV2SLLiV2SLLi", "nc", "lsx")
+
+
+TARGET_BUILTIN(__builtin_lsx_vmod_bu, "V16UcV16UcV16Uc", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vmod_hu, "V8UsV8UsV8Us", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vmod_wu, "V4UiV4UiV4Ui", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vmod_du, "V2ULLiV2ULLiV2ULLi", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vsat_b, "V16ScV16ScIUi", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vsat_h, "V8SsV8SsIUi", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vsat_w, "V4SiV4SiIUi", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vsat_d, "V2SLLiV2SLLiIUi", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vsat_bu, "V16UcV16UcIUi", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vsat_hu, "V8UsV8UsIUi", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vsat_wu, "V4UiV4UiIUi", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vsat_du, "V2ULLiV2ULLiIUi", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vexth_h_b, "V8sV16c", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vexth_w_h, "V4SiV8s", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vexth_d_w, "V2LLiV4Si", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vexth_q_d, "V2LLiV2LLi", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vexth_hu_bu, "V8UsV16Uc", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vexth_wu_hu, "V4UiV8Us", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vexth_du_wu, "V2ULLiV4Ui", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vexth_qu_du, "V2ULLiV2ULLi", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vsigncov_b, "V16ScV16ScV16Sc", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vsigncov_h, "V8SsV8SsV8Ss", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vsigncov_w, "V4SiV4SiV4Si", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vsigncov_d, "V2SLLiV2SLLiV2SLLi", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vmskltz_b, "V16cV16c", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vmskltz_h, "V8sV8s", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vmskltz_w, "V4iV4i", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vmskltz_d, "V2LLiV2LLi", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vmskgez_b, "V16cV16c", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vmsknz_b, "V8sV8s", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vldi, "V2LLiIi", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vrepli_b, "V16cIi", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vrepli_h, "V8sIi", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vrepli_w, "V4iIi", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vrepli_d, "V2LLiIi", "nc", "lsx")
+
+
+TARGET_BUILTIN(__builtin_lsx_vand_v, "V16UcV16UcV16Uc", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vor_v, "V16UcV16UcV16Uc", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vxor_v, "V16cV16cV16c", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vnor_v, "V16UcV16UcV16Uc", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vandn_v, "V16UcV16UcV16Uc", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vorn_v, "V16ScV16ScV16Sc", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vandi_b, "V16UcV16UcIUi", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vori_b, "V16UcV16UcIUi", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vxori_b, "V16UcV16UcIUi", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vnori_b, "V16UcV16UcIUi", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vsll_b, "V16cV16cV16c", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vsll_h, "V8sV8sV8s", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vsll_w, "V4iV4iV4i", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vsll_d, "V2LLiV2LLiV2LLi", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vslli_b, "V16cV16cIUi", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vslli_h, "V8sV8sIUi", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vslli_w, "V4iV4iIUi", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vslli_d, "V2LLiV2LLiIUi", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vsrl_b, "V16cV16cV16c", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vsrl_h, "V8sV8sV8s", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vsrl_w, "V4iV4iV4i", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vsrl_d, "V2LLiV2LLiV2LLi", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vsrli_b, "V16cV16cIUi", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vsrli_h, "V8sV8sIUi", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vsrli_w, "V4iV4iIUi", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vsrli_d, "V2LLiV2LLiIUi", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vsra_b, "V16cV16cV16c", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vsra_h, "V8sV8sV8s", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vsra_w, "V4iV4iV4i", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vsra_d, "V2LLiV2LLiV2LLi", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vsrai_b, "V16cV16cIUi", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vsrai_h, "V8sV8sIUi", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vsrai_w, "V4iV4iIUi", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vsrai_d, "V2LLiV2LLiIUi", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vrotr_b, "V16cV16cV16c", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vrotr_h, "V8sV8sV8s", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vrotr_w, "V4iV4iV4i", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vrotr_d, "V2LLiV2LLiV2LLi", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vrotri_b, "V16cV16cIUi", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vrotri_h, "V8sV8sIUi", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vrotri_w, "V4iV4iIUi", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vrotri_d, "V2LLiV2LLiIUi", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vsllwil_h_b, "V8sV16cIUi", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vsllwil_w_h, "V4SiV8sIUi", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vsllwil_d_w, "V2LLiV4SiIUi", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vextl_q_d, "V2LLiV2LLi", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vsllwil_hu_bu, "V8UsV16UcIUi", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vsllwil_wu_hu, "V4UiV8UsIUi", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vsllwil_du_wu, "V2ULLiV4UiIUi", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vextl_qu_du, "V2LLiV2ULLi", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vsrlr_b, "V16cV16cV16c", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vsrlr_h, "V8sV8sV8s", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vsrlr_w, "V4iV4iV4i", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vsrlr_d, "V2LLiV2LLiV2LLi", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vsrlri_b, "V16cV16cIUi", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vsrlri_h, "V8sV8sIUi", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vsrlri_w, "V4iV4iIUi", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vsrlri_d, "V2LLiV2LLiIUi", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vsrar_b, "V16cV16cV16c", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vsrar_h, "V8sV8sV8s", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vsrar_w, "V4iV4iV4i", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vsrar_d, "V2LLiV2LLiV2LLi", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vsrari_b, "V16cV16cIUi", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vsrari_h, "V8sV8sIUi", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vsrari_w, "V4iV4iIUi", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vsrari_d, "V2LLiV2LLiIUi", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vsrln_b_h, "V16ScV8sV8s", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vsrln_h_w, "V8sV4SiV4Si", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vsrln_w_d, "V4SiV2LLiV2LLi", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vsran_b_h, "V16ScV8sV8s", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vsran_h_w, "V8sV4SiV4Si", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vsran_w_d, "V4SiV2LLiV2LLi", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vsrlni_b_h, "V16cV16cV16cIUi", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vsrlni_h_w, "V8sV8sV8sIUi", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vsrlni_w_d, "V4iV4iV4iIUi", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vsrlni_d_q, "V2LLiV2LLiV2LLiIUi", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vsrani_b_h, "V16cV16cV16cIUi", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vsrani_h_w, "V8sV8sV8sIUi", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vsrani_w_d, "V4iV4iV4iIUi", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vsrani_d_q, "V2LLiV2LLiV2LLiIUi", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vsrlrn_b_h, "V16ScV8sV8s", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vsrlrn_h_w, "V8sV4SiV4Si", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vsrlrn_w_d, "V4SiV2LLiV2LLi", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vsrarn_b_h, "V16ScV8sV8s", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vsrarn_h_w, "V8sV4SiV4Si", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vsrarn_w_d, "V4SiV2LLiV2LLi", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vsrlrni_b_h, "V16cV16cV16cIUi", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vsrlrni_h_w, "V8sV8sV8sIUi", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vsrlrni_w_d, "V4iV4iV4iIUi", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vsrlrni_d_q, "V2LLiV2LLiV2LLiIUi", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vsrarni_b_h, "V16cV16cV16cIUi", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vsrarni_h_w, "V8sV8sV8sIUi", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vsrarni_w_d, "V4iV4iV4iIUi", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vsrarni_d_q, "V2LLiV2LLiV2LLiIUi", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vssrln_b_h, "V16ScV8sV8s", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vssrln_h_w, "V8sV4SiV4Si", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vssrln_w_d, "V4SiV2LLiV2LLi", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vssran_b_h, "V16ScV8sV8s", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vssran_h_w, "V8sV4SiV4Si", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vssran_w_d, "V4SiV2LLiV2LLi", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vssrln_bu_h, "V16UcV8UsV8Us", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vssrln_hu_w, "V8UsV4UiV4Ui", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vssrln_wu_d, "V4UiV2ULLiV2ULLi", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vssran_bu_h, "V16UcV8UsV8Us", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vssran_hu_w, "V8UsV4UiV4Ui", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vssran_wu_d, "V4UiV2ULLiV2ULLi", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vssrlni_b_h, "V16cV16cV16cIUi", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vssrlni_h_w, "V8sV8sV8sIUi", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vssrlni_w_d, "V4iV4iV4iIUi", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vssrlni_d_q, "V2LLiV2LLiV2LLiIUi", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vssrani_b_h, "V16cV16cV16cIUi", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vssrani_h_w, "V8sV8sV8sIUi", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vssrani_w_d, "V4iV4iV4iIUi", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vssrani_d_q, "V2LLiV2LLiV2LLiIUi", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vssrlrni_bu_h, "V16cV16cV16cIUi", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vssrlrni_hu_w, "V8sV8sV8sIUi", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vssrlrni_wu_d, "V4iV4iV4iIUi", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vssrlrni_du_q, "V2LLiV2LLiV2LLiIUi", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vssrani_bu_h, "V16cV16cV16cIUi", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vssrani_hu_w, "V8sV8sV8sIUi", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vssrani_wu_d, "V4iV4iV4iIUi", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vssrani_du_q, "V2LLiV2LLiV2LLiIUi", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vssrlrn_b_h, "V16ScV8sV8s", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vssrlrn_h_w, "V8sV4SiV4Si", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vssrlrn_w_d, "V4SiV2LLiV2LLi", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vssrarn_b_h, "V16ScV8sV8s", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vssrarn_h_w, "V8sV4SiV4Si", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vssrarn_w_d, "V4SiV2LLiV2LLi", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vssrlrn_bu_h, "V16UcV8UsV8Us", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vssrlrn_hu_w, "V8UsV4UiV4Ui", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vssrlrn_wu_d, "V4UiV2ULLiV2ULLi", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vssrarn_bu_h, "V16UcV8UsV8Us", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vssrarn_hu_w, "V8UsV4UiV4Ui", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vssrarn_wu_d, "V4UiV2ULLiV2ULLi", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vssrlrni_b_h, "V16cV16cV16cIUi", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vssrlrni_h_w, "V8sV8sV8sIUi", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vssrlrni_w_d, "V4iV4iV4iIUi", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vssrlrni_d_q, "V2LLiV2LLiV2LLiIUi", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vssrarni_b_h, "V16cV16cV16cIUi", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vssrarni_h_w, "V8sV8sV8sIUi", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vssrarni_w_d, "V4iV4iV4iIUi", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vssrarni_d_q, "V2LLiV2LLiV2LLiIUi", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vssrlni_bu_h, "V16cV16cV16cIUi", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vssrlni_hu_w, "V8sV8sV8sIUi", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vssrlni_wu_d, "V4iV4iV4iIUi", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vssrlni_du_q, "V2LLiV2LLiV2LLiIUi", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vssrarni_bu_h, "V16cV16cV16cIUi", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vssrarni_hu_w, "V8sV8sV8sIUi", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vssrarni_wu_d, "V4iV4iV4iIUi", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vssrarni_du_q, "V2LLiV2LLiV2LLiIUi", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vclo_b, "V16ScV16Sc", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vclo_h, "V8SsV8Ss", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vclo_w, "V4SiV4Si", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vclo_d, "V2SLLiV2SLLi", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vclz_b, "V16ScV16Sc", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vclz_h, "V8SsV8Ss", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vclz_w, "V4SiV4Si", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vclz_d, "V2SLLiV2SLLi", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vpcnt_b, "V16ScV16Sc", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vpcnt_h, "V8SsV8Ss", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vpcnt_w, "V4SiV4Si", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vpcnt_d, "V2SLLiV2SLLi", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vbitclr_b, "V16UcV16UcV16Uc", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vbitclr_h, "V8UsV8UsV8Us", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vbitclr_w, "V4UiV4UiV4Ui", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vbitclr_d, "V2ULLiV2ULLiV2ULLi", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vbitclri_b, "V16UcV16UcIUi", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vbitclri_h, "V8UsV8UsIUi", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vbitclri_w, "V4UiV4UiIUi", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vbitclri_d, "V2ULLiV2ULLiIUi", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vbitset_b, "V16UcV16UcV16Uc", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vbitset_h, "V8UsV8UsV8Us", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vbitset_w, "V4UiV4UiV4Ui", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vbitset_d, "V2ULLiV2ULLiV2ULLi", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vbitseti_b, "V16UcV16UcIUi", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vbitseti_h, "V8UsV8UsIUi", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vbitseti_w, "V4UiV4UiIUi", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vbitseti_d, "V2ULLiV2ULLiIUi", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vbitrev_b, "V16UcV16UcV16Uc", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vbitrev_h, "V8UsV8UsV8Us", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vbitrev_w, "V4UiV4UiV4Ui", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vbitrev_d, "V2ULLiV2ULLiV2ULLi", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vbitrevi_b, "V16UcV16UcIUi", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vbitrevi_h, "V8UsV8UsIUi", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vbitrevi_w, "V4UiV4UiIUi", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vbitrevi_d, "V2ULLiV2ULLiIUi", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vfrstp_b, "V16ScV16ScV16ScV16Sc", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vfrstp_h, "V8SsV8SsV8SsV8Ss", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vfrstpi_b, "V16cV16cV16cIUi", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vfrstpi_h, "V8sV8sV8sIUi", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vfadd_s, "V4fV4fV4f", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vfadd_d, "V2dV2dV2d", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vfsub_s, "V4fV4fV4f", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vfsub_d, "V2dV2dV2d", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vfmul_s, "V4fV4fV4f", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vfmul_d, "V2dV2dV2d", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vfdiv_s, "V4fV4fV4f", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vfdiv_d, "V2dV2dV2d", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vfmadd_s, "V4fV4fV4fV4f", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vfmadd_d, "V2dV2dV2dV2d", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vfmsub_s, "V4fV4fV4fV4f", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vfmsub_d, "V2dV2dV2dV2d", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vfnmadd_s, "V4fV4fV4fV4f", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vfnmadd_d, "V2dV2dV2dV2d", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vfnmsub_s, "V4fV4fV4fV4f", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vfnmsub_d, "V2dV2dV2dV2d", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vfmax_s, "V4fV4fV4f", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vfmax_d, "V2dV2dV2d", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vfmin_s, "V4fV4fV4f", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vfmin_d, "V2dV2dV2d", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vfmaxa_s, "V4fV4fV4f", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vfmaxa_d, "V2dV2dV2d", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vfmina_s, "V4fV4fV4f", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vfmina_d, "V2dV2dV2d", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vflogb_s, "V4fV4f", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vflogb_d, "V2dV2d", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vfclass_s, "V4iV4f", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vfclass_d, "V2LLiV2d", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vfsqrt_s, "V4fV4f", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vfsqrt_d, "V2dV2d", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vfrecip_s, "V4fV4f", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vfrecip_d, "V2dV2d", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vfrecipe_s, "V4fV4f", "nc", "lsx,frecipe")
+TARGET_BUILTIN(__builtin_lsx_vfrecipe_d, "V2dV2d", "nc", "lsx,frecipe")
+
+TARGET_BUILTIN(__builtin_lsx_vfrsqrt_s, "V4fV4f", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vfrsqrt_d, "V2dV2d", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vfrsqrte_s, "V4fV4f", "nc", "lsx,frecipe")
+TARGET_BUILTIN(__builtin_lsx_vfrsqrte_d, "V2dV2d", "nc", "lsx,frecipe")
+
+TARGET_BUILTIN(__builtin_lsx_vfcvtl_s_h, "V4fV8s", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vfcvtl_d_s, "V2dV4f", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vfcvth_s_h, "V4fV8s", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vfcvth_d_s, "V2dV4f", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vfcvt_h_s, "V8sV4fV4f", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vfcvt_s_d, "V4fV2dV2d", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vfrintrne_s, "V4SiV4f", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vfrintrne_d, "V2LLiV2d", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vfrintrz_s, "V4SiV4f", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vfrintrz_d, "V2LLiV2d", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vfrintrp_s, "V4SiV4f", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vfrintrp_d, "V2LLiV2d", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vfrintrm_s, "V4SiV4f", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vfrintrm_d, "V2LLiV2d", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vfrint_s, "V4fV4f", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vfrint_d, "V2dV2d", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vftintrne_w_s, "V4SiV4f", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vftintrne_l_d, "V2LLiV2d", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vftintrz_w_s, "V4SiV4f", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vftintrz_l_d, "V2LLiV2d", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vftintrp_w_s, "V4SiV4f", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vftintrp_l_d, "V2LLiV2d", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vftintrm_w_s, "V4SiV4f", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vftintrm_l_d, "V2LLiV2d", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vftint_w_s, "V4SiV4f", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vftint_l_d, "V2SLLiV2d", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vftintrz_wu_s, "V4UiV4f", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vftintrz_lu_d, "V2ULLiV2d", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vftint_wu_s, "V4UiV4f", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vftint_lu_d, "V2ULLiV2d", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vftintrne_w_d, "V4SiV2dV2d", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vftintrz_w_d, "V4SiV2dV2d", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vftintrp_w_d, "V4SiV2dV2d", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vftintrm_w_d, "V4SiV2dV2d", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vftint_w_d, "V4SiV2dV2d", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vftintrnel_l_s, "V2LLiV4f", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vftintrneh_l_s, "V2LLiV4f", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vftintrzl_l_s, "V2LLiV4f", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vftintrzh_l_s, "V2LLiV4f", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vftintrpl_l_s, "V2LLiV4f", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vftintrph_l_s, "V2LLiV4f", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vftintrml_l_s, "V2LLiV4f", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vftintrmh_l_s, "V2LLiV4f", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vftintl_l_s, "V2LLiV4f", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vftinth_l_s, "V2LLiV4f", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vffint_s_w, "V4fV4Si", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vffint_d_l, "V2dV2SLLi", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vffint_s_wu, "V4fV4Ui", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vffint_d_lu, "V2dV2ULLi", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vffintl_d_w, "V2dV4Si", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vffinth_d_w, "V2dV4Si", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vffint_s_l, "V4fV2LLiV2LLi", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vseq_b, "V16ScV16ScV16Sc", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vseq_h, "V8SsV8SsV8Ss", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vseq_w, "V4SiV4SiV4Si", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vseq_d, "V2SLLiV2SLLiV2SLLi", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vseqi_b, "V16ScV16ScISi", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vseqi_h, "V8SsV8SsISi", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vseqi_w, "V4SiV4SiISi", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vseqi_d, "V2SLLiV2SLLiISi", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vsle_b, "V16ScV16ScV16Sc", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vsle_h, "V8SsV8SsV8Ss", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vsle_w, "V4SiV4SiV4Si", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vsle_d, "V2SLLiV2SLLiV2SLLi", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vslei_b, "V16ScV16ScISi", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vslei_h, "V8SsV8SsISi", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vslei_w, "V4SiV4SiISi", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vslei_d, "V2SLLiV2SLLiISi", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vsle_bu, "V16ScV16UcV16Uc", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vsle_hu, "V8SsV8UsV8Us", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vsle_wu, "V4SiV4UiV4Ui", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vsle_du, "V2SLLiV2ULLiV2ULLi", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vslei_bu, "V16ScV16UcIUi", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vslei_hu, "V8SsV8UsIUi", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vslei_wu, "V4SiV4UiIUi", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vslei_du, "V2SLLiV2ULLiIUi", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vslt_b, "V16ScV16ScV16Sc", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vslt_h, "V8SsV8SsV8Ss", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vslt_w, "V4SiV4SiV4Si", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vslt_d, "V2SLLiV2SLLiV2SLLi", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vslti_b, "V16ScV16ScISi", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vslti_h, "V8SsV8SsISi", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vslti_w, "V4SiV4SiISi", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vslti_d, "V2SLLiV2SLLiISi", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vslt_bu, "V16ScV16UcV16Uc", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vslt_hu, "V8SsV8UsV8Us", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vslt_wu, "V4SiV4UiV4Ui", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vslt_du, "V2SLLiV2ULLiV2ULLi", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vslti_bu, "V16ScV16UcIUi", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vslti_hu, "V8SsV8UsIUi", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vslti_wu, "V4SiV4UiIUi", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vslti_du, "V2SLLiV2ULLiIUi", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vfcmp_caf_s, "V4SiV4fV4f", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vfcmp_caf_d, "V2SLLiV2dV2d", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vfcmp_cun_s, "V4SiV4fV4f", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vfcmp_cun_d, "V2SLLiV2dV2d", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vfcmp_ceq_s, "V4SiV4fV4f", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vfcmp_ceq_d, "V2SLLiV2dV2d", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vfcmp_cueq_s, "V4SiV4fV4f", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vfcmp_cueq_d, "V2SLLiV2dV2d", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vfcmp_clt_s, "V4SiV4fV4f", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vfcmp_clt_d, "V2SLLiV2dV2d", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vfcmp_cult_s, "V4SiV4fV4f", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vfcmp_cult_d, "V2SLLiV2dV2d", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vfcmp_cle_s, "V4SiV4fV4f", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vfcmp_cle_d, "V2SLLiV2dV2d", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vfcmp_cule_s, "V4SiV4fV4f", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vfcmp_cule_d, "V2SLLiV2dV2d", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vfcmp_cne_s, "V4SiV4fV4f", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vfcmp_cne_d, "V2SLLiV2dV2d", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vfcmp_cor_s, "V4SiV4fV4f", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vfcmp_cor_d, "V2SLLiV2dV2d", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vfcmp_cune_s, "V4SiV4fV4f", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vfcmp_cune_d, "V2SLLiV2dV2d", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vfcmp_saf_s, "V4SiV4fV4f", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vfcmp_saf_d, "V2SLLiV2dV2d", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vfcmp_sun_s, "V4SiV4fV4f", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vfcmp_sun_d, "V2SLLiV2dV2d", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vfcmp_seq_s, "V4SiV4fV4f", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vfcmp_seq_d, "V2SLLiV2dV2d", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vfcmp_sueq_s, "V4SiV4fV4f", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vfcmp_sueq_d, "V2SLLiV2dV2d", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vfcmp_slt_s, "V4SiV4fV4f", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vfcmp_slt_d, "V2SLLiV2dV2d", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vfcmp_sult_s, "V4SiV4fV4f", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vfcmp_sult_d, "V2SLLiV2dV2d", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vfcmp_sle_s, "V4SiV4fV4f", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vfcmp_sle_d, "V2SLLiV2dV2d", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vfcmp_sule_s, "V4SiV4fV4f", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vfcmp_sule_d, "V2SLLiV2dV2d", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vfcmp_sne_s, "V4SiV4fV4f", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vfcmp_sne_d, "V2SLLiV2dV2d", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vfcmp_sor_s, "V4SiV4fV4f", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vfcmp_sor_d, "V2SLLiV2dV2d", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vfcmp_sune_s, "V4SiV4fV4f", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vfcmp_sune_d, "V2SLLiV2dV2d", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vbitsel_v, "V16UcV16UcV16UcV16Uc", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vbitseli_b, "V16UcV16UcV16UcIUi", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vreplgr2vr_b, "V16Sci", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vreplgr2vr_h, "V8Ssi", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vreplgr2vr_w, "V4Sii", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vreplgr2vr_d, "V2SLLiLLi", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vinsgr2vr_b, "V16ScV16SciIUi", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vinsgr2vr_h, "V8SsV8SsiIUi", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vinsgr2vr_w, "V4SiV4SiiIUi", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vinsgr2vr_d, "V2SLLiV2SLLiLLiIUi", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vpickve2gr_b, "iV16ScIUi", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vpickve2gr_h, "iV8SsIUi", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vpickve2gr_w, "iV4SiIUi", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vpickve2gr_d, "LLiV2SLLiIUi", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vpickve2gr_bu, "iV16UcIUi", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vpickve2gr_hu, "iV8UsIUi", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vpickve2gr_wu, "iV4UiIUi", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vpickve2gr_du, "LLiV2ULLiIUi", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vreplve_b, "V16cV16cUi", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vreplve_h, "V8sV8sUi", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vreplve_w, "V4iV4iUi", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vreplve_d, "V2LLiV2LLiUi", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vreplvei_b, "V16cV16cIUi", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vreplvei_h, "V8sV8sIUi", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vreplvei_w, "V4iV4iIUi", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vreplvei_d, "V2LLiV2LLiIUi", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vbsll_v, "V16cV16cIUi", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vbsrl_v, "V16cV16cIUi", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vpackev_b, "V16cV16cV16c", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vpackev_h, "V8sV8sV8s", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vpackev_w, "V4iV4iV4i", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vpackev_d, "V2LLiV2LLiV2LLi", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vpackod_b, "V16cV16cV16c", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vpackod_h, "V8sV8sV8s", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vpackod_w, "V4iV4iV4i", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vpackod_d, "V2LLiV2LLiV2LLi", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vpickev_b, "V16cV16cV16c", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vpickev_h, "V8sV8sV8s", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vpickev_w, "V4iV4iV4i", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vpickev_d, "V2LLiV2LLiV2LLi", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vpickod_b, "V16cV16cV16c", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vpickod_h, "V8sV8sV8s", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vpickod_w, "V4iV4iV4i", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vpickod_d, "V2LLiV2LLiV2LLi", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vilvl_b, "V16cV16cV16c", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vilvl_h, "V8sV8sV8s", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vilvl_w, "V4iV4iV4i", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vilvl_d, "V2LLiV2LLiV2LLi", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vilvh_b, "V16cV16cV16c", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vilvh_h, "V8sV8sV8s", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vilvh_w, "V4iV4iV4i", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vilvh_d, "V2LLiV2LLiV2LLi", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vshuf_b, "V16UcV16UcV16UcV16Uc", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vshuf_h, "V8sV8sV8sV8s", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vshuf_w, "V4iV4iV4iV4i", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vshuf_d, "V2LLiV2LLiV2LLiV2LLi", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vshuf4i_b, "V16cV16cIUi", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vshuf4i_h, "V8sV8sIUi", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vshuf4i_w, "V4iV4iIUi", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vshuf4i_d, "V2LLiV2LLiV2LLiIUi", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vpermi_w, "V4iV4iV4iIUi", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vextrins_b, "V16cV16cV16cIUi", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vextrins_h, "V8sV8sV8sIUi", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vextrins_w, "V4iV4iV4iIUi", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vextrins_d, "V2LLiV2LLiV2LLiIUi", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vld, "V16ScvC*Ii", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vst, "vV16Scv*Ii", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vldx, "V16ScvC*LLi", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vstx, "vV16Scv*LLi", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vldrepl_b, "V16cvC*Ii", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vldrepl_h, "V8svC*Ii", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vldrepl_w, "V4ivC*Ii", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vldrepl_d, "V2LLivC*Ii", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_vstelm_b, "vV16Scv*IiUi", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vstelm_h, "vV8Ssv*IiUi", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vstelm_w, "vV4Siv*IiUi", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_vstelm_d, "vV2SLLiv*IiUi", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_bz_v, "iV16Uc", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_bnz_v, "iV16Uc", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_bz_b, "iV16Uc", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_bz_h, "iV8Us", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_bz_w, "iV4Ui", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_bz_d, "iV2ULLi", "nc", "lsx")
+
+TARGET_BUILTIN(__builtin_lsx_bnz_b, "iV16Uc", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_bnz_h, "iV8Us", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_bnz_w, "iV4Ui", "nc", "lsx")
+TARGET_BUILTIN(__builtin_lsx_bnz_d, "iV2ULLi", "nc", "lsx")
diff --git a/contrib/llvm-project/clang/include/clang/Basic/BuiltinsNEON.def b/contrib/llvm-project/clang/include/clang/Basic/BuiltinsNEON.def
index b8eb5a7b6173..9627005ba982 100644
--- a/contrib/llvm-project/clang/include/clang/Basic/BuiltinsNEON.def
+++ b/contrib/llvm-project/clang/include/clang/Basic/BuiltinsNEON.def
@@ -19,3 +19,4 @@
#undef GET_NEON_BUILTINS
#undef BUILTIN
+#undef TARGET_BUILTIN
diff --git a/contrib/llvm-project/clang/include/clang/Basic/BuiltinsNVPTX.def b/contrib/llvm-project/clang/include/clang/Basic/BuiltinsNVPTX.def
index 3c96900136a4..0f2e8260143b 100644
--- a/contrib/llvm-project/clang/include/clang/Basic/BuiltinsNVPTX.def
+++ b/contrib/llvm-project/clang/include/clang/Basic/BuiltinsNVPTX.def
@@ -17,12 +17,21 @@
# define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) BUILTIN(ID, TYPE, ATTRS)
#endif
+#pragma push_macro("SM_53")
#pragma push_macro("SM_70")
#pragma push_macro("SM_72")
#pragma push_macro("SM_75")
#pragma push_macro("SM_80")
#pragma push_macro("SM_86")
-#define SM_86 "sm_86"
+#pragma push_macro("SM_87")
+#pragma push_macro("SM_89")
+#pragma push_macro("SM_90")
+#pragma push_macro("SM_90a")
+#define SM_90a "sm_90a"
+#define SM_90 "sm_90|" SM_90a
+#define SM_89 "sm_89|" SM_90
+#define SM_87 "sm_87|" SM_89
+#define SM_86 "sm_86|" SM_87
#define SM_80 "sm_80|" SM_86
#define SM_75 "sm_75|" SM_80
#define SM_72 "sm_72|" SM_75
@@ -30,7 +39,9 @@
#pragma push_macro("SM_60")
#define SM_60 "sm_60|sm_61|sm_62|" SM_70
+#define SM_53 "sm_53|" SM_60
+#pragma push_macro("PTX42")
#pragma push_macro("PTX60")
#pragma push_macro("PTX61")
#pragma push_macro("PTX63")
@@ -39,7 +50,27 @@
#pragma push_macro("PTX70")
#pragma push_macro("PTX71")
#pragma push_macro("PTX72")
-#define PTX72 "ptx72"
+#pragma push_macro("PTX73")
+#pragma push_macro("PTX74")
+#pragma push_macro("PTX75")
+#pragma push_macro("PTX76")
+#pragma push_macro("PTX77")
+#pragma push_macro("PTX78")
+#pragma push_macro("PTX80")
+#pragma push_macro("PTX81")
+#pragma push_macro("PTX82")
+#pragma push_macro("PTX83")
+#define PTX83 "ptx83"
+#define PTX82 "ptx82|" PTX83
+#define PTX81 "ptx81|" PTX82
+#define PTX80 "ptx80|" PTX81
+#define PTX78 "ptx78|" PTX80
+#define PTX77 "ptx77|" PTX78
+#define PTX76 "ptx76|" PTX77
+#define PTX75 "ptx75|" PTX76
+#define PTX74 "ptx74|" PTX75
+#define PTX73 "ptx73|" PTX74
+#define PTX72 "ptx72|" PTX73
#define PTX71 "ptx71|" PTX72
#define PTX70 "ptx70|" PTX71
#define PTX65 "ptx65|" PTX70
@@ -47,6 +78,7 @@
#define PTX63 "ptx63|" PTX64
#define PTX61 "ptx61|" PTX63
#define PTX60 "ptx60|" PTX61
+#define PTX42 "ptx42|" PTX60
#pragma push_macro("AND")
#define AND(a, b) "(" a "),(" b ")"
@@ -73,6 +105,31 @@ BUILTIN(__nvvm_read_ptx_sreg_nctaid_y, "i", "nc")
BUILTIN(__nvvm_read_ptx_sreg_nctaid_z, "i", "nc")
BUILTIN(__nvvm_read_ptx_sreg_nctaid_w, "i", "nc")
+TARGET_BUILTIN(__nvvm_read_ptx_sreg_clusterid_x, "i", "nc", AND(SM_90, PTX78))
+TARGET_BUILTIN(__nvvm_read_ptx_sreg_clusterid_y, "i", "nc", AND(SM_90, PTX78))
+TARGET_BUILTIN(__nvvm_read_ptx_sreg_clusterid_z, "i", "nc", AND(SM_90, PTX78))
+TARGET_BUILTIN(__nvvm_read_ptx_sreg_clusterid_w, "i", "nc", AND(SM_90, PTX78))
+
+TARGET_BUILTIN(__nvvm_read_ptx_sreg_nclusterid_x, "i", "nc", AND(SM_90, PTX78))
+TARGET_BUILTIN(__nvvm_read_ptx_sreg_nclusterid_y, "i", "nc", AND(SM_90, PTX78))
+TARGET_BUILTIN(__nvvm_read_ptx_sreg_nclusterid_z, "i", "nc", AND(SM_90, PTX78))
+TARGET_BUILTIN(__nvvm_read_ptx_sreg_nclusterid_w, "i", "nc", AND(SM_90, PTX78))
+
+TARGET_BUILTIN(__nvvm_read_ptx_sreg_cluster_ctaid_x, "i", "nc", AND(SM_90, PTX78))
+TARGET_BUILTIN(__nvvm_read_ptx_sreg_cluster_ctaid_y, "i", "nc", AND(SM_90, PTX78))
+TARGET_BUILTIN(__nvvm_read_ptx_sreg_cluster_ctaid_z, "i", "nc", AND(SM_90, PTX78))
+TARGET_BUILTIN(__nvvm_read_ptx_sreg_cluster_ctaid_w, "i", "nc", AND(SM_90, PTX78))
+
+TARGET_BUILTIN(__nvvm_read_ptx_sreg_cluster_nctaid_x, "i", "nc", AND(SM_90, PTX78))
+TARGET_BUILTIN(__nvvm_read_ptx_sreg_cluster_nctaid_y, "i", "nc", AND(SM_90, PTX78))
+TARGET_BUILTIN(__nvvm_read_ptx_sreg_cluster_nctaid_z, "i", "nc", AND(SM_90, PTX78))
+TARGET_BUILTIN(__nvvm_read_ptx_sreg_cluster_nctaid_w, "i", "nc", AND(SM_90, PTX78))
+
+TARGET_BUILTIN(__nvvm_read_ptx_sreg_cluster_ctarank, "i", "nc", AND(SM_90, PTX78))
+TARGET_BUILTIN(__nvvm_read_ptx_sreg_cluster_nctarank, "i", "nc", AND(SM_90, PTX78))
+
+TARGET_BUILTIN(__nvvm_is_explicit_cluster, "b", "nc", AND(SM_90, PTX78))
+
BUILTIN(__nvvm_read_ptx_sreg_laneid, "i", "nc")
BUILTIN(__nvvm_read_ptx_sreg_warpid, "i", "nc")
BUILTIN(__nvvm_read_ptx_sreg_nwarpid, "i", "nc")
@@ -101,13 +158,97 @@ BUILTIN(__nvvm_prmt, "UiUiUiUi", "")
// Min Max
-BUILTIN(__nvvm_fmax_ftz_f, "fff", "")
-BUILTIN(__nvvm_fmax_f, "fff", "")
-BUILTIN(__nvvm_fmin_ftz_f, "fff", "")
-BUILTIN(__nvvm_fmin_f, "fff", "")
+TARGET_BUILTIN(__nvvm_fmin_f16, "hhh", "", AND(SM_80, PTX70))
+TARGET_BUILTIN(__nvvm_fmin_ftz_f16, "hhh", "", AND(SM_80, PTX70))
+TARGET_BUILTIN(__nvvm_fmin_nan_f16, "hhh", "", AND(SM_80, PTX70))
+TARGET_BUILTIN(__nvvm_fmin_ftz_nan_f16, "hhh", "", AND(SM_80, PTX70))
+TARGET_BUILTIN(__nvvm_fmin_xorsign_abs_f16, "hhh", "", AND(SM_86, PTX72))
+TARGET_BUILTIN(__nvvm_fmin_ftz_xorsign_abs_f16, "hhh", "", AND(SM_86, PTX72))
+TARGET_BUILTIN(__nvvm_fmin_nan_xorsign_abs_f16, "hhh", "", AND(SM_86, PTX72))
+TARGET_BUILTIN(__nvvm_fmin_ftz_nan_xorsign_abs_f16, "hhh", "",
+ AND(SM_86, PTX72))
+TARGET_BUILTIN(__nvvm_fmin_f16x2, "V2hV2hV2h", "", AND(SM_80, PTX70))
+TARGET_BUILTIN(__nvvm_fmin_ftz_f16x2, "V2hV2hV2h", "", AND(SM_80, PTX70))
+TARGET_BUILTIN(__nvvm_fmin_nan_f16x2, "V2hV2hV2h", "", AND(SM_80, PTX70))
+TARGET_BUILTIN(__nvvm_fmin_ftz_nan_f16x2, "V2hV2hV2h", "", AND(SM_80, PTX70))
+TARGET_BUILTIN(__nvvm_fmin_xorsign_abs_f16x2, "V2hV2hV2h", "",
+ AND(SM_86, PTX72))
+TARGET_BUILTIN(__nvvm_fmin_ftz_xorsign_abs_f16x2, "V2hV2hV2h", "",
+ AND(SM_86, PTX72))
+TARGET_BUILTIN(__nvvm_fmin_nan_xorsign_abs_f16x2, "V2hV2hV2h", "",
+ AND(SM_86, PTX72))
+TARGET_BUILTIN(__nvvm_fmin_ftz_nan_xorsign_abs_f16x2, "V2hV2hV2h", "",
+ AND(SM_86, PTX72))
+TARGET_BUILTIN(__nvvm_fmin_bf16, "yyy", "", AND(SM_80, PTX70))
+TARGET_BUILTIN(__nvvm_fmin_ftz_bf16, "yyy", "", AND(SM_80, PTX70))
+TARGET_BUILTIN(__nvvm_fmin_nan_bf16, "yyy", "", AND(SM_80, PTX70))
+TARGET_BUILTIN(__nvvm_fmin_ftz_nan_bf16, "yyy", "", AND(SM_80, PTX70))
+TARGET_BUILTIN(__nvvm_fmin_xorsign_abs_bf16, "yyy", "", AND(SM_86, PTX72))
+TARGET_BUILTIN(__nvvm_fmin_nan_xorsign_abs_bf16, "yyy", "",
+ AND(SM_86, PTX72))
+TARGET_BUILTIN(__nvvm_fmin_bf16x2, "V2yV2yV2y", "", AND(SM_80, PTX70))
+TARGET_BUILTIN(__nvvm_fmin_ftz_bf16x2, "V2yV2yV2y", "", AND(SM_80, PTX70))
+TARGET_BUILTIN(__nvvm_fmin_nan_bf16x2, "V2yV2yV2y", "", AND(SM_80, PTX70))
+TARGET_BUILTIN(__nvvm_fmin_ftz_nan_bf16x2, "V2yV2yV2y", "", AND(SM_80, PTX70))
+TARGET_BUILTIN(__nvvm_fmin_xorsign_abs_bf16x2, "V2yV2yV2y", "",
+ AND(SM_86, PTX72))
+TARGET_BUILTIN(__nvvm_fmin_nan_xorsign_abs_bf16x2, "V2yV2yV2y", "",
+ AND(SM_86, PTX72))
+BUILTIN(__nvvm_fmin_f, "fff", "")
+BUILTIN(__nvvm_fmin_ftz_f, "fff", "")
+TARGET_BUILTIN(__nvvm_fmin_nan_f, "fff", "", AND(SM_80, PTX70))
+TARGET_BUILTIN(__nvvm_fmin_ftz_nan_f, "fff", "", AND(SM_80, PTX70))
+TARGET_BUILTIN(__nvvm_fmin_xorsign_abs_f, "fff", "", AND(SM_86, PTX72))
+TARGET_BUILTIN(__nvvm_fmin_ftz_xorsign_abs_f, "fff", "", AND(SM_86, PTX72))
+TARGET_BUILTIN(__nvvm_fmin_nan_xorsign_abs_f, "fff", "", AND(SM_86, PTX72))
+TARGET_BUILTIN(__nvvm_fmin_ftz_nan_xorsign_abs_f, "fff", "", AND(SM_86, PTX72))
+BUILTIN(__nvvm_fmin_d, "ddd", "")
+TARGET_BUILTIN(__nvvm_fmax_f16, "hhh", "", AND(SM_80, PTX70))
+TARGET_BUILTIN(__nvvm_fmax_ftz_f16, "hhh", "", AND(SM_80, PTX70))
+TARGET_BUILTIN(__nvvm_fmax_nan_f16, "hhh", "", AND(SM_80, PTX70))
+TARGET_BUILTIN(__nvvm_fmax_ftz_nan_f16, "hhh", "", AND(SM_80, PTX70))
+TARGET_BUILTIN(__nvvm_fmax_xorsign_abs_f16, "hhh", "", AND(SM_86, PTX72))
+TARGET_BUILTIN(__nvvm_fmax_ftz_xorsign_abs_f16, "hhh", "", AND(SM_86, PTX72))
+TARGET_BUILTIN(__nvvm_fmax_nan_xorsign_abs_f16, "hhh", "", AND(SM_86, PTX72))
+TARGET_BUILTIN(__nvvm_fmax_ftz_nan_xorsign_abs_f16, "hhh", "",
+ AND(SM_86, PTX72))
+TARGET_BUILTIN(__nvvm_fmax_f16x2, "V2hV2hV2h", "", AND(SM_80, PTX70))
+TARGET_BUILTIN(__nvvm_fmax_ftz_f16x2, "V2hV2hV2h", "", AND(SM_80, PTX70))
+TARGET_BUILTIN(__nvvm_fmax_nan_f16x2, "V2hV2hV2h", "", AND(SM_80, PTX70))
+TARGET_BUILTIN(__nvvm_fmax_ftz_nan_f16x2, "V2hV2hV2h", "", AND(SM_80, PTX70))
+TARGET_BUILTIN(__nvvm_fmax_xorsign_abs_f16x2, "V2hV2hV2h", "",
+ AND(SM_86, PTX72))
+TARGET_BUILTIN(__nvvm_fmax_ftz_xorsign_abs_f16x2, "V2hV2hV2h", "",
+ AND(SM_86, PTX72))
+TARGET_BUILTIN(__nvvm_fmax_nan_xorsign_abs_f16x2, "V2hV2hV2h", "",
+ AND(SM_86, PTX72))
+TARGET_BUILTIN(__nvvm_fmax_ftz_nan_xorsign_abs_f16x2, "V2hV2hV2h", "",
+ AND(SM_86, PTX72))
+TARGET_BUILTIN(__nvvm_fmax_bf16, "yyy", "", AND(SM_80, PTX70))
+TARGET_BUILTIN(__nvvm_fmax_ftz_bf16, "yyy", "", AND(SM_80, PTX70))
+TARGET_BUILTIN(__nvvm_fmax_nan_bf16, "yyy", "", AND(SM_80, PTX70))
+TARGET_BUILTIN(__nvvm_fmax_ftz_nan_bf16, "yyy", "", AND(SM_80, PTX70))
+TARGET_BUILTIN(__nvvm_fmax_xorsign_abs_bf16, "yyy", "", AND(SM_86, PTX72))
+TARGET_BUILTIN(__nvvm_fmax_nan_xorsign_abs_bf16, "yyy", "",
+ AND(SM_86, PTX72))
+TARGET_BUILTIN(__nvvm_fmax_bf16x2, "V2yV2yV2y", "", AND(SM_80, PTX70))
+TARGET_BUILTIN(__nvvm_fmax_ftz_bf16x2, "V2yV2yV2y", "", AND(SM_80, PTX70))
+TARGET_BUILTIN(__nvvm_fmax_nan_bf16x2, "V2yV2yV2y", "", AND(SM_80, PTX70))
+TARGET_BUILTIN(__nvvm_fmax_ftz_nan_bf16x2, "V2yV2yV2y", "", AND(SM_80, PTX70))
+TARGET_BUILTIN(__nvvm_fmax_xorsign_abs_bf16x2, "V2yV2yV2y", "",
+ AND(SM_86, PTX72))
+TARGET_BUILTIN(__nvvm_fmax_nan_xorsign_abs_bf16x2, "V2yV2yV2y", "",
+ AND(SM_86, PTX72))
+BUILTIN(__nvvm_fmax_f, "fff", "")
+BUILTIN(__nvvm_fmax_ftz_f, "fff", "")
+TARGET_BUILTIN(__nvvm_fmax_nan_f, "fff", "", AND(SM_80, PTX70))
+TARGET_BUILTIN(__nvvm_fmax_ftz_nan_f, "fff", "", AND(SM_80, PTX70))
+TARGET_BUILTIN(__nvvm_fmax_xorsign_abs_f, "fff", "", AND(SM_86, PTX72))
+TARGET_BUILTIN(__nvvm_fmax_ftz_xorsign_abs_f, "fff", "", AND(SM_86, PTX72))
+TARGET_BUILTIN(__nvvm_fmax_nan_xorsign_abs_f, "fff", "", AND(SM_86, PTX72))
+TARGET_BUILTIN(__nvvm_fmax_ftz_nan_xorsign_abs_f, "fff", "", AND(SM_86, PTX72))
BUILTIN(__nvvm_fmax_d, "ddd", "")
-BUILTIN(__nvvm_fmin_d, "ddd", "")
// Multiplication
@@ -196,6 +337,8 @@ BUILTIN(__nvvm_saturate_d, "dd", "")
BUILTIN(__nvvm_ex2_approx_ftz_f, "ff", "")
BUILTIN(__nvvm_ex2_approx_f, "ff", "")
BUILTIN(__nvvm_ex2_approx_d, "dd", "")
+TARGET_BUILTIN(__nvvm_ex2_approx_f16, "hh", "", AND(SM_75, PTX70))
+TARGET_BUILTIN(__nvvm_ex2_approx_f16x2, "V2hV2h", "", AND(SM_75, PTX70))
BUILTIN(__nvvm_lg2_approx_ftz_f, "ff", "")
BUILTIN(__nvvm_lg2_approx_f, "ff", "")
@@ -211,6 +354,22 @@ BUILTIN(__nvvm_cos_approx_f, "ff", "")
// Fma
+TARGET_BUILTIN(__nvvm_fma_rn_f16, "hhhh", "", AND(SM_53, PTX42))
+TARGET_BUILTIN(__nvvm_fma_rn_ftz_f16, "hhhh", "", AND(SM_53, PTX42))
+TARGET_BUILTIN(__nvvm_fma_rn_sat_f16, "hhhh", "", AND(SM_53, PTX42))
+TARGET_BUILTIN(__nvvm_fma_rn_ftz_sat_f16, "hhhh", "", AND(SM_53, PTX42))
+TARGET_BUILTIN(__nvvm_fma_rn_relu_f16, "hhhh", "", AND(SM_80, PTX70))
+TARGET_BUILTIN(__nvvm_fma_rn_ftz_relu_f16, "hhhh", "", AND(SM_80, PTX70))
+TARGET_BUILTIN(__nvvm_fma_rn_f16x2, "V2hV2hV2hV2h", "", AND(SM_53, PTX42))
+TARGET_BUILTIN(__nvvm_fma_rn_ftz_f16x2, "V2hV2hV2hV2h", "", AND(SM_53, PTX42))
+TARGET_BUILTIN(__nvvm_fma_rn_sat_f16x2, "V2hV2hV2hV2h", "", AND(SM_53, PTX42))
+TARGET_BUILTIN(__nvvm_fma_rn_ftz_sat_f16x2, "V2hV2hV2hV2h", "", AND(SM_53, PTX42))
+TARGET_BUILTIN(__nvvm_fma_rn_relu_f16x2, "V2hV2hV2hV2h", "", AND(SM_80, PTX70))
+TARGET_BUILTIN(__nvvm_fma_rn_ftz_relu_f16x2, "V2hV2hV2hV2h", "", AND(SM_80, PTX70))
+TARGET_BUILTIN(__nvvm_fma_rn_bf16, "yyyy", "", AND(SM_80, PTX70))
+TARGET_BUILTIN(__nvvm_fma_rn_relu_bf16, "yyyy", "", AND(SM_80, PTX70))
+TARGET_BUILTIN(__nvvm_fma_rn_bf16x2, "V2yV2yV2yV2y", "", AND(SM_80, PTX70))
+TARGET_BUILTIN(__nvvm_fma_rn_relu_bf16x2, "V2yV2yV2yV2y", "", AND(SM_80, PTX70))
BUILTIN(__nvvm_fma_rn_ftz_f, "ffff", "")
BUILTIN(__nvvm_fma_rn_f, "ffff", "")
BUILTIN(__nvvm_fma_rz_ftz_f, "ffff", "")
@@ -239,6 +398,8 @@ BUILTIN(__nvvm_rcp_rn_d, "dd", "")
BUILTIN(__nvvm_rcp_rz_d, "dd", "")
BUILTIN(__nvvm_rcp_rm_d, "dd", "")
BUILTIN(__nvvm_rcp_rp_d, "dd", "")
+
+BUILTIN(__nvvm_rcp_approx_ftz_f, "ff", "")
BUILTIN(__nvvm_rcp_approx_ftz_d, "dd", "")
// Sqrt
@@ -396,6 +557,23 @@ BUILTIN(__nvvm_ull2d_rp, "dULLi", "")
BUILTIN(__nvvm_f2h_rn_ftz, "Usf", "")
BUILTIN(__nvvm_f2h_rn, "Usf", "")
+TARGET_BUILTIN(__nvvm_ff2bf16x2_rn, "V2yff", "", AND(SM_80,PTX70))
+TARGET_BUILTIN(__nvvm_ff2bf16x2_rn_relu, "V2yff", "", AND(SM_80,PTX70))
+TARGET_BUILTIN(__nvvm_ff2bf16x2_rz, "V2yff", "", AND(SM_80,PTX70))
+TARGET_BUILTIN(__nvvm_ff2bf16x2_rz_relu, "V2yff", "", 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, "yf", "", AND(SM_80,PTX70))
+TARGET_BUILTIN(__nvvm_f2bf16_rn_relu, "yf", "", AND(SM_80,PTX70))
+TARGET_BUILTIN(__nvvm_f2bf16_rz, "yf", "", AND(SM_80,PTX70))
+TARGET_BUILTIN(__nvvm_f2bf16_rz_relu, "yf", "", AND(SM_80,PTX70))
+
+TARGET_BUILTIN(__nvvm_f2tf32_rna, "ZUif", "", AND(SM_80,PTX70))
+
// Bitcast
BUILTIN(__nvvm_bitcast_f2i, "if", "")
@@ -418,6 +596,11 @@ TARGET_BUILTIN(__nvvm_bar_warp_sync, "vUi", "n", PTX60)
TARGET_BUILTIN(__nvvm_barrier_sync, "vUi", "n", PTX60)
TARGET_BUILTIN(__nvvm_barrier_sync_cnt, "vUiUi", "n", PTX60)
+TARGET_BUILTIN(__nvvm_barrier_cluster_arrive, "v", "n", AND(SM_90,PTX78))
+TARGET_BUILTIN(__nvvm_barrier_cluster_arrive_relaxed, "v", "n", AND(SM_90,PTX80))
+TARGET_BUILTIN(__nvvm_barrier_cluster_wait, "v", "n", AND(SM_90,PTX78))
+TARGET_BUILTIN(__nvvm_fence_sc_cluster, "v", "n", AND(SM_90,PTX78))
+
// Shuffle
BUILTIN(__nvvm_shfl_down_i32, "iiii", "")
@@ -450,11 +633,11 @@ TARGET_BUILTIN(__nvvm_vote_uni_sync, "bUib", "", PTX60)
TARGET_BUILTIN(__nvvm_vote_ballot_sync, "UiUib", "", PTX60)
// Match
-TARGET_BUILTIN(__nvvm_match_any_sync_i32, "UiUiUi", "", PTX60)
-TARGET_BUILTIN(__nvvm_match_any_sync_i64, "WiUiWi", "", PTX60)
+TARGET_BUILTIN(__nvvm_match_any_sync_i32, "UiUiUi", "", AND(SM_70,PTX60))
+TARGET_BUILTIN(__nvvm_match_any_sync_i64, "UiUiWi", "", AND(SM_70,PTX60))
// These return a pair {value, predicate}, which requires custom lowering.
-TARGET_BUILTIN(__nvvm_match_all_sync_i32p, "UiUiUii*", "", PTX60)
-TARGET_BUILTIN(__nvvm_match_all_sync_i64p, "WiUiWii*", "", PTX60)
+TARGET_BUILTIN(__nvvm_match_all_sync_i32p, "UiUiUii*", "", AND(SM_70,PTX60))
+TARGET_BUILTIN(__nvvm_match_all_sync_i64p, "UiUiWii*", "", AND(SM_70,PTX60))
// Redux
TARGET_BUILTIN(__nvvm_redux_sync_add, "iii", "", AND(SM_80,PTX70))
@@ -647,8 +830,50 @@ TARGET_BUILTIN(__nvvm_atom_sys_cas_gen_ll, "LLiLLiD*LLiLLi", "n", SM_60)
BUILTIN(__nvvm_compiler_error, "vcC*4", "n")
BUILTIN(__nvvm_compiler_warn, "vcC*4", "n")
-// __ldg. This is not implemented as a builtin by nvcc.
+BUILTIN(__nvvm_ldu_c, "ccC*", "")
+BUILTIN(__nvvm_ldu_sc, "ScScC*", "")
+BUILTIN(__nvvm_ldu_s, "ssC*", "")
+BUILTIN(__nvvm_ldu_i, "iiC*", "")
+BUILTIN(__nvvm_ldu_l, "LiLiC*", "")
+BUILTIN(__nvvm_ldu_ll, "LLiLLiC*", "")
+
+BUILTIN(__nvvm_ldu_uc, "UcUcC*", "")
+BUILTIN(__nvvm_ldu_us, "UsUsC*", "")
+BUILTIN(__nvvm_ldu_ui, "UiUiC*", "")
+BUILTIN(__nvvm_ldu_ul, "ULiULiC*", "")
+BUILTIN(__nvvm_ldu_ull, "ULLiULLiC*", "")
+
+BUILTIN(__nvvm_ldu_h, "hhC*", "")
+BUILTIN(__nvvm_ldu_f, "ffC*", "")
+BUILTIN(__nvvm_ldu_d, "ddC*", "")
+
+BUILTIN(__nvvm_ldu_c2, "E2cE2cC*", "")
+BUILTIN(__nvvm_ldu_sc2, "E2ScE2ScC*", "")
+BUILTIN(__nvvm_ldu_c4, "E4cE4cC*", "")
+BUILTIN(__nvvm_ldu_sc4, "E4ScE4ScC*", "")
+BUILTIN(__nvvm_ldu_s2, "E2sE2sC*", "")
+BUILTIN(__nvvm_ldu_s4, "E4sE4sC*", "")
+BUILTIN(__nvvm_ldu_i2, "E2iE2iC*", "")
+BUILTIN(__nvvm_ldu_i4, "E4iE4iC*", "")
+BUILTIN(__nvvm_ldu_l2, "E2LiE2LiC*", "")
+BUILTIN(__nvvm_ldu_ll2, "E2LLiE2LLiC*", "")
+
+BUILTIN(__nvvm_ldu_uc2, "E2UcE2UcC*", "")
+BUILTIN(__nvvm_ldu_uc4, "E4UcE4UcC*", "")
+BUILTIN(__nvvm_ldu_us2, "E2UsE2UsC*", "")
+BUILTIN(__nvvm_ldu_us4, "E4UsE4UsC*", "")
+BUILTIN(__nvvm_ldu_ui2, "E2UiE2UiC*", "")
+BUILTIN(__nvvm_ldu_ui4, "E4UiE4UiC*", "")
+BUILTIN(__nvvm_ldu_ul2, "E2ULiE2ULiC*", "")
+BUILTIN(__nvvm_ldu_ull2, "E2ULLiE2ULLiC*", "")
+
+BUILTIN(__nvvm_ldu_h2, "E2hE2hC*", "")
+BUILTIN(__nvvm_ldu_f2, "E2fE2fC*", "")
+BUILTIN(__nvvm_ldu_f4, "E4fE4fC*", "")
+BUILTIN(__nvvm_ldu_d2, "E2dE2dC*", "")
+
BUILTIN(__nvvm_ldg_c, "ccC*", "")
+BUILTIN(__nvvm_ldg_sc, "ScScC*", "")
BUILTIN(__nvvm_ldg_s, "ssC*", "")
BUILTIN(__nvvm_ldg_i, "iiC*", "")
BUILTIN(__nvvm_ldg_l, "LiLiC*", "")
@@ -660,15 +885,19 @@ BUILTIN(__nvvm_ldg_ui, "UiUiC*", "")
BUILTIN(__nvvm_ldg_ul, "ULiULiC*", "")
BUILTIN(__nvvm_ldg_ull, "ULLiULLiC*", "")
+BUILTIN(__nvvm_ldg_h, "hhC*", "")
BUILTIN(__nvvm_ldg_f, "ffC*", "")
BUILTIN(__nvvm_ldg_d, "ddC*", "")
BUILTIN(__nvvm_ldg_c2, "E2cE2cC*", "")
+BUILTIN(__nvvm_ldg_sc2, "E2ScE2ScC*", "")
BUILTIN(__nvvm_ldg_c4, "E4cE4cC*", "")
+BUILTIN(__nvvm_ldg_sc4, "E4ScE4ScC*", "")
BUILTIN(__nvvm_ldg_s2, "E2sE2sC*", "")
BUILTIN(__nvvm_ldg_s4, "E4sE4sC*", "")
BUILTIN(__nvvm_ldg_i2, "E2iE2iC*", "")
BUILTIN(__nvvm_ldg_i4, "E4iE4iC*", "")
+BUILTIN(__nvvm_ldg_l2, "E2LiE2LiC*", "")
BUILTIN(__nvvm_ldg_ll2, "E2LLiE2LLiC*", "")
BUILTIN(__nvvm_ldg_uc2, "E2UcE2UcC*", "")
@@ -677,33 +906,42 @@ BUILTIN(__nvvm_ldg_us2, "E2UsE2UsC*", "")
BUILTIN(__nvvm_ldg_us4, "E4UsE4UsC*", "")
BUILTIN(__nvvm_ldg_ui2, "E2UiE2UiC*", "")
BUILTIN(__nvvm_ldg_ui4, "E4UiE4UiC*", "")
+BUILTIN(__nvvm_ldg_ul2, "E2ULiE2ULiC*", "")
BUILTIN(__nvvm_ldg_ull2, "E2ULLiE2ULLiC*", "")
+BUILTIN(__nvvm_ldg_h2, "E2hE2hC*", "")
BUILTIN(__nvvm_ldg_f2, "E2fE2fC*", "")
BUILTIN(__nvvm_ldg_f4, "E4fE4fC*", "")
BUILTIN(__nvvm_ldg_d2, "E2dE2dC*", "")
+// Address space predicates.
+BUILTIN(__nvvm_isspacep_const, "bvC*", "nc")
+BUILTIN(__nvvm_isspacep_global, "bvC*", "nc")
+BUILTIN(__nvvm_isspacep_local, "bvC*", "nc")
+BUILTIN(__nvvm_isspacep_shared, "bvC*", "nc")
+TARGET_BUILTIN(__nvvm_isspacep_shared_cluster,"bvC*", "nc", AND(SM_90,PTX78))
+
// Builtins to support WMMA instructions on sm_70
TARGET_BUILTIN(__hmma_m16n16k16_ld_a, "vi*iC*UiIi", "", AND(SM_70,PTX60))
TARGET_BUILTIN(__hmma_m16n16k16_ld_b, "vi*iC*UiIi", "", AND(SM_70,PTX60))
TARGET_BUILTIN(__hmma_m16n16k16_ld_c_f16, "vi*iC*UiIi", "", AND(SM_70,PTX60))
TARGET_BUILTIN(__hmma_m16n16k16_ld_c_f32, "vf*fC*UiIi", "", AND(SM_70,PTX60))
-TARGET_BUILTIN(__hmma_m16n16k16_st_c_f16, "vi*i*UiIi", "", AND(SM_70,PTX60))
-TARGET_BUILTIN(__hmma_m16n16k16_st_c_f32, "vf*f*UiIi", "", AND(SM_70,PTX60))
+TARGET_BUILTIN(__hmma_m16n16k16_st_c_f16, "vi*iC*UiIi", "", AND(SM_70,PTX60))
+TARGET_BUILTIN(__hmma_m16n16k16_st_c_f32, "vf*fC*UiIi", "", AND(SM_70,PTX60))
TARGET_BUILTIN(__hmma_m32n8k16_ld_a, "vi*iC*UiIi", "", AND(SM_70,PTX61))
TARGET_BUILTIN(__hmma_m32n8k16_ld_b, "vi*iC*UiIi", "", AND(SM_70,PTX61))
TARGET_BUILTIN(__hmma_m32n8k16_ld_c_f16, "vi*iC*UiIi", "", AND(SM_70,PTX61))
TARGET_BUILTIN(__hmma_m32n8k16_ld_c_f32, "vf*fC*UiIi", "", AND(SM_70,PTX61))
-TARGET_BUILTIN(__hmma_m32n8k16_st_c_f16, "vi*i*UiIi", "", AND(SM_70,PTX61))
-TARGET_BUILTIN(__hmma_m32n8k16_st_c_f32, "vf*f*UiIi", "", AND(SM_70,PTX61))
+TARGET_BUILTIN(__hmma_m32n8k16_st_c_f16, "vi*iC*UiIi", "", AND(SM_70,PTX61))
+TARGET_BUILTIN(__hmma_m32n8k16_st_c_f32, "vf*fC*UiIi", "", AND(SM_70,PTX61))
TARGET_BUILTIN(__hmma_m8n32k16_ld_a, "vi*iC*UiIi", "", AND(SM_70,PTX61))
TARGET_BUILTIN(__hmma_m8n32k16_ld_b, "vi*iC*UiIi", "", AND(SM_70,PTX61))
TARGET_BUILTIN(__hmma_m8n32k16_ld_c_f16, "vi*iC*UiIi", "", AND(SM_70,PTX61))
TARGET_BUILTIN(__hmma_m8n32k16_ld_c_f32, "vf*fC*UiIi", "", AND(SM_70,PTX61))
-TARGET_BUILTIN(__hmma_m8n32k16_st_c_f16, "vi*i*UiIi", "", AND(SM_70,PTX61))
-TARGET_BUILTIN(__hmma_m8n32k16_st_c_f32, "vf*f*UiIi", "", AND(SM_70,PTX61))
+TARGET_BUILTIN(__hmma_m8n32k16_st_c_f16, "vi*iC*UiIi", "", AND(SM_70,PTX61))
+TARGET_BUILTIN(__hmma_m8n32k16_st_c_f32, "vf*fC*UiIi", "", AND(SM_70,PTX61))
TARGET_BUILTIN(__hmma_m16n16k16_mma_f16f16, "vi*iC*iC*iC*IiIi", "", AND(SM_70,PTX60))
TARGET_BUILTIN(__hmma_m16n16k16_mma_f32f16, "vf*iC*iC*iC*IiIi", "", AND(SM_70,PTX60))
@@ -724,7 +962,7 @@ TARGET_BUILTIN(__hmma_m8n32k16_mma_f16f32, "vi*iC*iC*fC*IiIi", "", AND(SM_70,PTX
TARGET_BUILTIN(__bmma_m8n8k128_ld_a_b1, "vi*iC*UiIi", "", AND(SM_75,PTX63))
TARGET_BUILTIN(__bmma_m8n8k128_ld_b_b1, "vi*iC*UiIi", "", AND(SM_75,PTX63))
TARGET_BUILTIN(__bmma_m8n8k128_ld_c, "vi*iC*UiIi", "", AND(SM_75,PTX63))
-TARGET_BUILTIN(__bmma_m8n8k128_mma_and_popc_b1, "vi*iC*iC*iC*Ii", "", AND(SM_75,PTX71))
+TARGET_BUILTIN(__bmma_m8n8k128_mma_and_popc_b1, "vi*iC*iC*iC*Ii", "", AND(SM_80,PTX71))
TARGET_BUILTIN(__bmma_m8n8k128_mma_xor_popc_b1, "vi*iC*iC*iC*Ii", "", AND(SM_75,PTX63))
TARGET_BUILTIN(__bmma_m8n8k128_st_c_i32, "vi*iC*UiIi", "", AND(SM_75,PTX63))
TARGET_BUILTIN(__imma_m16n16k16_ld_a_s8, "vi*iC*UiIi", "", AND(SM_72,PTX63))
@@ -789,24 +1027,42 @@ TARGET_BUILTIN(__nvvm_cp_async_mbarrier_arrive_shared, "vWi*3", "", AND(SM_80,PT
TARGET_BUILTIN(__nvvm_cp_async_mbarrier_arrive_noinc, "vWi*", "", AND(SM_80,PTX70))
TARGET_BUILTIN(__nvvm_cp_async_mbarrier_arrive_noinc_shared, "vWi*3", "", AND(SM_80,PTX70))
-TARGET_BUILTIN(__nvvm_cp_async_ca_shared_global_4, "vv*3vC*1", "", AND(SM_80,PTX70))
-TARGET_BUILTIN(__nvvm_cp_async_ca_shared_global_8, "vv*3vC*1", "", AND(SM_80,PTX70))
-TARGET_BUILTIN(__nvvm_cp_async_ca_shared_global_16, "vv*3vC*1", "", AND(SM_80,PTX70))
-TARGET_BUILTIN(__nvvm_cp_async_cg_shared_global_16, "vv*3vC*1", "", AND(SM_80,PTX70))
+TARGET_BUILTIN(__nvvm_cp_async_ca_shared_global_4, "vv*3vC*1.", "", AND(SM_80,PTX70))
+TARGET_BUILTIN(__nvvm_cp_async_ca_shared_global_8, "vv*3vC*1.", "", AND(SM_80,PTX70))
+TARGET_BUILTIN(__nvvm_cp_async_ca_shared_global_16, "vv*3vC*1.", "", AND(SM_80,PTX70))
+TARGET_BUILTIN(__nvvm_cp_async_cg_shared_global_16, "vv*3vC*1.", "", AND(SM_80,PTX70))
TARGET_BUILTIN(__nvvm_cp_async_commit_group, "v", "", AND(SM_80,PTX70))
TARGET_BUILTIN(__nvvm_cp_async_wait_group, "vIi", "", AND(SM_80,PTX70))
TARGET_BUILTIN(__nvvm_cp_async_wait_all, "v", "", AND(SM_80,PTX70))
+
+// bf16, bf16x2 abs, neg
+TARGET_BUILTIN(__nvvm_abs_bf16, "yy", "", AND(SM_80,PTX70))
+TARGET_BUILTIN(__nvvm_abs_bf16x2, "V2yV2y", "", AND(SM_80,PTX70))
+TARGET_BUILTIN(__nvvm_neg_bf16, "yy", "", AND(SM_80,PTX70))
+TARGET_BUILTIN(__nvvm_neg_bf16x2, "V2yV2y", "", AND(SM_80,PTX70))
+
+TARGET_BUILTIN(__nvvm_mapa, "v*v*i", "", AND(SM_90, PTX78))
+TARGET_BUILTIN(__nvvm_mapa_shared_cluster, "v*3v*3i", "", AND(SM_90, PTX78))
+TARGET_BUILTIN(__nvvm_getctarank, "iv*", "", AND(SM_90, PTX78))
+TARGET_BUILTIN(__nvvm_getctarank_shared_cluster, "iv*3", "", AND(SM_90,PTX78))
+
#undef BUILTIN
#undef TARGET_BUILTIN
#pragma pop_macro("AND")
+#pragma pop_macro("SM_53")
#pragma pop_macro("SM_60")
#pragma pop_macro("SM_70")
#pragma pop_macro("SM_72")
#pragma pop_macro("SM_75")
#pragma pop_macro("SM_80")
#pragma pop_macro("SM_86")
+#pragma pop_macro("SM_87")
+#pragma pop_macro("SM_89")
+#pragma pop_macro("SM_90")
+#pragma pop_macro("SM_90a")
+#pragma pop_macro("PTX42")
#pragma pop_macro("PTX60")
#pragma pop_macro("PTX61")
#pragma pop_macro("PTX63")
@@ -815,3 +1071,13 @@ TARGET_BUILTIN(__nvvm_cp_async_wait_all, "v", "", AND(SM_80,PTX70))
#pragma pop_macro("PTX70")
#pragma pop_macro("PTX71")
#pragma pop_macro("PTX72")
+#pragma pop_macro("PTX73")
+#pragma pop_macro("PTX74")
+#pragma pop_macro("PTX75")
+#pragma pop_macro("PTX76")
+#pragma pop_macro("PTX77")
+#pragma pop_macro("PTX78")
+#pragma pop_macro("PTX80")
+#pragma pop_macro("PTX81")
+#pragma pop_macro("PTX82")
+#pragma pop_macro("PTX83")
diff --git a/contrib/llvm-project/clang/include/clang/Basic/BuiltinsPPC.def b/contrib/llvm-project/clang/include/clang/Basic/BuiltinsPPC.def
index dfe97af300f4..88ae0ce94085 100644
--- a/contrib/llvm-project/clang/include/clang/Basic/BuiltinsPPC.def
+++ b/contrib/llvm-project/clang/include/clang/Basic/BuiltinsPPC.def
@@ -19,15 +19,33 @@
// The format of this database matches clang/Basic/Builtins.def except for the
// MMA builtins that are using their own format documented below.
-#if defined(BUILTIN) && !defined(CUSTOM_BUILTIN)
-# define CUSTOM_BUILTIN(ID, INTR, TYPES, ACCUMULATE) \
- BUILTIN(__builtin_##ID, "i.", "t")
-#elif defined(CUSTOM_BUILTIN) && !defined(BUILTIN)
-# define BUILTIN(ID, TYPES, ATTRS)
+#ifndef BUILTIN
+#define BUILTIN(ID, TYPE, ATTRS)
#endif
-#define UNALIASED_CUSTOM_BUILTIN(ID, TYPES, ACCUMULATE) \
- CUSTOM_BUILTIN(ID, ID, TYPES, ACCUMULATE)
+#if defined(BUILTIN) && !defined(TARGET_BUILTIN)
+#define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) BUILTIN(ID, TYPE, ATTRS)
+#endif
+
+#ifndef CUSTOM_BUILTIN
+#define CUSTOM_BUILTIN(ID, INTR, TYPES, ACCUMULATE, FEATURE) \
+ TARGET_BUILTIN(__builtin_##ID, "i.", "t", FEATURE)
+#endif
+
+#define UNALIASED_CUSTOM_BUILTIN(ID, TYPES, ACCUMULATE, FEATURE) \
+ CUSTOM_BUILTIN(ID, ID, TYPES, ACCUMULATE, FEATURE)
+
+// GCC predefined macros to rename builtins, undef them to keep original names.
+#if defined(__GNUC__) && !defined(__clang__)
+#undef __builtin_vsx_xvnmaddadp
+#undef __builtin_vsx_xvnmaddasp
+#undef __builtin_vsx_xvmsubasp
+#undef __builtin_vsx_xvmsubadp
+#undef __builtin_vsx_xvmaddadp
+#undef __builtin_vsx_xvnmsubasp
+#undef __builtin_vsx_xvnmsubadp
+#undef __builtin_vsx_xvmaddasp
+#endif
// XL Compatibility built-ins
BUILTIN(__builtin_ppc_popcntb, "ULiULi", "")
@@ -46,7 +64,7 @@ BUILTIN(__builtin_ppc_dcbst, "vvC*", "")
BUILTIN(__builtin_ppc_dcbt, "vv*", "")
BUILTIN(__builtin_ppc_dcbtst, "vv*", "")
BUILTIN(__builtin_ppc_dcbz, "vv*", "")
-BUILTIN(__builtin_ppc_icbt, "vv*", "")
+TARGET_BUILTIN(__builtin_ppc_icbt, "vv*", "", "isa-v207-instructions")
BUILTIN(__builtin_ppc_fric, "dd", "")
BUILTIN(__builtin_ppc_frim, "dd", "")
BUILTIN(__builtin_ppc_frims, "ff", "")
@@ -74,12 +92,12 @@ BUILTIN(__builtin_ppc_fetch_and_swap, "UiUiD*Ui", "")
BUILTIN(__builtin_ppc_fetch_and_swaplp, "ULiULiD*ULi", "")
BUILTIN(__builtin_ppc_ldarx, "LiLiD*", "")
BUILTIN(__builtin_ppc_lwarx, "iiD*", "")
-BUILTIN(__builtin_ppc_lharx, "isD*", "")
-BUILTIN(__builtin_ppc_lbarx, "UiUcD*", "")
+TARGET_BUILTIN(__builtin_ppc_lharx, "ssD*", "", "isa-v207-instructions")
+TARGET_BUILTIN(__builtin_ppc_lbarx, "ccD*", "", "isa-v207-instructions")
BUILTIN(__builtin_ppc_stdcx, "iLiD*Li", "")
BUILTIN(__builtin_ppc_stwcx, "iiD*i", "")
-BUILTIN(__builtin_ppc_sthcx, "isD*s", "")
-BUILTIN(__builtin_ppc_stbcx, "icD*i", "")
+TARGET_BUILTIN(__builtin_ppc_sthcx, "isD*s", "", "isa-v207-instructions")
+TARGET_BUILTIN(__builtin_ppc_stbcx, "icD*i", "", "isa-v207-instructions")
BUILTIN(__builtin_ppc_tdw, "vLLiLLiIUi", "")
BUILTIN(__builtin_ppc_tw, "viiIUi", "")
BUILTIN(__builtin_ppc_trap, "vi", "")
@@ -92,42 +110,57 @@ BUILTIN(__builtin_ppc_fctiw, "dd", "")
BUILTIN(__builtin_ppc_fctiwz, "dd", "")
BUILTIN(__builtin_ppc_fctudz, "dd", "")
BUILTIN(__builtin_ppc_fctuwz, "dd", "")
+
+// fence builtin prevents all instructions moved across it
+BUILTIN(__builtin_ppc_fence, "v", "")
+
BUILTIN(__builtin_ppc_swdiv_nochk, "ddd", "")
BUILTIN(__builtin_ppc_swdivs_nochk, "fff", "")
BUILTIN(__builtin_ppc_alignx, "vIivC*", "nc")
BUILTIN(__builtin_ppc_rdlam, "UWiUWiUWiUWIi", "nc")
+TARGET_BUILTIN(__builtin_ppc_compare_exp_uo, "idd", "", "isa-v30-instructions,vsx")
+TARGET_BUILTIN(__builtin_ppc_compare_exp_lt, "idd", "", "isa-v30-instructions,vsx")
+TARGET_BUILTIN(__builtin_ppc_compare_exp_gt, "idd", "", "isa-v30-instructions,vsx")
+TARGET_BUILTIN(__builtin_ppc_compare_exp_eq, "idd", "", "isa-v30-instructions,vsx")
+TARGET_BUILTIN(__builtin_ppc_test_data_class, "idIi", "t", "isa-v30-instructions,vsx")
+BUILTIN(__builtin_ppc_swdiv, "ddd", "")
+BUILTIN(__builtin_ppc_swdivs, "fff", "")
// Compare
-BUILTIN(__builtin_ppc_cmpeqb, "LLiLLiLLi", "")
-BUILTIN(__builtin_ppc_cmprb, "iCIiii", "")
-BUILTIN(__builtin_ppc_setb, "LLiLLiLLi", "")
+TARGET_BUILTIN(__builtin_ppc_cmpeqb, "LLiLLiLLi", "", "isa-v30-instructions")
+TARGET_BUILTIN(__builtin_ppc_cmprb, "iCIiii", "", "isa-v30-instructions")
+TARGET_BUILTIN(__builtin_ppc_setb, "LLiLLiLLi", "", "isa-v30-instructions")
BUILTIN(__builtin_ppc_cmpb, "LLiLLiLLi", "")
// Multiply
BUILTIN(__builtin_ppc_mulhd, "LLiLiLi", "")
BUILTIN(__builtin_ppc_mulhdu, "ULLiULiULi", "")
BUILTIN(__builtin_ppc_mulhw, "iii", "")
BUILTIN(__builtin_ppc_mulhwu, "UiUiUi", "")
-BUILTIN(__builtin_ppc_maddhd, "LLiLLiLLiLLi", "")
-BUILTIN(__builtin_ppc_maddhdu, "ULLiULLiULLiULLi", "")
-BUILTIN(__builtin_ppc_maddld, "LLiLLiLLiLLi", "")
+TARGET_BUILTIN(__builtin_ppc_maddhd, "LLiLLiLLiLLi", "", "isa-v30-instructions")
+TARGET_BUILTIN(__builtin_ppc_maddhdu, "ULLiULLiULLiULLi", "",
+ "isa-v30-instructions")
+TARGET_BUILTIN(__builtin_ppc_maddld, "LLiLLiLLiLLi", "", "isa-v30-instructions")
// Rotate
-BUILTIN(__builtin_ppc_rlwnm, "UiUiIUiIUi", "")
+BUILTIN(__builtin_ppc_rlwnm, "UiUiUiIUi", "")
BUILTIN(__builtin_ppc_rlwimi, "UiUiUiIUiIUi", "")
BUILTIN(__builtin_ppc_rldimi, "ULLiULLiULLiIUiIULLi", "")
// load
-BUILTIN(__builtin_ppc_load2r, "UiUs*", "")
+BUILTIN(__builtin_ppc_load2r, "UsUs*", "")
BUILTIN(__builtin_ppc_load4r, "UiUi*", "")
-BUILTIN(__builtin_ppc_load8r, "ULLiULLi*", "")
+TARGET_BUILTIN(__builtin_ppc_load8r, "ULLiULLi*", "", "isa-v206-instructions")
// store
BUILTIN(__builtin_ppc_store2r, "vUiUs*", "")
BUILTIN(__builtin_ppc_store4r, "vUiUi*", "")
-BUILTIN(__builtin_ppc_store8r, "vULLiULLi*", "")
-BUILTIN(__builtin_ppc_extract_exp, "Uid", "")
-BUILTIN(__builtin_ppc_extract_sig, "ULLid", "")
+TARGET_BUILTIN(__builtin_ppc_store8r, "vULLiULLi*", "", "isa-v206-instructions")
+TARGET_BUILTIN(__builtin_ppc_extract_exp, "Uid", "", "power9-vector")
+TARGET_BUILTIN(__builtin_ppc_extract_sig, "ULLid", "", "power9-vector")
BUILTIN(__builtin_ppc_mtfsb0, "vUIi", "")
BUILTIN(__builtin_ppc_mtfsb1, "vUIi", "")
+BUILTIN(__builtin_ppc_mffs, "d", "")
+TARGET_BUILTIN(__builtin_ppc_mffsl, "d", "", "isa-v30-instructions")
BUILTIN(__builtin_ppc_mtfsf, "vUIiUi", "")
BUILTIN(__builtin_ppc_mtfsfi, "vUIiUIi", "")
-BUILTIN(__builtin_ppc_insert_exp, "ddULLi", "")
+BUILTIN(__builtin_ppc_set_fpscr_rn, "di", "")
+TARGET_BUILTIN(__builtin_ppc_insert_exp, "ddULLi", "", "power9-vector")
BUILTIN(__builtin_ppc_fmsub, "dddd", "")
BUILTIN(__builtin_ppc_fmsubs, "ffff", "")
BUILTIN(__builtin_ppc_fnmadd, "dddd", "")
@@ -138,589 +171,717 @@ BUILTIN(__builtin_ppc_fre, "dd", "")
BUILTIN(__builtin_ppc_fres, "ff", "")
BUILTIN(__builtin_ppc_dcbtstt, "vv*", "")
BUILTIN(__builtin_ppc_dcbtt, "vv*", "")
-BUILTIN(__builtin_ppc_mftbu, "Ui","")
+BUILTIN(__builtin_ppc_mftbu, "Ui", "")
BUILTIN(__builtin_ppc_mfmsr, "Ui", "")
BUILTIN(__builtin_ppc_mfspr, "ULiIi", "")
BUILTIN(__builtin_ppc_mtmsr, "vUi", "")
BUILTIN(__builtin_ppc_mtspr, "vIiULi", "")
BUILTIN(__builtin_ppc_stfiw, "viC*d", "")
+TARGET_BUILTIN(__builtin_ppc_addex, "LLiLLiLLiCIi", "", "isa-v30-instructions")
+// select
+BUILTIN(__builtin_ppc_maxfe, "LdLdLdLd.", "t")
+BUILTIN(__builtin_ppc_maxfl, "dddd.", "t")
+BUILTIN(__builtin_ppc_maxfs, "ffff.", "t")
+BUILTIN(__builtin_ppc_minfe, "LdLdLdLd.", "t")
+BUILTIN(__builtin_ppc_minfl, "dddd.", "t")
+BUILTIN(__builtin_ppc_minfs, "ffff.", "t")
+// Floating Negative Absolute Value
+BUILTIN(__builtin_ppc_fnabs, "dd", "")
+BUILTIN(__builtin_ppc_fnabss, "ff", "")
BUILTIN(__builtin_ppc_get_timebase, "ULLi", "n")
// This is just a placeholder, the types and attributes are wrong.
-BUILTIN(__builtin_altivec_vaddcuw, "V4UiV4UiV4Ui", "")
-
-BUILTIN(__builtin_altivec_vaddsbs, "V16ScV16ScV16Sc", "")
-BUILTIN(__builtin_altivec_vaddubs, "V16UcV16UcV16Uc", "")
-BUILTIN(__builtin_altivec_vaddshs, "V8SsV8SsV8Ss", "")
-BUILTIN(__builtin_altivec_vadduhs, "V8UsV8UsV8Us", "")
-BUILTIN(__builtin_altivec_vaddsws, "V4SiV4SiV4Si", "")
-BUILTIN(__builtin_altivec_vadduws, "V4UiV4UiV4Ui", "")
-BUILTIN(__builtin_altivec_vaddeuqm, "V1ULLLiV1ULLLiV1ULLLiV1ULLLi","")
-BUILTIN(__builtin_altivec_vaddcuq, "V1ULLLiV1ULLLiV1ULLLi","")
-BUILTIN(__builtin_altivec_vaddecuq, "V1ULLLiV1ULLLiV1ULLLiV1ULLLi","")
-BUILTIN(__builtin_altivec_vadduqm, "V1ULLLiV16UcV16Uc","")
-
-BUILTIN(__builtin_altivec_vsubsbs, "V16ScV16ScV16Sc", "")
-BUILTIN(__builtin_altivec_vsububs, "V16UcV16UcV16Uc", "")
-BUILTIN(__builtin_altivec_vsubshs, "V8SsV8SsV8Ss", "")
-BUILTIN(__builtin_altivec_vsubuhs, "V8UsV8UsV8Us", "")
-BUILTIN(__builtin_altivec_vsubsws, "V4SiV4SiV4Si", "")
-BUILTIN(__builtin_altivec_vsubuws, "V4UiV4UiV4Ui", "")
-BUILTIN(__builtin_altivec_vsubeuqm, "V1ULLLiV1ULLLiV1ULLLiV1ULLLi","")
-BUILTIN(__builtin_altivec_vsubcuq, "V1ULLLiV1ULLLiV1ULLLi","")
-BUILTIN(__builtin_altivec_vsubecuq, "V1ULLLiV1ULLLiV1ULLLiV1ULLLi","")
-BUILTIN(__builtin_altivec_vsubuqm, "V1ULLLiV16UcV16Uc","")
-
-BUILTIN(__builtin_altivec_vavgsb, "V16ScV16ScV16Sc", "")
-BUILTIN(__builtin_altivec_vavgub, "V16UcV16UcV16Uc", "")
-BUILTIN(__builtin_altivec_vavgsh, "V8SsV8SsV8Ss", "")
-BUILTIN(__builtin_altivec_vavguh, "V8UsV8UsV8Us", "")
-BUILTIN(__builtin_altivec_vavgsw, "V4SiV4SiV4Si", "")
-BUILTIN(__builtin_altivec_vavguw, "V4UiV4UiV4Ui", "")
-
-BUILTIN(__builtin_altivec_vrfip, "V4fV4f", "")
-
-BUILTIN(__builtin_altivec_vcfsx, "V4fV4SiIi", "")
-BUILTIN(__builtin_altivec_vcfux, "V4fV4UiIi", "")
-BUILTIN(__builtin_altivec_vctsxs, "V4SiV4fIi", "")
-BUILTIN(__builtin_altivec_vctuxs, "V4UiV4fIi", "")
-
-BUILTIN(__builtin_altivec_dss, "vUIi", "")
-BUILTIN(__builtin_altivec_dssall, "v", "")
-BUILTIN(__builtin_altivec_dst, "vvC*iUIi", "")
-BUILTIN(__builtin_altivec_dstt, "vvC*iUIi", "")
-BUILTIN(__builtin_altivec_dstst, "vvC*iUIi", "")
-BUILTIN(__builtin_altivec_dststt, "vvC*iUIi", "")
-
-BUILTIN(__builtin_altivec_vexptefp, "V4fV4f", "")
-
-BUILTIN(__builtin_altivec_vrfim, "V4fV4f", "")
-
-BUILTIN(__builtin_altivec_lvx, "V4iLivC*", "")
-BUILTIN(__builtin_altivec_lvxl, "V4iLivC*", "")
-BUILTIN(__builtin_altivec_lvebx, "V16cLivC*", "")
-BUILTIN(__builtin_altivec_lvehx, "V8sLivC*", "")
-BUILTIN(__builtin_altivec_lvewx, "V4iLivC*", "")
-
-BUILTIN(__builtin_altivec_vlogefp, "V4fV4f", "")
-
-BUILTIN(__builtin_altivec_lvsl, "V16cUcvC*", "")
-BUILTIN(__builtin_altivec_lvsr, "V16cUcvC*", "")
-
-BUILTIN(__builtin_altivec_vmaddfp, "V4fV4fV4fV4f", "")
-BUILTIN(__builtin_altivec_vmhaddshs, "V8sV8sV8sV8s", "")
-BUILTIN(__builtin_altivec_vmhraddshs, "V8sV8sV8sV8s", "")
-
-BUILTIN(__builtin_altivec_vmsumubm, "V4UiV16UcV16UcV4Ui", "")
-BUILTIN(__builtin_altivec_vmsummbm, "V4SiV16ScV16UcV4Si", "")
-BUILTIN(__builtin_altivec_vmsumuhm, "V4UiV8UsV8UsV4Ui", "")
-BUILTIN(__builtin_altivec_vmsumshm, "V4SiV8SsV8SsV4Si", "")
-BUILTIN(__builtin_altivec_vmsumuhs, "V4UiV8UsV8UsV4Ui", "")
-BUILTIN(__builtin_altivec_vmsumshs, "V4SiV8SsV8SsV4Si", "")
-
-BUILTIN(__builtin_altivec_vmuleub, "V8UsV16UcV16Uc", "")
-BUILTIN(__builtin_altivec_vmulesb, "V8SsV16ScV16Sc", "")
-BUILTIN(__builtin_altivec_vmuleuh, "V4UiV8UsV8Us", "")
-BUILTIN(__builtin_altivec_vmulesh, "V4SiV8SsV8Ss", "")
-BUILTIN(__builtin_altivec_vmuleuw, "V2ULLiV4UiV4Ui", "")
-BUILTIN(__builtin_altivec_vmulesw, "V2SLLiV4SiV4Si", "")
-BUILTIN(__builtin_altivec_vmuloub, "V8UsV16UcV16Uc", "")
-BUILTIN(__builtin_altivec_vmulosb, "V8SsV16ScV16Sc", "")
-BUILTIN(__builtin_altivec_vmulouh, "V4UiV8UsV8Us", "")
-BUILTIN(__builtin_altivec_vmulosh, "V4SiV8SsV8Ss", "")
-BUILTIN(__builtin_altivec_vmulouw, "V2ULLiV4UiV4Ui", "")
-BUILTIN(__builtin_altivec_vmulosw, "V2SLLiV4SiV4Si", "")
-BUILTIN(__builtin_altivec_vmuleud, "V1ULLLiV2ULLiV2ULLi", "")
-BUILTIN(__builtin_altivec_vmulesd, "V1SLLLiV2SLLiV2SLLi", "")
-BUILTIN(__builtin_altivec_vmuloud, "V1ULLLiV2ULLiV2ULLi", "")
-BUILTIN(__builtin_altivec_vmulosd, "V1SLLLiV2SLLiV2SLLi", "")
-BUILTIN(__builtin_altivec_vmsumcud, "V1ULLLiV2ULLiV2ULLiV1ULLLi", "")
-
-BUILTIN(__builtin_altivec_vnmsubfp, "V4fV4fV4fV4f", "")
-
-BUILTIN(__builtin_altivec_vpkpx, "V8sV4UiV4Ui", "")
-BUILTIN(__builtin_altivec_vpkuhus, "V16UcV8UsV8Us", "")
-BUILTIN(__builtin_altivec_vpkshss, "V16ScV8SsV8Ss", "")
-BUILTIN(__builtin_altivec_vpkuwus, "V8UsV4UiV4Ui", "")
-BUILTIN(__builtin_altivec_vpkswss, "V8SsV4SiV4Si", "")
-BUILTIN(__builtin_altivec_vpkshus, "V16UcV8SsV8Ss", "")
-BUILTIN(__builtin_altivec_vpkswus, "V8UsV4SiV4Si", "")
-BUILTIN(__builtin_altivec_vpksdss, "V4SiV2SLLiV2SLLi", "")
-BUILTIN(__builtin_altivec_vpksdus, "V4UiV2SLLiV2SLLi", "")
-BUILTIN(__builtin_altivec_vpkudus, "V4UiV2ULLiV2ULLi", "")
-BUILTIN(__builtin_altivec_vpkudum, "V4UiV2ULLiV2ULLi", "")
-
-BUILTIN(__builtin_altivec_vperm_4si, "V4iV4iV4iV16Uc", "")
-
-BUILTIN(__builtin_altivec_stvx, "vV4iLiv*", "")
-BUILTIN(__builtin_altivec_stvxl, "vV4iLiv*", "")
-BUILTIN(__builtin_altivec_stvebx, "vV16cLiv*", "")
-BUILTIN(__builtin_altivec_stvehx, "vV8sLiv*", "")
-BUILTIN(__builtin_altivec_stvewx, "vV4iLiv*", "")
-
-BUILTIN(__builtin_altivec_vcmpbfp, "V4iV4fV4f", "")
-
-BUILTIN(__builtin_altivec_vcmpgefp, "V4iV4fV4f", "")
-
-BUILTIN(__builtin_altivec_vcmpequb, "V16cV16cV16c", "")
-BUILTIN(__builtin_altivec_vcmpequh, "V8sV8sV8s", "")
-BUILTIN(__builtin_altivec_vcmpequw, "V4iV4iV4i", "")
-BUILTIN(__builtin_altivec_vcmpequd, "V2LLiV2LLiV2LLi", "")
-BUILTIN(__builtin_altivec_vcmpeqfp, "V4iV4fV4f", "")
-
-BUILTIN(__builtin_altivec_vcmpneb, "V16cV16cV16c", "")
-BUILTIN(__builtin_altivec_vcmpneh, "V8sV8sV8s", "")
-BUILTIN(__builtin_altivec_vcmpnew, "V4iV4iV4i", "")
-
-BUILTIN(__builtin_altivec_vcmpnezb, "V16cV16cV16c", "")
-BUILTIN(__builtin_altivec_vcmpnezh, "V8sV8sV8s", "")
-BUILTIN(__builtin_altivec_vcmpnezw, "V4iV4iV4i", "")
-
-BUILTIN(__builtin_altivec_vcmpgtsb, "V16cV16ScV16Sc", "")
-BUILTIN(__builtin_altivec_vcmpgtub, "V16cV16UcV16Uc", "")
-BUILTIN(__builtin_altivec_vcmpgtsh, "V8sV8SsV8Ss", "")
-BUILTIN(__builtin_altivec_vcmpgtuh, "V8sV8UsV8Us", "")
-BUILTIN(__builtin_altivec_vcmpgtsw, "V4iV4SiV4Si", "")
-BUILTIN(__builtin_altivec_vcmpgtuw, "V4iV4UiV4Ui", "")
-BUILTIN(__builtin_altivec_vcmpgtsd, "V2LLiV2LLiV2LLi", "")
-BUILTIN(__builtin_altivec_vcmpgtud, "V2LLiV2ULLiV2ULLi", "")
-BUILTIN(__builtin_altivec_vcmpgtfp, "V4iV4fV4f", "")
+TARGET_BUILTIN(__builtin_altivec_vaddcuw, "V4UiV4UiV4Ui", "", "altivec")
+
+TARGET_BUILTIN(__builtin_altivec_vaddsbs, "V16ScV16ScV16Sc", "", "altivec")
+TARGET_BUILTIN(__builtin_altivec_vaddubs, "V16UcV16UcV16Uc", "", "altivec")
+TARGET_BUILTIN(__builtin_altivec_vaddshs, "V8SsV8SsV8Ss", "", "altivec")
+TARGET_BUILTIN(__builtin_altivec_vadduhs, "V8UsV8UsV8Us", "", "altivec")
+TARGET_BUILTIN(__builtin_altivec_vaddsws, "V4SiV4SiV4Si", "", "altivec")
+TARGET_BUILTIN(__builtin_altivec_vadduws, "V4UiV4UiV4Ui", "", "altivec")
+TARGET_BUILTIN(__builtin_altivec_vaddeuqm, "V1ULLLiV1ULLLiV1ULLLiV1ULLLi", "",
+ "power8-vector")
+TARGET_BUILTIN(__builtin_altivec_vaddcuq, "V1ULLLiV1ULLLiV1ULLLi", "",
+ "power8-vector")
+TARGET_BUILTIN(__builtin_altivec_vaddecuq, "V1ULLLiV1ULLLiV1ULLLiV1ULLLi", "",
+ "power8-vector")
+TARGET_BUILTIN(__builtin_altivec_vadduqm, "V1ULLLiV16UcV16Uc", "",
+ "power8-vector")
+TARGET_BUILTIN(__builtin_altivec_vaddeuqm_c, "V16UcV16UcV16UcV16Uc", "",
+ "power8-vector")
+TARGET_BUILTIN(__builtin_altivec_vaddcuq_c, "V16UcV16UcV16Uc", "",
+ "power8-vector")
+TARGET_BUILTIN(__builtin_altivec_vaddecuq_c, "V16UcV16UcV16UcV16Uc", "",
+ "power8-vector")
+
+TARGET_BUILTIN(__builtin_altivec_vsubsbs, "V16ScV16ScV16Sc", "", "altivec")
+TARGET_BUILTIN(__builtin_altivec_vsububs, "V16UcV16UcV16Uc", "", "altivec")
+TARGET_BUILTIN(__builtin_altivec_vsubshs, "V8SsV8SsV8Ss", "", "altivec")
+TARGET_BUILTIN(__builtin_altivec_vsubuhs, "V8UsV8UsV8Us", "", "altivec")
+TARGET_BUILTIN(__builtin_altivec_vsubsws, "V4SiV4SiV4Si", "", "altivec")
+TARGET_BUILTIN(__builtin_altivec_vsubuws, "V4UiV4UiV4Ui", "", "altivec")
+TARGET_BUILTIN(__builtin_altivec_vsubeuqm, "V1ULLLiV1ULLLiV1ULLLiV1ULLLi", "",
+ "power8-vector")
+TARGET_BUILTIN(__builtin_altivec_vsubcuq, "V1ULLLiV1ULLLiV1ULLLi", "",
+ "power8-vector")
+TARGET_BUILTIN(__builtin_altivec_vsubecuq, "V1ULLLiV1ULLLiV1ULLLiV1ULLLi", "",
+ "power8-vector")
+TARGET_BUILTIN(__builtin_altivec_vsubuqm, "V1ULLLiV16UcV16Uc", "",
+ "power8-vector")
+TARGET_BUILTIN(__builtin_altivec_vsubeuqm_c, "V16UcV16UcV16UcV16Uc", "",
+ "power8-vector")
+TARGET_BUILTIN(__builtin_altivec_vsubcuq_c, "V16UcV16UcV16Uc", "",
+ "power8-vector")
+TARGET_BUILTIN(__builtin_altivec_vsubecuq_c, "V16UcV16UcV16UcV16Uc", "",
+ "power8-vector")
+
+TARGET_BUILTIN(__builtin_altivec_vavgsb, "V16ScV16ScV16Sc", "", "altivec")
+TARGET_BUILTIN(__builtin_altivec_vavgub, "V16UcV16UcV16Uc", "", "altivec")
+TARGET_BUILTIN(__builtin_altivec_vavgsh, "V8SsV8SsV8Ss", "", "altivec")
+TARGET_BUILTIN(__builtin_altivec_vavguh, "V8UsV8UsV8Us", "", "altivec")
+TARGET_BUILTIN(__builtin_altivec_vavgsw, "V4SiV4SiV4Si", "", "altivec")
+TARGET_BUILTIN(__builtin_altivec_vavguw, "V4UiV4UiV4Ui", "", "altivec")
+
+TARGET_BUILTIN(__builtin_altivec_vrfip, "V4fV4f", "", "altivec")
+
+TARGET_BUILTIN(__builtin_altivec_vcfsx, "V4fV4SiIi", "", "altivec")
+TARGET_BUILTIN(__builtin_altivec_vcfux, "V4fV4UiIi", "", "altivec")
+TARGET_BUILTIN(__builtin_altivec_vctsxs, "V4SiV4fIi", "", "altivec")
+TARGET_BUILTIN(__builtin_altivec_vctuxs, "V4UiV4fIi", "", "altivec")
+
+TARGET_BUILTIN(__builtin_altivec_dss, "vUIi", "", "altivec")
+TARGET_BUILTIN(__builtin_altivec_dssall, "v", "", "altivec")
+TARGET_BUILTIN(__builtin_altivec_dst, "vvC*iUIi", "", "altivec")
+TARGET_BUILTIN(__builtin_altivec_dstt, "vvC*iUIi", "", "altivec")
+TARGET_BUILTIN(__builtin_altivec_dstst, "vvC*iUIi", "", "altivec")
+TARGET_BUILTIN(__builtin_altivec_dststt, "vvC*iUIi", "", "altivec")
+
+TARGET_BUILTIN(__builtin_altivec_vexptefp, "V4fV4f", "", "altivec")
+
+TARGET_BUILTIN(__builtin_altivec_vrfim, "V4fV4f", "", "altivec")
+
+TARGET_BUILTIN(__builtin_altivec_lvx, "V4iLivC*", "", "altivec")
+TARGET_BUILTIN(__builtin_altivec_lvxl, "V4iLivC*", "", "altivec")
+TARGET_BUILTIN(__builtin_altivec_lvebx, "V16cLivC*", "", "altivec")
+TARGET_BUILTIN(__builtin_altivec_lvehx, "V8sLivC*", "", "altivec")
+TARGET_BUILTIN(__builtin_altivec_lvewx, "V4iLivC*", "", "altivec")
+
+TARGET_BUILTIN(__builtin_altivec_vlogefp, "V4fV4f", "", "altivec")
+
+TARGET_BUILTIN(__builtin_altivec_lvsl, "V16cUcvC*", "", "altivec")
+TARGET_BUILTIN(__builtin_altivec_lvsr, "V16cUcvC*", "", "altivec")
+
+TARGET_BUILTIN(__builtin_altivec_vmaddfp, "V4fV4fV4fV4f", "", "altivec")
+TARGET_BUILTIN(__builtin_altivec_vmhaddshs, "V8sV8sV8sV8s", "", "altivec")
+TARGET_BUILTIN(__builtin_altivec_vmhraddshs, "V8sV8sV8sV8s", "", "altivec")
+
+TARGET_BUILTIN(__builtin_altivec_vmsumubm, "V4UiV16UcV16UcV4Ui", "", "altivec")
+TARGET_BUILTIN(__builtin_altivec_vmsummbm, "V4SiV16ScV16UcV4Si", "", "altivec")
+TARGET_BUILTIN(__builtin_altivec_vmsumuhm, "V4UiV8UsV8UsV4Ui", "", "altivec")
+TARGET_BUILTIN(__builtin_altivec_vmsumshm, "V4SiV8SsV8SsV4Si", "", "altivec")
+TARGET_BUILTIN(__builtin_altivec_vmsumuhs, "V4UiV8UsV8UsV4Ui", "", "altivec")
+TARGET_BUILTIN(__builtin_altivec_vmsumshs, "V4SiV8SsV8SsV4Si", "", "altivec")
+
+TARGET_BUILTIN(__builtin_altivec_vmuleub, "V8UsV16UcV16Uc", "", "altivec")
+TARGET_BUILTIN(__builtin_altivec_vmulesb, "V8SsV16ScV16Sc", "", "altivec")
+TARGET_BUILTIN(__builtin_altivec_vmuleuh, "V4UiV8UsV8Us", "", "altivec")
+TARGET_BUILTIN(__builtin_altivec_vmulesh, "V4SiV8SsV8Ss", "", "altivec")
+TARGET_BUILTIN(__builtin_altivec_vmuleuw, "V2ULLiV4UiV4Ui", "", "power8-vector")
+TARGET_BUILTIN(__builtin_altivec_vmulesw, "V2SLLiV4SiV4Si", "", "power8-vector")
+TARGET_BUILTIN(__builtin_altivec_vmuloub, "V8UsV16UcV16Uc", "", "altivec")
+TARGET_BUILTIN(__builtin_altivec_vmulosb, "V8SsV16ScV16Sc", "", "altivec")
+TARGET_BUILTIN(__builtin_altivec_vmulouh, "V4UiV8UsV8Us", "", "altivec")
+TARGET_BUILTIN(__builtin_altivec_vmulosh, "V4SiV8SsV8Ss", "", "altivec")
+TARGET_BUILTIN(__builtin_altivec_vmulouw, "V2ULLiV4UiV4Ui", "", "power8-vector")
+TARGET_BUILTIN(__builtin_altivec_vmulosw, "V2SLLiV4SiV4Si", "", "power8-vector")
+TARGET_BUILTIN(__builtin_altivec_vmuleud, "V1ULLLiV2ULLiV2ULLi", "",
+ "power10-vector")
+TARGET_BUILTIN(__builtin_altivec_vmulesd, "V1SLLLiV2SLLiV2SLLi", "",
+ "power10-vector")
+TARGET_BUILTIN(__builtin_altivec_vmuloud, "V1ULLLiV2ULLiV2ULLi", "",
+ "power10-vector")
+TARGET_BUILTIN(__builtin_altivec_vmulosd, "V1SLLLiV2SLLiV2SLLi", "",
+ "power10-vector")
+TARGET_BUILTIN(__builtin_altivec_vmsumcud, "V1ULLLiV2ULLiV2ULLiV1ULLLi", "",
+ "power10-vector")
+
+TARGET_BUILTIN(__builtin_altivec_vnmsubfp, "V4fV4fV4fV4f", "", "altivec")
+
+TARGET_BUILTIN(__builtin_altivec_vpkpx, "V8sV4UiV4Ui", "", "altivec")
+TARGET_BUILTIN(__builtin_altivec_vpkuhus, "V16UcV8UsV8Us", "", "altivec")
+TARGET_BUILTIN(__builtin_altivec_vpkshss, "V16ScV8SsV8Ss", "", "altivec")
+TARGET_BUILTIN(__builtin_altivec_vpkuwus, "V8UsV4UiV4Ui", "", "altivec")
+TARGET_BUILTIN(__builtin_altivec_vpkswss, "V8SsV4SiV4Si", "", "altivec")
+TARGET_BUILTIN(__builtin_altivec_vpkshus, "V16UcV8SsV8Ss", "", "altivec")
+TARGET_BUILTIN(__builtin_altivec_vpkswus, "V8UsV4SiV4Si", "", "altivec")
+TARGET_BUILTIN(__builtin_altivec_vpksdss, "V4SiV2SLLiV2SLLi", "",
+ "power8-vector")
+TARGET_BUILTIN(__builtin_altivec_vpksdus, "V4UiV2SLLiV2SLLi", "",
+ "power8-vector")
+TARGET_BUILTIN(__builtin_altivec_vpkudus, "V4UiV2ULLiV2ULLi", "",
+ "power8-vector")
+TARGET_BUILTIN(__builtin_altivec_vpkudum, "V4UiV2ULLiV2ULLi", "",
+ "power8-vector")
+
+TARGET_BUILTIN(__builtin_altivec_vperm_4si, "V4iV4iV4iV16Uc", "", "altivec")
+
+TARGET_BUILTIN(__builtin_altivec_stvx, "vV4iLiv*", "", "altivec")
+TARGET_BUILTIN(__builtin_altivec_stvxl, "vV4iLiv*", "", "altivec")
+TARGET_BUILTIN(__builtin_altivec_stvebx, "vV16cLiv*", "", "altivec")
+TARGET_BUILTIN(__builtin_altivec_stvehx, "vV8sLiv*", "", "altivec")
+TARGET_BUILTIN(__builtin_altivec_stvewx, "vV4iLiv*", "", "altivec")
+
+TARGET_BUILTIN(__builtin_altivec_vcmpbfp, "V4iV4fV4f", "", "altivec")
+
+TARGET_BUILTIN(__builtin_altivec_vcmpgefp, "V4iV4fV4f", "", "altivec")
+
+TARGET_BUILTIN(__builtin_altivec_vcmpequb, "V16cV16cV16c", "", "altivec")
+TARGET_BUILTIN(__builtin_altivec_vcmpequh, "V8sV8sV8s", "", "altivec")
+TARGET_BUILTIN(__builtin_altivec_vcmpequw, "V4iV4iV4i", "", "altivec")
+TARGET_BUILTIN(__builtin_altivec_vcmpequd, "V2LLiV2LLiV2LLi", "",
+ "power8-vector")
+TARGET_BUILTIN(__builtin_altivec_vcmpeqfp, "V4iV4fV4f", "", "altivec")
+
+TARGET_BUILTIN(__builtin_altivec_vcmpneb, "V16cV16cV16c", "", "power9-vector")
+TARGET_BUILTIN(__builtin_altivec_vcmpneh, "V8sV8sV8s", "", "power9-vector")
+TARGET_BUILTIN(__builtin_altivec_vcmpnew, "V4iV4iV4i", "", "power9-vector")
+
+TARGET_BUILTIN(__builtin_altivec_vcmpnezb, "V16cV16cV16c", "", "power9-vector")
+TARGET_BUILTIN(__builtin_altivec_vcmpnezh, "V8sV8sV8s", "", "power9-vector")
+TARGET_BUILTIN(__builtin_altivec_vcmpnezw, "V4iV4iV4i", "", "power9-vector")
+
+TARGET_BUILTIN(__builtin_altivec_vcmpgtsb, "V16cV16ScV16Sc", "", "altivec")
+TARGET_BUILTIN(__builtin_altivec_vcmpgtub, "V16cV16UcV16Uc", "", "altivec")
+TARGET_BUILTIN(__builtin_altivec_vcmpgtsh, "V8sV8SsV8Ss", "", "altivec")
+TARGET_BUILTIN(__builtin_altivec_vcmpgtuh, "V8sV8UsV8Us", "", "altivec")
+TARGET_BUILTIN(__builtin_altivec_vcmpgtsw, "V4iV4SiV4Si", "", "altivec")
+TARGET_BUILTIN(__builtin_altivec_vcmpgtuw, "V4iV4UiV4Ui", "", "altivec")
+TARGET_BUILTIN(__builtin_altivec_vcmpgtsd, "V2LLiV2LLiV2LLi", "",
+ "power8-vector")
+TARGET_BUILTIN(__builtin_altivec_vcmpgtud, "V2LLiV2ULLiV2ULLi", "",
+ "power8-vector")
+TARGET_BUILTIN(__builtin_altivec_vcmpgtfp, "V4iV4fV4f", "", "altivec")
// P10 Vector compare builtins.
-BUILTIN(__builtin_altivec_vcmpequq, "V1LLLiV1ULLLiV1ULLLi", "")
-BUILTIN(__builtin_altivec_vcmpgtsq, "V1LLLiV1SLLLiV1SLLLi", "")
-BUILTIN(__builtin_altivec_vcmpgtuq, "V1LLLiV1ULLLiV1ULLLi", "")
-BUILTIN(__builtin_altivec_vcmpequq_p, "iiV1ULLLiV1LLLi", "")
-BUILTIN(__builtin_altivec_vcmpgtsq_p, "iiV1SLLLiV1SLLLi", "")
-BUILTIN(__builtin_altivec_vcmpgtuq_p, "iiV1ULLLiV1ULLLi", "")
-
-BUILTIN(__builtin_altivec_vmaxsb, "V16ScV16ScV16Sc", "")
-BUILTIN(__builtin_altivec_vmaxub, "V16UcV16UcV16Uc", "")
-BUILTIN(__builtin_altivec_vmaxsh, "V8SsV8SsV8Ss", "")
-BUILTIN(__builtin_altivec_vmaxuh, "V8UsV8UsV8Us", "")
-BUILTIN(__builtin_altivec_vmaxsw, "V4SiV4SiV4Si", "")
-BUILTIN(__builtin_altivec_vmaxuw, "V4UiV4UiV4Ui", "")
-BUILTIN(__builtin_altivec_vmaxsd, "V2LLiV2LLiV2LLi", "")
-BUILTIN(__builtin_altivec_vmaxud, "V2ULLiV2ULLiV2ULLi", "")
-BUILTIN(__builtin_altivec_vmaxfp, "V4fV4fV4f", "")
-
-BUILTIN(__builtin_altivec_mfvscr, "V8Us", "")
-
-BUILTIN(__builtin_altivec_vminsb, "V16ScV16ScV16Sc", "")
-BUILTIN(__builtin_altivec_vminub, "V16UcV16UcV16Uc", "")
-BUILTIN(__builtin_altivec_vminsh, "V8SsV8SsV8Ss", "")
-BUILTIN(__builtin_altivec_vminuh, "V8UsV8UsV8Us", "")
-BUILTIN(__builtin_altivec_vminsw, "V4SiV4SiV4Si", "")
-BUILTIN(__builtin_altivec_vminuw, "V4UiV4UiV4Ui", "")
-BUILTIN(__builtin_altivec_vminsd, "V2LLiV2LLiV2LLi", "")
-BUILTIN(__builtin_altivec_vminud, "V2ULLiV2ULLiV2ULLi", "")
-BUILTIN(__builtin_altivec_vminfp, "V4fV4fV4f", "")
-
-BUILTIN(__builtin_altivec_mtvscr, "vV4i", "")
-
-BUILTIN(__builtin_altivec_vrefp, "V4fV4f", "")
-
-BUILTIN(__builtin_altivec_vrlb, "V16cV16cV16Uc", "")
-BUILTIN(__builtin_altivec_vrlh, "V8sV8sV8Us", "")
-BUILTIN(__builtin_altivec_vrlw, "V4iV4iV4Ui", "")
-BUILTIN(__builtin_altivec_vrld, "V2LLiV2LLiV2ULLi", "")
-
-BUILTIN(__builtin_altivec_vsel_4si, "V4iV4iV4iV4Ui", "")
-
-BUILTIN(__builtin_altivec_vsl, "V4iV4iV4i", "")
-BUILTIN(__builtin_altivec_vslo, "V4iV4iV4i", "")
-
-BUILTIN(__builtin_altivec_vsrab, "V16cV16cV16Uc", "")
-BUILTIN(__builtin_altivec_vsrah, "V8sV8sV8Us", "")
-BUILTIN(__builtin_altivec_vsraw, "V4iV4iV4Ui", "")
-
-BUILTIN(__builtin_altivec_vsr, "V4iV4iV4i", "")
-BUILTIN(__builtin_altivec_vsro, "V4iV4iV4i", "")
-
-BUILTIN(__builtin_altivec_vrfin, "V4fV4f", "")
-
-BUILTIN(__builtin_altivec_vrsqrtefp, "V4fV4f", "")
-
-BUILTIN(__builtin_altivec_vsubcuw, "V4UiV4UiV4Ui", "")
-
-BUILTIN(__builtin_altivec_vsum4sbs, "V4SiV16ScV4Si", "")
-BUILTIN(__builtin_altivec_vsum4ubs, "V4UiV16UcV4Ui", "")
-BUILTIN(__builtin_altivec_vsum4shs, "V4SiV8SsV4Si", "")
-
-BUILTIN(__builtin_altivec_vsum2sws, "V4SiV4SiV4Si", "")
-
-BUILTIN(__builtin_altivec_vsumsws, "V4SiV4SiV4Si", "")
-
-BUILTIN(__builtin_altivec_vrfiz, "V4fV4f", "")
-
-BUILTIN(__builtin_altivec_vupkhsb, "V8sV16c", "")
-BUILTIN(__builtin_altivec_vupkhpx, "V4UiV8s", "")
-BUILTIN(__builtin_altivec_vupkhsh, "V4iV8s", "")
-BUILTIN(__builtin_altivec_vupkhsw, "V2LLiV4i", "")
-
-BUILTIN(__builtin_altivec_vupklsb, "V8sV16c", "")
-BUILTIN(__builtin_altivec_vupklpx, "V4UiV8s", "")
-BUILTIN(__builtin_altivec_vupklsh, "V4iV8s", "")
-BUILTIN(__builtin_altivec_vupklsw, "V2LLiV4i", "")
-
-BUILTIN(__builtin_altivec_vcmpbfp_p, "iiV4fV4f", "")
-
-BUILTIN(__builtin_altivec_vcmpgefp_p, "iiV4fV4f", "")
-
-BUILTIN(__builtin_altivec_vcmpequb_p, "iiV16cV16c", "")
-BUILTIN(__builtin_altivec_vcmpequh_p, "iiV8sV8s", "")
-BUILTIN(__builtin_altivec_vcmpequw_p, "iiV4iV4i", "")
-BUILTIN(__builtin_altivec_vcmpequd_p, "iiV2LLiV2LLi", "")
-BUILTIN(__builtin_altivec_vcmpeqfp_p, "iiV4fV4f", "")
-
-BUILTIN(__builtin_altivec_vcmpneb_p, "iiV16cV16c", "")
-BUILTIN(__builtin_altivec_vcmpneh_p, "iiV8sV8s", "")
-BUILTIN(__builtin_altivec_vcmpnew_p, "iiV4iV4i", "")
-BUILTIN(__builtin_altivec_vcmpned_p, "iiV2LLiV2LLi", "")
-
-BUILTIN(__builtin_altivec_vcmpgtsb_p, "iiV16ScV16Sc", "")
-BUILTIN(__builtin_altivec_vcmpgtub_p, "iiV16UcV16Uc", "")
-BUILTIN(__builtin_altivec_vcmpgtsh_p, "iiV8SsV8Ss", "")
-BUILTIN(__builtin_altivec_vcmpgtuh_p, "iiV8UsV8Us", "")
-BUILTIN(__builtin_altivec_vcmpgtsw_p, "iiV4SiV4Si", "")
-BUILTIN(__builtin_altivec_vcmpgtuw_p, "iiV4UiV4Ui", "")
-BUILTIN(__builtin_altivec_vcmpgtsd_p, "iiV2LLiV2LLi", "")
-BUILTIN(__builtin_altivec_vcmpgtud_p, "iiV2ULLiV2ULLi", "")
-BUILTIN(__builtin_altivec_vcmpgtfp_p, "iiV4fV4f", "")
+TARGET_BUILTIN(__builtin_altivec_vcmpequq, "V1LLLiV1ULLLiV1ULLLi", "",
+ "power10-vector")
+TARGET_BUILTIN(__builtin_altivec_vcmpgtsq, "V1LLLiV1SLLLiV1SLLLi", "",
+ "power10-vector")
+TARGET_BUILTIN(__builtin_altivec_vcmpgtuq, "V1LLLiV1ULLLiV1ULLLi", "",
+ "power10-vector")
+TARGET_BUILTIN(__builtin_altivec_vcmpequq_p, "iiV1ULLLiV1LLLi", "", "altivec")
+TARGET_BUILTIN(__builtin_altivec_vcmpgtsq_p, "iiV1SLLLiV1SLLLi", "",
+ "power10-vector")
+TARGET_BUILTIN(__builtin_altivec_vcmpgtuq_p, "iiV1ULLLiV1ULLLi", "",
+ "power10-vector")
+
+TARGET_BUILTIN(__builtin_altivec_vmaxsb, "V16ScV16ScV16Sc", "", "altivec")
+TARGET_BUILTIN(__builtin_altivec_vmaxub, "V16UcV16UcV16Uc", "", "altivec")
+TARGET_BUILTIN(__builtin_altivec_vmaxsh, "V8SsV8SsV8Ss", "", "altivec")
+TARGET_BUILTIN(__builtin_altivec_vmaxuh, "V8UsV8UsV8Us", "", "altivec")
+TARGET_BUILTIN(__builtin_altivec_vmaxsw, "V4SiV4SiV4Si", "", "altivec")
+TARGET_BUILTIN(__builtin_altivec_vmaxuw, "V4UiV4UiV4Ui", "", "altivec")
+TARGET_BUILTIN(__builtin_altivec_vmaxsd, "V2LLiV2LLiV2LLi", "", "power8-vector")
+TARGET_BUILTIN(__builtin_altivec_vmaxud, "V2ULLiV2ULLiV2ULLi", "",
+ "power8-vector")
+TARGET_BUILTIN(__builtin_altivec_vmaxfp, "V4fV4fV4f", "", "altivec")
+
+TARGET_BUILTIN(__builtin_altivec_mfvscr, "V8Us", "", "altivec")
+
+TARGET_BUILTIN(__builtin_altivec_vminsb, "V16ScV16ScV16Sc", "", "altivec")
+TARGET_BUILTIN(__builtin_altivec_vminub, "V16UcV16UcV16Uc", "", "altivec")
+TARGET_BUILTIN(__builtin_altivec_vminsh, "V8SsV8SsV8Ss", "", "altivec")
+TARGET_BUILTIN(__builtin_altivec_vminuh, "V8UsV8UsV8Us", "", "altivec")
+TARGET_BUILTIN(__builtin_altivec_vminsw, "V4SiV4SiV4Si", "", "altivec")
+TARGET_BUILTIN(__builtin_altivec_vminuw, "V4UiV4UiV4Ui", "", "altivec")
+TARGET_BUILTIN(__builtin_altivec_vminsd, "V2LLiV2LLiV2LLi", "", "power8-vector")
+TARGET_BUILTIN(__builtin_altivec_vminud, "V2ULLiV2ULLiV2ULLi", "",
+ "power8-vector")
+TARGET_BUILTIN(__builtin_altivec_vminfp, "V4fV4fV4f", "", "altivec")
+
+TARGET_BUILTIN(__builtin_altivec_mtvscr, "vV4i", "", "altivec")
+
+TARGET_BUILTIN(__builtin_altivec_vrefp, "V4fV4f", "", "altivec")
+
+TARGET_BUILTIN(__builtin_altivec_vrlb, "V16cV16cV16Uc", "", "altivec")
+TARGET_BUILTIN(__builtin_altivec_vrlh, "V8sV8sV8Us", "", "altivec")
+TARGET_BUILTIN(__builtin_altivec_vrlw, "V4iV4iV4Ui", "", "altivec")
+TARGET_BUILTIN(__builtin_altivec_vrld, "V2LLiV2LLiV2ULLi", "", "power8-vector")
+
+TARGET_BUILTIN(__builtin_altivec_vsel_4si, "V4iV4iV4iV4Ui", "", "altivec")
+
+TARGET_BUILTIN(__builtin_altivec_vsl, "V4iV4iV4i", "", "altivec")
+TARGET_BUILTIN(__builtin_altivec_vslo, "V4iV4iV4i", "", "altivec")
+
+TARGET_BUILTIN(__builtin_altivec_vsrab, "V16cV16cV16Uc", "", "altivec")
+TARGET_BUILTIN(__builtin_altivec_vsrah, "V8sV8sV8Us", "", "altivec")
+TARGET_BUILTIN(__builtin_altivec_vsraw, "V4iV4iV4Ui", "", "altivec")
+
+TARGET_BUILTIN(__builtin_altivec_vsr, "V4iV4iV4i", "", "altivec")
+TARGET_BUILTIN(__builtin_altivec_vsro, "V4iV4iV4i", "", "altivec")
+
+TARGET_BUILTIN(__builtin_altivec_vrfin, "V4fV4f", "", "altivec")
+
+TARGET_BUILTIN(__builtin_altivec_vrsqrtefp, "V4fV4f", "", "altivec")
+
+TARGET_BUILTIN(__builtin_altivec_vsubcuw, "V4UiV4UiV4Ui", "", "altivec")
+
+TARGET_BUILTIN(__builtin_altivec_vsum4sbs, "V4SiV16ScV4Si", "", "altivec")
+TARGET_BUILTIN(__builtin_altivec_vsum4ubs, "V4UiV16UcV4Ui", "", "altivec")
+TARGET_BUILTIN(__builtin_altivec_vsum4shs, "V4SiV8SsV4Si", "", "altivec")
+
+TARGET_BUILTIN(__builtin_altivec_vsum2sws, "V4SiV4SiV4Si", "", "altivec")
+
+TARGET_BUILTIN(__builtin_altivec_vsumsws, "V4SiV4SiV4Si", "", "altivec")
+
+TARGET_BUILTIN(__builtin_altivec_vrfiz, "V4fV4f", "", "altivec")
+
+TARGET_BUILTIN(__builtin_altivec_vupkhsb, "V8sV16c", "", "altivec")
+TARGET_BUILTIN(__builtin_altivec_vupkhpx, "V4UiV8s", "", "altivec")
+TARGET_BUILTIN(__builtin_altivec_vupkhsh, "V4iV8s", "", "altivec")
+TARGET_BUILTIN(__builtin_altivec_vupkhsw, "V2LLiV4i", "", "power8-vector")
+
+TARGET_BUILTIN(__builtin_altivec_vupklsb, "V8sV16c", "", "altivec")
+TARGET_BUILTIN(__builtin_altivec_vupklpx, "V4UiV8s", "", "altivec")
+TARGET_BUILTIN(__builtin_altivec_vupklsh, "V4iV8s", "", "altivec")
+TARGET_BUILTIN(__builtin_altivec_vupklsw, "V2LLiV4i", "", "power8-vector")
+
+TARGET_BUILTIN(__builtin_altivec_vcmpbfp_p, "iiV4fV4f", "", "altivec")
+
+TARGET_BUILTIN(__builtin_altivec_vcmpgefp_p, "iiV4fV4f", "", "altivec")
+
+TARGET_BUILTIN(__builtin_altivec_vcmpequb_p, "iiV16cV16c", "", "altivec")
+TARGET_BUILTIN(__builtin_altivec_vcmpequh_p, "iiV8sV8s", "", "altivec")
+TARGET_BUILTIN(__builtin_altivec_vcmpequw_p, "iiV4iV4i", "", "altivec")
+TARGET_BUILTIN(__builtin_altivec_vcmpequd_p, "iiV2LLiV2LLi", "", "vsx")
+TARGET_BUILTIN(__builtin_altivec_vcmpeqfp_p, "iiV4fV4f", "", "altivec")
+
+TARGET_BUILTIN(__builtin_altivec_vcmpneb_p, "iiV16cV16c", "", "power9-vector")
+TARGET_BUILTIN(__builtin_altivec_vcmpneh_p, "iiV8sV8s", "", "power9-vector")
+TARGET_BUILTIN(__builtin_altivec_vcmpnew_p, "iiV4iV4i", "", "power9-vector")
+TARGET_BUILTIN(__builtin_altivec_vcmpned_p, "iiV2LLiV2LLi", "", "vsx")
+
+TARGET_BUILTIN(__builtin_altivec_vcmpgtsb_p, "iiV16ScV16Sc", "", "altivec")
+TARGET_BUILTIN(__builtin_altivec_vcmpgtub_p, "iiV16UcV16Uc", "", "altivec")
+TARGET_BUILTIN(__builtin_altivec_vcmpgtsh_p, "iiV8SsV8Ss", "", "altivec")
+TARGET_BUILTIN(__builtin_altivec_vcmpgtuh_p, "iiV8UsV8Us", "", "altivec")
+TARGET_BUILTIN(__builtin_altivec_vcmpgtsw_p, "iiV4SiV4Si", "", "altivec")
+TARGET_BUILTIN(__builtin_altivec_vcmpgtuw_p, "iiV4UiV4Ui", "", "altivec")
+TARGET_BUILTIN(__builtin_altivec_vcmpgtsd_p, "iiV2LLiV2LLi", "", "vsx")
+TARGET_BUILTIN(__builtin_altivec_vcmpgtud_p, "iiV2ULLiV2ULLi", "", "vsx")
+TARGET_BUILTIN(__builtin_altivec_vcmpgtfp_p, "iiV4fV4f", "", "altivec")
-BUILTIN(__builtin_altivec_vgbbd, "V16UcV16Uc", "")
-BUILTIN(__builtin_altivec_vbpermq, "V2ULLiV16UcV16Uc", "")
+TARGET_BUILTIN(__builtin_altivec_vgbbd, "V16UcV16Uc", "", "power8-vector")
+TARGET_BUILTIN(__builtin_altivec_vbpermq, "V2ULLiV16UcV16Uc", "",
+ "power8-vector")
+TARGET_BUILTIN(__builtin_altivec_vbpermd, "V2ULLiV2ULLiV16Uc", "",
+ "power9-vector")
// P8 Crypto built-ins.
-BUILTIN(__builtin_altivec_crypto_vsbox, "V2ULLiV2ULLi", "")
-BUILTIN(__builtin_altivec_crypto_vpermxor, "V16UcV16UcV16UcV16Uc", "")
-BUILTIN(__builtin_altivec_crypto_vshasigmaw, "V4UiV4UiIiIi", "")
-BUILTIN(__builtin_altivec_crypto_vshasigmad, "V2ULLiV2ULLiIiIi", "")
-BUILTIN(__builtin_altivec_crypto_vcipher, "V2ULLiV2ULLiV2ULLi", "")
-BUILTIN(__builtin_altivec_crypto_vcipherlast, "V2ULLiV2ULLiV2ULLi", "")
-BUILTIN(__builtin_altivec_crypto_vncipher, "V2ULLiV2ULLiV2ULLi", "")
-BUILTIN(__builtin_altivec_crypto_vncipherlast, "V2ULLiV2ULLiV2ULLi", "")
-BUILTIN(__builtin_altivec_crypto_vpmsumb, "V16UcV16UcV16Uc", "")
-BUILTIN(__builtin_altivec_crypto_vpmsumh, "V8UsV8UsV8Us", "")
-BUILTIN(__builtin_altivec_crypto_vpmsumw, "V4UiV4UiV4Ui", "")
-BUILTIN(__builtin_altivec_crypto_vpmsumd, "V2ULLiV2ULLiV2ULLi", "")
-
-BUILTIN(__builtin_altivec_vclzb, "V16UcV16Uc", "")
-BUILTIN(__builtin_altivec_vclzh, "V8UsV8Us", "")
-BUILTIN(__builtin_altivec_vclzw, "V4UiV4Ui", "")
-BUILTIN(__builtin_altivec_vclzd, "V2ULLiV2ULLi", "")
-BUILTIN(__builtin_altivec_vctzb, "V16UcV16Uc", "")
-BUILTIN(__builtin_altivec_vctzh, "V8UsV8Us", "")
-BUILTIN(__builtin_altivec_vctzw, "V4UiV4Ui", "")
-BUILTIN(__builtin_altivec_vctzd, "V2ULLiV2ULLi", "")
-
-BUILTIN(__builtin_altivec_vclzlsbb, "SiV16Uc", "")
-BUILTIN(__builtin_altivec_vctzlsbb, "SiV16Uc", "")
-BUILTIN(__builtin_altivec_vprtybw, "V4UiV4Ui", "")
-BUILTIN(__builtin_altivec_vprtybd, "V2ULLiV2ULLi", "")
-BUILTIN(__builtin_altivec_vprtybq, "V1ULLLiV1ULLLi", "")
+TARGET_BUILTIN(__builtin_altivec_crypto_vsbox, "V16UcV16Uc", "",
+ "power8-vector")
+TARGET_BUILTIN(__builtin_altivec_crypto_vpermxor, "V16UcV16UcV16UcV16Uc", "",
+ "power8-vector")
+TARGET_BUILTIN(__builtin_altivec_crypto_vpermxor_be, "V16UcV16UcV16UcV16Uc", "",
+ "power8-vector")
+TARGET_BUILTIN(__builtin_altivec_crypto_vshasigmaw, "V4UiV4UiIiIi", "",
+ "power8-vector")
+TARGET_BUILTIN(__builtin_altivec_crypto_vshasigmad, "V2ULLiV2ULLiIiIi", "",
+ "power8-vector")
+TARGET_BUILTIN(__builtin_altivec_crypto_vcipher, "V16UcV16UcV16Uc", "",
+ "power8-vector")
+TARGET_BUILTIN(__builtin_altivec_crypto_vcipherlast, "V16UcV16UcV16Uc", "",
+ "power8-vector")
+TARGET_BUILTIN(__builtin_altivec_crypto_vncipher, "V16UcV16UcV16Uc", "",
+ "power8-vector")
+TARGET_BUILTIN(__builtin_altivec_crypto_vncipherlast, "V16UcV16UcV16Uc", "",
+ "power8-vector")
+TARGET_BUILTIN(__builtin_altivec_crypto_vpmsumb, "V16UcV16UcV16Uc", "",
+ "power8-vector")
+TARGET_BUILTIN(__builtin_altivec_crypto_vpmsumh, "V8UsV8UsV8Us", "",
+ "power8-vector")
+TARGET_BUILTIN(__builtin_altivec_crypto_vpmsumw, "V4UiV4UiV4Ui", "",
+ "power8-vector")
+TARGET_BUILTIN(__builtin_altivec_crypto_vpmsumd, "V2ULLiV2ULLiV2ULLi", "",
+ "power8-vector")
+
+TARGET_BUILTIN(__builtin_altivec_vclzb, "V16UcV16Uc", "", "power8-vector")
+TARGET_BUILTIN(__builtin_altivec_vclzh, "V8UsV8Us", "", "power8-vector")
+TARGET_BUILTIN(__builtin_altivec_vclzw, "V4UiV4Ui", "", "power8-vector")
+TARGET_BUILTIN(__builtin_altivec_vclzd, "V2ULLiV2ULLi", "", "power8-vector")
+TARGET_BUILTIN(__builtin_altivec_vctzb, "V16UcV16Uc", "", "power9-vector")
+TARGET_BUILTIN(__builtin_altivec_vctzh, "V8UsV8Us", "", "power9-vector")
+TARGET_BUILTIN(__builtin_altivec_vctzw, "V4UiV4Ui", "", "power9-vector")
+TARGET_BUILTIN(__builtin_altivec_vctzd, "V2ULLiV2ULLi", "", "power9-vector")
+
+// P8 BCD builtins.
+TARGET_BUILTIN(__builtin_ppc_bcdadd, "V16UcV16UcV16UcIi", "",
+ "isa-v207-instructions")
+TARGET_BUILTIN(__builtin_ppc_bcdsub, "V16UcV16UcV16UcIi", "",
+ "isa-v207-instructions")
+TARGET_BUILTIN(__builtin_ppc_bcdadd_p, "iiV16UcV16Uc", "",
+ "isa-v207-instructions")
+TARGET_BUILTIN(__builtin_ppc_bcdsub_p, "iiV16UcV16Uc", "",
+ "isa-v207-instructions")
+
+TARGET_BUILTIN(__builtin_altivec_vclzlsbb, "SiV16Uc", "", "power9-vector")
+TARGET_BUILTIN(__builtin_altivec_vctzlsbb, "SiV16Uc", "", "power9-vector")
+TARGET_BUILTIN(__builtin_altivec_vprtybw, "V4UiV4Ui", "", "power9-vector")
+TARGET_BUILTIN(__builtin_altivec_vprtybd, "V2ULLiV2ULLi", "", "power9-vector")
+TARGET_BUILTIN(__builtin_altivec_vprtybq, "V1ULLLiV1ULLLi", "", "power9-vector")
// Vector population count built-ins
-BUILTIN(__builtin_altivec_vpopcntb, "V16UcV16Uc", "")
-BUILTIN(__builtin_altivec_vpopcnth, "V8UsV8Us", "")
-BUILTIN(__builtin_altivec_vpopcntw, "V4UiV4Ui", "")
-BUILTIN(__builtin_altivec_vpopcntd, "V2ULLiV2ULLi", "")
+TARGET_BUILTIN(__builtin_altivec_vpopcntb, "V16UcV16Uc", "", "power8-vector")
+TARGET_BUILTIN(__builtin_altivec_vpopcnth, "V8UsV8Us", "", "power8-vector")
+TARGET_BUILTIN(__builtin_altivec_vpopcntw, "V4UiV4Ui", "", "power8-vector")
+TARGET_BUILTIN(__builtin_altivec_vpopcntd, "V2ULLiV2ULLi", "", "power8-vector")
// Absolute difference built-ins
-BUILTIN(__builtin_altivec_vabsdub, "V16UcV16UcV16Uc", "")
-BUILTIN(__builtin_altivec_vabsduh, "V8UsV8UsV8Us", "")
-BUILTIN(__builtin_altivec_vabsduw, "V4UiV4UiV4Ui", "")
+TARGET_BUILTIN(__builtin_altivec_vabsdub, "V16UcV16UcV16Uc", "",
+ "power9-vector")
+TARGET_BUILTIN(__builtin_altivec_vabsduh, "V8UsV8UsV8Us", "", "power9-vector")
+TARGET_BUILTIN(__builtin_altivec_vabsduw, "V4UiV4UiV4Ui", "", "power9-vector")
// P9 Shift built-ins.
-BUILTIN(__builtin_altivec_vslv, "V16UcV16UcV16Uc", "")
-BUILTIN(__builtin_altivec_vsrv, "V16UcV16UcV16Uc", "")
+TARGET_BUILTIN(__builtin_altivec_vslv, "V16UcV16UcV16Uc", "", "power9-vector")
+TARGET_BUILTIN(__builtin_altivec_vsrv, "V16UcV16UcV16Uc", "", "power9-vector")
// P9 Vector rotate built-ins
-BUILTIN(__builtin_altivec_vrlwmi, "V4UiV4UiV4UiV4Ui", "")
-BUILTIN(__builtin_altivec_vrldmi, "V2ULLiV2ULLiV2ULLiV2ULLi", "")
-BUILTIN(__builtin_altivec_vrlwnm, "V4UiV4UiV4Ui", "")
-BUILTIN(__builtin_altivec_vrldnm, "V2ULLiV2ULLiV2ULLi", "")
+TARGET_BUILTIN(__builtin_altivec_vrlwmi, "V4UiV4UiV4UiV4Ui", "",
+ "power9-vector")
+TARGET_BUILTIN(__builtin_altivec_vrldmi, "V2ULLiV2ULLiV2ULLiV2ULLi", "",
+ "power9-vector")
+TARGET_BUILTIN(__builtin_altivec_vrlwnm, "V4UiV4UiV4Ui", "", "power9-vector")
+TARGET_BUILTIN(__builtin_altivec_vrldnm, "V2ULLiV2ULLiV2ULLi", "",
+ "power9-vector")
// P9 Vector extend sign builtins.
-BUILTIN(__builtin_altivec_vextsb2w, "V4SiV16Sc", "")
-BUILTIN(__builtin_altivec_vextsb2d, "V2SLLiV16Sc", "")
-BUILTIN(__builtin_altivec_vextsh2w, "V4SiV8Ss", "")
-BUILTIN(__builtin_altivec_vextsh2d, "V2SLLiV8Ss", "")
-BUILTIN(__builtin_altivec_vextsw2d, "V2SLLiV4Si", "")
+TARGET_BUILTIN(__builtin_altivec_vextsb2w, "V4SiV16Sc", "", "power9-vector")
+TARGET_BUILTIN(__builtin_altivec_vextsb2d, "V2SLLiV16Sc", "", "power9-vector")
+TARGET_BUILTIN(__builtin_altivec_vextsh2w, "V4SiV8Ss", "", "power9-vector")
+TARGET_BUILTIN(__builtin_altivec_vextsh2d, "V2SLLiV8Ss", "", "power9-vector")
+TARGET_BUILTIN(__builtin_altivec_vextsw2d, "V2SLLiV4Si", "", "power9-vector")
// P10 Vector extend sign builtins.
-BUILTIN(__builtin_altivec_vextsd2q, "V1SLLLiV2SLLi", "")
+TARGET_BUILTIN(__builtin_altivec_vextsd2q, "V1SLLLiV2SLLi", "",
+ "power10-vector")
// P10 Vector Extract with Mask built-ins.
-BUILTIN(__builtin_altivec_vextractbm, "UiV16Uc", "")
-BUILTIN(__builtin_altivec_vextracthm, "UiV8Us", "")
-BUILTIN(__builtin_altivec_vextractwm, "UiV4Ui", "")
-BUILTIN(__builtin_altivec_vextractdm, "UiV2ULLi", "")
-BUILTIN(__builtin_altivec_vextractqm, "UiV1ULLLi", "")
+TARGET_BUILTIN(__builtin_altivec_vextractbm, "UiV16Uc", "", "power10-vector")
+TARGET_BUILTIN(__builtin_altivec_vextracthm, "UiV8Us", "", "power10-vector")
+TARGET_BUILTIN(__builtin_altivec_vextractwm, "UiV4Ui", "", "power10-vector")
+TARGET_BUILTIN(__builtin_altivec_vextractdm, "UiV2ULLi", "", "power10-vector")
+TARGET_BUILTIN(__builtin_altivec_vextractqm, "UiV1ULLLi", "", "power10-vector")
// P10 Vector Divide Extended built-ins.
-BUILTIN(__builtin_altivec_vdivesw, "V4SiV4SiV4Si", "")
-BUILTIN(__builtin_altivec_vdiveuw, "V4UiV4UiV4Ui", "")
-BUILTIN(__builtin_altivec_vdivesd, "V2LLiV2LLiV2LLi", "")
-BUILTIN(__builtin_altivec_vdiveud, "V2ULLiV2ULLiV2ULLi", "")
-BUILTIN(__builtin_altivec_vdivesq, "V1SLLLiV1SLLLiV1SLLLi", "")
-BUILTIN(__builtin_altivec_vdiveuq, "V1ULLLiV1ULLLiV1ULLLi", "")
+TARGET_BUILTIN(__builtin_altivec_vdivesw, "V4SiV4SiV4Si", "", "power10-vector")
+TARGET_BUILTIN(__builtin_altivec_vdiveuw, "V4UiV4UiV4Ui", "", "power10-vector")
+TARGET_BUILTIN(__builtin_altivec_vdivesd, "V2LLiV2LLiV2LLi", "",
+ "power10-vector")
+TARGET_BUILTIN(__builtin_altivec_vdiveud, "V2ULLiV2ULLiV2ULLi", "",
+ "power10-vector")
+TARGET_BUILTIN(__builtin_altivec_vdivesq, "V1SLLLiV1SLLLiV1SLLLi", "",
+ "power10-vector")
+TARGET_BUILTIN(__builtin_altivec_vdiveuq, "V1ULLLiV1ULLLiV1ULLLi", "",
+ "power10-vector")
// P10 Vector Multiply High built-ins.
-BUILTIN(__builtin_altivec_vmulhsw, "V4SiV4SiV4Si", "")
-BUILTIN(__builtin_altivec_vmulhuw, "V4UiV4UiV4Ui", "")
-BUILTIN(__builtin_altivec_vmulhsd, "V2LLiV2LLiV2LLi", "")
-BUILTIN(__builtin_altivec_vmulhud, "V2ULLiV2ULLiV2ULLi", "")
+TARGET_BUILTIN(__builtin_altivec_vmulhsw, "V4SiV4SiV4Si", "", "power10-vector")
+TARGET_BUILTIN(__builtin_altivec_vmulhuw, "V4UiV4UiV4Ui", "", "power10-vector")
+TARGET_BUILTIN(__builtin_altivec_vmulhsd, "V2LLiV2LLiV2LLi", "",
+ "power10-vector")
+TARGET_BUILTIN(__builtin_altivec_vmulhud, "V2ULLiV2ULLiV2ULLi", "",
+ "power10-vector")
// P10 Vector Expand with Mask built-ins.
-BUILTIN(__builtin_altivec_vexpandbm, "V16UcV16Uc", "")
-BUILTIN(__builtin_altivec_vexpandhm, "V8UsV8Us", "")
-BUILTIN(__builtin_altivec_vexpandwm, "V4UiV4Ui", "")
-BUILTIN(__builtin_altivec_vexpanddm, "V2ULLiV2ULLi", "")
-BUILTIN(__builtin_altivec_vexpandqm, "V1ULLLiV1ULLLi", "")
+TARGET_BUILTIN(__builtin_altivec_vexpandbm, "V16UcV16Uc", "", "power10-vector")
+TARGET_BUILTIN(__builtin_altivec_vexpandhm, "V8UsV8Us", "", "power10-vector")
+TARGET_BUILTIN(__builtin_altivec_vexpandwm, "V4UiV4Ui", "", "power10-vector")
+TARGET_BUILTIN(__builtin_altivec_vexpanddm, "V2ULLiV2ULLi", "",
+ "power10-vector")
+TARGET_BUILTIN(__builtin_altivec_vexpandqm, "V1ULLLiV1ULLLi", "",
+ "power10-vector")
// P10 Vector Count with Mask built-ins.
-BUILTIN(__builtin_altivec_vcntmbb, "ULLiV16UcUi", "")
-BUILTIN(__builtin_altivec_vcntmbh, "ULLiV8UsUi", "")
-BUILTIN(__builtin_altivec_vcntmbw, "ULLiV4UiUi", "")
-BUILTIN(__builtin_altivec_vcntmbd, "ULLiV2ULLiUi", "")
+TARGET_BUILTIN(__builtin_altivec_vcntmbb, "ULLiV16UcUi", "", "power10-vector")
+TARGET_BUILTIN(__builtin_altivec_vcntmbh, "ULLiV8UsUi", "", "power10-vector")
+TARGET_BUILTIN(__builtin_altivec_vcntmbw, "ULLiV4UiUi", "", "power10-vector")
+TARGET_BUILTIN(__builtin_altivec_vcntmbd, "ULLiV2ULLiUi", "", "power10-vector")
// P10 Move to VSR with Mask built-ins.
-BUILTIN(__builtin_altivec_mtvsrbm, "V16UcULLi", "")
-BUILTIN(__builtin_altivec_mtvsrhm, "V8UsULLi", "")
-BUILTIN(__builtin_altivec_mtvsrwm, "V4UiULLi", "")
-BUILTIN(__builtin_altivec_mtvsrdm, "V2ULLiULLi", "")
-BUILTIN(__builtin_altivec_mtvsrqm, "V1ULLLiULLi", "")
+TARGET_BUILTIN(__builtin_altivec_mtvsrbm, "V16UcULLi", "", "power10-vector")
+TARGET_BUILTIN(__builtin_altivec_mtvsrhm, "V8UsULLi", "", "power10-vector")
+TARGET_BUILTIN(__builtin_altivec_mtvsrwm, "V4UiULLi", "", "power10-vector")
+TARGET_BUILTIN(__builtin_altivec_mtvsrdm, "V2ULLiULLi", "", "power10-vector")
+TARGET_BUILTIN(__builtin_altivec_mtvsrqm, "V1ULLLiULLi", "", "power10-vector")
// P10 Vector Parallel Bits built-ins.
-BUILTIN(__builtin_altivec_vpdepd, "V2ULLiV2ULLiV2ULLi", "")
-BUILTIN(__builtin_altivec_vpextd, "V2ULLiV2ULLiV2ULLi", "")
+TARGET_BUILTIN(__builtin_altivec_vpdepd, "V2ULLiV2ULLiV2ULLi", "",
+ "power10-vector")
+TARGET_BUILTIN(__builtin_altivec_vpextd, "V2ULLiV2ULLiV2ULLi", "",
+ "power10-vector")
// P10 Vector String Isolate Built-ins.
-BUILTIN(__builtin_altivec_vstribr, "V16cV16c", "")
-BUILTIN(__builtin_altivec_vstribl, "V16cV16c", "")
-BUILTIN(__builtin_altivec_vstrihr, "V8sV8s", "")
-BUILTIN(__builtin_altivec_vstrihl, "V8sV8s", "")
-BUILTIN(__builtin_altivec_vstribr_p, "iiV16c", "")
-BUILTIN(__builtin_altivec_vstribl_p, "iiV16c", "")
-BUILTIN(__builtin_altivec_vstrihr_p, "iiV8s", "")
-BUILTIN(__builtin_altivec_vstrihl_p, "iiV8s", "")
+TARGET_BUILTIN(__builtin_altivec_vstribr, "V16UcV16Uc", "", "power10-vector")
+TARGET_BUILTIN(__builtin_altivec_vstribl, "V16UcV16Uc", "", "power10-vector")
+TARGET_BUILTIN(__builtin_altivec_vstrihr, "V8sV8s", "", "power10-vector")
+TARGET_BUILTIN(__builtin_altivec_vstrihl, "V8sV8s", "", "power10-vector")
+TARGET_BUILTIN(__builtin_altivec_vstribr_p, "iiV16Uc", "", "power10-vector")
+TARGET_BUILTIN(__builtin_altivec_vstribl_p, "iiV16Uc", "", "power10-vector")
+TARGET_BUILTIN(__builtin_altivec_vstrihr_p, "iiV8s", "", "power10-vector")
+TARGET_BUILTIN(__builtin_altivec_vstrihl_p, "iiV8s", "", "power10-vector")
// P10 Vector Centrifuge built-in.
-BUILTIN(__builtin_altivec_vcfuged, "V2ULLiV2ULLiV2ULLi", "")
+TARGET_BUILTIN(__builtin_altivec_vcfuged, "V2ULLiV2ULLiV2ULLi", "",
+ "power10-vector")
// P10 Vector Gather Every N-th Bit built-in.
-BUILTIN(__builtin_altivec_vgnb, "ULLiV1ULLLiIi", "")
+TARGET_BUILTIN(__builtin_altivec_vgnb, "ULLiV1ULLLiIi", "", "power10-vector")
// P10 Vector Clear Bytes built-ins.
-BUILTIN(__builtin_altivec_vclrlb, "V16cV16cUi", "")
-BUILTIN(__builtin_altivec_vclrrb, "V16cV16cUi", "")
+TARGET_BUILTIN(__builtin_altivec_vclrlb, "V16UcV16UcUi", "", "power10-vector")
+TARGET_BUILTIN(__builtin_altivec_vclrrb, "V16UcV16UcUi", "", "power10-vector")
// P10 Vector Count Leading / Trailing Zeroes under bit Mask built-ins.
-BUILTIN(__builtin_altivec_vclzdm, "V2ULLiV2ULLiV2ULLi", "")
-BUILTIN(__builtin_altivec_vctzdm, "V2ULLiV2ULLiV2ULLi", "")
+TARGET_BUILTIN(__builtin_altivec_vclzdm, "V2ULLiV2ULLiV2ULLi", "",
+ "power10-vector")
+TARGET_BUILTIN(__builtin_altivec_vctzdm, "V2ULLiV2ULLiV2ULLi", "",
+ "power10-vector")
// P10 Vector Shift built-ins.
-BUILTIN(__builtin_altivec_vsldbi, "V16UcV16UcV16UcIi", "")
-BUILTIN(__builtin_altivec_vsrdbi, "V16UcV16UcV16UcIi", "")
+TARGET_BUILTIN(__builtin_altivec_vsldbi, "V16UcV16UcV16UcIi", "",
+ "power10-vector")
+TARGET_BUILTIN(__builtin_altivec_vsrdbi, "V16UcV16UcV16UcIi", "",
+ "power10-vector")
// P10 Vector Insert built-ins.
-BUILTIN(__builtin_altivec_vinsblx, "V16UcV16UcUiUi", "")
-BUILTIN(__builtin_altivec_vinsbrx, "V16UcV16UcUiUi", "")
-BUILTIN(__builtin_altivec_vinshlx, "V8UsV8UsUiUi", "")
-BUILTIN(__builtin_altivec_vinshrx, "V8UsV8UsUiUi", "")
-BUILTIN(__builtin_altivec_vinswlx, "V4UiV4UiUiUi", "")
-BUILTIN(__builtin_altivec_vinswrx, "V4UiV4UiUiUi", "")
-BUILTIN(__builtin_altivec_vinsdlx, "V2ULLiV2ULLiULLiULLi", "")
-BUILTIN(__builtin_altivec_vinsdrx, "V2ULLiV2ULLiULLiULLi", "")
-BUILTIN(__builtin_altivec_vinsbvlx, "V16UcV16UcUiV16Uc", "")
-BUILTIN(__builtin_altivec_vinsbvrx, "V16UcV16UcUiV16Uc", "")
-BUILTIN(__builtin_altivec_vinshvlx, "V8UsV8UsUiV8Us", "")
-BUILTIN(__builtin_altivec_vinshvrx, "V8UsV8UsUiV8Us", "")
-BUILTIN(__builtin_altivec_vinswvlx, "V4UiV4UiUiV4Ui", "")
-BUILTIN(__builtin_altivec_vinswvrx, "V4UiV4UiUiV4Ui", "")
-BUILTIN(__builtin_altivec_vec_replace_elt, "V4UiV4UiUiIi", "t")
-BUILTIN(__builtin_altivec_vec_replace_unaligned, "V4UiV4UiUiIi", "t")
+TARGET_BUILTIN(__builtin_altivec_vinsblx, "V16UcV16UcUiUi", "",
+ "power10-vector")
+TARGET_BUILTIN(__builtin_altivec_vinsbrx, "V16UcV16UcUiUi", "",
+ "power10-vector")
+TARGET_BUILTIN(__builtin_altivec_vinshlx, "V8UsV8UsUiUi", "", "power10-vector")
+TARGET_BUILTIN(__builtin_altivec_vinshrx, "V8UsV8UsUiUi", "", "power10-vector")
+TARGET_BUILTIN(__builtin_altivec_vinswlx, "V4UiV4UiUiUi", "", "power10-vector")
+TARGET_BUILTIN(__builtin_altivec_vinswrx, "V4UiV4UiUiUi", "", "power10-vector")
+TARGET_BUILTIN(__builtin_altivec_vinsdlx, "V2ULLiV2ULLiULLiULLi", "",
+ "power10-vector")
+TARGET_BUILTIN(__builtin_altivec_vinsdrx, "V2ULLiV2ULLiULLiULLi", "",
+ "power10-vector")
+TARGET_BUILTIN(__builtin_altivec_vinsbvlx, "V16UcV16UcUiV16Uc", "",
+ "power10-vector")
+TARGET_BUILTIN(__builtin_altivec_vinsbvrx, "V16UcV16UcUiV16Uc", "",
+ "power10-vector")
+TARGET_BUILTIN(__builtin_altivec_vinshvlx, "V8UsV8UsUiV8Us", "",
+ "power10-vector")
+TARGET_BUILTIN(__builtin_altivec_vinshvrx, "V8UsV8UsUiV8Us", "",
+ "power10-vector")
+TARGET_BUILTIN(__builtin_altivec_vinswvlx, "V4UiV4UiUiV4Ui", "",
+ "power10-vector")
+TARGET_BUILTIN(__builtin_altivec_vinswvrx, "V4UiV4UiUiV4Ui", "",
+ "power10-vector")
+TARGET_BUILTIN(__builtin_altivec_vinsw, "V16UcV16UcUiIi", "", "power10-vector")
+TARGET_BUILTIN(__builtin_altivec_vinsd, "V16UcV16UcULLiIi", "",
+ "power10-vector")
+TARGET_BUILTIN(__builtin_altivec_vinsw_elt, "V16UcV16UcUiiC", "",
+ "power10-vector")
+TARGET_BUILTIN(__builtin_altivec_vinsd_elt, "V16UcV16UcULLiiC", "",
+ "power10-vector")
// P10 Vector Extract built-ins.
-BUILTIN(__builtin_altivec_vextdubvlx, "V2ULLiV16UcV16UcUi", "")
-BUILTIN(__builtin_altivec_vextdubvrx, "V2ULLiV16UcV16UcUi", "")
-BUILTIN(__builtin_altivec_vextduhvlx, "V2ULLiV8UsV8UsUi", "")
-BUILTIN(__builtin_altivec_vextduhvrx, "V2ULLiV8UsV8UsUi", "")
-BUILTIN(__builtin_altivec_vextduwvlx, "V2ULLiV4UiV4UiUi", "")
-BUILTIN(__builtin_altivec_vextduwvrx, "V2ULLiV4UiV4UiUi", "")
-BUILTIN(__builtin_altivec_vextddvlx, "V2ULLiV2ULLiV2ULLiUi", "")
-BUILTIN(__builtin_altivec_vextddvrx, "V2ULLiV2ULLiV2ULLiUi", "")
+TARGET_BUILTIN(__builtin_altivec_vextdubvlx, "V2ULLiV16UcV16UcUi", "",
+ "power10-vector")
+TARGET_BUILTIN(__builtin_altivec_vextdubvrx, "V2ULLiV16UcV16UcUi", "",
+ "power10-vector")
+TARGET_BUILTIN(__builtin_altivec_vextduhvlx, "V2ULLiV8UsV8UsUi", "",
+ "power10-vector")
+TARGET_BUILTIN(__builtin_altivec_vextduhvrx, "V2ULLiV8UsV8UsUi", "",
+ "power10-vector")
+TARGET_BUILTIN(__builtin_altivec_vextduwvlx, "V2ULLiV4UiV4UiUi", "",
+ "power10-vector")
+TARGET_BUILTIN(__builtin_altivec_vextduwvrx, "V2ULLiV4UiV4UiUi", "",
+ "power10-vector")
+TARGET_BUILTIN(__builtin_altivec_vextddvlx, "V2ULLiV2ULLiV2ULLiUi", "",
+ "power10-vector")
+TARGET_BUILTIN(__builtin_altivec_vextddvrx, "V2ULLiV2ULLiV2ULLiUi", "",
+ "power10-vector")
// P10 Vector rotate built-ins.
-BUILTIN(__builtin_altivec_vrlqmi, "V1ULLLiV1ULLLiV1ULLLiV1ULLLi", "")
-BUILTIN(__builtin_altivec_vrlqnm, "V1ULLLiV1ULLLiV1ULLLi", "")
+TARGET_BUILTIN(__builtin_altivec_vrlqmi, "V1ULLLiV1ULLLiV1ULLLiV1ULLLi", "",
+ "power10-vector")
+TARGET_BUILTIN(__builtin_altivec_vrlqnm, "V1ULLLiV1ULLLiV1ULLLi", "",
+ "power10-vector")
// VSX built-ins.
-BUILTIN(__builtin_vsx_lxvd2x, "V2dLivC*", "")
-BUILTIN(__builtin_vsx_lxvw4x, "V4iLivC*", "")
-BUILTIN(__builtin_vsx_lxvd2x_be, "V2dSLLivC*", "")
-BUILTIN(__builtin_vsx_lxvw4x_be, "V4iSLLivC*", "")
+TARGET_BUILTIN(__builtin_vsx_lxvd2x, "V2dLivC*", "", "vsx")
+TARGET_BUILTIN(__builtin_vsx_lxvw4x, "V4iLivC*", "", "vsx")
+TARGET_BUILTIN(__builtin_vsx_lxvd2x_be, "V2dSLLivC*", "", "vsx")
+TARGET_BUILTIN(__builtin_vsx_lxvw4x_be, "V4iSLLivC*", "", "vsx")
-BUILTIN(__builtin_vsx_stxvd2x, "vV2dLiv*", "")
-BUILTIN(__builtin_vsx_stxvw4x, "vV4iLiv*", "")
-BUILTIN(__builtin_vsx_stxvd2x_be, "vV2dSLLivC*", "")
-BUILTIN(__builtin_vsx_stxvw4x_be, "vV4iSLLivC*", "")
+TARGET_BUILTIN(__builtin_vsx_stxvd2x, "vV2dLiv*", "", "vsx")
+TARGET_BUILTIN(__builtin_vsx_stxvw4x, "vV4iLiv*", "", "vsx")
+TARGET_BUILTIN(__builtin_vsx_stxvd2x_be, "vV2dSLLivC*", "", "vsx")
+TARGET_BUILTIN(__builtin_vsx_stxvw4x_be, "vV4iSLLivC*", "", "vsx")
-BUILTIN(__builtin_vsx_lxvl, "V4ivC*ULLi", "")
-BUILTIN(__builtin_vsx_lxvll, "V4ivC*ULLi", "")
-BUILTIN(__builtin_vsx_stxvl, "vV4iv*ULLi", "")
-BUILTIN(__builtin_vsx_stxvll, "vV4iv*ULLi", "")
-BUILTIN(__builtin_vsx_ldrmb, "V16UcCc*Ii", "")
-BUILTIN(__builtin_vsx_strmb, "vCc*IiV16Uc", "")
+TARGET_BUILTIN(__builtin_vsx_lxvl, "V4ivC*ULLi", "", "power9-vector")
+TARGET_BUILTIN(__builtin_vsx_lxvll, "V4ivC*ULLi", "", "power9-vector")
+TARGET_BUILTIN(__builtin_vsx_stxvl, "vV4iv*ULLi", "", "power9-vector")
+TARGET_BUILTIN(__builtin_vsx_stxvll, "vV4iv*ULLi", "", "power9-vector")
+TARGET_BUILTIN(__builtin_vsx_ldrmb, "V16UcCc*Ii", "", "isa-v207-instructions")
+TARGET_BUILTIN(__builtin_vsx_strmb, "vCc*IiV16Uc", "", "isa-v207-instructions")
-BUILTIN(__builtin_vsx_xvmaxdp, "V2dV2dV2d", "")
-BUILTIN(__builtin_vsx_xvmaxsp, "V4fV4fV4f", "")
-BUILTIN(__builtin_vsx_xsmaxdp, "ddd", "")
+TARGET_BUILTIN(__builtin_vsx_xvmaxdp, "V2dV2dV2d", "", "vsx")
+TARGET_BUILTIN(__builtin_vsx_xvmaxsp, "V4fV4fV4f", "", "vsx")
+TARGET_BUILTIN(__builtin_vsx_xsmaxdp, "ddd", "", "vsx")
-BUILTIN(__builtin_vsx_xvmindp, "V2dV2dV2d", "")
-BUILTIN(__builtin_vsx_xvminsp, "V4fV4fV4f", "")
-BUILTIN(__builtin_vsx_xsmindp, "ddd", "")
+TARGET_BUILTIN(__builtin_vsx_xvmindp, "V2dV2dV2d", "", "vsx")
+TARGET_BUILTIN(__builtin_vsx_xvminsp, "V4fV4fV4f", "", "vsx")
+TARGET_BUILTIN(__builtin_vsx_xsmindp, "ddd", "", "vsx")
-BUILTIN(__builtin_vsx_xvdivdp, "V2dV2dV2d", "")
-BUILTIN(__builtin_vsx_xvdivsp, "V4fV4fV4f", "")
+TARGET_BUILTIN(__builtin_vsx_xvdivdp, "V2dV2dV2d", "", "vsx")
+TARGET_BUILTIN(__builtin_vsx_xvdivsp, "V4fV4fV4f", "", "vsx")
-BUILTIN(__builtin_vsx_xvrdpip, "V2dV2d", "")
-BUILTIN(__builtin_vsx_xvrspip, "V4fV4f", "")
+TARGET_BUILTIN(__builtin_vsx_xvrdpip, "V2dV2d", "", "vsx")
+TARGET_BUILTIN(__builtin_vsx_xvrspip, "V4fV4f", "", "vsx")
-BUILTIN(__builtin_vsx_xvcmpeqdp, "V2ULLiV2dV2d", "")
-BUILTIN(__builtin_vsx_xvcmpeqsp, "V4UiV4fV4f", "")
+TARGET_BUILTIN(__builtin_vsx_xvcmpeqdp, "V2ULLiV2dV2d", "", "vsx")
+TARGET_BUILTIN(__builtin_vsx_xvcmpeqsp, "V4UiV4fV4f", "", "vsx")
-BUILTIN(__builtin_vsx_xvcmpeqdp_p, "iiV2dV2d", "")
-BUILTIN(__builtin_vsx_xvcmpeqsp_p, "iiV4fV4f", "")
+TARGET_BUILTIN(__builtin_vsx_xvcmpeqdp_p, "iiV2dV2d", "", "vsx")
+TARGET_BUILTIN(__builtin_vsx_xvcmpeqsp_p, "iiV4fV4f", "", "vsx")
-BUILTIN(__builtin_vsx_xvcmpgedp, "V2ULLiV2dV2d", "")
-BUILTIN(__builtin_vsx_xvcmpgesp, "V4UiV4fV4f", "")
+TARGET_BUILTIN(__builtin_vsx_xvcmpgedp, "V2ULLiV2dV2d", "", "vsx")
+TARGET_BUILTIN(__builtin_vsx_xvcmpgesp, "V4UiV4fV4f", "", "vsx")
-BUILTIN(__builtin_vsx_xvcmpgedp_p, "iiV2dV2d", "")
-BUILTIN(__builtin_vsx_xvcmpgesp_p, "iiV4fV4f", "")
+TARGET_BUILTIN(__builtin_vsx_xvcmpgedp_p, "iiV2dV2d", "", "vsx")
+TARGET_BUILTIN(__builtin_vsx_xvcmpgesp_p, "iiV4fV4f", "", "vsx")
-BUILTIN(__builtin_vsx_xvcmpgtdp, "V2ULLiV2dV2d", "")
-BUILTIN(__builtin_vsx_xvcmpgtsp, "V4UiV4fV4f", "")
+TARGET_BUILTIN(__builtin_vsx_xvcmpgtdp, "V2ULLiV2dV2d", "", "vsx")
+TARGET_BUILTIN(__builtin_vsx_xvcmpgtsp, "V4UiV4fV4f", "", "vsx")
-BUILTIN(__builtin_vsx_xvcmpgtdp_p, "iiV2dV2d", "")
-BUILTIN(__builtin_vsx_xvcmpgtsp_p, "iiV4fV4f", "")
+TARGET_BUILTIN(__builtin_vsx_xvcmpgtdp_p, "iiV2dV2d", "", "vsx")
+TARGET_BUILTIN(__builtin_vsx_xvcmpgtsp_p, "iiV4fV4f", "", "vsx")
-BUILTIN(__builtin_vsx_xvrdpim, "V2dV2d", "")
-BUILTIN(__builtin_vsx_xvrspim, "V4fV4f", "")
+TARGET_BUILTIN(__builtin_vsx_xvrdpim, "V2dV2d", "", "vsx")
+TARGET_BUILTIN(__builtin_vsx_xvrspim, "V4fV4f", "", "vsx")
-BUILTIN(__builtin_vsx_xvrdpi, "V2dV2d", "")
-BUILTIN(__builtin_vsx_xvrspi, "V4fV4f", "")
+TARGET_BUILTIN(__builtin_vsx_xvrdpi, "V2dV2d", "", "vsx")
+TARGET_BUILTIN(__builtin_vsx_xvrspi, "V4fV4f", "", "vsx")
-BUILTIN(__builtin_vsx_xvrdpic, "V2dV2d", "")
-BUILTIN(__builtin_vsx_xvrspic, "V4fV4f", "")
+TARGET_BUILTIN(__builtin_vsx_xvrdpic, "V2dV2d", "", "vsx")
+TARGET_BUILTIN(__builtin_vsx_xvrspic, "V4fV4f", "", "vsx")
-BUILTIN(__builtin_vsx_xvrdpiz, "V2dV2d", "")
-BUILTIN(__builtin_vsx_xvrspiz, "V4fV4f", "")
+TARGET_BUILTIN(__builtin_vsx_xvrdpiz, "V2dV2d", "", "vsx")
+TARGET_BUILTIN(__builtin_vsx_xvrspiz, "V4fV4f", "", "vsx")
-BUILTIN(__builtin_vsx_xvmaddadp, "V2dV2dV2dV2d", "")
-BUILTIN(__builtin_vsx_xvmaddasp, "V4fV4fV4fV4f", "")
+TARGET_BUILTIN(__builtin_vsx_xvmaddadp, "V2dV2dV2dV2d", "", "vsx")
+TARGET_BUILTIN(__builtin_vsx_xvmaddasp, "V4fV4fV4fV4f", "", "vsx")
-BUILTIN(__builtin_vsx_xvmsubadp, "V2dV2dV2dV2d", "")
-BUILTIN(__builtin_vsx_xvmsubasp, "V4fV4fV4fV4f", "")
+TARGET_BUILTIN(__builtin_vsx_xvmsubadp, "V2dV2dV2dV2d", "", "vsx")
+TARGET_BUILTIN(__builtin_vsx_xvmsubasp, "V4fV4fV4fV4f", "", "vsx")
-BUILTIN(__builtin_vsx_xvmuldp, "V2dV2dV2d", "")
-BUILTIN(__builtin_vsx_xvmulsp, "V4fV4fV4f", "")
+TARGET_BUILTIN(__builtin_vsx_xvmuldp, "V2dV2dV2d", "", "vsx")
+TARGET_BUILTIN(__builtin_vsx_xvmulsp, "V4fV4fV4f", "", "vsx")
-BUILTIN(__builtin_vsx_xvnmaddadp, "V2dV2dV2dV2d", "")
-BUILTIN(__builtin_vsx_xvnmaddasp, "V4fV4fV4fV4f", "")
+TARGET_BUILTIN(__builtin_vsx_xvnmaddadp, "V2dV2dV2dV2d", "", "vsx")
+TARGET_BUILTIN(__builtin_vsx_xvnmaddasp, "V4fV4fV4fV4f", "", "vsx")
-BUILTIN(__builtin_vsx_xvnmsubadp, "V2dV2dV2dV2d", "")
-BUILTIN(__builtin_vsx_xvnmsubasp, "V4fV4fV4fV4f", "")
+TARGET_BUILTIN(__builtin_vsx_xvnmsubadp, "V2dV2dV2dV2d", "", "vsx")
+TARGET_BUILTIN(__builtin_vsx_xvnmsubasp, "V4fV4fV4fV4f", "", "vsx")
-BUILTIN(__builtin_vsx_xvredp, "V2dV2d", "")
-BUILTIN(__builtin_vsx_xvresp, "V4fV4f", "")
+TARGET_BUILTIN(__builtin_vsx_xvredp, "V2dV2d", "", "vsx")
+TARGET_BUILTIN(__builtin_vsx_xvresp, "V4fV4f", "", "vsx")
-BUILTIN(__builtin_vsx_xvrsqrtedp, "V2dV2d", "")
-BUILTIN(__builtin_vsx_xvrsqrtesp, "V4fV4f", "")
+TARGET_BUILTIN(__builtin_vsx_xvrsqrtedp, "V2dV2d", "", "vsx")
+TARGET_BUILTIN(__builtin_vsx_xvrsqrtesp, "V4fV4f", "", "vsx")
-BUILTIN(__builtin_vsx_xvsqrtdp, "V2dV2d", "")
-BUILTIN(__builtin_vsx_xvsqrtsp, "V4fV4f", "")
+TARGET_BUILTIN(__builtin_vsx_xvsqrtdp, "V2dV2d", "", "vsx")
+TARGET_BUILTIN(__builtin_vsx_xvsqrtsp, "V4fV4f", "", "vsx")
-BUILTIN(__builtin_vsx_xxleqv, "V4UiV4UiV4Ui", "")
+TARGET_BUILTIN(__builtin_vsx_xxleqv, "V4UiV4UiV4Ui", "", "power8-vector")
-BUILTIN(__builtin_vsx_xvcpsgndp, "V2dV2dV2d", "")
-BUILTIN(__builtin_vsx_xvcpsgnsp, "V4fV4fV4f", "")
+TARGET_BUILTIN(__builtin_vsx_xvcpsgndp, "V2dV2dV2d", "", "vsx")
+TARGET_BUILTIN(__builtin_vsx_xvcpsgnsp, "V4fV4fV4f", "", "vsx")
-BUILTIN(__builtin_vsx_xvabssp, "V4fV4f", "")
-BUILTIN(__builtin_vsx_xvabsdp, "V2dV2d", "")
+TARGET_BUILTIN(__builtin_vsx_xvabssp, "V4fV4f", "", "vsx")
+TARGET_BUILTIN(__builtin_vsx_xvabsdp, "V2dV2d", "", "vsx")
-BUILTIN(__builtin_vsx_xxgenpcvbm, "V16UcV16Uci", "")
-BUILTIN(__builtin_vsx_xxgenpcvhm, "V8UsV8Usi", "")
-BUILTIN(__builtin_vsx_xxgenpcvwm, "V4UiV4Uii", "")
-BUILTIN(__builtin_vsx_xxgenpcvdm, "V2ULLiV2ULLii", "")
+TARGET_BUILTIN(__builtin_vsx_xxgenpcvbm, "V16UcV16Uci", "", "power10-vector")
+TARGET_BUILTIN(__builtin_vsx_xxgenpcvhm, "V8UsV8Usi", "", "power10-vector")
+TARGET_BUILTIN(__builtin_vsx_xxgenpcvwm, "V4UiV4Uii", "", "power10-vector")
+TARGET_BUILTIN(__builtin_vsx_xxgenpcvdm, "V2ULLiV2ULLii", "", "power10-vector")
// vector Insert/Extract exponent/significand builtins
-BUILTIN(__builtin_vsx_xviexpdp, "V2dV2ULLiV2ULLi", "")
-BUILTIN(__builtin_vsx_xviexpsp, "V4fV4UiV4Ui", "")
-BUILTIN(__builtin_vsx_xvxexpdp, "V2ULLiV2d", "")
-BUILTIN(__builtin_vsx_xvxexpsp, "V4UiV4f", "")
-BUILTIN(__builtin_vsx_xvxsigdp, "V2ULLiV2d", "")
-BUILTIN(__builtin_vsx_xvxsigsp, "V4UiV4f", "")
+TARGET_BUILTIN(__builtin_vsx_xviexpdp, "V2dV2ULLiV2ULLi", "", "power9-vector")
+TARGET_BUILTIN(__builtin_vsx_xviexpsp, "V4fV4UiV4Ui", "", "power9-vector")
+TARGET_BUILTIN(__builtin_vsx_xvxexpdp, "V2ULLiV2d", "", "power9-vector")
+TARGET_BUILTIN(__builtin_vsx_xvxexpsp, "V4UiV4f", "", "power9-vector")
+TARGET_BUILTIN(__builtin_vsx_xvxsigdp, "V2ULLiV2d", "", "power9-vector")
+TARGET_BUILTIN(__builtin_vsx_xvxsigsp, "V4UiV4f", "", "power9-vector")
// Conversion builtins
-BUILTIN(__builtin_vsx_xvcvdpsxws, "V4SiV2d", "")
-BUILTIN(__builtin_vsx_xvcvdpuxws, "V4UiV2d", "")
-BUILTIN(__builtin_vsx_xvcvspsxds, "V2SLLiV4f", "")
-BUILTIN(__builtin_vsx_xvcvspuxds, "V2ULLiV4f", "")
-BUILTIN(__builtin_vsx_xvcvsxwdp, "V2dV4Si", "")
-BUILTIN(__builtin_vsx_xvcvuxwdp, "V2dV4Ui", "")
-BUILTIN(__builtin_vsx_xvcvspdp, "V2dV4f", "")
-BUILTIN(__builtin_vsx_xvcvsxdsp, "V4fV2SLLi", "")
-BUILTIN(__builtin_vsx_xvcvuxdsp, "V4fV2ULLi", "")
-BUILTIN(__builtin_vsx_xvcvdpsp, "V4fV2d", "")
-
-BUILTIN(__builtin_vsx_xvcvsphp, "V4fV4f", "")
-BUILTIN(__builtin_vsx_xvcvhpsp, "V4fV8Us", "")
-
-BUILTIN(__builtin_vsx_xvcvspbf16, "V16UcV16Uc", "")
-BUILTIN(__builtin_vsx_xvcvbf16spn, "V16UcV16Uc", "")
+TARGET_BUILTIN(__builtin_vsx_xvcvdpsxws, "V4SiV2d", "", "vsx")
+TARGET_BUILTIN(__builtin_vsx_xvcvdpuxws, "V4UiV2d", "", "vsx")
+TARGET_BUILTIN(__builtin_vsx_xvcvspsxds, "V2SLLiV4f", "", "vsx")
+TARGET_BUILTIN(__builtin_vsx_xvcvspuxds, "V2ULLiV4f", "", "vsx")
+TARGET_BUILTIN(__builtin_vsx_xvcvsxwdp, "V2dV4Si", "", "vsx")
+TARGET_BUILTIN(__builtin_vsx_xvcvuxwdp, "V2dV4Ui", "", "vsx")
+TARGET_BUILTIN(__builtin_vsx_xvcvspdp, "V2dV4f", "", "vsx")
+TARGET_BUILTIN(__builtin_vsx_xvcvsxdsp, "V4fV2SLLi", "", "vsx")
+TARGET_BUILTIN(__builtin_vsx_xvcvuxdsp, "V4fV2ULLi", "", "vsx")
+TARGET_BUILTIN(__builtin_vsx_xvcvdpsp, "V4fV2d", "", "vsx")
+
+TARGET_BUILTIN(__builtin_vsx_xvcvsphp, "V4fV4f", "", "power9-vector")
+TARGET_BUILTIN(__builtin_vsx_xvcvhpsp, "V4fV8Us", "", "power9-vector")
+
+TARGET_BUILTIN(__builtin_vsx_xvcvspbf16, "V16UcV16Uc", "", "power10-vector")
+TARGET_BUILTIN(__builtin_vsx_xvcvbf16spn, "V16UcV16Uc", "", "power10-vector")
// Vector Test Data Class builtins
-BUILTIN(__builtin_vsx_xvtstdcdp, "V2ULLiV2dIi", "")
-BUILTIN(__builtin_vsx_xvtstdcsp, "V4UiV4fIi", "")
+TARGET_BUILTIN(__builtin_vsx_xvtstdcdp, "V2ULLiV2dIi", "", "power9-vector")
+TARGET_BUILTIN(__builtin_vsx_xvtstdcsp, "V4UiV4fIi", "", "power9-vector")
-BUILTIN(__builtin_vsx_insertword, "V16UcV4UiV16UcIi", "")
-BUILTIN(__builtin_vsx_extractuword, "V2ULLiV16UcIi", "")
+TARGET_BUILTIN(__builtin_vsx_insertword, "V16UcV4UiV16UcIi", "", "vsx")
+TARGET_BUILTIN(__builtin_vsx_extractuword, "V2ULLiV16UcIi", "", "vsx")
-BUILTIN(__builtin_vsx_xxpermdi, "v.", "t")
-BUILTIN(__builtin_vsx_xxsldwi, "v.", "t")
+TARGET_BUILTIN(__builtin_vsx_xxpermdi, "v.", "t", "vsx")
+TARGET_BUILTIN(__builtin_vsx_xxsldwi, "v.", "t", "vsx")
-BUILTIN(__builtin_vsx_xxeval, "V2ULLiV2ULLiV2ULLiV2ULLiIi", "")
+TARGET_BUILTIN(__builtin_vsx_xxeval, "V2ULLiV2ULLiV2ULLiV2ULLiIi", "",
+ "power10-vector")
-BUILTIN(__builtin_vsx_xvtlsbb, "iV16UcUi", "")
+TARGET_BUILTIN(__builtin_vsx_xvtlsbb, "iV16UcUi", "", "power10-vector")
-BUILTIN(__builtin_vsx_xvtdivdp, "iV2dV2d", "")
-BUILTIN(__builtin_vsx_xvtdivsp, "iV4fV4f", "")
-BUILTIN(__builtin_vsx_xvtsqrtdp, "iV2d", "")
-BUILTIN(__builtin_vsx_xvtsqrtsp, "iV4f", "")
+TARGET_BUILTIN(__builtin_vsx_xvtdivdp, "iV2dV2d", "", "vsx")
+TARGET_BUILTIN(__builtin_vsx_xvtdivsp, "iV4fV4f", "", "vsx")
+TARGET_BUILTIN(__builtin_vsx_xvtsqrtdp, "iV2d", "", "vsx")
+TARGET_BUILTIN(__builtin_vsx_xvtsqrtsp, "iV4f", "", "vsx")
// P10 Vector Permute Extended built-in.
-BUILTIN(__builtin_vsx_xxpermx, "V16UcV16UcV16UcV16UcIi", "")
+TARGET_BUILTIN(__builtin_vsx_xxpermx, "V16UcV16UcV16UcV16UcIi", "",
+ "power10-vector")
// P10 Vector Blend built-ins.
-BUILTIN(__builtin_vsx_xxblendvb, "V16UcV16UcV16UcV16Uc", "")
-BUILTIN(__builtin_vsx_xxblendvh, "V8UsV8UsV8UsV8Us", "")
-BUILTIN(__builtin_vsx_xxblendvw, "V4UiV4UiV4UiV4Ui", "")
-BUILTIN(__builtin_vsx_xxblendvd, "V2ULLiV2ULLiV2ULLiV2ULLi", "")
+TARGET_BUILTIN(__builtin_vsx_xxblendvb, "V16UcV16UcV16UcV16Uc", "",
+ "power10-vector")
+TARGET_BUILTIN(__builtin_vsx_xxblendvh, "V8UsV8UsV8UsV8Us", "",
+ "power10-vector")
+TARGET_BUILTIN(__builtin_vsx_xxblendvw, "V4UiV4UiV4UiV4Ui", "",
+ "power10-vector")
+TARGET_BUILTIN(__builtin_vsx_xxblendvd, "V2ULLiV2ULLiV2ULLiV2ULLi", "",
+ "power10-vector")
// Float 128 built-ins
-BUILTIN(__builtin_sqrtf128_round_to_odd, "LLdLLd", "")
-BUILTIN(__builtin_addf128_round_to_odd, "LLdLLdLLd", "")
-BUILTIN(__builtin_subf128_round_to_odd, "LLdLLdLLd", "")
-BUILTIN(__builtin_mulf128_round_to_odd, "LLdLLdLLd", "")
-BUILTIN(__builtin_divf128_round_to_odd, "LLdLLdLLd", "")
-BUILTIN(__builtin_fmaf128_round_to_odd, "LLdLLdLLdLLd", "")
-BUILTIN(__builtin_truncf128_round_to_odd, "dLLd", "")
-BUILTIN(__builtin_vsx_scalar_extract_expq, "ULLiLLd", "")
-BUILTIN(__builtin_vsx_scalar_insert_exp_qp, "LLdLLdULLi", "")
+TARGET_BUILTIN(__builtin_sqrtf128_round_to_odd, "LLdLLd", "", "float128")
+TARGET_BUILTIN(__builtin_addf128_round_to_odd, "LLdLLdLLd", "", "float128")
+TARGET_BUILTIN(__builtin_subf128_round_to_odd, "LLdLLdLLd", "", "float128")
+TARGET_BUILTIN(__builtin_mulf128_round_to_odd, "LLdLLdLLd", "", "float128")
+TARGET_BUILTIN(__builtin_divf128_round_to_odd, "LLdLLdLLd", "", "float128")
+TARGET_BUILTIN(__builtin_fmaf128_round_to_odd, "LLdLLdLLdLLd", "", "float128")
+TARGET_BUILTIN(__builtin_truncf128_round_to_odd, "dLLd", "", "float128")
+TARGET_BUILTIN(__builtin_vsx_scalar_extract_expq, "ULLiLLd", "", "float128")
+TARGET_BUILTIN(__builtin_vsx_scalar_insert_exp_qp, "LLdLLdULLi", "", "float128")
// Fastmath by default builtins
BUILTIN(__builtin_ppc_rsqrtf, "V4fV4f", "")
@@ -729,56 +890,60 @@ BUILTIN(__builtin_ppc_recipdivf, "V4fV4fV4f", "")
BUILTIN(__builtin_ppc_recipdivd, "V2dV2dV2d", "")
// HTM builtins
-BUILTIN(__builtin_tbegin, "UiUIi", "")
-BUILTIN(__builtin_tend, "UiUIi", "")
+TARGET_BUILTIN(__builtin_tbegin, "UiUIi", "", "htm")
+TARGET_BUILTIN(__builtin_tend, "UiUIi", "", "htm")
-BUILTIN(__builtin_tabort, "UiUi", "")
-BUILTIN(__builtin_tabortdc, "UiUiUiUi", "")
-BUILTIN(__builtin_tabortdci, "UiUiUii", "")
-BUILTIN(__builtin_tabortwc, "UiUiUiUi", "")
-BUILTIN(__builtin_tabortwci, "UiUiUii", "")
+TARGET_BUILTIN(__builtin_tabort, "UiUi", "", "htm")
+TARGET_BUILTIN(__builtin_tabortdc, "UiUiUiUi", "", "htm")
+TARGET_BUILTIN(__builtin_tabortdci, "UiUiUii", "", "htm")
+TARGET_BUILTIN(__builtin_tabortwc, "UiUiUiUi", "", "htm")
+TARGET_BUILTIN(__builtin_tabortwci, "UiUiUii", "", "htm")
-BUILTIN(__builtin_tcheck, "Ui", "")
-BUILTIN(__builtin_treclaim, "UiUi", "")
-BUILTIN(__builtin_trechkpt, "Ui", "")
-BUILTIN(__builtin_tsr, "UiUi", "")
+TARGET_BUILTIN(__builtin_tcheck, "Ui", "", "htm")
+TARGET_BUILTIN(__builtin_treclaim, "UiUi", "", "htm")
+TARGET_BUILTIN(__builtin_trechkpt, "Ui", "", "htm")
+TARGET_BUILTIN(__builtin_tsr, "UiUi", "", "htm")
-BUILTIN(__builtin_tendall, "Ui", "")
-BUILTIN(__builtin_tresume, "Ui", "")
-BUILTIN(__builtin_tsuspend, "Ui", "")
+TARGET_BUILTIN(__builtin_tendall, "Ui", "", "htm")
+TARGET_BUILTIN(__builtin_tresume, "Ui", "", "htm")
+TARGET_BUILTIN(__builtin_tsuspend, "Ui", "", "htm")
-BUILTIN(__builtin_get_texasr, "LUi", "c")
-BUILTIN(__builtin_get_texasru, "LUi", "c")
-BUILTIN(__builtin_get_tfhar, "LUi", "c")
-BUILTIN(__builtin_get_tfiar, "LUi", "c")
+TARGET_BUILTIN(__builtin_get_texasr, "LUi", "c", "htm")
+TARGET_BUILTIN(__builtin_get_texasru, "LUi", "c", "htm")
+TARGET_BUILTIN(__builtin_get_tfhar, "LUi", "c", "htm")
+TARGET_BUILTIN(__builtin_get_tfiar, "LUi", "c", "htm")
-BUILTIN(__builtin_set_texasr, "vLUi", "c")
-BUILTIN(__builtin_set_texasru, "vLUi", "c")
-BUILTIN(__builtin_set_tfhar, "vLUi", "c")
-BUILTIN(__builtin_set_tfiar, "vLUi", "c")
+TARGET_BUILTIN(__builtin_set_texasr, "vLUi", "c", "htm")
+TARGET_BUILTIN(__builtin_set_texasru, "vLUi", "c", "htm")
+TARGET_BUILTIN(__builtin_set_tfhar, "vLUi", "c", "htm")
+TARGET_BUILTIN(__builtin_set_tfiar, "vLUi", "c", "htm")
-BUILTIN(__builtin_ttest, "LUi", "")
+TARGET_BUILTIN(__builtin_ttest, "LUi", "", "htm")
// Scalar built-ins
-BUILTIN(__builtin_divwe, "SiSiSi", "")
-BUILTIN(__builtin_divweu, "UiUiUi", "")
-BUILTIN(__builtin_divde, "SLLiSLLiSLLi", "")
-BUILTIN(__builtin_divdeu, "ULLiULLiULLi", "")
-BUILTIN(__builtin_bpermd, "SLLiSLLiSLLi", "")
-BUILTIN(__builtin_pdepd, "ULLiULLiULLi", "")
-BUILTIN(__builtin_pextd, "ULLiULLiULLi", "")
-BUILTIN(__builtin_cfuged, "ULLiULLiULLi", "")
-BUILTIN(__builtin_cntlzdm, "ULLiULLiULLi", "")
-BUILTIN(__builtin_cnttzdm, "ULLiULLiULLi", "")
+TARGET_BUILTIN(__builtin_divwe, "SiSiSi", "", "extdiv")
+TARGET_BUILTIN(__builtin_divweu, "UiUiUi", "", "extdiv")
+TARGET_BUILTIN(__builtin_divde, "SLLiSLLiSLLi", "", "extdiv")
+TARGET_BUILTIN(__builtin_divdeu, "ULLiULLiULLi", "", "extdiv")
+TARGET_BUILTIN(__builtin_bpermd, "SLLiSLLiSLLi", "", "bpermd")
+TARGET_BUILTIN(__builtin_pdepd, "ULLiULLiULLi", "", "isa-v31-instructions")
+TARGET_BUILTIN(__builtin_pextd, "ULLiULLiULLi", "", "isa-v31-instructions")
+TARGET_BUILTIN(__builtin_cfuged, "ULLiULLiULLi", "", "isa-v31-instructions")
+TARGET_BUILTIN(__builtin_cntlzdm, "ULLiULLiULLi", "", "isa-v31-instructions")
+TARGET_BUILTIN(__builtin_cnttzdm, "ULLiULLiULLi", "", "isa-v31-instructions")
+
+// Double-double (un)pack
+BUILTIN(__builtin_unpack_longdouble, "dLdIi", "")
+BUILTIN(__builtin_pack_longdouble, "Lddd", "")
// Generate random number
-BUILTIN(__builtin_darn, "LLi", "")
-BUILTIN(__builtin_darn_raw, "LLi", "")
-BUILTIN(__builtin_darn_32, "i", "")
+TARGET_BUILTIN(__builtin_darn, "LLi", "", "isa-v30-instructions")
+TARGET_BUILTIN(__builtin_darn_raw, "LLi", "", "isa-v30-instructions")
+TARGET_BUILTIN(__builtin_darn_32, "i", "", "isa-v30-instructions")
// Vector int128 (un)pack
-BUILTIN(__builtin_unpack_vector_int128, "ULLiV1LLLii", "")
-BUILTIN(__builtin_pack_vector_int128, "V1LLLiULLiULLi", "")
+TARGET_BUILTIN(__builtin_unpack_vector_int128, "ULLiV1LLLii", "", "vsx")
+TARGET_BUILTIN(__builtin_pack_vector_int128, "V1LLLiULLiULLi", "", "vsx")
// Set the floating point rounding mode
BUILTIN(__builtin_setrnd, "di", "")
@@ -812,84 +977,159 @@ BUILTIN(__builtin_dcbf, "vvC*", "")
// its given accumulator.
// Provided builtins with _mma_ prefix for compatibility.
-CUSTOM_BUILTIN(mma_lxvp, vsx_lxvp, "W256SLLiW256C*", false)
-CUSTOM_BUILTIN(mma_stxvp, vsx_stxvp, "vW256SLLiW256C*", false)
-CUSTOM_BUILTIN(mma_assemble_pair, vsx_assemble_pair, "vW256*VV", false)
-CUSTOM_BUILTIN(mma_disassemble_pair, vsx_disassemble_pair, "vv*W256*", false)
+CUSTOM_BUILTIN(mma_lxvp, vsx_lxvp, "W256SLiW256C*", false,
+ "paired-vector-memops")
+CUSTOM_BUILTIN(mma_stxvp, vsx_stxvp, "vW256SLiW256*", false,
+ "paired-vector-memops")
+CUSTOM_BUILTIN(mma_assemble_pair, vsx_assemble_pair, "vW256*VV", false,
+ "paired-vector-memops")
+CUSTOM_BUILTIN(mma_disassemble_pair, vsx_disassemble_pair, "vv*W256*", false,
+ "paired-vector-memops")
+CUSTOM_BUILTIN(vsx_build_pair, vsx_assemble_pair, "vW256*VV", false,
+ "paired-vector-memops")
+CUSTOM_BUILTIN(mma_build_acc, mma_assemble_acc, "vW512*VVVV", false, "mma")
// UNALIASED_CUSTOM_BUILTIN macro is used for built-ins that have
// the same name as that of the intrinsic they generate, i.e. the
// ID and INTR are the same.
// This avoids repeating the ID and INTR in the macro expression.
-UNALIASED_CUSTOM_BUILTIN(vsx_lxvp, "W256SLLiW256C*", false)
-UNALIASED_CUSTOM_BUILTIN(vsx_stxvp, "vW256SLLiW256C*", false)
-UNALIASED_CUSTOM_BUILTIN(vsx_assemble_pair, "vW256*VV", false)
-UNALIASED_CUSTOM_BUILTIN(vsx_disassemble_pair, "vv*W256*", false)
-
-UNALIASED_CUSTOM_BUILTIN(mma_assemble_acc, "vW512*VVVV", false)
-UNALIASED_CUSTOM_BUILTIN(mma_disassemble_acc, "vv*W512*", false)
-UNALIASED_CUSTOM_BUILTIN(mma_xxmtacc, "vW512*", true)
-UNALIASED_CUSTOM_BUILTIN(mma_xxmfacc, "vW512*", true)
-UNALIASED_CUSTOM_BUILTIN(mma_xxsetaccz, "vW512*", false)
-UNALIASED_CUSTOM_BUILTIN(mma_xvi4ger8, "vW512*VV", false)
-UNALIASED_CUSTOM_BUILTIN(mma_xvi8ger4, "vW512*VV", false)
-UNALIASED_CUSTOM_BUILTIN(mma_xvi16ger2, "vW512*VV", false)
-UNALIASED_CUSTOM_BUILTIN(mma_xvi16ger2s, "vW512*VV", false)
-UNALIASED_CUSTOM_BUILTIN(mma_xvf16ger2, "vW512*VV", false)
-UNALIASED_CUSTOM_BUILTIN(mma_xvf32ger, "vW512*VV", false)
-UNALIASED_CUSTOM_BUILTIN(mma_xvf64ger, "vW512*W256V", false)
-UNALIASED_CUSTOM_BUILTIN(mma_pmxvi4ger8, "vW512*VVi15i15i255", false)
-UNALIASED_CUSTOM_BUILTIN(mma_pmxvi8ger4, "vW512*VVi15i15i15", false)
-UNALIASED_CUSTOM_BUILTIN(mma_pmxvi16ger2, "vW512*VVi15i15i3", false)
-UNALIASED_CUSTOM_BUILTIN(mma_pmxvi16ger2s, "vW512*VVi15i15i3", false)
-UNALIASED_CUSTOM_BUILTIN(mma_pmxvf16ger2, "vW512*VVi15i15i3", false)
-UNALIASED_CUSTOM_BUILTIN(mma_pmxvf32ger, "vW512*VVi15i15", false)
-UNALIASED_CUSTOM_BUILTIN(mma_pmxvf64ger, "vW512*W256Vi15i3", false)
-UNALIASED_CUSTOM_BUILTIN(mma_xvi4ger8pp, "vW512*VV", true)
-UNALIASED_CUSTOM_BUILTIN(mma_xvi8ger4pp, "vW512*VV", true)
-UNALIASED_CUSTOM_BUILTIN(mma_xvi8ger4spp, "vW512*VV", true)
-UNALIASED_CUSTOM_BUILTIN(mma_xvi16ger2pp, "vW512*VV", true)
-UNALIASED_CUSTOM_BUILTIN(mma_xvi16ger2spp, "vW512*VV", true)
-UNALIASED_CUSTOM_BUILTIN(mma_pmxvi4ger8pp, "vW512*VVi15i15i255", true)
-UNALIASED_CUSTOM_BUILTIN(mma_pmxvi8ger4pp, "vW512*VVi15i15i15", true)
-UNALIASED_CUSTOM_BUILTIN(mma_pmxvi8ger4spp, "vW512*VVi15i15i15", true)
-UNALIASED_CUSTOM_BUILTIN(mma_pmxvi16ger2pp, "vW512*VVi15i15i3", true)
-UNALIASED_CUSTOM_BUILTIN(mma_pmxvi16ger2spp, "vW512*VVi15i15i3", true)
-UNALIASED_CUSTOM_BUILTIN(mma_xvf16ger2pp, "vW512*VV", true)
-UNALIASED_CUSTOM_BUILTIN(mma_xvf16ger2pn, "vW512*VV", true)
-UNALIASED_CUSTOM_BUILTIN(mma_xvf16ger2np, "vW512*VV", true)
-UNALIASED_CUSTOM_BUILTIN(mma_xvf16ger2nn, "vW512*VV", true)
-UNALIASED_CUSTOM_BUILTIN(mma_pmxvf16ger2pp, "vW512*VVi15i15i3", true)
-UNALIASED_CUSTOM_BUILTIN(mma_pmxvf16ger2pn, "vW512*VVi15i15i3", true)
-UNALIASED_CUSTOM_BUILTIN(mma_pmxvf16ger2np, "vW512*VVi15i15i3", true)
-UNALIASED_CUSTOM_BUILTIN(mma_pmxvf16ger2nn, "vW512*VVi15i15i3", true)
-UNALIASED_CUSTOM_BUILTIN(mma_xvf32gerpp, "vW512*VV", true)
-UNALIASED_CUSTOM_BUILTIN(mma_xvf32gerpn, "vW512*VV", true)
-UNALIASED_CUSTOM_BUILTIN(mma_xvf32gernp, "vW512*VV", true)
-UNALIASED_CUSTOM_BUILTIN(mma_xvf32gernn, "vW512*VV", true)
-UNALIASED_CUSTOM_BUILTIN(mma_pmxvf32gerpp, "vW512*VVi15i15", true)
-UNALIASED_CUSTOM_BUILTIN(mma_pmxvf32gerpn, "vW512*VVi15i15", true)
-UNALIASED_CUSTOM_BUILTIN(mma_pmxvf32gernp, "vW512*VVi15i15", true)
-UNALIASED_CUSTOM_BUILTIN(mma_pmxvf32gernn, "vW512*VVi15i15", true)
-UNALIASED_CUSTOM_BUILTIN(mma_xvf64gerpp, "vW512*W256V", true)
-UNALIASED_CUSTOM_BUILTIN(mma_xvf64gerpn, "vW512*W256V", true)
-UNALIASED_CUSTOM_BUILTIN(mma_xvf64gernp, "vW512*W256V", true)
-UNALIASED_CUSTOM_BUILTIN(mma_xvf64gernn, "vW512*W256V", true)
-UNALIASED_CUSTOM_BUILTIN(mma_pmxvf64gerpp, "vW512*W256Vi15i3", true)
-UNALIASED_CUSTOM_BUILTIN(mma_pmxvf64gerpn, "vW512*W256Vi15i3", true)
-UNALIASED_CUSTOM_BUILTIN(mma_pmxvf64gernp, "vW512*W256Vi15i3", true)
-UNALIASED_CUSTOM_BUILTIN(mma_pmxvf64gernn, "vW512*W256Vi15i3", true)
-UNALIASED_CUSTOM_BUILTIN(mma_xvbf16ger2, "vW512*VV", false)
-UNALIASED_CUSTOM_BUILTIN(mma_pmxvbf16ger2, "vW512*VVi15i15i3", false)
-UNALIASED_CUSTOM_BUILTIN(mma_xvbf16ger2pp, "vW512*VV", true)
-UNALIASED_CUSTOM_BUILTIN(mma_xvbf16ger2pn, "vW512*VV", true)
-UNALIASED_CUSTOM_BUILTIN(mma_xvbf16ger2np, "vW512*VV", true)
-UNALIASED_CUSTOM_BUILTIN(mma_xvbf16ger2nn, "vW512*VV", true)
-UNALIASED_CUSTOM_BUILTIN(mma_pmxvbf16ger2pp, "vW512*VVi15i15i3", true)
-UNALIASED_CUSTOM_BUILTIN(mma_pmxvbf16ger2pn, "vW512*VVi15i15i3", true)
-UNALIASED_CUSTOM_BUILTIN(mma_pmxvbf16ger2np, "vW512*VVi15i15i3", true)
-UNALIASED_CUSTOM_BUILTIN(mma_pmxvbf16ger2nn, "vW512*VVi15i15i3", true)
+UNALIASED_CUSTOM_BUILTIN(vsx_lxvp, "W256SLiW256C*", false,
+ "paired-vector-memops")
+UNALIASED_CUSTOM_BUILTIN(vsx_stxvp, "vW256SLiW256*", false,
+ "paired-vector-memops")
+UNALIASED_CUSTOM_BUILTIN(vsx_assemble_pair, "vW256*VV", false,
+ "paired-vector-memops")
+UNALIASED_CUSTOM_BUILTIN(vsx_disassemble_pair, "vv*W256*", false,
+ "paired-vector-memops")
+
+// TODO: Require only mma after backend supports these without paired memops
+UNALIASED_CUSTOM_BUILTIN(mma_assemble_acc, "vW512*VVVV", false,
+ "mma,paired-vector-memops")
+UNALIASED_CUSTOM_BUILTIN(mma_disassemble_acc, "vv*W512*", false,
+ "mma,paired-vector-memops")
+UNALIASED_CUSTOM_BUILTIN(mma_xxmtacc, "vW512*", true,
+ "mma,paired-vector-memops")
+UNALIASED_CUSTOM_BUILTIN(mma_xxmfacc, "vW512*", true,
+ "mma,paired-vector-memops")
+UNALIASED_CUSTOM_BUILTIN(mma_xxsetaccz, "vW512*", false,
+ "mma,paired-vector-memops")
+UNALIASED_CUSTOM_BUILTIN(mma_xvi4ger8, "vW512*VV", false,
+ "mma,paired-vector-memops")
+UNALIASED_CUSTOM_BUILTIN(mma_xvi8ger4, "vW512*VV", false,
+ "mma,paired-vector-memops")
+UNALIASED_CUSTOM_BUILTIN(mma_xvi16ger2, "vW512*VV", false,
+ "mma,paired-vector-memops")
+UNALIASED_CUSTOM_BUILTIN(mma_xvi16ger2s, "vW512*VV", false,
+ "mma,paired-vector-memops")
+UNALIASED_CUSTOM_BUILTIN(mma_xvf16ger2, "vW512*VV", false,
+ "mma,paired-vector-memops")
+UNALIASED_CUSTOM_BUILTIN(mma_xvf32ger, "vW512*VV", false,
+ "mma,paired-vector-memops")
+UNALIASED_CUSTOM_BUILTIN(mma_xvf64ger, "vW512*W256V", false,
+ "mma,paired-vector-memops")
+UNALIASED_CUSTOM_BUILTIN(mma_pmxvi4ger8, "vW512*VVi15i15i255", false,
+ "mma,paired-vector-memops")
+UNALIASED_CUSTOM_BUILTIN(mma_pmxvi8ger4, "vW512*VVi15i15i15", false,
+ "mma,paired-vector-memops")
+UNALIASED_CUSTOM_BUILTIN(mma_pmxvi16ger2, "vW512*VVi15i15i3", false,
+ "mma,paired-vector-memops")
+UNALIASED_CUSTOM_BUILTIN(mma_pmxvi16ger2s, "vW512*VVi15i15i3", false,
+ "mma,paired-vector-memops")
+UNALIASED_CUSTOM_BUILTIN(mma_pmxvf16ger2, "vW512*VVi15i15i3", false,
+ "mma,paired-vector-memops")
+UNALIASED_CUSTOM_BUILTIN(mma_pmxvf32ger, "vW512*VVi15i15", false,
+ "mma,paired-vector-memops")
+UNALIASED_CUSTOM_BUILTIN(mma_pmxvf64ger, "vW512*W256Vi15i3", false,
+ "mma,paired-vector-memops")
+UNALIASED_CUSTOM_BUILTIN(mma_xvi4ger8pp, "vW512*VV", true,
+ "mma,paired-vector-memops")
+UNALIASED_CUSTOM_BUILTIN(mma_xvi8ger4pp, "vW512*VV", true,
+ "mma,paired-vector-memops")
+UNALIASED_CUSTOM_BUILTIN(mma_xvi8ger4spp, "vW512*VV", true,
+ "mma,paired-vector-memops")
+UNALIASED_CUSTOM_BUILTIN(mma_xvi16ger2pp, "vW512*VV", true,
+ "mma,paired-vector-memops")
+UNALIASED_CUSTOM_BUILTIN(mma_xvi16ger2spp, "vW512*VV", true,
+ "mma,paired-vector-memops")
+UNALIASED_CUSTOM_BUILTIN(mma_pmxvi4ger8pp, "vW512*VVi15i15i255", true,
+ "mma,paired-vector-memops")
+UNALIASED_CUSTOM_BUILTIN(mma_pmxvi8ger4pp, "vW512*VVi15i15i15", true,
+ "mma,paired-vector-memops")
+UNALIASED_CUSTOM_BUILTIN(mma_pmxvi8ger4spp, "vW512*VVi15i15i15", true,
+ "mma,paired-vector-memops")
+UNALIASED_CUSTOM_BUILTIN(mma_pmxvi16ger2pp, "vW512*VVi15i15i3", true,
+ "mma,paired-vector-memops")
+UNALIASED_CUSTOM_BUILTIN(mma_pmxvi16ger2spp, "vW512*VVi15i15i3", true,
+ "mma,paired-vector-memops")
+UNALIASED_CUSTOM_BUILTIN(mma_xvf16ger2pp, "vW512*VV", true,
+ "mma,paired-vector-memops")
+UNALIASED_CUSTOM_BUILTIN(mma_xvf16ger2pn, "vW512*VV", true,
+ "mma,paired-vector-memops")
+UNALIASED_CUSTOM_BUILTIN(mma_xvf16ger2np, "vW512*VV", true,
+ "mma,paired-vector-memops")
+UNALIASED_CUSTOM_BUILTIN(mma_xvf16ger2nn, "vW512*VV", true,
+ "mma,paired-vector-memops")
+UNALIASED_CUSTOM_BUILTIN(mma_pmxvf16ger2pp, "vW512*VVi15i15i3", true,
+ "mma,paired-vector-memops")
+UNALIASED_CUSTOM_BUILTIN(mma_pmxvf16ger2pn, "vW512*VVi15i15i3", true,
+ "mma,paired-vector-memops")
+UNALIASED_CUSTOM_BUILTIN(mma_pmxvf16ger2np, "vW512*VVi15i15i3", true,
+ "mma,paired-vector-memops")
+UNALIASED_CUSTOM_BUILTIN(mma_pmxvf16ger2nn, "vW512*VVi15i15i3", true,
+ "mma,paired-vector-memops")
+UNALIASED_CUSTOM_BUILTIN(mma_xvf32gerpp, "vW512*VV", true,
+ "mma,paired-vector-memops")
+UNALIASED_CUSTOM_BUILTIN(mma_xvf32gerpn, "vW512*VV", true,
+ "mma,paired-vector-memops")
+UNALIASED_CUSTOM_BUILTIN(mma_xvf32gernp, "vW512*VV", true,
+ "mma,paired-vector-memops")
+UNALIASED_CUSTOM_BUILTIN(mma_xvf32gernn, "vW512*VV", true,
+ "mma,paired-vector-memops")
+UNALIASED_CUSTOM_BUILTIN(mma_pmxvf32gerpp, "vW512*VVi15i15", true,
+ "mma,paired-vector-memops")
+UNALIASED_CUSTOM_BUILTIN(mma_pmxvf32gerpn, "vW512*VVi15i15", true,
+ "mma,paired-vector-memops")
+UNALIASED_CUSTOM_BUILTIN(mma_pmxvf32gernp, "vW512*VVi15i15", true,
+ "mma,paired-vector-memops")
+UNALIASED_CUSTOM_BUILTIN(mma_pmxvf32gernn, "vW512*VVi15i15", true,
+ "mma,paired-vector-memops")
+UNALIASED_CUSTOM_BUILTIN(mma_xvf64gerpp, "vW512*W256V", true,
+ "mma,paired-vector-memops")
+UNALIASED_CUSTOM_BUILTIN(mma_xvf64gerpn, "vW512*W256V", true,
+ "mma,paired-vector-memops")
+UNALIASED_CUSTOM_BUILTIN(mma_xvf64gernp, "vW512*W256V", true,
+ "mma,paired-vector-memops")
+UNALIASED_CUSTOM_BUILTIN(mma_xvf64gernn, "vW512*W256V", true,
+ "mma,paired-vector-memops")
+UNALIASED_CUSTOM_BUILTIN(mma_pmxvf64gerpp, "vW512*W256Vi15i3", true,
+ "mma,paired-vector-memops")
+UNALIASED_CUSTOM_BUILTIN(mma_pmxvf64gerpn, "vW512*W256Vi15i3", true,
+ "mma,paired-vector-memops")
+UNALIASED_CUSTOM_BUILTIN(mma_pmxvf64gernp, "vW512*W256Vi15i3", true,
+ "mma,paired-vector-memops")
+UNALIASED_CUSTOM_BUILTIN(mma_pmxvf64gernn, "vW512*W256Vi15i3", true,
+ "mma,paired-vector-memops")
+UNALIASED_CUSTOM_BUILTIN(mma_xvbf16ger2, "vW512*VV", false,
+ "mma,paired-vector-memops")
+UNALIASED_CUSTOM_BUILTIN(mma_pmxvbf16ger2, "vW512*VVi15i15i3", false,
+ "mma,paired-vector-memops")
+UNALIASED_CUSTOM_BUILTIN(mma_xvbf16ger2pp, "vW512*VV", true,
+ "mma,paired-vector-memops")
+UNALIASED_CUSTOM_BUILTIN(mma_xvbf16ger2pn, "vW512*VV", true,
+ "mma,paired-vector-memops")
+UNALIASED_CUSTOM_BUILTIN(mma_xvbf16ger2np, "vW512*VV", true,
+ "mma,paired-vector-memops")
+UNALIASED_CUSTOM_BUILTIN(mma_xvbf16ger2nn, "vW512*VV", true,
+ "mma,paired-vector-memops")
+UNALIASED_CUSTOM_BUILTIN(mma_pmxvbf16ger2pp, "vW512*VVi15i15i3", true,
+ "mma,paired-vector-memops")
+UNALIASED_CUSTOM_BUILTIN(mma_pmxvbf16ger2pn, "vW512*VVi15i15i3", true,
+ "mma,paired-vector-memops")
+UNALIASED_CUSTOM_BUILTIN(mma_pmxvbf16ger2np, "vW512*VVi15i15i3", true,
+ "mma,paired-vector-memops")
+UNALIASED_CUSTOM_BUILTIN(mma_pmxvbf16ger2nn, "vW512*VVi15i15i3", true,
+ "mma,paired-vector-memops")
// FIXME: Obviously incomplete.
diff --git a/contrib/llvm-project/clang/include/clang/Basic/BuiltinsRISCV.def b/contrib/llvm-project/clang/include/clang/Basic/BuiltinsRISCV.def
index b2b4950f92bd..1528b18c82ea 100644
--- a/contrib/llvm-project/clang/include/clang/Basic/BuiltinsRISCV.def
+++ b/contrib/llvm-project/clang/include/clang/Basic/BuiltinsRISCV.def
@@ -15,49 +15,79 @@
# define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) BUILTIN(ID, TYPE, ATTRS)
#endif
-#include "clang/Basic/riscv_vector_builtins.inc"
-
// 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")
-
-// 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")
-
-// Zbe extension
-TARGET_BUILTIN(__builtin_riscv_bcompress_32, "ZiZiZi", "nc", "experimental-zbe")
-TARGET_BUILTIN(__builtin_riscv_bcompress_64, "WiWiWi", "nc",
- "experimental-zbe,64bit")
-TARGET_BUILTIN(__builtin_riscv_bdecompress_32, "ZiZiZi", "nc",
- "experimental-zbe")
-TARGET_BUILTIN(__builtin_riscv_bdecompress_64, "WiWiWi", "nc",
- "experimental-zbe,64bit")
-
-// Zbp extension
-TARGET_BUILTIN(__builtin_riscv_grev_32, "ZiZiZi", "nc", "experimental-zbp")
-TARGET_BUILTIN(__builtin_riscv_grev_64, "WiWiWi", "nc", "experimental-zbp,64bit")
-TARGET_BUILTIN(__builtin_riscv_gorc_32, "ZiZiZi", "nc", "experimental-zbp")
-TARGET_BUILTIN(__builtin_riscv_gorc_64, "WiWiWi", "nc", "experimental-zbp,64bit")
-TARGET_BUILTIN(__builtin_riscv_shfl_32, "ZiZiZi", "nc", "experimental-zbp")
-TARGET_BUILTIN(__builtin_riscv_shfl_64, "WiWiWi", "nc", "experimental-zbp,64bit")
-TARGET_BUILTIN(__builtin_riscv_unshfl_32, "ZiZiZi", "nc", "experimental-zbp")
-TARGET_BUILTIN(__builtin_riscv_unshfl_64, "WiWiWi", "nc", "experimental-zbp,64bit")
-TARGET_BUILTIN(__builtin_riscv_xperm_n, "LiLiLi", "nc", "experimental-zbp")
-TARGET_BUILTIN(__builtin_riscv_xperm_b, "LiLiLi", "nc", "experimental-zbp")
-TARGET_BUILTIN(__builtin_riscv_xperm_h, "LiLiLi", "nc", "experimental-zbp")
-TARGET_BUILTIN(__builtin_riscv_xperm_w, "WiWiWi", "nc", "experimental-zbp,64bit")
-
-// Zbr extension
-TARGET_BUILTIN(__builtin_riscv_crc32_b, "LiLi", "nc", "experimental-zbr")
-TARGET_BUILTIN(__builtin_riscv_crc32_h, "LiLi", "nc", "experimental-zbr")
-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_orc_b_32, "UiUi", "nc", "zbb")
+TARGET_BUILTIN(__builtin_riscv_orc_b_64, "UWiUWi", "nc", "zbb,64bit")
+TARGET_BUILTIN(__builtin_riscv_clz_32, "UiUi", "nc", "zbb|xtheadbb")
+TARGET_BUILTIN(__builtin_riscv_clz_64, "UiUWi", "nc", "zbb|xtheadbb,64bit")
+TARGET_BUILTIN(__builtin_riscv_ctz_32, "UiUi", "nc", "zbb")
+TARGET_BUILTIN(__builtin_riscv_ctz_64, "UiUWi", "nc", "zbb,64bit")
+
+// Zbc or Zbkc extension
+TARGET_BUILTIN(__builtin_riscv_clmul_32, "UiUiUi", "nc", "zbc|zbkc")
+TARGET_BUILTIN(__builtin_riscv_clmul_64, "UWiUWiUWi", "nc", "zbc|zbkc,64bit")
+TARGET_BUILTIN(__builtin_riscv_clmulh_32, "UiUiUi", "nc", "zbc|zbkc,32bit")
+TARGET_BUILTIN(__builtin_riscv_clmulh_64, "UWiUWiUWi", "nc", "zbc|zbkc,64bit")
+TARGET_BUILTIN(__builtin_riscv_clmulr_32, "UiUiUi", "nc", "zbc,32bit")
+TARGET_BUILTIN(__builtin_riscv_clmulr_64, "UWiUWiUWi", "nc", "zbc,64bit")
+
+// Zbkx
+TARGET_BUILTIN(__builtin_riscv_xperm4_32, "UiUiUi", "nc", "zbkx,32bit")
+TARGET_BUILTIN(__builtin_riscv_xperm4_64, "UWiUWiUWi", "nc", "zbkx,64bit")
+TARGET_BUILTIN(__builtin_riscv_xperm8_32, "UiUiUi", "nc", "zbkx,32bit")
+TARGET_BUILTIN(__builtin_riscv_xperm8_64, "UWiUWiUWi", "nc", "zbkx,64bit")
+
+// Zbkb extension
+TARGET_BUILTIN(__builtin_riscv_brev8_32, "UiUi", "nc", "zbkb")
+TARGET_BUILTIN(__builtin_riscv_brev8_64, "UWiUWi", "nc", "zbkb,64bit")
+TARGET_BUILTIN(__builtin_riscv_zip_32, "UiUi", "nc", "zbkb,32bit")
+TARGET_BUILTIN(__builtin_riscv_unzip_32, "UiUi", "nc", "zbkb,32bit")
+
+// Zknd extension
+TARGET_BUILTIN(__builtin_riscv_aes32dsi, "UiUiUiIUi", "nc", "zknd,32bit")
+TARGET_BUILTIN(__builtin_riscv_aes32dsmi, "UiUiUiIUi", "nc", "zknd,32bit")
+TARGET_BUILTIN(__builtin_riscv_aes64ds, "UWiUWiUWi", "nc", "zknd,64bit")
+TARGET_BUILTIN(__builtin_riscv_aes64dsm, "UWiUWiUWi", "nc", "zknd,64bit")
+TARGET_BUILTIN(__builtin_riscv_aes64im, "UWiUWi", "nc", "zknd,64bit")
+
+// Zknd & Zkne
+TARGET_BUILTIN(__builtin_riscv_aes64ks1i, "UWiUWiIUi", "nc", "zknd|zkne,64bit")
+TARGET_BUILTIN(__builtin_riscv_aes64ks2, "UWiUWiUWi", "nc", "zknd|zkne,64bit")
+
+// Zkne extension
+TARGET_BUILTIN(__builtin_riscv_aes32esi, "UiUiUiIUi", "nc", "zkne,32bit")
+TARGET_BUILTIN(__builtin_riscv_aes32esmi, "UiUiUiIUi", "nc", "zkne,32bit")
+TARGET_BUILTIN(__builtin_riscv_aes64es, "UWiUWiUWi", "nc", "zkne,64bit")
+TARGET_BUILTIN(__builtin_riscv_aes64esm, "UWiUWiUWi", "nc", "zkne,64bit")
+
+// Zknh extension
+TARGET_BUILTIN(__builtin_riscv_sha256sig0, "UiUi", "nc", "zknh")
+TARGET_BUILTIN(__builtin_riscv_sha256sig1, "UiUi", "nc", "zknh")
+TARGET_BUILTIN(__builtin_riscv_sha256sum0, "UiUi", "nc", "zknh")
+TARGET_BUILTIN(__builtin_riscv_sha256sum1, "UiUi", "nc", "zknh")
+
+TARGET_BUILTIN(__builtin_riscv_sha512sig0h, "UiUiUi", "nc", "zknh,32bit")
+TARGET_BUILTIN(__builtin_riscv_sha512sig0l, "UiUiUi", "nc", "zknh,32bit")
+TARGET_BUILTIN(__builtin_riscv_sha512sig1h, "UiUiUi", "nc", "zknh,32bit")
+TARGET_BUILTIN(__builtin_riscv_sha512sig1l, "UiUiUi", "nc", "zknh,32bit")
+TARGET_BUILTIN(__builtin_riscv_sha512sum0r, "UiUiUi", "nc", "zknh,32bit")
+TARGET_BUILTIN(__builtin_riscv_sha512sum1r, "UiUiUi", "nc", "zknh,32bit")
+TARGET_BUILTIN(__builtin_riscv_sha512sig0, "UWiUWi", "nc", "zknh,64bit")
+TARGET_BUILTIN(__builtin_riscv_sha512sig1, "UWiUWi", "nc", "zknh,64bit")
+TARGET_BUILTIN(__builtin_riscv_sha512sum0, "UWiUWi", "nc", "zknh,64bit")
+TARGET_BUILTIN(__builtin_riscv_sha512sum1, "UWiUWi", "nc", "zknh,64bit")
+
+// Zksed extension
+TARGET_BUILTIN(__builtin_riscv_sm4ed, "UiUiUiIUi", "nc", "zksed")
+TARGET_BUILTIN(__builtin_riscv_sm4ks, "UiUiUiIUi", "nc", "zksed")
+
+// Zksh extension
+TARGET_BUILTIN(__builtin_riscv_sm3p0, "UiUi", "nc", "zksh")
+TARGET_BUILTIN(__builtin_riscv_sm3p1, "UiUi", "nc", "zksh")
+
+// Zihintntl extension
+TARGET_BUILTIN(__builtin_riscv_ntl_load, "v.", "t", "zihintntl")
+TARGET_BUILTIN(__builtin_riscv_ntl_store, "v.", "t", "zihintntl")
#undef BUILTIN
#undef TARGET_BUILTIN
diff --git a/contrib/llvm-project/clang/include/clang/Basic/BuiltinsRISCVVector.def b/contrib/llvm-project/clang/include/clang/Basic/BuiltinsRISCVVector.def
new file mode 100644
index 000000000000..6dfa87a1a1d3
--- /dev/null
+++ b/contrib/llvm-project/clang/include/clang/Basic/BuiltinsRISCVVector.def
@@ -0,0 +1,22 @@
+//==- BuiltinsRISCVVector.def - RISC-V Vector Builtin Database ---*- 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 the RISC-V-specific builtin function database. Users of
+// this file must define the BUILTIN macro to make use of this information.
+//
+//===----------------------------------------------------------------------===//
+
+#if defined(BUILTIN) && !defined(TARGET_BUILTIN)
+# define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) BUILTIN(ID, TYPE, ATTRS)
+#endif
+
+#include "clang/Basic/riscv_vector_builtins.inc"
+#include "clang/Basic/riscv_sifive_vector_builtins.inc"
+
+#undef BUILTIN
+#undef TARGET_BUILTIN
diff --git a/contrib/llvm-project/clang/include/clang/Basic/BuiltinsSME.def b/contrib/llvm-project/clang/include/clang/Basic/BuiltinsSME.def
new file mode 100644
index 000000000000..180ee20295cc
--- /dev/null
+++ b/contrib/llvm-project/clang/include/clang/Basic/BuiltinsSME.def
@@ -0,0 +1,21 @@
+//===--- BuiltinsSME.def - SME Builtin function database --------*- 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 the SME-specific builtin function database. Users of
+// this file must define the BUILTIN macro to make use of this information.
+//
+//===----------------------------------------------------------------------===//
+
+// The format of this database matches clang/Basic/Builtins.def.
+
+#define GET_SME_BUILTINS
+#include "clang/Basic/arm_sme_builtins.inc"
+#undef GET_SME_BUILTINS
+
+#undef BUILTIN
+#undef TARGET_BUILTIN
diff --git a/contrib/llvm-project/clang/include/clang/Basic/BuiltinsSVE.def b/contrib/llvm-project/clang/include/clang/Basic/BuiltinsSVE.def
index 2839ca992d98..a83f1c8f82dd 100644
--- a/contrib/llvm-project/clang/include/clang/Basic/BuiltinsSVE.def
+++ b/contrib/llvm-project/clang/include/clang/Basic/BuiltinsSVE.def
@@ -15,6 +15,8 @@
#define GET_SVE_BUILTINS
#include "clang/Basic/arm_sve_builtins.inc"
+#include "clang/Basic/BuiltinsAArch64NeonSVEBridge.def"
#undef GET_SVE_BUILTINS
#undef BUILTIN
+#undef TARGET_BUILTIN
diff --git a/contrib/llvm-project/clang/include/clang/Basic/BuiltinsSystemZ.def b/contrib/llvm-project/clang/include/clang/Basic/BuiltinsSystemZ.def
index 079e41136488..f0c0ebfa622a 100644
--- a/contrib/llvm-project/clang/include/clang/Basic/BuiltinsSystemZ.def
+++ b/contrib/llvm-project/clang/include/clang/Basic/BuiltinsSystemZ.def
@@ -64,14 +64,14 @@ TARGET_BUILTIN(__builtin_s390_vupllh, "V4UiV8Us", "nc", "vector")
TARGET_BUILTIN(__builtin_s390_vupllf, "V2ULLiV4Ui", "nc", "vector")
// Vector integer instructions (chapter 22 of the PoP)
-TARGET_BUILTIN(__builtin_s390_vaq, "V16UcV16UcV16Uc", "nc", "vector")
-TARGET_BUILTIN(__builtin_s390_vacq, "V16UcV16UcV16UcV16Uc", "nc", "vector")
+TARGET_BUILTIN(__builtin_s390_vaq, "SLLLiSLLLiSLLLi", "nc", "vector")
+TARGET_BUILTIN(__builtin_s390_vacq, "ULLLiULLLiULLLiULLLi", "nc", "vector")
TARGET_BUILTIN(__builtin_s390_vaccb, "V16UcV16UcV16Uc", "nc", "vector")
TARGET_BUILTIN(__builtin_s390_vacch, "V8UsV8UsV8Us", "nc", "vector")
TARGET_BUILTIN(__builtin_s390_vaccf, "V4UiV4UiV4Ui", "nc", "vector")
TARGET_BUILTIN(__builtin_s390_vaccg, "V2ULLiV2ULLiV2ULLi", "nc", "vector")
-TARGET_BUILTIN(__builtin_s390_vaccq, "V16UcV16UcV16Uc", "nc", "vector")
-TARGET_BUILTIN(__builtin_s390_vacccq, "V16UcV16UcV16UcV16Uc", "nc", "vector")
+TARGET_BUILTIN(__builtin_s390_vaccq, "ULLLiULLLiULLLi", "nc", "vector")
+TARGET_BUILTIN(__builtin_s390_vacccq, "ULLLiULLLiULLLiULLLi", "nc", "vector")
TARGET_BUILTIN(__builtin_s390_vavgb, "V16ScV16ScV16Sc", "nc", "vector")
TARGET_BUILTIN(__builtin_s390_vavgh, "V8SsV8SsV8Ss", "nc", "vector")
TARGET_BUILTIN(__builtin_s390_vavgf, "V4SiV4SiV4Si", "nc", "vector")
@@ -80,10 +80,10 @@ TARGET_BUILTIN(__builtin_s390_vavglb, "V16UcV16UcV16Uc", "nc", "vector")
TARGET_BUILTIN(__builtin_s390_vavglh, "V8UsV8UsV8Us", "nc", "vector")
TARGET_BUILTIN(__builtin_s390_vavglf, "V4UiV4UiV4Ui", "nc", "vector")
TARGET_BUILTIN(__builtin_s390_vavglg, "V2ULLiV2ULLiV2ULLi", "nc", "vector")
-TARGET_BUILTIN(__builtin_s390_vceqbs, "V16ScV16ScV16Sci*", "nc", "vector")
-TARGET_BUILTIN(__builtin_s390_vceqhs, "V8SsV8SsV8Ssi*", "nc", "vector")
-TARGET_BUILTIN(__builtin_s390_vceqfs, "V4SiV4SiV4Sii*", "nc", "vector")
-TARGET_BUILTIN(__builtin_s390_vceqgs, "V2SLLiV2SLLiV2SLLii*", "nc", "vector")
+TARGET_BUILTIN(__builtin_s390_vceqbs, "V16ScV16UcV16Uci*", "nc", "vector")
+TARGET_BUILTIN(__builtin_s390_vceqhs, "V8SsV8UsV8Usi*", "nc", "vector")
+TARGET_BUILTIN(__builtin_s390_vceqfs, "V4SiV4UiV4Uii*", "nc", "vector")
+TARGET_BUILTIN(__builtin_s390_vceqgs, "V2SLLiV2ULLiV2ULLii*", "nc", "vector")
TARGET_BUILTIN(__builtin_s390_vchbs, "V16ScV16ScV16Sci*", "nc", "vector")
TARGET_BUILTIN(__builtin_s390_vchhs, "V8SsV8SsV8Ssi*", "nc", "vector")
TARGET_BUILTIN(__builtin_s390_vchfs, "V4SiV4SiV4Sii*", "nc", "vector")
@@ -105,10 +105,10 @@ TARGET_BUILTIN(__builtin_s390_verimb, "V16UcV16UcV16UcV16UcIi", "nc", "vector")
TARGET_BUILTIN(__builtin_s390_verimh, "V8UsV8UsV8UsV8UsIi", "nc", "vector")
TARGET_BUILTIN(__builtin_s390_verimf, "V4UiV4UiV4UiV4UiIi", "nc", "vector")
TARGET_BUILTIN(__builtin_s390_verimg, "V2ULLiV2ULLiV2ULLiV2ULLiIi", "nc", "vector")
-TARGET_BUILTIN(__builtin_s390_verllb, "V16UcV16UcUi", "nc", "vector")
-TARGET_BUILTIN(__builtin_s390_verllh, "V8UsV8UsUi", "nc", "vector")
-TARGET_BUILTIN(__builtin_s390_verllf, "V4UiV4UiUi", "nc", "vector")
-TARGET_BUILTIN(__builtin_s390_verllg, "V2ULLiV2ULLiUi", "nc", "vector")
+TARGET_BUILTIN(__builtin_s390_verllb, "V16UcV16UcUc", "nc", "vector")
+TARGET_BUILTIN(__builtin_s390_verllh, "V8UsV8UsUc", "nc", "vector")
+TARGET_BUILTIN(__builtin_s390_verllf, "V4UiV4UiUc", "nc", "vector")
+TARGET_BUILTIN(__builtin_s390_verllg, "V2ULLiV2ULLiUc", "nc", "vector")
TARGET_BUILTIN(__builtin_s390_verllvb, "V16UcV16UcV16Uc", "nc", "vector")
TARGET_BUILTIN(__builtin_s390_verllvh, "V8UsV8UsV8Us", "nc", "vector")
TARGET_BUILTIN(__builtin_s390_verllvf, "V4UiV4UiV4Ui", "nc", "vector")
@@ -116,11 +116,11 @@ TARGET_BUILTIN(__builtin_s390_verllvg, "V2ULLiV2ULLiV2ULLi", "nc", "vector")
TARGET_BUILTIN(__builtin_s390_vgfmb, "V8UsV16UcV16Uc", "nc", "vector")
TARGET_BUILTIN(__builtin_s390_vgfmh, "V4UiV8UsV8Us", "nc", "vector")
TARGET_BUILTIN(__builtin_s390_vgfmf, "V2ULLiV4UiV4Ui", "nc", "vector")
-TARGET_BUILTIN(__builtin_s390_vgfmg, "V16UcV2ULLiV2ULLi", "nc", "vector")
+TARGET_BUILTIN(__builtin_s390_vgfmg, "ULLLiV2ULLiV2ULLi", "nc", "vector")
TARGET_BUILTIN(__builtin_s390_vgfmab, "V8UsV16UcV16UcV8Us", "nc", "vector")
TARGET_BUILTIN(__builtin_s390_vgfmah, "V4UiV8UsV8UsV4Ui", "nc", "vector")
TARGET_BUILTIN(__builtin_s390_vgfmaf, "V2ULLiV4UiV4UiV2ULLi", "nc", "vector")
-TARGET_BUILTIN(__builtin_s390_vgfmag, "V16UcV2ULLiV2ULLiV16Uc", "nc", "vector")
+TARGET_BUILTIN(__builtin_s390_vgfmag, "ULLLiV2ULLiV2ULLiULLLi", "nc", "vector")
TARGET_BUILTIN(__builtin_s390_vmahb, "V16ScV16ScV16ScV16Sc", "nc", "vector")
TARGET_BUILTIN(__builtin_s390_vmahh, "V8SsV8SsV8SsV8Ss", "nc", "vector")
TARGET_BUILTIN(__builtin_s390_vmahf, "V4SiV4SiV4SiV4Si", "nc", "vector")
@@ -161,14 +161,14 @@ TARGET_BUILTIN(__builtin_s390_vpopctb, "V16UcV16Uc", "nc", "vector")
TARGET_BUILTIN(__builtin_s390_vpopcth, "V8UsV8Us", "nc", "vector")
TARGET_BUILTIN(__builtin_s390_vpopctf, "V4UiV4Ui", "nc", "vector")
TARGET_BUILTIN(__builtin_s390_vpopctg, "V2ULLiV2ULLi", "nc", "vector")
-TARGET_BUILTIN(__builtin_s390_vsq, "V16UcV16UcV16Uc", "nc", "vector")
-TARGET_BUILTIN(__builtin_s390_vsbcbiq, "V16UcV16UcV16UcV16Uc", "nc", "vector")
-TARGET_BUILTIN(__builtin_s390_vsbiq, "V16UcV16UcV16UcV16Uc", "nc", "vector")
+TARGET_BUILTIN(__builtin_s390_vsq, "SLLLiSLLLiSLLLi", "nc", "vector")
+TARGET_BUILTIN(__builtin_s390_vsbcbiq, "ULLLiULLLiULLLiULLLi", "nc", "vector")
+TARGET_BUILTIN(__builtin_s390_vsbiq, "ULLLiULLLiULLLiULLLi", "nc", "vector")
TARGET_BUILTIN(__builtin_s390_vscbib, "V16UcV16UcV16Uc", "nc", "vector")
TARGET_BUILTIN(__builtin_s390_vscbih, "V8UsV8UsV8Us", "nc", "vector")
TARGET_BUILTIN(__builtin_s390_vscbif, "V4UiV4UiV4Ui", "nc", "vector")
TARGET_BUILTIN(__builtin_s390_vscbig, "V2ULLiV2ULLiV2ULLi", "nc", "vector")
-TARGET_BUILTIN(__builtin_s390_vscbiq, "V16UcV16UcV16Uc", "nc", "vector")
+TARGET_BUILTIN(__builtin_s390_vscbiq, "ULLLiULLLiULLLi", "nc", "vector")
TARGET_BUILTIN(__builtin_s390_vsl, "V16UcV16UcV16Uc", "nc", "vector")
TARGET_BUILTIN(__builtin_s390_vslb, "V16UcV16UcV16Uc", "nc", "vector")
TARGET_BUILTIN(__builtin_s390_vsldb, "V16UcV16UcV16UcIi", "nc", "vector")
@@ -180,8 +180,8 @@ TARGET_BUILTIN(__builtin_s390_vsumb, "V4UiV16UcV16Uc", "nc", "vector")
TARGET_BUILTIN(__builtin_s390_vsumh, "V4UiV8UsV8Us", "nc", "vector")
TARGET_BUILTIN(__builtin_s390_vsumgh, "V2ULLiV8UsV8Us", "nc", "vector")
TARGET_BUILTIN(__builtin_s390_vsumgf, "V2ULLiV4UiV4Ui", "nc", "vector")
-TARGET_BUILTIN(__builtin_s390_vsumqf, "V16UcV4UiV4Ui", "nc", "vector")
-TARGET_BUILTIN(__builtin_s390_vsumqg, "V16UcV2ULLiV2ULLi", "nc", "vector")
+TARGET_BUILTIN(__builtin_s390_vsumqf, "ULLLiV4UiV4Ui", "nc", "vector")
+TARGET_BUILTIN(__builtin_s390_vsumqg, "ULLLiV2ULLiV2ULLi", "nc", "vector")
TARGET_BUILTIN(__builtin_s390_vtm, "iV16UcV16Uc", "nc", "vector")
// Vector string instructions (chapter 23 of the PoP)
@@ -253,10 +253,10 @@ TARGET_BUILTIN(__builtin_s390_vfsqdb, "V2dV2d", "nc", "vector")
TARGET_BUILTIN(__builtin_s390_vftcidb, "V2SLLiV2dIii*", "nc", "vector")
// Vector-enhancements facility 1 intrinsics.
-TARGET_BUILTIN(__builtin_s390_vlrl, "V16ScUivC*", "", "vector-enhancements-1")
-TARGET_BUILTIN(__builtin_s390_vstrl, "vV16ScUiv*", "", "vector-enhancements-1")
+TARGET_BUILTIN(__builtin_s390_vlrlr, "V16ScUivC*", "", "vector-enhancements-1")
+TARGET_BUILTIN(__builtin_s390_vstrlr, "vV16ScUiv*", "", "vector-enhancements-1")
TARGET_BUILTIN(__builtin_s390_vbperm, "V2ULLiV16UcV16Uc", "nc", "vector-enhancements-1")
-TARGET_BUILTIN(__builtin_s390_vmslg, "V16UcV2ULLiV2ULLiV16UcIi", "nc", "vector-enhancements-1")
+TARGET_BUILTIN(__builtin_s390_vmslg, "ULLLiV2ULLiV2ULLiULLLiIi", "nc", "vector-enhancements-1")
TARGET_BUILTIN(__builtin_s390_vfmaxdb, "V2dV2dV2dIi", "nc", "vector-enhancements-1")
TARGET_BUILTIN(__builtin_s390_vfmindb, "V2dV2dV2dIi", "nc", "vector-enhancements-1")
TARGET_BUILTIN(__builtin_s390_vfnmadb, "V2dV2dV2dV2d", "nc", "vector-enhancements-1")
diff --git a/contrib/llvm-project/clang/include/clang/Basic/BuiltinsVE.def b/contrib/llvm-project/clang/include/clang/Basic/BuiltinsVE.def
new file mode 100644
index 000000000000..23bfb0e03aa7
--- /dev/null
+++ b/contrib/llvm-project/clang/include/clang/Basic/BuiltinsVE.def
@@ -0,0 +1,32 @@
+//===--- BuiltinsVE.def - VE Builtin function database ----------*- 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 the VE-specific builtin function database. Users of
+// this file must define the BUILTIN macro to make use of this information.
+//
+//===----------------------------------------------------------------------===//
+
+#if defined(BUILTIN) && !defined(TARGET_BUILTIN)
+# define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) BUILTIN(ID, TYPE, ATTRS)
+#endif
+
+// The format of this database is described in clang/Basic/Builtins.def.
+
+BUILTIN(__builtin_ve_vl_pack_f32p, "ULifC*fC*", "n")
+BUILTIN(__builtin_ve_vl_pack_f32a, "ULifC*", "n")
+
+BUILTIN(__builtin_ve_vl_extract_vm512u, "V256bV512b", "n")
+BUILTIN(__builtin_ve_vl_extract_vm512l, "V256bV512b", "n")
+BUILTIN(__builtin_ve_vl_insert_vm512u, "V512bV512bV256b", "n")
+BUILTIN(__builtin_ve_vl_insert_vm512l, "V512bV512bV256b", "n")
+
+// Use generated BUILTIN definitions
+#include "clang/Basic/BuiltinsVEVL.gen.def"
+
+#undef BUILTIN
+#undef TARGET_BUILTIN
diff --git a/contrib/llvm-project/clang/include/clang/Basic/BuiltinsVEVL.gen.def b/contrib/llvm-project/clang/include/clang/Basic/BuiltinsVEVL.gen.def
new file mode 100644
index 000000000000..7b06e5c30e93
--- /dev/null
+++ b/contrib/llvm-project/clang/include/clang/Basic/BuiltinsVEVL.gen.def
@@ -0,0 +1,1257 @@
+BUILTIN(__builtin_ve_vl_vld_vssl, "V256dLUivC*Ui", "n")
+BUILTIN(__builtin_ve_vl_vld_vssvl, "V256dLUivC*V256dUi", "n")
+BUILTIN(__builtin_ve_vl_vldnc_vssl, "V256dLUivC*Ui", "n")
+BUILTIN(__builtin_ve_vl_vldnc_vssvl, "V256dLUivC*V256dUi", "n")
+BUILTIN(__builtin_ve_vl_vldu_vssl, "V256dLUivC*Ui", "n")
+BUILTIN(__builtin_ve_vl_vldu_vssvl, "V256dLUivC*V256dUi", "n")
+BUILTIN(__builtin_ve_vl_vldunc_vssl, "V256dLUivC*Ui", "n")
+BUILTIN(__builtin_ve_vl_vldunc_vssvl, "V256dLUivC*V256dUi", "n")
+BUILTIN(__builtin_ve_vl_vldlsx_vssl, "V256dLUivC*Ui", "n")
+BUILTIN(__builtin_ve_vl_vldlsx_vssvl, "V256dLUivC*V256dUi", "n")
+BUILTIN(__builtin_ve_vl_vldlsxnc_vssl, "V256dLUivC*Ui", "n")
+BUILTIN(__builtin_ve_vl_vldlsxnc_vssvl, "V256dLUivC*V256dUi", "n")
+BUILTIN(__builtin_ve_vl_vldlzx_vssl, "V256dLUivC*Ui", "n")
+BUILTIN(__builtin_ve_vl_vldlzx_vssvl, "V256dLUivC*V256dUi", "n")
+BUILTIN(__builtin_ve_vl_vldlzxnc_vssl, "V256dLUivC*Ui", "n")
+BUILTIN(__builtin_ve_vl_vldlzxnc_vssvl, "V256dLUivC*V256dUi", "n")
+BUILTIN(__builtin_ve_vl_vld2d_vssl, "V256dLUivC*Ui", "n")
+BUILTIN(__builtin_ve_vl_vld2d_vssvl, "V256dLUivC*V256dUi", "n")
+BUILTIN(__builtin_ve_vl_vld2dnc_vssl, "V256dLUivC*Ui", "n")
+BUILTIN(__builtin_ve_vl_vld2dnc_vssvl, "V256dLUivC*V256dUi", "n")
+BUILTIN(__builtin_ve_vl_vldu2d_vssl, "V256dLUivC*Ui", "n")
+BUILTIN(__builtin_ve_vl_vldu2d_vssvl, "V256dLUivC*V256dUi", "n")
+BUILTIN(__builtin_ve_vl_vldu2dnc_vssl, "V256dLUivC*Ui", "n")
+BUILTIN(__builtin_ve_vl_vldu2dnc_vssvl, "V256dLUivC*V256dUi", "n")
+BUILTIN(__builtin_ve_vl_vldl2dsx_vssl, "V256dLUivC*Ui", "n")
+BUILTIN(__builtin_ve_vl_vldl2dsx_vssvl, "V256dLUivC*V256dUi", "n")
+BUILTIN(__builtin_ve_vl_vldl2dsxnc_vssl, "V256dLUivC*Ui", "n")
+BUILTIN(__builtin_ve_vl_vldl2dsxnc_vssvl, "V256dLUivC*V256dUi", "n")
+BUILTIN(__builtin_ve_vl_vldl2dzx_vssl, "V256dLUivC*Ui", "n")
+BUILTIN(__builtin_ve_vl_vldl2dzx_vssvl, "V256dLUivC*V256dUi", "n")
+BUILTIN(__builtin_ve_vl_vldl2dzxnc_vssl, "V256dLUivC*Ui", "n")
+BUILTIN(__builtin_ve_vl_vldl2dzxnc_vssvl, "V256dLUivC*V256dUi", "n")
+BUILTIN(__builtin_ve_vl_vst_vssl, "vV256dLUiv*Ui", "n")
+BUILTIN(__builtin_ve_vl_vst_vssml, "vV256dLUiv*V256bUi", "n")
+BUILTIN(__builtin_ve_vl_vstnc_vssl, "vV256dLUiv*Ui", "n")
+BUILTIN(__builtin_ve_vl_vstnc_vssml, "vV256dLUiv*V256bUi", "n")
+BUILTIN(__builtin_ve_vl_vstot_vssl, "vV256dLUiv*Ui", "n")
+BUILTIN(__builtin_ve_vl_vstot_vssml, "vV256dLUiv*V256bUi", "n")
+BUILTIN(__builtin_ve_vl_vstncot_vssl, "vV256dLUiv*Ui", "n")
+BUILTIN(__builtin_ve_vl_vstncot_vssml, "vV256dLUiv*V256bUi", "n")
+BUILTIN(__builtin_ve_vl_vstu_vssl, "vV256dLUiv*Ui", "n")
+BUILTIN(__builtin_ve_vl_vstu_vssml, "vV256dLUiv*V256bUi", "n")
+BUILTIN(__builtin_ve_vl_vstunc_vssl, "vV256dLUiv*Ui", "n")
+BUILTIN(__builtin_ve_vl_vstunc_vssml, "vV256dLUiv*V256bUi", "n")
+BUILTIN(__builtin_ve_vl_vstuot_vssl, "vV256dLUiv*Ui", "n")
+BUILTIN(__builtin_ve_vl_vstuot_vssml, "vV256dLUiv*V256bUi", "n")
+BUILTIN(__builtin_ve_vl_vstuncot_vssl, "vV256dLUiv*Ui", "n")
+BUILTIN(__builtin_ve_vl_vstuncot_vssml, "vV256dLUiv*V256bUi", "n")
+BUILTIN(__builtin_ve_vl_vstl_vssl, "vV256dLUiv*Ui", "n")
+BUILTIN(__builtin_ve_vl_vstl_vssml, "vV256dLUiv*V256bUi", "n")
+BUILTIN(__builtin_ve_vl_vstlnc_vssl, "vV256dLUiv*Ui", "n")
+BUILTIN(__builtin_ve_vl_vstlnc_vssml, "vV256dLUiv*V256bUi", "n")
+BUILTIN(__builtin_ve_vl_vstlot_vssl, "vV256dLUiv*Ui", "n")
+BUILTIN(__builtin_ve_vl_vstlot_vssml, "vV256dLUiv*V256bUi", "n")
+BUILTIN(__builtin_ve_vl_vstlncot_vssl, "vV256dLUiv*Ui", "n")
+BUILTIN(__builtin_ve_vl_vstlncot_vssml, "vV256dLUiv*V256bUi", "n")
+BUILTIN(__builtin_ve_vl_vst2d_vssl, "vV256dLUiv*Ui", "n")
+BUILTIN(__builtin_ve_vl_vst2d_vssml, "vV256dLUiv*V256bUi", "n")
+BUILTIN(__builtin_ve_vl_vst2dnc_vssl, "vV256dLUiv*Ui", "n")
+BUILTIN(__builtin_ve_vl_vst2dnc_vssml, "vV256dLUiv*V256bUi", "n")
+BUILTIN(__builtin_ve_vl_vst2dot_vssl, "vV256dLUiv*Ui", "n")
+BUILTIN(__builtin_ve_vl_vst2dot_vssml, "vV256dLUiv*V256bUi", "n")
+BUILTIN(__builtin_ve_vl_vst2dncot_vssl, "vV256dLUiv*Ui", "n")
+BUILTIN(__builtin_ve_vl_vst2dncot_vssml, "vV256dLUiv*V256bUi", "n")
+BUILTIN(__builtin_ve_vl_vstu2d_vssl, "vV256dLUiv*Ui", "n")
+BUILTIN(__builtin_ve_vl_vstu2d_vssml, "vV256dLUiv*V256bUi", "n")
+BUILTIN(__builtin_ve_vl_vstu2dnc_vssl, "vV256dLUiv*Ui", "n")
+BUILTIN(__builtin_ve_vl_vstu2dnc_vssml, "vV256dLUiv*V256bUi", "n")
+BUILTIN(__builtin_ve_vl_vstu2dot_vssl, "vV256dLUiv*Ui", "n")
+BUILTIN(__builtin_ve_vl_vstu2dot_vssml, "vV256dLUiv*V256bUi", "n")
+BUILTIN(__builtin_ve_vl_vstu2dncot_vssl, "vV256dLUiv*Ui", "n")
+BUILTIN(__builtin_ve_vl_vstu2dncot_vssml, "vV256dLUiv*V256bUi", "n")
+BUILTIN(__builtin_ve_vl_vstl2d_vssl, "vV256dLUiv*Ui", "n")
+BUILTIN(__builtin_ve_vl_vstl2d_vssml, "vV256dLUiv*V256bUi", "n")
+BUILTIN(__builtin_ve_vl_vstl2dnc_vssl, "vV256dLUiv*Ui", "n")
+BUILTIN(__builtin_ve_vl_vstl2dnc_vssml, "vV256dLUiv*V256bUi", "n")
+BUILTIN(__builtin_ve_vl_vstl2dot_vssl, "vV256dLUiv*Ui", "n")
+BUILTIN(__builtin_ve_vl_vstl2dot_vssml, "vV256dLUiv*V256bUi", "n")
+BUILTIN(__builtin_ve_vl_vstl2dncot_vssl, "vV256dLUiv*Ui", "n")
+BUILTIN(__builtin_ve_vl_vstl2dncot_vssml, "vV256dLUiv*V256bUi", "n")
+BUILTIN(__builtin_ve_vl_pfchv_ssl, "vLivC*Ui", "n")
+BUILTIN(__builtin_ve_vl_pfchvnc_ssl, "vLivC*Ui", "n")
+BUILTIN(__builtin_ve_vl_lsv_vvss, "V256dV256dUiLUi", "n")
+BUILTIN(__builtin_ve_vl_lvsl_svs, "LUiV256dUi", "n")
+BUILTIN(__builtin_ve_vl_lvsd_svs, "dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_lvss_svs, "fV256dUi", "n")
+BUILTIN(__builtin_ve_vl_lvm_mmss, "V256bV256bLUiLUi", "n")
+BUILTIN(__builtin_ve_vl_lvm_MMss, "V512bV512bLUiLUi", "n")
+BUILTIN(__builtin_ve_vl_svm_sms, "LUiV256bLUi", "n")
+BUILTIN(__builtin_ve_vl_svm_sMs, "LUiV512bLUi", "n")
+BUILTIN(__builtin_ve_vl_vbrdd_vsl, "V256ddUi", "n")
+BUILTIN(__builtin_ve_vl_vbrdd_vsvl, "V256ddV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vbrdd_vsmvl, "V256ddV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vbrdl_vsl, "V256dLiUi", "n")
+BUILTIN(__builtin_ve_vl_vbrdl_vsvl, "V256dLiV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vbrdl_vsmvl, "V256dLiV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vbrds_vsl, "V256dfUi", "n")
+BUILTIN(__builtin_ve_vl_vbrds_vsvl, "V256dfV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vbrds_vsmvl, "V256dfV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vbrdw_vsl, "V256diUi", "n")
+BUILTIN(__builtin_ve_vl_vbrdw_vsvl, "V256diV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vbrdw_vsmvl, "V256diV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvbrd_vsl, "V256dLUiUi", "n")
+BUILTIN(__builtin_ve_vl_pvbrd_vsvl, "V256dLUiV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvbrd_vsMvl, "V256dLUiV512bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vmv_vsvl, "V256dUiV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vmv_vsvvl, "V256dUiV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vmv_vsvmvl, "V256dUiV256dV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vaddul_vvvl, "V256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vaddul_vvvvl, "V256dV256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vaddul_vsvl, "V256dLUiV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vaddul_vsvvl, "V256dLUiV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vaddul_vvvmvl, "V256dV256dV256dV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vaddul_vsvmvl, "V256dLUiV256dV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vadduw_vvvl, "V256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vadduw_vvvvl, "V256dV256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vadduw_vsvl, "V256dUiV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vadduw_vsvvl, "V256dUiV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vadduw_vvvmvl, "V256dV256dV256dV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vadduw_vsvmvl, "V256dUiV256dV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvaddu_vvvl, "V256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvaddu_vvvvl, "V256dV256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvaddu_vsvl, "V256dLUiV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvaddu_vsvvl, "V256dLUiV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvaddu_vvvMvl, "V256dV256dV256dV512bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvaddu_vsvMvl, "V256dLUiV256dV512bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vaddswsx_vvvl, "V256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vaddswsx_vvvvl, "V256dV256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vaddswsx_vsvl, "V256diV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vaddswsx_vsvvl, "V256diV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vaddswsx_vvvmvl, "V256dV256dV256dV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vaddswsx_vsvmvl, "V256diV256dV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vaddswzx_vvvl, "V256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vaddswzx_vvvvl, "V256dV256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vaddswzx_vsvl, "V256diV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vaddswzx_vsvvl, "V256diV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vaddswzx_vvvmvl, "V256dV256dV256dV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vaddswzx_vsvmvl, "V256diV256dV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvadds_vvvl, "V256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvadds_vvvvl, "V256dV256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvadds_vsvl, "V256dLUiV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvadds_vsvvl, "V256dLUiV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvadds_vvvMvl, "V256dV256dV256dV512bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvadds_vsvMvl, "V256dLUiV256dV512bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vaddsl_vvvl, "V256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vaddsl_vvvvl, "V256dV256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vaddsl_vsvl, "V256dLiV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vaddsl_vsvvl, "V256dLiV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vaddsl_vvvmvl, "V256dV256dV256dV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vaddsl_vsvmvl, "V256dLiV256dV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vsubul_vvvl, "V256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vsubul_vvvvl, "V256dV256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vsubul_vsvl, "V256dLUiV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vsubul_vsvvl, "V256dLUiV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vsubul_vvvmvl, "V256dV256dV256dV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vsubul_vsvmvl, "V256dLUiV256dV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vsubuw_vvvl, "V256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vsubuw_vvvvl, "V256dV256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vsubuw_vsvl, "V256dUiV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vsubuw_vsvvl, "V256dUiV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vsubuw_vvvmvl, "V256dV256dV256dV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vsubuw_vsvmvl, "V256dUiV256dV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvsubu_vvvl, "V256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvsubu_vvvvl, "V256dV256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvsubu_vsvl, "V256dLUiV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvsubu_vsvvl, "V256dLUiV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvsubu_vvvMvl, "V256dV256dV256dV512bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvsubu_vsvMvl, "V256dLUiV256dV512bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vsubswsx_vvvl, "V256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vsubswsx_vvvvl, "V256dV256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vsubswsx_vsvl, "V256diV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vsubswsx_vsvvl, "V256diV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vsubswsx_vvvmvl, "V256dV256dV256dV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vsubswsx_vsvmvl, "V256diV256dV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vsubswzx_vvvl, "V256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vsubswzx_vvvvl, "V256dV256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vsubswzx_vsvl, "V256diV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vsubswzx_vsvvl, "V256diV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vsubswzx_vvvmvl, "V256dV256dV256dV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vsubswzx_vsvmvl, "V256diV256dV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvsubs_vvvl, "V256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvsubs_vvvvl, "V256dV256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvsubs_vsvl, "V256dLUiV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvsubs_vsvvl, "V256dLUiV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvsubs_vvvMvl, "V256dV256dV256dV512bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvsubs_vsvMvl, "V256dLUiV256dV512bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vsubsl_vvvl, "V256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vsubsl_vvvvl, "V256dV256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vsubsl_vsvl, "V256dLiV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vsubsl_vsvvl, "V256dLiV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vsubsl_vvvmvl, "V256dV256dV256dV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vsubsl_vsvmvl, "V256dLiV256dV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vmulul_vvvl, "V256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vmulul_vvvvl, "V256dV256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vmulul_vsvl, "V256dLUiV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vmulul_vsvvl, "V256dLUiV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vmulul_vvvmvl, "V256dV256dV256dV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vmulul_vsvmvl, "V256dLUiV256dV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vmuluw_vvvl, "V256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vmuluw_vvvvl, "V256dV256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vmuluw_vsvl, "V256dUiV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vmuluw_vsvvl, "V256dUiV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vmuluw_vvvmvl, "V256dV256dV256dV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vmuluw_vsvmvl, "V256dUiV256dV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vmulswsx_vvvl, "V256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vmulswsx_vvvvl, "V256dV256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vmulswsx_vsvl, "V256diV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vmulswsx_vsvvl, "V256diV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vmulswsx_vvvmvl, "V256dV256dV256dV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vmulswsx_vsvmvl, "V256diV256dV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vmulswzx_vvvl, "V256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vmulswzx_vvvvl, "V256dV256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vmulswzx_vsvl, "V256diV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vmulswzx_vsvvl, "V256diV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vmulswzx_vvvmvl, "V256dV256dV256dV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vmulswzx_vsvmvl, "V256diV256dV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vmulsl_vvvl, "V256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vmulsl_vvvvl, "V256dV256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vmulsl_vsvl, "V256dLiV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vmulsl_vsvvl, "V256dLiV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vmulsl_vvvmvl, "V256dV256dV256dV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vmulsl_vsvmvl, "V256dLiV256dV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vmulslw_vvvl, "V256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vmulslw_vvvvl, "V256dV256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vmulslw_vsvl, "V256diV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vmulslw_vsvvl, "V256diV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vdivul_vvvl, "V256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vdivul_vvvvl, "V256dV256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vdivul_vsvl, "V256dLUiV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vdivul_vsvvl, "V256dLUiV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vdivul_vvvmvl, "V256dV256dV256dV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vdivul_vsvmvl, "V256dLUiV256dV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vdivuw_vvvl, "V256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vdivuw_vvvvl, "V256dV256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vdivuw_vsvl, "V256dUiV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vdivuw_vsvvl, "V256dUiV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vdivuw_vvvmvl, "V256dV256dV256dV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vdivuw_vsvmvl, "V256dUiV256dV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vdivul_vvsl, "V256dV256dLUiUi", "n")
+BUILTIN(__builtin_ve_vl_vdivul_vvsvl, "V256dV256dLUiV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vdivul_vvsmvl, "V256dV256dLUiV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vdivuw_vvsl, "V256dV256dUiUi", "n")
+BUILTIN(__builtin_ve_vl_vdivuw_vvsvl, "V256dV256dUiV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vdivuw_vvsmvl, "V256dV256dUiV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vdivswsx_vvvl, "V256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vdivswsx_vvvvl, "V256dV256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vdivswsx_vsvl, "V256diV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vdivswsx_vsvvl, "V256diV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vdivswsx_vvvmvl, "V256dV256dV256dV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vdivswsx_vsvmvl, "V256diV256dV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vdivswzx_vvvl, "V256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vdivswzx_vvvvl, "V256dV256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vdivswzx_vsvl, "V256diV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vdivswzx_vsvvl, "V256diV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vdivswzx_vvvmvl, "V256dV256dV256dV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vdivswzx_vsvmvl, "V256diV256dV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vdivswsx_vvsl, "V256dV256diUi", "n")
+BUILTIN(__builtin_ve_vl_vdivswsx_vvsvl, "V256dV256diV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vdivswsx_vvsmvl, "V256dV256diV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vdivswzx_vvsl, "V256dV256diUi", "n")
+BUILTIN(__builtin_ve_vl_vdivswzx_vvsvl, "V256dV256diV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vdivswzx_vvsmvl, "V256dV256diV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vdivsl_vvvl, "V256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vdivsl_vvvvl, "V256dV256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vdivsl_vsvl, "V256dLiV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vdivsl_vsvvl, "V256dLiV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vdivsl_vvvmvl, "V256dV256dV256dV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vdivsl_vsvmvl, "V256dLiV256dV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vdivsl_vvsl, "V256dV256dLiUi", "n")
+BUILTIN(__builtin_ve_vl_vdivsl_vvsvl, "V256dV256dLiV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vdivsl_vvsmvl, "V256dV256dLiV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vcmpul_vvvl, "V256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vcmpul_vvvvl, "V256dV256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vcmpul_vsvl, "V256dLUiV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vcmpul_vsvvl, "V256dLUiV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vcmpul_vvvmvl, "V256dV256dV256dV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vcmpul_vsvmvl, "V256dLUiV256dV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vcmpuw_vvvl, "V256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vcmpuw_vvvvl, "V256dV256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vcmpuw_vsvl, "V256dUiV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vcmpuw_vsvvl, "V256dUiV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vcmpuw_vvvmvl, "V256dV256dV256dV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vcmpuw_vsvmvl, "V256dUiV256dV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvcmpu_vvvl, "V256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvcmpu_vvvvl, "V256dV256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvcmpu_vsvl, "V256dLUiV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvcmpu_vsvvl, "V256dLUiV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvcmpu_vvvMvl, "V256dV256dV256dV512bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvcmpu_vsvMvl, "V256dLUiV256dV512bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vcmpswsx_vvvl, "V256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vcmpswsx_vvvvl, "V256dV256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vcmpswsx_vsvl, "V256diV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vcmpswsx_vsvvl, "V256diV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vcmpswsx_vvvmvl, "V256dV256dV256dV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vcmpswsx_vsvmvl, "V256diV256dV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vcmpswzx_vvvl, "V256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vcmpswzx_vvvvl, "V256dV256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vcmpswzx_vsvl, "V256diV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vcmpswzx_vsvvl, "V256diV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vcmpswzx_vvvmvl, "V256dV256dV256dV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vcmpswzx_vsvmvl, "V256diV256dV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvcmps_vvvl, "V256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvcmps_vvvvl, "V256dV256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvcmps_vsvl, "V256dLUiV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvcmps_vsvvl, "V256dLUiV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvcmps_vvvMvl, "V256dV256dV256dV512bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvcmps_vsvMvl, "V256dLUiV256dV512bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vcmpsl_vvvl, "V256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vcmpsl_vvvvl, "V256dV256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vcmpsl_vsvl, "V256dLiV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vcmpsl_vsvvl, "V256dLiV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vcmpsl_vvvmvl, "V256dV256dV256dV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vcmpsl_vsvmvl, "V256dLiV256dV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vmaxswsx_vvvl, "V256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vmaxswsx_vvvvl, "V256dV256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vmaxswsx_vsvl, "V256diV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vmaxswsx_vsvvl, "V256diV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vmaxswsx_vvvmvl, "V256dV256dV256dV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vmaxswsx_vsvmvl, "V256diV256dV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vmaxswzx_vvvl, "V256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vmaxswzx_vvvvl, "V256dV256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vmaxswzx_vsvl, "V256diV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vmaxswzx_vsvvl, "V256diV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vmaxswzx_vvvmvl, "V256dV256dV256dV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vmaxswzx_vsvmvl, "V256diV256dV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvmaxs_vvvl, "V256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvmaxs_vvvvl, "V256dV256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvmaxs_vsvl, "V256dLUiV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvmaxs_vsvvl, "V256dLUiV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvmaxs_vvvMvl, "V256dV256dV256dV512bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvmaxs_vsvMvl, "V256dLUiV256dV512bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vminswsx_vvvl, "V256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vminswsx_vvvvl, "V256dV256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vminswsx_vsvl, "V256diV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vminswsx_vsvvl, "V256diV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vminswsx_vvvmvl, "V256dV256dV256dV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vminswsx_vsvmvl, "V256diV256dV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vminswzx_vvvl, "V256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vminswzx_vvvvl, "V256dV256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vminswzx_vsvl, "V256diV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vminswzx_vsvvl, "V256diV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vminswzx_vvvmvl, "V256dV256dV256dV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vminswzx_vsvmvl, "V256diV256dV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvmins_vvvl, "V256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvmins_vvvvl, "V256dV256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvmins_vsvl, "V256dLUiV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvmins_vsvvl, "V256dLUiV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvmins_vvvMvl, "V256dV256dV256dV512bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvmins_vsvMvl, "V256dLUiV256dV512bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vmaxsl_vvvl, "V256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vmaxsl_vvvvl, "V256dV256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vmaxsl_vsvl, "V256dLiV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vmaxsl_vsvvl, "V256dLiV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vmaxsl_vvvmvl, "V256dV256dV256dV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vmaxsl_vsvmvl, "V256dLiV256dV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vminsl_vvvl, "V256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vminsl_vvvvl, "V256dV256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vminsl_vsvl, "V256dLiV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vminsl_vsvvl, "V256dLiV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vminsl_vvvmvl, "V256dV256dV256dV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vminsl_vsvmvl, "V256dLiV256dV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vand_vvvl, "V256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vand_vvvvl, "V256dV256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vand_vsvl, "V256dLUiV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vand_vsvvl, "V256dLUiV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vand_vvvmvl, "V256dV256dV256dV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vand_vsvmvl, "V256dLUiV256dV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvand_vvvl, "V256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvand_vvvvl, "V256dV256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvand_vsvl, "V256dLUiV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvand_vsvvl, "V256dLUiV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvand_vvvMvl, "V256dV256dV256dV512bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvand_vsvMvl, "V256dLUiV256dV512bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vor_vvvl, "V256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vor_vvvvl, "V256dV256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vor_vsvl, "V256dLUiV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vor_vsvvl, "V256dLUiV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vor_vvvmvl, "V256dV256dV256dV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vor_vsvmvl, "V256dLUiV256dV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvor_vvvl, "V256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvor_vvvvl, "V256dV256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvor_vsvl, "V256dLUiV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvor_vsvvl, "V256dLUiV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvor_vvvMvl, "V256dV256dV256dV512bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvor_vsvMvl, "V256dLUiV256dV512bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vxor_vvvl, "V256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vxor_vvvvl, "V256dV256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vxor_vsvl, "V256dLUiV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vxor_vsvvl, "V256dLUiV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vxor_vvvmvl, "V256dV256dV256dV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vxor_vsvmvl, "V256dLUiV256dV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvxor_vvvl, "V256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvxor_vvvvl, "V256dV256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvxor_vsvl, "V256dLUiV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvxor_vsvvl, "V256dLUiV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvxor_vvvMvl, "V256dV256dV256dV512bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvxor_vsvMvl, "V256dLUiV256dV512bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_veqv_vvvl, "V256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_veqv_vvvvl, "V256dV256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_veqv_vsvl, "V256dLUiV256dUi", "n")
+BUILTIN(__builtin_ve_vl_veqv_vsvvl, "V256dLUiV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_veqv_vvvmvl, "V256dV256dV256dV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_veqv_vsvmvl, "V256dLUiV256dV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pveqv_vvvl, "V256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pveqv_vvvvl, "V256dV256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pveqv_vsvl, "V256dLUiV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pveqv_vsvvl, "V256dLUiV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pveqv_vvvMvl, "V256dV256dV256dV512bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pveqv_vsvMvl, "V256dLUiV256dV512bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vldz_vvl, "V256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vldz_vvvl, "V256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vldz_vvmvl, "V256dV256dV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvldzlo_vvl, "V256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvldzlo_vvvl, "V256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvldzlo_vvmvl, "V256dV256dV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvldzup_vvl, "V256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvldzup_vvvl, "V256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvldzup_vvmvl, "V256dV256dV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvldz_vvl, "V256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvldz_vvvl, "V256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvldz_vvMvl, "V256dV256dV512bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vpcnt_vvl, "V256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vpcnt_vvvl, "V256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vpcnt_vvmvl, "V256dV256dV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvpcntlo_vvl, "V256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvpcntlo_vvvl, "V256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvpcntlo_vvmvl, "V256dV256dV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvpcntup_vvl, "V256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvpcntup_vvvl, "V256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvpcntup_vvmvl, "V256dV256dV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvpcnt_vvl, "V256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvpcnt_vvvl, "V256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvpcnt_vvMvl, "V256dV256dV512bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vbrv_vvl, "V256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vbrv_vvvl, "V256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vbrv_vvmvl, "V256dV256dV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvbrvlo_vvl, "V256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvbrvlo_vvvl, "V256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvbrvlo_vvmvl, "V256dV256dV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvbrvup_vvl, "V256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvbrvup_vvvl, "V256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvbrvup_vvmvl, "V256dV256dV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvbrv_vvl, "V256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvbrv_vvvl, "V256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvbrv_vvMvl, "V256dV256dV512bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vseq_vl, "V256dUi", "n")
+BUILTIN(__builtin_ve_vl_vseq_vvl, "V256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvseqlo_vl, "V256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvseqlo_vvl, "V256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvsequp_vl, "V256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvsequp_vvl, "V256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvseq_vl, "V256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvseq_vvl, "V256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vsll_vvvl, "V256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vsll_vvvvl, "V256dV256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vsll_vvsl, "V256dV256dLUiUi", "n")
+BUILTIN(__builtin_ve_vl_vsll_vvsvl, "V256dV256dLUiV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vsll_vvvmvl, "V256dV256dV256dV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vsll_vvsmvl, "V256dV256dLUiV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvsll_vvvl, "V256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvsll_vvvvl, "V256dV256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvsll_vvsl, "V256dV256dLUiUi", "n")
+BUILTIN(__builtin_ve_vl_pvsll_vvsvl, "V256dV256dLUiV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvsll_vvvMvl, "V256dV256dV256dV512bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvsll_vvsMvl, "V256dV256dLUiV512bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vsrl_vvvl, "V256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vsrl_vvvvl, "V256dV256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vsrl_vvsl, "V256dV256dLUiUi", "n")
+BUILTIN(__builtin_ve_vl_vsrl_vvsvl, "V256dV256dLUiV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vsrl_vvvmvl, "V256dV256dV256dV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vsrl_vvsmvl, "V256dV256dLUiV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvsrl_vvvl, "V256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvsrl_vvvvl, "V256dV256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvsrl_vvsl, "V256dV256dLUiUi", "n")
+BUILTIN(__builtin_ve_vl_pvsrl_vvsvl, "V256dV256dLUiV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvsrl_vvvMvl, "V256dV256dV256dV512bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvsrl_vvsMvl, "V256dV256dLUiV512bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vslawsx_vvvl, "V256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vslawsx_vvvvl, "V256dV256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vslawsx_vvsl, "V256dV256diUi", "n")
+BUILTIN(__builtin_ve_vl_vslawsx_vvsvl, "V256dV256diV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vslawsx_vvvmvl, "V256dV256dV256dV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vslawsx_vvsmvl, "V256dV256diV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vslawzx_vvvl, "V256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vslawzx_vvvvl, "V256dV256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vslawzx_vvsl, "V256dV256diUi", "n")
+BUILTIN(__builtin_ve_vl_vslawzx_vvsvl, "V256dV256diV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vslawzx_vvvmvl, "V256dV256dV256dV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vslawzx_vvsmvl, "V256dV256diV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvsla_vvvl, "V256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvsla_vvvvl, "V256dV256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvsla_vvsl, "V256dV256dLUiUi", "n")
+BUILTIN(__builtin_ve_vl_pvsla_vvsvl, "V256dV256dLUiV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvsla_vvvMvl, "V256dV256dV256dV512bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvsla_vvsMvl, "V256dV256dLUiV512bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vslal_vvvl, "V256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vslal_vvvvl, "V256dV256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vslal_vvsl, "V256dV256dLiUi", "n")
+BUILTIN(__builtin_ve_vl_vslal_vvsvl, "V256dV256dLiV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vslal_vvvmvl, "V256dV256dV256dV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vslal_vvsmvl, "V256dV256dLiV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vsrawsx_vvvl, "V256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vsrawsx_vvvvl, "V256dV256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vsrawsx_vvsl, "V256dV256diUi", "n")
+BUILTIN(__builtin_ve_vl_vsrawsx_vvsvl, "V256dV256diV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vsrawsx_vvvmvl, "V256dV256dV256dV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vsrawsx_vvsmvl, "V256dV256diV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vsrawzx_vvvl, "V256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vsrawzx_vvvvl, "V256dV256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vsrawzx_vvsl, "V256dV256diUi", "n")
+BUILTIN(__builtin_ve_vl_vsrawzx_vvsvl, "V256dV256diV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vsrawzx_vvvmvl, "V256dV256dV256dV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vsrawzx_vvsmvl, "V256dV256diV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvsra_vvvl, "V256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvsra_vvvvl, "V256dV256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvsra_vvsl, "V256dV256dLUiUi", "n")
+BUILTIN(__builtin_ve_vl_pvsra_vvsvl, "V256dV256dLUiV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvsra_vvvMvl, "V256dV256dV256dV512bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvsra_vvsMvl, "V256dV256dLUiV512bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vsral_vvvl, "V256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vsral_vvvvl, "V256dV256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vsral_vvsl, "V256dV256dLiUi", "n")
+BUILTIN(__builtin_ve_vl_vsral_vvsvl, "V256dV256dLiV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vsral_vvvmvl, "V256dV256dV256dV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vsral_vvsmvl, "V256dV256dLiV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vsfa_vvssl, "V256dV256dLUiLUiUi", "n")
+BUILTIN(__builtin_ve_vl_vsfa_vvssvl, "V256dV256dLUiLUiV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vsfa_vvssmvl, "V256dV256dLUiLUiV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfaddd_vvvl, "V256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfaddd_vvvvl, "V256dV256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfaddd_vsvl, "V256ddV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfaddd_vsvvl, "V256ddV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfaddd_vvvmvl, "V256dV256dV256dV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfaddd_vsvmvl, "V256ddV256dV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfadds_vvvl, "V256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfadds_vvvvl, "V256dV256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfadds_vsvl, "V256dfV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfadds_vsvvl, "V256dfV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfadds_vvvmvl, "V256dV256dV256dV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfadds_vsvmvl, "V256dfV256dV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvfadd_vvvl, "V256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvfadd_vvvvl, "V256dV256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvfadd_vsvl, "V256dLUiV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvfadd_vsvvl, "V256dLUiV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvfadd_vvvMvl, "V256dV256dV256dV512bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvfadd_vsvMvl, "V256dLUiV256dV512bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfsubd_vvvl, "V256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfsubd_vvvvl, "V256dV256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfsubd_vsvl, "V256ddV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfsubd_vsvvl, "V256ddV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfsubd_vvvmvl, "V256dV256dV256dV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfsubd_vsvmvl, "V256ddV256dV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfsubs_vvvl, "V256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfsubs_vvvvl, "V256dV256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfsubs_vsvl, "V256dfV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfsubs_vsvvl, "V256dfV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfsubs_vvvmvl, "V256dV256dV256dV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfsubs_vsvmvl, "V256dfV256dV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvfsub_vvvl, "V256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvfsub_vvvvl, "V256dV256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvfsub_vsvl, "V256dLUiV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvfsub_vsvvl, "V256dLUiV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvfsub_vvvMvl, "V256dV256dV256dV512bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvfsub_vsvMvl, "V256dLUiV256dV512bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfmuld_vvvl, "V256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfmuld_vvvvl, "V256dV256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfmuld_vsvl, "V256ddV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfmuld_vsvvl, "V256ddV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfmuld_vvvmvl, "V256dV256dV256dV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfmuld_vsvmvl, "V256ddV256dV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfmuls_vvvl, "V256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfmuls_vvvvl, "V256dV256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfmuls_vsvl, "V256dfV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfmuls_vsvvl, "V256dfV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfmuls_vvvmvl, "V256dV256dV256dV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfmuls_vsvmvl, "V256dfV256dV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmul_vvvl, "V256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmul_vvvvl, "V256dV256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmul_vsvl, "V256dLUiV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmul_vsvvl, "V256dLUiV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmul_vvvMvl, "V256dV256dV256dV512bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmul_vsvMvl, "V256dLUiV256dV512bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfdivd_vvvl, "V256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfdivd_vvvvl, "V256dV256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfdivd_vsvl, "V256ddV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfdivd_vsvvl, "V256ddV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfdivd_vvvmvl, "V256dV256dV256dV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfdivd_vsvmvl, "V256ddV256dV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfdivs_vvvl, "V256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfdivs_vvvvl, "V256dV256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfdivs_vsvl, "V256dfV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfdivs_vsvvl, "V256dfV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfdivs_vvvmvl, "V256dV256dV256dV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfdivs_vsvmvl, "V256dfV256dV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfsqrtd_vvl, "V256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfsqrtd_vvvl, "V256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfsqrts_vvl, "V256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfsqrts_vvvl, "V256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfcmpd_vvvl, "V256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfcmpd_vvvvl, "V256dV256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfcmpd_vsvl, "V256ddV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfcmpd_vsvvl, "V256ddV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfcmpd_vvvmvl, "V256dV256dV256dV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfcmpd_vsvmvl, "V256ddV256dV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfcmps_vvvl, "V256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfcmps_vvvvl, "V256dV256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfcmps_vsvl, "V256dfV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfcmps_vsvvl, "V256dfV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfcmps_vvvmvl, "V256dV256dV256dV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfcmps_vsvmvl, "V256dfV256dV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvfcmp_vvvl, "V256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvfcmp_vvvvl, "V256dV256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvfcmp_vsvl, "V256dLUiV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvfcmp_vsvvl, "V256dLUiV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvfcmp_vvvMvl, "V256dV256dV256dV512bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvfcmp_vsvMvl, "V256dLUiV256dV512bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfmaxd_vvvl, "V256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfmaxd_vvvvl, "V256dV256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfmaxd_vsvl, "V256ddV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfmaxd_vsvvl, "V256ddV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfmaxd_vvvmvl, "V256dV256dV256dV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfmaxd_vsvmvl, "V256ddV256dV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfmaxs_vvvl, "V256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfmaxs_vvvvl, "V256dV256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfmaxs_vsvl, "V256dfV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfmaxs_vsvvl, "V256dfV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfmaxs_vvvmvl, "V256dV256dV256dV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfmaxs_vsvmvl, "V256dfV256dV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmax_vvvl, "V256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmax_vvvvl, "V256dV256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmax_vsvl, "V256dLUiV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmax_vsvvl, "V256dLUiV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmax_vvvMvl, "V256dV256dV256dV512bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmax_vsvMvl, "V256dLUiV256dV512bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfmind_vvvl, "V256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfmind_vvvvl, "V256dV256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfmind_vsvl, "V256ddV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfmind_vsvvl, "V256ddV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfmind_vvvmvl, "V256dV256dV256dV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfmind_vsvmvl, "V256ddV256dV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfmins_vvvl, "V256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfmins_vvvvl, "V256dV256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfmins_vsvl, "V256dfV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfmins_vsvvl, "V256dfV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfmins_vvvmvl, "V256dV256dV256dV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfmins_vsvmvl, "V256dfV256dV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmin_vvvl, "V256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmin_vvvvl, "V256dV256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmin_vsvl, "V256dLUiV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmin_vsvvl, "V256dLUiV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmin_vvvMvl, "V256dV256dV256dV512bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmin_vsvMvl, "V256dLUiV256dV512bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfmadd_vvvvl, "V256dV256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfmadd_vvvvvl, "V256dV256dV256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfmadd_vsvvl, "V256ddV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfmadd_vsvvvl, "V256ddV256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfmadd_vvsvl, "V256dV256ddV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfmadd_vvsvvl, "V256dV256ddV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfmadd_vvvvmvl, "V256dV256dV256dV256dV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfmadd_vsvvmvl, "V256ddV256dV256dV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfmadd_vvsvmvl, "V256dV256ddV256dV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfmads_vvvvl, "V256dV256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfmads_vvvvvl, "V256dV256dV256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfmads_vsvvl, "V256dfV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfmads_vsvvvl, "V256dfV256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfmads_vvsvl, "V256dV256dfV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfmads_vvsvvl, "V256dV256dfV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfmads_vvvvmvl, "V256dV256dV256dV256dV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfmads_vsvvmvl, "V256dfV256dV256dV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfmads_vvsvmvl, "V256dV256dfV256dV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmad_vvvvl, "V256dV256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmad_vvvvvl, "V256dV256dV256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmad_vsvvl, "V256dLUiV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmad_vsvvvl, "V256dLUiV256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmad_vvsvl, "V256dV256dLUiV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmad_vvsvvl, "V256dV256dLUiV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmad_vvvvMvl, "V256dV256dV256dV256dV512bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmad_vsvvMvl, "V256dLUiV256dV256dV512bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmad_vvsvMvl, "V256dV256dLUiV256dV512bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfmsbd_vvvvl, "V256dV256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfmsbd_vvvvvl, "V256dV256dV256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfmsbd_vsvvl, "V256ddV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfmsbd_vsvvvl, "V256ddV256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfmsbd_vvsvl, "V256dV256ddV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfmsbd_vvsvvl, "V256dV256ddV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfmsbd_vvvvmvl, "V256dV256dV256dV256dV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfmsbd_vsvvmvl, "V256ddV256dV256dV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfmsbd_vvsvmvl, "V256dV256ddV256dV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfmsbs_vvvvl, "V256dV256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfmsbs_vvvvvl, "V256dV256dV256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfmsbs_vsvvl, "V256dfV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfmsbs_vsvvvl, "V256dfV256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfmsbs_vvsvl, "V256dV256dfV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfmsbs_vvsvvl, "V256dV256dfV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfmsbs_vvvvmvl, "V256dV256dV256dV256dV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfmsbs_vsvvmvl, "V256dfV256dV256dV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfmsbs_vvsvmvl, "V256dV256dfV256dV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmsb_vvvvl, "V256dV256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmsb_vvvvvl, "V256dV256dV256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmsb_vsvvl, "V256dLUiV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmsb_vsvvvl, "V256dLUiV256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmsb_vvsvl, "V256dV256dLUiV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmsb_vvsvvl, "V256dV256dLUiV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmsb_vvvvMvl, "V256dV256dV256dV256dV512bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmsb_vsvvMvl, "V256dLUiV256dV256dV512bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmsb_vvsvMvl, "V256dV256dLUiV256dV512bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfnmadd_vvvvl, "V256dV256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfnmadd_vvvvvl, "V256dV256dV256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfnmadd_vsvvl, "V256ddV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfnmadd_vsvvvl, "V256ddV256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfnmadd_vvsvl, "V256dV256ddV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfnmadd_vvsvvl, "V256dV256ddV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfnmadd_vvvvmvl, "V256dV256dV256dV256dV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfnmadd_vsvvmvl, "V256ddV256dV256dV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfnmadd_vvsvmvl, "V256dV256ddV256dV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfnmads_vvvvl, "V256dV256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfnmads_vvvvvl, "V256dV256dV256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfnmads_vsvvl, "V256dfV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfnmads_vsvvvl, "V256dfV256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfnmads_vvsvl, "V256dV256dfV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfnmads_vvsvvl, "V256dV256dfV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfnmads_vvvvmvl, "V256dV256dV256dV256dV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfnmads_vsvvmvl, "V256dfV256dV256dV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfnmads_vvsvmvl, "V256dV256dfV256dV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvfnmad_vvvvl, "V256dV256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvfnmad_vvvvvl, "V256dV256dV256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvfnmad_vsvvl, "V256dLUiV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvfnmad_vsvvvl, "V256dLUiV256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvfnmad_vvsvl, "V256dV256dLUiV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvfnmad_vvsvvl, "V256dV256dLUiV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvfnmad_vvvvMvl, "V256dV256dV256dV256dV512bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvfnmad_vsvvMvl, "V256dLUiV256dV256dV512bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvfnmad_vvsvMvl, "V256dV256dLUiV256dV512bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfnmsbd_vvvvl, "V256dV256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfnmsbd_vvvvvl, "V256dV256dV256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfnmsbd_vsvvl, "V256ddV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfnmsbd_vsvvvl, "V256ddV256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfnmsbd_vvsvl, "V256dV256ddV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfnmsbd_vvsvvl, "V256dV256ddV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfnmsbd_vvvvmvl, "V256dV256dV256dV256dV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfnmsbd_vsvvmvl, "V256ddV256dV256dV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfnmsbd_vvsvmvl, "V256dV256ddV256dV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfnmsbs_vvvvl, "V256dV256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfnmsbs_vvvvvl, "V256dV256dV256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfnmsbs_vsvvl, "V256dfV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfnmsbs_vsvvvl, "V256dfV256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfnmsbs_vvsvl, "V256dV256dfV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfnmsbs_vvsvvl, "V256dV256dfV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfnmsbs_vvvvmvl, "V256dV256dV256dV256dV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfnmsbs_vsvvmvl, "V256dfV256dV256dV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfnmsbs_vvsvmvl, "V256dV256dfV256dV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvfnmsb_vvvvl, "V256dV256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvfnmsb_vvvvvl, "V256dV256dV256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvfnmsb_vsvvl, "V256dLUiV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvfnmsb_vsvvvl, "V256dLUiV256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvfnmsb_vvsvl, "V256dV256dLUiV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvfnmsb_vvsvvl, "V256dV256dLUiV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvfnmsb_vvvvMvl, "V256dV256dV256dV256dV512bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvfnmsb_vsvvMvl, "V256dLUiV256dV256dV512bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvfnmsb_vvsvMvl, "V256dV256dLUiV256dV512bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vrcpd_vvl, "V256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vrcpd_vvvl, "V256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vrcps_vvl, "V256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vrcps_vvvl, "V256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvrcp_vvl, "V256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvrcp_vvvl, "V256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vrsqrtd_vvl, "V256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vrsqrtd_vvvl, "V256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vrsqrts_vvl, "V256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vrsqrts_vvvl, "V256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvrsqrt_vvl, "V256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvrsqrt_vvvl, "V256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vrsqrtdnex_vvl, "V256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vrsqrtdnex_vvvl, "V256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vrsqrtsnex_vvl, "V256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vrsqrtsnex_vvvl, "V256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvrsqrtnex_vvl, "V256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvrsqrtnex_vvvl, "V256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vcvtwdsx_vvl, "V256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vcvtwdsx_vvvl, "V256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vcvtwdsx_vvmvl, "V256dV256dV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vcvtwdsxrz_vvl, "V256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vcvtwdsxrz_vvvl, "V256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vcvtwdsxrz_vvmvl, "V256dV256dV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vcvtwdzx_vvl, "V256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vcvtwdzx_vvvl, "V256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vcvtwdzx_vvmvl, "V256dV256dV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vcvtwdzxrz_vvl, "V256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vcvtwdzxrz_vvvl, "V256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vcvtwdzxrz_vvmvl, "V256dV256dV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vcvtwssx_vvl, "V256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vcvtwssx_vvvl, "V256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vcvtwssx_vvmvl, "V256dV256dV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vcvtwssxrz_vvl, "V256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vcvtwssxrz_vvvl, "V256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vcvtwssxrz_vvmvl, "V256dV256dV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vcvtwszx_vvl, "V256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vcvtwszx_vvvl, "V256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vcvtwszx_vvmvl, "V256dV256dV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vcvtwszxrz_vvl, "V256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vcvtwszxrz_vvvl, "V256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vcvtwszxrz_vvmvl, "V256dV256dV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvcvtws_vvl, "V256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvcvtws_vvvl, "V256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvcvtws_vvMvl, "V256dV256dV512bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvcvtwsrz_vvl, "V256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvcvtwsrz_vvvl, "V256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvcvtwsrz_vvMvl, "V256dV256dV512bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vcvtld_vvl, "V256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vcvtld_vvvl, "V256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vcvtld_vvmvl, "V256dV256dV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vcvtldrz_vvl, "V256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vcvtldrz_vvvl, "V256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vcvtldrz_vvmvl, "V256dV256dV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vcvtdw_vvl, "V256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vcvtdw_vvvl, "V256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vcvtsw_vvl, "V256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vcvtsw_vvvl, "V256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvcvtsw_vvl, "V256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvcvtsw_vvvl, "V256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vcvtdl_vvl, "V256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vcvtdl_vvvl, "V256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vcvtds_vvl, "V256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vcvtds_vvvl, "V256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vcvtsd_vvl, "V256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vcvtsd_vvvl, "V256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vmrg_vvvml, "V256dV256dV256dV256bUi", "n")
+BUILTIN(__builtin_ve_vl_vmrg_vvvmvl, "V256dV256dV256dV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vmrg_vsvml, "V256dLUiV256dV256bUi", "n")
+BUILTIN(__builtin_ve_vl_vmrg_vsvmvl, "V256dLUiV256dV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vmrgw_vvvMl, "V256dV256dV256dV512bUi", "n")
+BUILTIN(__builtin_ve_vl_vmrgw_vvvMvl, "V256dV256dV256dV512bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vmrgw_vsvMl, "V256dUiV256dV512bUi", "n")
+BUILTIN(__builtin_ve_vl_vmrgw_vsvMvl, "V256dUiV256dV512bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vshf_vvvsl, "V256dV256dV256dLUiUi", "n")
+BUILTIN(__builtin_ve_vl_vshf_vvvsvl, "V256dV256dV256dLUiV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vcp_vvmvl, "V256dV256dV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vex_vvmvl, "V256dV256dV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfmklat_ml, "V256bUi", "n")
+BUILTIN(__builtin_ve_vl_vfmklaf_ml, "V256bUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmkat_Ml, "V512bUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmkaf_Ml, "V512bUi", "n")
+BUILTIN(__builtin_ve_vl_vfmklgt_mvl, "V256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfmklgt_mvml, "V256bV256dV256bUi", "n")
+BUILTIN(__builtin_ve_vl_vfmkllt_mvl, "V256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfmkllt_mvml, "V256bV256dV256bUi", "n")
+BUILTIN(__builtin_ve_vl_vfmklne_mvl, "V256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfmklne_mvml, "V256bV256dV256bUi", "n")
+BUILTIN(__builtin_ve_vl_vfmkleq_mvl, "V256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfmkleq_mvml, "V256bV256dV256bUi", "n")
+BUILTIN(__builtin_ve_vl_vfmklge_mvl, "V256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfmklge_mvml, "V256bV256dV256bUi", "n")
+BUILTIN(__builtin_ve_vl_vfmklle_mvl, "V256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfmklle_mvml, "V256bV256dV256bUi", "n")
+BUILTIN(__builtin_ve_vl_vfmklnum_mvl, "V256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfmklnum_mvml, "V256bV256dV256bUi", "n")
+BUILTIN(__builtin_ve_vl_vfmklnan_mvl, "V256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfmklnan_mvml, "V256bV256dV256bUi", "n")
+BUILTIN(__builtin_ve_vl_vfmklgtnan_mvl, "V256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfmklgtnan_mvml, "V256bV256dV256bUi", "n")
+BUILTIN(__builtin_ve_vl_vfmklltnan_mvl, "V256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfmklltnan_mvml, "V256bV256dV256bUi", "n")
+BUILTIN(__builtin_ve_vl_vfmklnenan_mvl, "V256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfmklnenan_mvml, "V256bV256dV256bUi", "n")
+BUILTIN(__builtin_ve_vl_vfmkleqnan_mvl, "V256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfmkleqnan_mvml, "V256bV256dV256bUi", "n")
+BUILTIN(__builtin_ve_vl_vfmklgenan_mvl, "V256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfmklgenan_mvml, "V256bV256dV256bUi", "n")
+BUILTIN(__builtin_ve_vl_vfmkllenan_mvl, "V256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfmkllenan_mvml, "V256bV256dV256bUi", "n")
+BUILTIN(__builtin_ve_vl_vfmkwgt_mvl, "V256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfmkwgt_mvml, "V256bV256dV256bUi", "n")
+BUILTIN(__builtin_ve_vl_vfmkwlt_mvl, "V256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfmkwlt_mvml, "V256bV256dV256bUi", "n")
+BUILTIN(__builtin_ve_vl_vfmkwne_mvl, "V256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfmkwne_mvml, "V256bV256dV256bUi", "n")
+BUILTIN(__builtin_ve_vl_vfmkweq_mvl, "V256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfmkweq_mvml, "V256bV256dV256bUi", "n")
+BUILTIN(__builtin_ve_vl_vfmkwge_mvl, "V256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfmkwge_mvml, "V256bV256dV256bUi", "n")
+BUILTIN(__builtin_ve_vl_vfmkwle_mvl, "V256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfmkwle_mvml, "V256bV256dV256bUi", "n")
+BUILTIN(__builtin_ve_vl_vfmkwnum_mvl, "V256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfmkwnum_mvml, "V256bV256dV256bUi", "n")
+BUILTIN(__builtin_ve_vl_vfmkwnan_mvl, "V256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfmkwnan_mvml, "V256bV256dV256bUi", "n")
+BUILTIN(__builtin_ve_vl_vfmkwgtnan_mvl, "V256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfmkwgtnan_mvml, "V256bV256dV256bUi", "n")
+BUILTIN(__builtin_ve_vl_vfmkwltnan_mvl, "V256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfmkwltnan_mvml, "V256bV256dV256bUi", "n")
+BUILTIN(__builtin_ve_vl_vfmkwnenan_mvl, "V256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfmkwnenan_mvml, "V256bV256dV256bUi", "n")
+BUILTIN(__builtin_ve_vl_vfmkweqnan_mvl, "V256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfmkweqnan_mvml, "V256bV256dV256bUi", "n")
+BUILTIN(__builtin_ve_vl_vfmkwgenan_mvl, "V256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfmkwgenan_mvml, "V256bV256dV256bUi", "n")
+BUILTIN(__builtin_ve_vl_vfmkwlenan_mvl, "V256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfmkwlenan_mvml, "V256bV256dV256bUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmkwlogt_mvl, "V256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmkwupgt_mvl, "V256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmkwlogt_mvml, "V256bV256dV256bUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmkwupgt_mvml, "V256bV256dV256bUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmkwlolt_mvl, "V256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmkwuplt_mvl, "V256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmkwlolt_mvml, "V256bV256dV256bUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmkwuplt_mvml, "V256bV256dV256bUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmkwlone_mvl, "V256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmkwupne_mvl, "V256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmkwlone_mvml, "V256bV256dV256bUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmkwupne_mvml, "V256bV256dV256bUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmkwloeq_mvl, "V256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmkwupeq_mvl, "V256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmkwloeq_mvml, "V256bV256dV256bUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmkwupeq_mvml, "V256bV256dV256bUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmkwloge_mvl, "V256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmkwupge_mvl, "V256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmkwloge_mvml, "V256bV256dV256bUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmkwupge_mvml, "V256bV256dV256bUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmkwlole_mvl, "V256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmkwuple_mvl, "V256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmkwlole_mvml, "V256bV256dV256bUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmkwuple_mvml, "V256bV256dV256bUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmkwlonum_mvl, "V256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmkwupnum_mvl, "V256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmkwlonum_mvml, "V256bV256dV256bUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmkwupnum_mvml, "V256bV256dV256bUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmkwlonan_mvl, "V256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmkwupnan_mvl, "V256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmkwlonan_mvml, "V256bV256dV256bUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmkwupnan_mvml, "V256bV256dV256bUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmkwlogtnan_mvl, "V256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmkwupgtnan_mvl, "V256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmkwlogtnan_mvml, "V256bV256dV256bUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmkwupgtnan_mvml, "V256bV256dV256bUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmkwloltnan_mvl, "V256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmkwupltnan_mvl, "V256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmkwloltnan_mvml, "V256bV256dV256bUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmkwupltnan_mvml, "V256bV256dV256bUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmkwlonenan_mvl, "V256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmkwupnenan_mvl, "V256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmkwlonenan_mvml, "V256bV256dV256bUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmkwupnenan_mvml, "V256bV256dV256bUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmkwloeqnan_mvl, "V256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmkwupeqnan_mvl, "V256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmkwloeqnan_mvml, "V256bV256dV256bUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmkwupeqnan_mvml, "V256bV256dV256bUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmkwlogenan_mvl, "V256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmkwupgenan_mvl, "V256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmkwlogenan_mvml, "V256bV256dV256bUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmkwupgenan_mvml, "V256bV256dV256bUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmkwlolenan_mvl, "V256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmkwuplenan_mvl, "V256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmkwlolenan_mvml, "V256bV256dV256bUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmkwuplenan_mvml, "V256bV256dV256bUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmkwgt_Mvl, "V512bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmkwgt_MvMl, "V512bV256dV512bUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmkwlt_Mvl, "V512bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmkwlt_MvMl, "V512bV256dV512bUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmkwne_Mvl, "V512bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmkwne_MvMl, "V512bV256dV512bUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmkweq_Mvl, "V512bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmkweq_MvMl, "V512bV256dV512bUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmkwge_Mvl, "V512bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmkwge_MvMl, "V512bV256dV512bUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmkwle_Mvl, "V512bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmkwle_MvMl, "V512bV256dV512bUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmkwnum_Mvl, "V512bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmkwnum_MvMl, "V512bV256dV512bUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmkwnan_Mvl, "V512bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmkwnan_MvMl, "V512bV256dV512bUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmkwgtnan_Mvl, "V512bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmkwgtnan_MvMl, "V512bV256dV512bUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmkwltnan_Mvl, "V512bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmkwltnan_MvMl, "V512bV256dV512bUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmkwnenan_Mvl, "V512bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmkwnenan_MvMl, "V512bV256dV512bUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmkweqnan_Mvl, "V512bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmkweqnan_MvMl, "V512bV256dV512bUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmkwgenan_Mvl, "V512bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmkwgenan_MvMl, "V512bV256dV512bUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmkwlenan_Mvl, "V512bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmkwlenan_MvMl, "V512bV256dV512bUi", "n")
+BUILTIN(__builtin_ve_vl_vfmkdgt_mvl, "V256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfmkdgt_mvml, "V256bV256dV256bUi", "n")
+BUILTIN(__builtin_ve_vl_vfmkdlt_mvl, "V256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfmkdlt_mvml, "V256bV256dV256bUi", "n")
+BUILTIN(__builtin_ve_vl_vfmkdne_mvl, "V256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfmkdne_mvml, "V256bV256dV256bUi", "n")
+BUILTIN(__builtin_ve_vl_vfmkdeq_mvl, "V256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfmkdeq_mvml, "V256bV256dV256bUi", "n")
+BUILTIN(__builtin_ve_vl_vfmkdge_mvl, "V256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfmkdge_mvml, "V256bV256dV256bUi", "n")
+BUILTIN(__builtin_ve_vl_vfmkdle_mvl, "V256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfmkdle_mvml, "V256bV256dV256bUi", "n")
+BUILTIN(__builtin_ve_vl_vfmkdnum_mvl, "V256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfmkdnum_mvml, "V256bV256dV256bUi", "n")
+BUILTIN(__builtin_ve_vl_vfmkdnan_mvl, "V256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfmkdnan_mvml, "V256bV256dV256bUi", "n")
+BUILTIN(__builtin_ve_vl_vfmkdgtnan_mvl, "V256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfmkdgtnan_mvml, "V256bV256dV256bUi", "n")
+BUILTIN(__builtin_ve_vl_vfmkdltnan_mvl, "V256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfmkdltnan_mvml, "V256bV256dV256bUi", "n")
+BUILTIN(__builtin_ve_vl_vfmkdnenan_mvl, "V256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfmkdnenan_mvml, "V256bV256dV256bUi", "n")
+BUILTIN(__builtin_ve_vl_vfmkdeqnan_mvl, "V256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfmkdeqnan_mvml, "V256bV256dV256bUi", "n")
+BUILTIN(__builtin_ve_vl_vfmkdgenan_mvl, "V256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfmkdgenan_mvml, "V256bV256dV256bUi", "n")
+BUILTIN(__builtin_ve_vl_vfmkdlenan_mvl, "V256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfmkdlenan_mvml, "V256bV256dV256bUi", "n")
+BUILTIN(__builtin_ve_vl_vfmksgt_mvl, "V256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfmksgt_mvml, "V256bV256dV256bUi", "n")
+BUILTIN(__builtin_ve_vl_vfmkslt_mvl, "V256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfmkslt_mvml, "V256bV256dV256bUi", "n")
+BUILTIN(__builtin_ve_vl_vfmksne_mvl, "V256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfmksne_mvml, "V256bV256dV256bUi", "n")
+BUILTIN(__builtin_ve_vl_vfmkseq_mvl, "V256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfmkseq_mvml, "V256bV256dV256bUi", "n")
+BUILTIN(__builtin_ve_vl_vfmksge_mvl, "V256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfmksge_mvml, "V256bV256dV256bUi", "n")
+BUILTIN(__builtin_ve_vl_vfmksle_mvl, "V256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfmksle_mvml, "V256bV256dV256bUi", "n")
+BUILTIN(__builtin_ve_vl_vfmksnum_mvl, "V256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfmksnum_mvml, "V256bV256dV256bUi", "n")
+BUILTIN(__builtin_ve_vl_vfmksnan_mvl, "V256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfmksnan_mvml, "V256bV256dV256bUi", "n")
+BUILTIN(__builtin_ve_vl_vfmksgtnan_mvl, "V256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfmksgtnan_mvml, "V256bV256dV256bUi", "n")
+BUILTIN(__builtin_ve_vl_vfmksltnan_mvl, "V256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfmksltnan_mvml, "V256bV256dV256bUi", "n")
+BUILTIN(__builtin_ve_vl_vfmksnenan_mvl, "V256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfmksnenan_mvml, "V256bV256dV256bUi", "n")
+BUILTIN(__builtin_ve_vl_vfmkseqnan_mvl, "V256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfmkseqnan_mvml, "V256bV256dV256bUi", "n")
+BUILTIN(__builtin_ve_vl_vfmksgenan_mvl, "V256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfmksgenan_mvml, "V256bV256dV256bUi", "n")
+BUILTIN(__builtin_ve_vl_vfmkslenan_mvl, "V256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfmkslenan_mvml, "V256bV256dV256bUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmkslogt_mvl, "V256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmksupgt_mvl, "V256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmkslogt_mvml, "V256bV256dV256bUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmksupgt_mvml, "V256bV256dV256bUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmkslolt_mvl, "V256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmksuplt_mvl, "V256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmkslolt_mvml, "V256bV256dV256bUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmksuplt_mvml, "V256bV256dV256bUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmkslone_mvl, "V256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmksupne_mvl, "V256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmkslone_mvml, "V256bV256dV256bUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmksupne_mvml, "V256bV256dV256bUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmksloeq_mvl, "V256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmksupeq_mvl, "V256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmksloeq_mvml, "V256bV256dV256bUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmksupeq_mvml, "V256bV256dV256bUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmksloge_mvl, "V256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmksupge_mvl, "V256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmksloge_mvml, "V256bV256dV256bUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmksupge_mvml, "V256bV256dV256bUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmkslole_mvl, "V256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmksuple_mvl, "V256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmkslole_mvml, "V256bV256dV256bUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmksuple_mvml, "V256bV256dV256bUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmkslonum_mvl, "V256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmksupnum_mvl, "V256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmkslonum_mvml, "V256bV256dV256bUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmksupnum_mvml, "V256bV256dV256bUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmkslonan_mvl, "V256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmksupnan_mvl, "V256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmkslonan_mvml, "V256bV256dV256bUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmksupnan_mvml, "V256bV256dV256bUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmkslogtnan_mvl, "V256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmksupgtnan_mvl, "V256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmkslogtnan_mvml, "V256bV256dV256bUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmksupgtnan_mvml, "V256bV256dV256bUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmksloltnan_mvl, "V256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmksupltnan_mvl, "V256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmksloltnan_mvml, "V256bV256dV256bUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmksupltnan_mvml, "V256bV256dV256bUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmkslonenan_mvl, "V256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmksupnenan_mvl, "V256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmkslonenan_mvml, "V256bV256dV256bUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmksupnenan_mvml, "V256bV256dV256bUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmksloeqnan_mvl, "V256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmksupeqnan_mvl, "V256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmksloeqnan_mvml, "V256bV256dV256bUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmksupeqnan_mvml, "V256bV256dV256bUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmkslogenan_mvl, "V256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmksupgenan_mvl, "V256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmkslogenan_mvml, "V256bV256dV256bUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmksupgenan_mvml, "V256bV256dV256bUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmkslolenan_mvl, "V256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmksuplenan_mvl, "V256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmkslolenan_mvml, "V256bV256dV256bUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmksuplenan_mvml, "V256bV256dV256bUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmksgt_Mvl, "V512bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmksgt_MvMl, "V512bV256dV512bUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmkslt_Mvl, "V512bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmkslt_MvMl, "V512bV256dV512bUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmksne_Mvl, "V512bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmksne_MvMl, "V512bV256dV512bUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmkseq_Mvl, "V512bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmkseq_MvMl, "V512bV256dV512bUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmksge_Mvl, "V512bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmksge_MvMl, "V512bV256dV512bUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmksle_Mvl, "V512bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmksle_MvMl, "V512bV256dV512bUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmksnum_Mvl, "V512bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmksnum_MvMl, "V512bV256dV512bUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmksnan_Mvl, "V512bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmksnan_MvMl, "V512bV256dV512bUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmksgtnan_Mvl, "V512bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmksgtnan_MvMl, "V512bV256dV512bUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmksltnan_Mvl, "V512bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmksltnan_MvMl, "V512bV256dV512bUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmksnenan_Mvl, "V512bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmksnenan_MvMl, "V512bV256dV512bUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmkseqnan_Mvl, "V512bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmkseqnan_MvMl, "V512bV256dV512bUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmksgenan_Mvl, "V512bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmksgenan_MvMl, "V512bV256dV512bUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmkslenan_Mvl, "V512bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_pvfmkslenan_MvMl, "V512bV256dV512bUi", "n")
+BUILTIN(__builtin_ve_vl_vsumwsx_vvl, "V256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vsumwsx_vvml, "V256dV256dV256bUi", "n")
+BUILTIN(__builtin_ve_vl_vsumwzx_vvl, "V256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vsumwzx_vvml, "V256dV256dV256bUi", "n")
+BUILTIN(__builtin_ve_vl_vsuml_vvl, "V256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vsuml_vvml, "V256dV256dV256bUi", "n")
+BUILTIN(__builtin_ve_vl_vfsumd_vvl, "V256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfsumd_vvml, "V256dV256dV256bUi", "n")
+BUILTIN(__builtin_ve_vl_vfsums_vvl, "V256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfsums_vvml, "V256dV256dV256bUi", "n")
+BUILTIN(__builtin_ve_vl_vrmaxswfstsx_vvl, "V256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vrmaxswfstsx_vvvl, "V256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vrmaxswlstsx_vvl, "V256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vrmaxswlstsx_vvvl, "V256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vrmaxswfstzx_vvl, "V256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vrmaxswfstzx_vvvl, "V256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vrmaxswlstzx_vvl, "V256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vrmaxswlstzx_vvvl, "V256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vrminswfstsx_vvl, "V256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vrminswfstsx_vvvl, "V256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vrminswlstsx_vvl, "V256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vrminswlstsx_vvvl, "V256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vrminswfstzx_vvl, "V256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vrminswfstzx_vvvl, "V256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vrminswlstzx_vvl, "V256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vrminswlstzx_vvvl, "V256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vrmaxslfst_vvl, "V256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vrmaxslfst_vvvl, "V256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vrmaxsllst_vvl, "V256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vrmaxsllst_vvvl, "V256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vrminslfst_vvl, "V256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vrminslfst_vvvl, "V256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vrminsllst_vvl, "V256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vrminsllst_vvvl, "V256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfrmaxdfst_vvl, "V256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfrmaxdfst_vvvl, "V256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfrmaxdlst_vvl, "V256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfrmaxdlst_vvvl, "V256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfrmaxsfst_vvl, "V256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfrmaxsfst_vvvl, "V256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfrmaxslst_vvl, "V256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfrmaxslst_vvvl, "V256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfrmindfst_vvl, "V256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfrmindfst_vvvl, "V256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfrmindlst_vvl, "V256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfrmindlst_vvvl, "V256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfrminsfst_vvl, "V256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfrminsfst_vvvl, "V256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfrminslst_vvl, "V256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vfrminslst_vvvl, "V256dV256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vrand_vvl, "V256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vrand_vvml, "V256dV256dV256bUi", "n")
+BUILTIN(__builtin_ve_vl_vror_vvl, "V256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vror_vvml, "V256dV256dV256bUi", "n")
+BUILTIN(__builtin_ve_vl_vrxor_vvl, "V256dV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vrxor_vvml, "V256dV256dV256bUi", "n")
+BUILTIN(__builtin_ve_vl_vgt_vvssl, "V256dV256dLUiLUiUi", "n")
+BUILTIN(__builtin_ve_vl_vgt_vvssvl, "V256dV256dLUiLUiV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vgt_vvssml, "V256dV256dLUiLUiV256bUi", "n")
+BUILTIN(__builtin_ve_vl_vgt_vvssmvl, "V256dV256dLUiLUiV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vgtnc_vvssl, "V256dV256dLUiLUiUi", "n")
+BUILTIN(__builtin_ve_vl_vgtnc_vvssvl, "V256dV256dLUiLUiV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vgtnc_vvssml, "V256dV256dLUiLUiV256bUi", "n")
+BUILTIN(__builtin_ve_vl_vgtnc_vvssmvl, "V256dV256dLUiLUiV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vgtu_vvssl, "V256dV256dLUiLUiUi", "n")
+BUILTIN(__builtin_ve_vl_vgtu_vvssvl, "V256dV256dLUiLUiV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vgtu_vvssml, "V256dV256dLUiLUiV256bUi", "n")
+BUILTIN(__builtin_ve_vl_vgtu_vvssmvl, "V256dV256dLUiLUiV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vgtunc_vvssl, "V256dV256dLUiLUiUi", "n")
+BUILTIN(__builtin_ve_vl_vgtunc_vvssvl, "V256dV256dLUiLUiV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vgtunc_vvssml, "V256dV256dLUiLUiV256bUi", "n")
+BUILTIN(__builtin_ve_vl_vgtunc_vvssmvl, "V256dV256dLUiLUiV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vgtlsx_vvssl, "V256dV256dLUiLUiUi", "n")
+BUILTIN(__builtin_ve_vl_vgtlsx_vvssvl, "V256dV256dLUiLUiV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vgtlsx_vvssml, "V256dV256dLUiLUiV256bUi", "n")
+BUILTIN(__builtin_ve_vl_vgtlsx_vvssmvl, "V256dV256dLUiLUiV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vgtlsxnc_vvssl, "V256dV256dLUiLUiUi", "n")
+BUILTIN(__builtin_ve_vl_vgtlsxnc_vvssvl, "V256dV256dLUiLUiV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vgtlsxnc_vvssml, "V256dV256dLUiLUiV256bUi", "n")
+BUILTIN(__builtin_ve_vl_vgtlsxnc_vvssmvl, "V256dV256dLUiLUiV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vgtlzx_vvssl, "V256dV256dLUiLUiUi", "n")
+BUILTIN(__builtin_ve_vl_vgtlzx_vvssvl, "V256dV256dLUiLUiV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vgtlzx_vvssml, "V256dV256dLUiLUiV256bUi", "n")
+BUILTIN(__builtin_ve_vl_vgtlzx_vvssmvl, "V256dV256dLUiLUiV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vgtlzxnc_vvssl, "V256dV256dLUiLUiUi", "n")
+BUILTIN(__builtin_ve_vl_vgtlzxnc_vvssvl, "V256dV256dLUiLUiV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vgtlzxnc_vvssml, "V256dV256dLUiLUiV256bUi", "n")
+BUILTIN(__builtin_ve_vl_vgtlzxnc_vvssmvl, "V256dV256dLUiLUiV256bV256dUi", "n")
+BUILTIN(__builtin_ve_vl_vsc_vvssl, "vV256dV256dLUiLUiUi", "n")
+BUILTIN(__builtin_ve_vl_vsc_vvssml, "vV256dV256dLUiLUiV256bUi", "n")
+BUILTIN(__builtin_ve_vl_vscnc_vvssl, "vV256dV256dLUiLUiUi", "n")
+BUILTIN(__builtin_ve_vl_vscnc_vvssml, "vV256dV256dLUiLUiV256bUi", "n")
+BUILTIN(__builtin_ve_vl_vscot_vvssl, "vV256dV256dLUiLUiUi", "n")
+BUILTIN(__builtin_ve_vl_vscot_vvssml, "vV256dV256dLUiLUiV256bUi", "n")
+BUILTIN(__builtin_ve_vl_vscncot_vvssl, "vV256dV256dLUiLUiUi", "n")
+BUILTIN(__builtin_ve_vl_vscncot_vvssml, "vV256dV256dLUiLUiV256bUi", "n")
+BUILTIN(__builtin_ve_vl_vscu_vvssl, "vV256dV256dLUiLUiUi", "n")
+BUILTIN(__builtin_ve_vl_vscu_vvssml, "vV256dV256dLUiLUiV256bUi", "n")
+BUILTIN(__builtin_ve_vl_vscunc_vvssl, "vV256dV256dLUiLUiUi", "n")
+BUILTIN(__builtin_ve_vl_vscunc_vvssml, "vV256dV256dLUiLUiV256bUi", "n")
+BUILTIN(__builtin_ve_vl_vscuot_vvssl, "vV256dV256dLUiLUiUi", "n")
+BUILTIN(__builtin_ve_vl_vscuot_vvssml, "vV256dV256dLUiLUiV256bUi", "n")
+BUILTIN(__builtin_ve_vl_vscuncot_vvssl, "vV256dV256dLUiLUiUi", "n")
+BUILTIN(__builtin_ve_vl_vscuncot_vvssml, "vV256dV256dLUiLUiV256bUi", "n")
+BUILTIN(__builtin_ve_vl_vscl_vvssl, "vV256dV256dLUiLUiUi", "n")
+BUILTIN(__builtin_ve_vl_vscl_vvssml, "vV256dV256dLUiLUiV256bUi", "n")
+BUILTIN(__builtin_ve_vl_vsclnc_vvssl, "vV256dV256dLUiLUiUi", "n")
+BUILTIN(__builtin_ve_vl_vsclnc_vvssml, "vV256dV256dLUiLUiV256bUi", "n")
+BUILTIN(__builtin_ve_vl_vsclot_vvssl, "vV256dV256dLUiLUiUi", "n")
+BUILTIN(__builtin_ve_vl_vsclot_vvssml, "vV256dV256dLUiLUiV256bUi", "n")
+BUILTIN(__builtin_ve_vl_vsclncot_vvssl, "vV256dV256dLUiLUiUi", "n")
+BUILTIN(__builtin_ve_vl_vsclncot_vvssml, "vV256dV256dLUiLUiV256bUi", "n")
+BUILTIN(__builtin_ve_vl_andm_mmm, "V256bV256bV256b", "n")
+BUILTIN(__builtin_ve_vl_andm_MMM, "V512bV512bV512b", "n")
+BUILTIN(__builtin_ve_vl_orm_mmm, "V256bV256bV256b", "n")
+BUILTIN(__builtin_ve_vl_orm_MMM, "V512bV512bV512b", "n")
+BUILTIN(__builtin_ve_vl_xorm_mmm, "V256bV256bV256b", "n")
+BUILTIN(__builtin_ve_vl_xorm_MMM, "V512bV512bV512b", "n")
+BUILTIN(__builtin_ve_vl_eqvm_mmm, "V256bV256bV256b", "n")
+BUILTIN(__builtin_ve_vl_eqvm_MMM, "V512bV512bV512b", "n")
+BUILTIN(__builtin_ve_vl_nndm_mmm, "V256bV256bV256b", "n")
+BUILTIN(__builtin_ve_vl_nndm_MMM, "V512bV512bV512b", "n")
+BUILTIN(__builtin_ve_vl_negm_mm, "V256bV256b", "n")
+BUILTIN(__builtin_ve_vl_negm_MM, "V512bV512b", "n")
+BUILTIN(__builtin_ve_vl_pcvm_sml, "LUiV256bUi", "n")
+BUILTIN(__builtin_ve_vl_lzvm_sml, "LUiV256bUi", "n")
+BUILTIN(__builtin_ve_vl_tovm_sml, "LUiV256bUi", "n")
+BUILTIN(__builtin_ve_vl_lcr_sss, "LUiLUiLUi", "n")
+BUILTIN(__builtin_ve_vl_scr_sss, "vLUiLUiLUi", "n")
+BUILTIN(__builtin_ve_vl_tscr_ssss, "LUiLUiLUiLUi", "n")
+BUILTIN(__builtin_ve_vl_fidcr_sss, "LUiLUiUi", "n")
+BUILTIN(__builtin_ve_vl_fencei, "v", "n")
+BUILTIN(__builtin_ve_vl_fencem_s, "vUi", "n")
+BUILTIN(__builtin_ve_vl_fencec_s, "vUi", "n")
+BUILTIN(__builtin_ve_vl_svob, "v", "n")
diff --git a/contrib/llvm-project/clang/include/clang/Basic/BuiltinsWebAssembly.def b/contrib/llvm-project/clang/include/clang/Basic/BuiltinsWebAssembly.def
index 04ec45aa3b74..7e950914ad94 100644
--- a/contrib/llvm-project/clang/include/clang/Basic/BuiltinsWebAssembly.def
+++ b/contrib/llvm-project/clang/include/clang/Basic/BuiltinsWebAssembly.def
@@ -119,18 +119,22 @@ TARGET_BUILTIN(__builtin_wasm_all_true_i16x8, "iV8s", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_all_true_i32x4, "iV4i", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_all_true_i64x2, "iV2LLi", "nc", "simd128")
-TARGET_BUILTIN(__builtin_wasm_bitmask_i8x16, "iV16Sc", "nc", "simd128")
-TARGET_BUILTIN(__builtin_wasm_bitmask_i16x8, "iV8s", "nc", "simd128")
-TARGET_BUILTIN(__builtin_wasm_bitmask_i32x4, "iV4i", "nc", "simd128")
-TARGET_BUILTIN(__builtin_wasm_bitmask_i64x2, "iV2LLi", "nc", "simd128")
+TARGET_BUILTIN(__builtin_wasm_bitmask_i8x16, "UiV16Sc", "nc", "simd128")
+TARGET_BUILTIN(__builtin_wasm_bitmask_i16x8, "UiV8s", "nc", "simd128")
+TARGET_BUILTIN(__builtin_wasm_bitmask_i32x4, "UiV4i", "nc", "simd128")
+TARGET_BUILTIN(__builtin_wasm_bitmask_i64x2, "UiV2LLi", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_abs_f32x4, "V4fV4f", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_abs_f64x2, "V2dV2d", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_min_f32x4, "V4fV4fV4f", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_max_f32x4, "V4fV4fV4f", "nc", "simd128")
+TARGET_BUILTIN(__builtin_wasm_pmin_f32x4, "V4fV4fV4f", "nc", "simd128")
+TARGET_BUILTIN(__builtin_wasm_pmax_f32x4, "V4fV4fV4f", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_min_f64x2, "V2dV2dV2d", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_max_f64x2, "V2dV2dV2d", "nc", "simd128")
+TARGET_BUILTIN(__builtin_wasm_pmin_f64x2, "V2dV2dV2d", "nc", "simd128")
+TARGET_BUILTIN(__builtin_wasm_pmax_f64x2, "V2dV2dV2d", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_ceil_f32x4, "V4fV4f", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_floor_f32x4, "V4fV4f", "nc", "simd128")
@@ -154,8 +158,56 @@ TARGET_BUILTIN(__builtin_wasm_narrow_u_i8x16_i16x8, "V16UcV8sV8s", "nc", "simd12
TARGET_BUILTIN(__builtin_wasm_narrow_s_i16x8_i32x4, "V8sV4iV4i", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_narrow_u_i16x8_i32x4, "V8UsV4iV4i", "nc", "simd128")
-TARGET_BUILTIN(__builtin_wasm_trunc_sat_zero_s_f64x2_i32x4, "V4iV2d", "nc", "simd128")
-TARGET_BUILTIN(__builtin_wasm_trunc_sat_zero_u_f64x2_i32x4, "V4UiV2d", "nc", "simd128")
+TARGET_BUILTIN(__builtin_wasm_trunc_sat_s_zero_f64x2_i32x4, "V4iV2d", "nc", "simd128")
+TARGET_BUILTIN(__builtin_wasm_trunc_sat_u_zero_f64x2_i32x4, "V4UiV2d", "nc", "simd128")
+
+// Relaxed SIMD builtins
+TARGET_BUILTIN(__builtin_wasm_relaxed_madd_f32x4, "V4fV4fV4fV4f", "nc", "relaxed-simd")
+TARGET_BUILTIN(__builtin_wasm_relaxed_nmadd_f32x4, "V4fV4fV4fV4f", "nc", "relaxed-simd")
+TARGET_BUILTIN(__builtin_wasm_relaxed_madd_f64x2, "V2dV2dV2dV2d", "nc", "relaxed-simd")
+TARGET_BUILTIN(__builtin_wasm_relaxed_nmadd_f64x2, "V2dV2dV2dV2d", "nc", "relaxed-simd")
+
+TARGET_BUILTIN(__builtin_wasm_relaxed_laneselect_i8x16, "V16ScV16ScV16ScV16Sc", "nc", "relaxed-simd")
+TARGET_BUILTIN(__builtin_wasm_relaxed_laneselect_i16x8, "V8sV8sV8sV8s", "nc", "relaxed-simd")
+TARGET_BUILTIN(__builtin_wasm_relaxed_laneselect_i32x4, "V4iV4iV4iV4i", "nc", "relaxed-simd")
+TARGET_BUILTIN(__builtin_wasm_relaxed_laneselect_i64x2, "V2LLiV2LLiV2LLiV2LLi", "nc", "relaxed-simd")
+
+TARGET_BUILTIN(__builtin_wasm_relaxed_swizzle_i8x16, "V16ScV16ScV16Sc", "nc", "relaxed-simd")
+
+TARGET_BUILTIN(__builtin_wasm_relaxed_min_f32x4, "V4fV4fV4f", "nc", "relaxed-simd")
+TARGET_BUILTIN(__builtin_wasm_relaxed_max_f32x4, "V4fV4fV4f", "nc", "relaxed-simd")
+TARGET_BUILTIN(__builtin_wasm_relaxed_min_f64x2, "V2dV2dV2d", "nc", "relaxed-simd")
+TARGET_BUILTIN(__builtin_wasm_relaxed_max_f64x2, "V2dV2dV2d", "nc", "relaxed-simd")
+
+TARGET_BUILTIN(__builtin_wasm_relaxed_trunc_s_i32x4_f32x4, "V4iV4f", "nc", "relaxed-simd")
+TARGET_BUILTIN(__builtin_wasm_relaxed_trunc_u_i32x4_f32x4, "V4UiV4f", "nc", "relaxed-simd")
+TARGET_BUILTIN(__builtin_wasm_relaxed_trunc_s_zero_i32x4_f64x2, "V4iV2d", "nc", "relaxed-simd")
+TARGET_BUILTIN(__builtin_wasm_relaxed_trunc_u_zero_i32x4_f64x2, "V4UiV2d", "nc", "relaxed-simd")
+
+TARGET_BUILTIN(__builtin_wasm_relaxed_q15mulr_s_i16x8, "V8sV8sV8s", "nc", "relaxed-simd")
+
+TARGET_BUILTIN(__builtin_wasm_relaxed_dot_i8x16_i7x16_s_i16x8, "V8sV16ScV16Sc", "nc", "relaxed-simd")
+TARGET_BUILTIN(__builtin_wasm_relaxed_dot_i8x16_i7x16_add_s_i32x4, "V4iV16ScV16ScV4i", "nc", "relaxed-simd")
+TARGET_BUILTIN(__builtin_wasm_relaxed_dot_bf16x8_add_f32_f32x4, "V4fV8UsV8UsV4f", "nc", "relaxed-simd")
+
+// Reference Types builtins
+// Some builtins are custom type-checked - see 't' as part of the third argument,
+// in which case the argument spec (second argument) is unused.
+
+TARGET_BUILTIN(__builtin_wasm_ref_null_extern, "i", "nct", "reference-types")
+
+// A funcref represented as a function pointer with the funcref attribute
+// attached to the type, therefore SemaChecking will check for the right
+// return type.
+TARGET_BUILTIN(__builtin_wasm_ref_null_func, "i", "nct", "reference-types")
+
+// Table builtins
+TARGET_BUILTIN(__builtin_wasm_table_set, "viii", "t", "reference-types")
+TARGET_BUILTIN(__builtin_wasm_table_get, "iii", "t", "reference-types")
+TARGET_BUILTIN(__builtin_wasm_table_size, "zi", "nt", "reference-types")
+TARGET_BUILTIN(__builtin_wasm_table_grow, "iiii", "nt", "reference-types")
+TARGET_BUILTIN(__builtin_wasm_table_fill, "viiii", "t", "reference-types")
+TARGET_BUILTIN(__builtin_wasm_table_copy, "viiiii", "t", "reference-types")
#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 18e541fe9cb5..60b752ad4854 100644
--- a/contrib/llvm-project/clang/include/clang/Basic/BuiltinsX86.def
+++ b/contrib/llvm-project/clang/include/clang/Basic/BuiltinsX86.def
@@ -254,25 +254,14 @@ TARGET_BUILTIN(__builtin_ia32_minpd, "V2dV2dV2d", "ncV:128:", "sse2")
TARGET_BUILTIN(__builtin_ia32_maxpd, "V2dV2dV2d", "ncV:128:", "sse2")
TARGET_BUILTIN(__builtin_ia32_minsd, "V2dV2dV2d", "ncV:128:", "sse2")
TARGET_BUILTIN(__builtin_ia32_maxsd, "V2dV2dV2d", "ncV:128:", "sse2")
-TARGET_BUILTIN(__builtin_ia32_paddsb128, "V16cV16cV16c", "ncV:128:", "sse2")
-TARGET_BUILTIN(__builtin_ia32_paddsw128, "V8sV8sV8s", "ncV:128:", "sse2")
-TARGET_BUILTIN(__builtin_ia32_psubsb128, "V16cV16cV16c", "ncV:128:", "sse2")
-TARGET_BUILTIN(__builtin_ia32_psubsw128, "V8sV8sV8s", "ncV:128:", "sse2")
-TARGET_BUILTIN(__builtin_ia32_paddusb128, "V16cV16cV16c", "ncV:128:", "sse2")
-TARGET_BUILTIN(__builtin_ia32_paddusw128, "V8sV8sV8s", "ncV:128:", "sse2")
-TARGET_BUILTIN(__builtin_ia32_psubusb128, "V16cV16cV16c", "ncV:128:", "sse2")
-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")
TARGET_BUILTIN(__builtin_ia32_pmulhuw128, "V8sV8sV8s", "ncV:128:", "sse2")
+TARGET_BUILTIN(__builtin_ia32_vec_ext_v2di, "OiV2OiIi", "ncV:128:", "sse2")
TARGET_BUILTIN(__builtin_ia32_vec_ext_v4si, "iV4iIi", "ncV:128:", "sse2")
TARGET_BUILTIN(__builtin_ia32_vec_ext_v4sf, "fV4fIi", "ncV:128:", "sse2")
TARGET_BUILTIN(__builtin_ia32_vec_ext_v8hi, "sV8sIi", "ncV:128:", "sse2")
@@ -296,19 +285,16 @@ 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")
+TARGET_HEADER_BUILTIN(_mm_setcsr, "vUi", "nh",XMMINTRIN_H, ALL_LANGUAGES, "sse")
TARGET_BUILTIN(__builtin_ia32_stmxcsr, "Ui", "n", "sse")
-TARGET_HEADER_BUILTIN(_mm_getcsr, "Ui", "nh", "xmmintrin.h", ALL_LANGUAGES, "sse")
+TARGET_HEADER_BUILTIN(_mm_getcsr, "Ui", "nh", XMMINTRIN_H, ALL_LANGUAGES, "sse")
TARGET_BUILTIN(__builtin_ia32_cvtss2si, "iV4f", "ncV:128:", "sse")
TARGET_BUILTIN(__builtin_ia32_cvttss2si, "iV4f", "ncV:128:", "sse")
TARGET_BUILTIN(__builtin_ia32_movmskps, "iV4f", "nV:128:", "sse")
TARGET_BUILTIN(__builtin_ia32_sfence, "v", "n", "sse")
-TARGET_HEADER_BUILTIN(_mm_sfence, "v", "nh", "xmmintrin.h", ALL_LANGUAGES, "sse")
+TARGET_HEADER_BUILTIN(_mm_sfence, "v", "nh", XMMINTRIN_H, ALL_LANGUAGES, "sse")
TARGET_BUILTIN(__builtin_ia32_rcpps, "V4fV4f", "ncV:128:", "sse")
TARGET_BUILTIN(__builtin_ia32_rcpss, "V4fV4f", "ncV:128:", "sse")
TARGET_BUILTIN(__builtin_ia32_rsqrtps, "V4fV4f", "ncV:128:", "sse")
@@ -337,13 +323,13 @@ TARGET_BUILTIN(__builtin_ia32_cvtsd2ss, "V4fV4fV2d", "ncV:128:", "sse2")
TARGET_BUILTIN(__builtin_ia32_cvtps2dq, "V4iV4f", "ncV:128:", "sse2")
TARGET_BUILTIN(__builtin_ia32_cvttps2dq, "V4iV4f", "ncV:128:", "sse2")
TARGET_BUILTIN(__builtin_ia32_clflush, "vvC*", "n", "sse2")
-TARGET_HEADER_BUILTIN(_mm_clflush, "vvC*", "nh", "emmintrin.h", ALL_LANGUAGES, "sse2")
+TARGET_HEADER_BUILTIN(_mm_clflush, "vvC*", "nh", EMMINTRIN_H, ALL_LANGUAGES, "sse2")
TARGET_BUILTIN(__builtin_ia32_lfence, "v", "n", "sse2")
-TARGET_HEADER_BUILTIN(_mm_lfence, "v", "nh", "emmintrin.h", ALL_LANGUAGES, "sse2")
+TARGET_HEADER_BUILTIN(_mm_lfence, "v", "nh", EMMINTRIN_H, ALL_LANGUAGES, "sse2")
TARGET_BUILTIN(__builtin_ia32_mfence, "v", "n", "sse2")
-TARGET_HEADER_BUILTIN(_mm_mfence, "v", "nh", "emmintrin.h", ALL_LANGUAGES, "sse2")
+TARGET_HEADER_BUILTIN(_mm_mfence, "v", "nh", EMMINTRIN_H, ALL_LANGUAGES, "sse2")
TARGET_BUILTIN(__builtin_ia32_pause, "v", "n", "")
-TARGET_HEADER_BUILTIN(_mm_pause, "v", "nh", "emmintrin.h", ALL_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_mm_pause, "v", "nh", EMMINTRIN_H, ALL_LANGUAGES, "")
TARGET_BUILTIN(__builtin_ia32_pmuludq128, "V2OiV4iV4i", "ncV:128:", "sse2")
TARGET_BUILTIN(__builtin_ia32_psraw128, "V8sV8sV8s", "ncV:128:", "sse2")
TARGET_BUILTIN(__builtin_ia32_psrad128, "V4iV4iV4i", "ncV:128:", "sse2")
@@ -380,14 +366,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")
@@ -421,9 +399,9 @@ TARGET_BUILTIN(__builtin_ia32_pcmpestrio128, "iV16ciV16ciIc","ncV:128:", "sse4.2
TARGET_BUILTIN(__builtin_ia32_pcmpestris128, "iV16ciV16ciIc","ncV:128:", "sse4.2")
TARGET_BUILTIN(__builtin_ia32_pcmpestriz128, "iV16ciV16ciIc","ncV:128:", "sse4.2")
-TARGET_BUILTIN(__builtin_ia32_crc32qi, "UiUiUc", "nc", "sse4.2")
-TARGET_BUILTIN(__builtin_ia32_crc32hi, "UiUiUs", "nc", "sse4.2")
-TARGET_BUILTIN(__builtin_ia32_crc32si, "UiUiUi", "nc", "sse4.2")
+TARGET_BUILTIN(__builtin_ia32_crc32qi, "UiUiUc", "nc", "crc32")
+TARGET_BUILTIN(__builtin_ia32_crc32hi, "UiUiUs", "nc", "crc32")
+TARGET_BUILTIN(__builtin_ia32_crc32si, "UiUiUi", "nc", "crc32")
// SSE4a
TARGET_BUILTIN(__builtin_ia32_extrqi, "V2OiV2OiIcIc", "ncV:128:", "sse4a")
@@ -443,31 +421,31 @@ TARGET_BUILTIN(__builtin_ia32_aeskeygenassist128, "V2OiV2OiIc", "ncV:128:", "aes
// VAES
TARGET_BUILTIN(__builtin_ia32_aesenc256, "V4OiV4OiV4Oi", "ncV:256:", "vaes")
-TARGET_BUILTIN(__builtin_ia32_aesenc512, "V8OiV8OiV8Oi", "ncV:512:", "avx512f,vaes")
+TARGET_BUILTIN(__builtin_ia32_aesenc512, "V8OiV8OiV8Oi", "ncV:512:", "avx512f,evex512,vaes")
TARGET_BUILTIN(__builtin_ia32_aesenclast256, "V4OiV4OiV4Oi", "ncV:256:", "vaes")
-TARGET_BUILTIN(__builtin_ia32_aesenclast512, "V8OiV8OiV8Oi", "ncV:512:", "avx512f,vaes")
+TARGET_BUILTIN(__builtin_ia32_aesenclast512, "V8OiV8OiV8Oi", "ncV:512:", "avx512f,evex512,vaes")
TARGET_BUILTIN(__builtin_ia32_aesdec256, "V4OiV4OiV4Oi", "ncV:256:", "vaes")
-TARGET_BUILTIN(__builtin_ia32_aesdec512, "V8OiV8OiV8Oi", "ncV:512:", "avx512f,vaes")
+TARGET_BUILTIN(__builtin_ia32_aesdec512, "V8OiV8OiV8Oi", "ncV:512:", "avx512f,evex512,vaes")
TARGET_BUILTIN(__builtin_ia32_aesdeclast256, "V4OiV4OiV4Oi", "ncV:256:", "vaes")
-TARGET_BUILTIN(__builtin_ia32_aesdeclast512, "V8OiV8OiV8Oi", "ncV:512:", "avx512f,vaes")
+TARGET_BUILTIN(__builtin_ia32_aesdeclast512, "V8OiV8OiV8Oi", "ncV:512:", "avx512f,evex512,vaes")
// GFNI
TARGET_BUILTIN(__builtin_ia32_vgf2p8affineinvqb_v16qi, "V16cV16cV16cIc", "ncV:128:", "gfni")
TARGET_BUILTIN(__builtin_ia32_vgf2p8affineinvqb_v32qi, "V32cV32cV32cIc", "ncV:256:", "avx,gfni")
-TARGET_BUILTIN(__builtin_ia32_vgf2p8affineinvqb_v64qi, "V64cV64cV64cIc", "ncV:512:", "avx512bw,gfni")
+TARGET_BUILTIN(__builtin_ia32_vgf2p8affineinvqb_v64qi, "V64cV64cV64cIc", "ncV:512:", "avx512f,evex512,gfni")
TARGET_BUILTIN(__builtin_ia32_vgf2p8affineqb_v16qi, "V16cV16cV16cIc", "ncV:128:", "gfni")
TARGET_BUILTIN(__builtin_ia32_vgf2p8affineqb_v32qi, "V32cV32cV32cIc", "ncV:256:", "avx,gfni")
-TARGET_BUILTIN(__builtin_ia32_vgf2p8affineqb_v64qi, "V64cV64cV64cIc", "ncV:512:", "avx512bw,gfni")
+TARGET_BUILTIN(__builtin_ia32_vgf2p8affineqb_v64qi, "V64cV64cV64cIc", "ncV:512:", "avx512f,evex512,gfni")
TARGET_BUILTIN(__builtin_ia32_vgf2p8mulb_v16qi, "V16cV16cV16c", "ncV:128:", "gfni")
TARGET_BUILTIN(__builtin_ia32_vgf2p8mulb_v32qi, "V32cV32cV32c", "ncV:256:", "avx,gfni")
-TARGET_BUILTIN(__builtin_ia32_vgf2p8mulb_v64qi, "V64cV64cV64c", "ncV:512:", "avx512bw,gfni")
+TARGET_BUILTIN(__builtin_ia32_vgf2p8mulb_v64qi, "V64cV64cV64c", "ncV:512:", "avx512f,evex512,gfni")
// CLMUL
TARGET_BUILTIN(__builtin_ia32_pclmulqdq128, "V2OiV2OiV2OiIc", "ncV:128:", "pclmul")
// VPCLMULQDQ
TARGET_BUILTIN(__builtin_ia32_pclmulqdq256, "V4OiV4OiV4OiIc", "ncV:256:", "vpclmulqdq")
-TARGET_BUILTIN(__builtin_ia32_pclmulqdq512, "V8OiV8OiV8OiIc", "ncV:512:", "avx512f,vpclmulqdq")
+TARGET_BUILTIN(__builtin_ia32_pclmulqdq512, "V8OiV8OiV8OiIc", "ncV:512:", "avx512f,evex512,vpclmulqdq")
// AVX
TARGET_BUILTIN(__builtin_ia32_addsubpd256, "V4dV4dV4d", "ncV:256:", "avx")
@@ -558,21 +536,10 @@ 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")
TARGET_BUILTIN(__builtin_ia32_packusdw256, "V16sV8iV8i", "ncV:256:", "avx2")
-TARGET_BUILTIN(__builtin_ia32_paddsb256, "V32cV32cV32c", "ncV:256:", "avx2")
-TARGET_BUILTIN(__builtin_ia32_paddsw256, "V16sV16sV16s", "ncV:256:", "avx2")
-TARGET_BUILTIN(__builtin_ia32_psubsb256, "V32cV32cV32c", "ncV:256:", "avx2")
-TARGET_BUILTIN(__builtin_ia32_psubsw256, "V16sV16sV16s", "ncV:256:", "avx2")
-TARGET_BUILTIN(__builtin_ia32_paddusb256, "V32cV32cV32c", "ncV:256:", "avx2")
-TARGET_BUILTIN(__builtin_ia32_paddusw256, "V16sV16sV16s", "ncV:256:", "avx2")
-TARGET_BUILTIN(__builtin_ia32_psubusb256, "V32cV32cV32c", "ncV:256:", "avx2")
-TARGET_BUILTIN(__builtin_ia32_psubusw256, "V16sV16sV16s", "ncV:256:", "avx2")
TARGET_BUILTIN(__builtin_ia32_palignr256, "V32cV32cV32cIi", "ncV:256:", "avx2")
TARGET_BUILTIN(__builtin_ia32_pavgb256, "V32cV32cV32c", "ncV:256:", "avx2")
TARGET_BUILTIN(__builtin_ia32_pavgw256, "V16sV16sV16s", "ncV:256:", "avx2")
@@ -586,18 +553,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")
@@ -695,9 +650,9 @@ TARGET_BUILTIN(__builtin_ia32_fxsave, "vv*", "n", "fxsr")
TARGET_BUILTIN(__builtin_ia32_xsave, "vv*UOi", "n", "xsave")
TARGET_BUILTIN(__builtin_ia32_xrstor, "vv*UOi", "n", "xsave")
TARGET_BUILTIN(__builtin_ia32_xgetbv, "UOiUi", "n", "xsave")
-TARGET_HEADER_BUILTIN(_xgetbv, "UWiUi", "nh", "immintrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_xgetbv, "UWiUi", "nh", IMMINTRIN_H, ALL_MS_LANGUAGES, "")
TARGET_BUILTIN(__builtin_ia32_xsetbv, "vUiUOi", "n", "xsave")
-TARGET_HEADER_BUILTIN(_xsetbv, "vUiUWi", "nh", "immintrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_xsetbv, "vUiUWi", "nh", IMMINTRIN_H, ALL_MS_LANGUAGES, "")
TARGET_BUILTIN(__builtin_ia32_xsaveopt, "vv*UOi", "n", "xsaveopt")
TARGET_BUILTIN(__builtin_ia32_xrstors, "vv*UOi", "n", "xsaves")
TARGET_BUILTIN(__builtin_ia32_xsavec, "vv*UOi", "n", "xsavec")
@@ -777,22 +732,22 @@ TARGET_BUILTIN(__builtin_ia32_vfmaddpd256, "V4dV4dV4dV4d", "ncV:256:", "fma|fma4
TARGET_BUILTIN(__builtin_ia32_vfmaddsubps256, "V8fV8fV8fV8f", "ncV:256:", "fma|fma4")
TARGET_BUILTIN(__builtin_ia32_vfmaddsubpd256, "V4dV4dV4dV4d", "ncV:256:", "fma|fma4")
-TARGET_BUILTIN(__builtin_ia32_vfmaddpd512_mask, "V8dV8dV8dV8dUcIi", "ncV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_vfmaddpd512_maskz, "V8dV8dV8dV8dUcIi", "ncV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_vfmaddpd512_mask3, "V8dV8dV8dV8dUcIi", "ncV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_vfmsubpd512_mask3, "V8dV8dV8dV8dUcIi", "ncV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_vfmaddps512_mask, "V16fV16fV16fV16fUsIi", "ncV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_vfmaddps512_maskz, "V16fV16fV16fV16fUsIi", "ncV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_vfmaddps512_mask3, "V16fV16fV16fV16fUsIi", "ncV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_vfmsubps512_mask3, "V16fV16fV16fV16fUsIi", "ncV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_vfmaddsubpd512_mask, "V8dV8dV8dV8dUcIi", "ncV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_vfmaddsubpd512_maskz, "V8dV8dV8dV8dUcIi", "ncV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_vfmaddsubpd512_mask3, "V8dV8dV8dV8dUcIi", "ncV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_vfmsubaddpd512_mask3, "V8dV8dV8dV8dUcIi", "ncV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_vfmaddsubps512_mask, "V16fV16fV16fV16fUsIi", "ncV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_vfmaddsubps512_maskz, "V16fV16fV16fV16fUsIi", "ncV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_vfmaddsubps512_mask3, "V16fV16fV16fV16fUsIi", "ncV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_vfmsubaddps512_mask3, "V16fV16fV16fV16fUsIi", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_vfmaddpd512_mask, "V8dV8dV8dV8dUcIi", "ncV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_vfmaddpd512_maskz, "V8dV8dV8dV8dUcIi", "ncV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_vfmaddpd512_mask3, "V8dV8dV8dV8dUcIi", "ncV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_vfmsubpd512_mask3, "V8dV8dV8dV8dUcIi", "ncV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_vfmaddps512_mask, "V16fV16fV16fV16fUsIi", "ncV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_vfmaddps512_maskz, "V16fV16fV16fV16fUsIi", "ncV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_vfmaddps512_mask3, "V16fV16fV16fV16fUsIi", "ncV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_vfmsubps512_mask3, "V16fV16fV16fV16fUsIi", "ncV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_vfmaddsubpd512_mask, "V8dV8dV8dV8dUcIi", "ncV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_vfmaddsubpd512_maskz, "V8dV8dV8dV8dUcIi", "ncV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_vfmaddsubpd512_mask3, "V8dV8dV8dV8dUcIi", "ncV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_vfmsubaddpd512_mask3, "V8dV8dV8dV8dUcIi", "ncV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_vfmaddsubps512_mask, "V16fV16fV16fV16fUsIi", "ncV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_vfmaddsubps512_maskz, "V16fV16fV16fV16fUsIi", "ncV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_vfmaddsubps512_mask3, "V16fV16fV16fV16fUsIi", "ncV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_vfmsubaddps512_mask3, "V16fV16fV16fV16fUsIi", "ncV:512:", "avx512f,evex512")
// XOP
TARGET_BUILTIN(__builtin_ia32_vpmacssww, "V8sV8sV8sV8s", "ncV:128:", "xop")
@@ -870,108 +825,114 @@ BUILTIN(__rdtsc, "UOi", "")
BUILTIN(__builtin_ia32_rdtscp, "UOiUi*", "")
TARGET_BUILTIN(__builtin_ia32_rdpid, "Ui", "n", "rdpid")
+TARGET_BUILTIN(__builtin_ia32_rdpru, "ULLii", "n", "rdpru")
// PKU
TARGET_BUILTIN(__builtin_ia32_rdpkru, "Ui", "n", "pku")
TARGET_BUILTIN(__builtin_ia32_wrpkru, "vUi", "n", "pku")
// AVX-512
-TARGET_BUILTIN(__builtin_ia32_sqrtpd512, "V8dV8dIi", "ncV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_sqrtps512, "V16fV16fIi", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_sqrtpd512, "V8dV8dIi", "ncV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_sqrtps512, "V16fV16fIi", "ncV:512:", "avx512f,evex512")
TARGET_BUILTIN(__builtin_ia32_rsqrt14sd_mask, "V2dV2dV2dV2dUc", "ncV:128:", "avx512f")
TARGET_BUILTIN(__builtin_ia32_rsqrt14ss_mask, "V4fV4fV4fV4fUc", "ncV:128:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_rsqrt14pd512_mask, "V8dV8dV8dUc", "ncV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_rsqrt14ps512_mask, "V16fV16fV16fUs", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_rsqrt14pd512_mask, "V8dV8dV8dUc", "ncV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_rsqrt14ps512_mask, "V16fV16fV16fUs", "ncV:512:", "avx512f,evex512")
TARGET_BUILTIN(__builtin_ia32_rsqrt28sd_round_mask, "V2dV2dV2dV2dUcIi", "ncV:128:", "avx512er")
TARGET_BUILTIN(__builtin_ia32_rsqrt28ss_round_mask, "V4fV4fV4fV4fUcIi", "ncV:128:", "avx512er")
-TARGET_BUILTIN(__builtin_ia32_rsqrt28pd_mask, "V8dV8dV8dUcIi", "ncV:512:", "avx512er")
-TARGET_BUILTIN(__builtin_ia32_rsqrt28ps_mask, "V16fV16fV16fUsIi", "ncV:512:", "avx512er")
+TARGET_BUILTIN(__builtin_ia32_rsqrt28pd_mask, "V8dV8dV8dUcIi", "ncV:512:", "avx512er,evex512")
+TARGET_BUILTIN(__builtin_ia32_rsqrt28ps_mask, "V16fV16fV16fUsIi", "ncV:512:", "avx512er,evex512")
TARGET_BUILTIN(__builtin_ia32_rcp14sd_mask, "V2dV2dV2dV2dUc", "ncV:128:", "avx512f")
TARGET_BUILTIN(__builtin_ia32_rcp14ss_mask, "V4fV4fV4fV4fUc", "ncV:128:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_rcp14pd512_mask, "V8dV8dV8dUc", "ncV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_rcp14ps512_mask, "V16fV16fV16fUs", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_rcp14pd512_mask, "V8dV8dV8dUc", "ncV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_rcp14ps512_mask, "V16fV16fV16fUs", "ncV:512:", "avx512f,evex512")
TARGET_BUILTIN(__builtin_ia32_rcp28sd_round_mask, "V2dV2dV2dV2dUcIi", "ncV:128:", "avx512er")
TARGET_BUILTIN(__builtin_ia32_rcp28ss_round_mask, "V4fV4fV4fV4fUcIi", "ncV:128:", "avx512er")
-TARGET_BUILTIN(__builtin_ia32_rcp28pd_mask, "V8dV8dV8dUcIi", "ncV:512:", "avx512er")
-TARGET_BUILTIN(__builtin_ia32_rcp28ps_mask, "V16fV16fV16fUsIi", "ncV:512:", "avx512er")
-TARGET_BUILTIN(__builtin_ia32_exp2pd_mask, "V8dV8dV8dUcIi", "ncV:512:", "avx512er")
-TARGET_BUILTIN(__builtin_ia32_exp2ps_mask, "V16fV16fV16fUsIi", "ncV:512:", "avx512er")
+TARGET_BUILTIN(__builtin_ia32_rcp28pd_mask, "V8dV8dV8dUcIi", "ncV:512:", "avx512er,evex512")
+TARGET_BUILTIN(__builtin_ia32_rcp28ps_mask, "V16fV16fV16fUsIi", "ncV:512:", "avx512er,evex512")
+TARGET_BUILTIN(__builtin_ia32_exp2pd_mask, "V8dV8dV8dUcIi", "ncV:512:", "avx512er,evex512")
+TARGET_BUILTIN(__builtin_ia32_exp2ps_mask, "V16fV16fV16fUsIi", "ncV:512:", "avx512er,evex512")
-TARGET_BUILTIN(__builtin_ia32_cvttps2dq512_mask, "V16iV16fV16iUsIi", "ncV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_cvttps2udq512_mask, "V16iV16fV16iUsIi", "ncV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_cvttpd2dq512_mask, "V8iV8dV8iUcIi", "ncV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_cvttpd2udq512_mask, "V8iV8dV8iUcIi", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_cvttps2dq512_mask, "V16iV16fV16iUsIi", "ncV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_cvttps2udq512_mask, "V16iV16fV16iUsIi", "ncV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_cvttpd2dq512_mask, "V8iV8dV8iUcIi", "ncV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_cvttpd2udq512_mask, "V8iV8dV8iUcIi", "ncV:512:", "avx512f,evex512")
-TARGET_BUILTIN(__builtin_ia32_cmpps512_mask, "UsV16fV16fIiUsIi", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_cmpps512_mask, "UsV16fV16fIiUsIi", "ncV:512:", "avx512f,evex512")
TARGET_BUILTIN(__builtin_ia32_cmpps256_mask, "UcV8fV8fIiUc", "ncV:256:", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_cmpps128_mask, "UcV4fV4fIiUc", "ncV:128:", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_cmppd512_mask, "UcV8dV8dIiUcIi", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_cmppd512_mask, "UcV8dV8dIiUcIi", "ncV:512:", "avx512f,evex512")
TARGET_BUILTIN(__builtin_ia32_cmppd256_mask, "UcV4dV4dIiUc", "ncV:256:", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_cmppd128_mask, "UcV2dV2dIiUc", "ncV:128:", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_rndscaleps_mask, "V16fV16fIiV16fUsIi", "ncV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_rndscalepd_mask, "V8dV8dIiV8dUcIi", "ncV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_cvtps2dq512_mask, "V16iV16fV16iUsIi", "ncV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_cvtpd2dq512_mask, "V8iV8dV8iUcIi", "ncV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_cvtps2udq512_mask, "V16iV16fV16iUsIi", "ncV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_cvtpd2udq512_mask, "V8iV8dV8iUcIi", "ncV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_minps512, "V16fV16fV16fIi", "ncV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_minpd512, "V8dV8dV8dIi", "ncV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_maxps512, "V16fV16fV16fIi", "ncV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_maxpd512, "V8dV8dV8dIi", "ncV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_cvtdq2ps512_mask, "V16fV16iV16fUsIi", "ncV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_cvtudq2ps512_mask, "V16fV16iV16fUsIi", "ncV:512:", "avx512f")
-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")
-TARGET_BUILTIN(__builtin_ia32_loaddqudi512_mask, "V8OiOiC*V8OiUc", "nV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_loadups512_mask, "V16ffC*V16fUs", "nV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_loadaps512_mask, "V16fV16fC*V16fUs", "nV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_loadupd512_mask, "V8ddC*V8dUc", "nV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_loadapd512_mask, "V8dV8dC*V8dUc", "nV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_storedqudi512_mask, "vOi*V8OiUc", "nV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_storedqusi512_mask, "vi*V16iUs", "nV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_storeupd512_mask, "vd*V8dUc", "nV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_storeapd512_mask, "vV8d*V8dUc", "nV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_storeups512_mask, "vf*V16fUs", "nV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_storeaps512_mask, "vV16f*V16fUs", "nV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_alignq512, "V8OiV8OiV8OiIi", "ncV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_alignd512, "V16iV16iV16iIi", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_rndscaleps_mask, "V16fV16fIiV16fUsIi", "ncV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_rndscalepd_mask, "V8dV8dIiV8dUcIi", "ncV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_cvtps2dq512_mask, "V16iV16fV16iUsIi", "ncV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_cvtpd2dq512_mask, "V8iV8dV8iUcIi", "ncV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_cvtps2udq512_mask, "V16iV16fV16iUsIi", "ncV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_cvtpd2udq512_mask, "V8iV8dV8iUcIi", "ncV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_minps512, "V16fV16fV16fIi", "ncV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_minpd512, "V8dV8dV8dIi", "ncV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_maxps512, "V16fV16fV16fIi", "ncV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_maxpd512, "V8dV8dV8dIi", "ncV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_cvtdq2ps512_mask, "V16fV16iV16fUsIi", "ncV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_cvtudq2ps512_mask, "V16fV16iV16fUsIi", "ncV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_cvtpd2ps512_mask, "V8fV8dV8fUcIi", "ncV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_vcvtps2ph512_mask, "V16sV16fIiV16sUs", "ncV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_vcvtph2ps512_mask, "V16fV16sV16fUsIi", "ncV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_pmuldq512, "V8OiV16iV16i", "ncV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_pmuludq512, "V8OiV16iV16i", "ncV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_loaddqusi512_mask, "V16iiC*V16iUs", "nV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_loaddqudi512_mask, "V8OiOiC*V8OiUc", "nV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_loadups512_mask, "V16ffC*V16fUs", "nV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_loadaps512_mask, "V16fV16fC*V16fUs", "nV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_loadupd512_mask, "V8ddC*V8dUc", "nV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_loadapd512_mask, "V8dV8dC*V8dUc", "nV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_storedqudi512_mask, "vOi*V8OiUc", "nV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_storedqusi512_mask, "vi*V16iUs", "nV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_storeupd512_mask, "vd*V8dUc", "nV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_storeapd512_mask, "vV8d*V8dUc", "nV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_storeups512_mask, "vf*V16fUs", "nV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_storeaps512_mask, "vV16f*V16fUs", "nV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_alignq512, "V8OiV8OiV8OiIi", "ncV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_alignd512, "V16iV16iV16iIi", "ncV:512:", "avx512f,evex512")
TARGET_BUILTIN(__builtin_ia32_alignd128, "V4iV4iV4iIi", "ncV:128:", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_alignd256, "V8iV8iV8iIi", "ncV:256:", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_alignq128, "V2OiV2OiV2OiIi", "ncV:128:", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_alignq256, "V4OiV4OiV4OiIi", "ncV:256:", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_extractf64x4_mask, "V4dV8dIiV4dUc", "ncV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_extractf32x4_mask, "V4fV16fIiV4fUc", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_extractf64x4_mask, "V4dV8dIiV4dUc", "ncV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_extractf32x4_mask, "V4fV16fIiV4fUc", "ncV:512:", "avx512f,evex512")
+// AVX-VNNI and AVX512-VNNI
TARGET_BUILTIN(__builtin_ia32_vpdpbusd128, "V4iV4iV4iV4i", "ncV:128:", "avx512vl,avx512vnni|avxvnni")
TARGET_BUILTIN(__builtin_ia32_vpdpbusd256, "V8iV8iV8iV8i", "ncV:256:", "avx512vl,avx512vnni|avxvnni")
-TARGET_BUILTIN(__builtin_ia32_vpdpbusd512, "V16iV16iV16iV16i", "ncV:512:", "avx512vnni")
+TARGET_BUILTIN(__builtin_ia32_vpdpbusd512, "V16iV16iV16iV16i", "ncV:512:", "avx512vnni,evex512")
TARGET_BUILTIN(__builtin_ia32_vpdpbusds128, "V4iV4iV4iV4i", "ncV:128:", "avx512vl,avx512vnni|avxvnni")
TARGET_BUILTIN(__builtin_ia32_vpdpbusds256, "V8iV8iV8iV8i", "ncV:256:", "avx512vl,avx512vnni|avxvnni")
-TARGET_BUILTIN(__builtin_ia32_vpdpbusds512, "V16iV16iV16iV16i", "ncV:512:", "avx512vnni")
+TARGET_BUILTIN(__builtin_ia32_vpdpbusds512, "V16iV16iV16iV16i", "ncV:512:", "avx512vnni,evex512")
TARGET_BUILTIN(__builtin_ia32_vpdpwssd128, "V4iV4iV4iV4i", "ncV:128:", "avx512vl,avx512vnni|avxvnni")
TARGET_BUILTIN(__builtin_ia32_vpdpwssd256, "V8iV8iV8iV8i", "ncV:256:", "avx512vl,avx512vnni|avxvnni")
-TARGET_BUILTIN(__builtin_ia32_vpdpwssd512, "V16iV16iV16iV16i", "ncV:512:", "avx512vnni")
+TARGET_BUILTIN(__builtin_ia32_vpdpwssd512, "V16iV16iV16iV16i", "ncV:512:", "avx512vnni,evex512")
TARGET_BUILTIN(__builtin_ia32_vpdpwssds128, "V4iV4iV4iV4i", "ncV:128:", "avx512vl,avx512vnni|avxvnni")
TARGET_BUILTIN(__builtin_ia32_vpdpwssds256, "V8iV8iV8iV8i", "ncV:256:", "avx512vl,avx512vnni|avxvnni")
-TARGET_BUILTIN(__builtin_ia32_vpdpwssds512, "V16iV16iV16iV16i", "ncV:512:", "avx512vnni")
+TARGET_BUILTIN(__builtin_ia32_vpdpwssds512, "V16iV16iV16iV16i", "ncV:512:", "avx512vnni,evex512")
+
+// AVX-VNNI-INT8
+TARGET_BUILTIN(__builtin_ia32_vpdpbssd128, "V4iV4iV4iV4i", "ncV:128:", "avxvnniint8")
+TARGET_BUILTIN(__builtin_ia32_vpdpbssd256, "V8iV8iV8iV8i", "ncV:256:", "avxvnniint8")
+TARGET_BUILTIN(__builtin_ia32_vpdpbssds128, "V4iV4iV4iV4i", "ncV:128:", "avxvnniint8")
+TARGET_BUILTIN(__builtin_ia32_vpdpbssds256, "V8iV8iV8iV8i", "ncV:256:", "avxvnniint8")
+TARGET_BUILTIN(__builtin_ia32_vpdpbsud128, "V4iV4iV4iV4i", "ncV:128:", "avxvnniint8")
+TARGET_BUILTIN(__builtin_ia32_vpdpbsud256, "V8iV8iV8iV8i", "ncV:256:", "avxvnniint8")
+TARGET_BUILTIN(__builtin_ia32_vpdpbsuds128, "V4iV4iV4iV4i", "ncV:128:", "avxvnniint8")
+TARGET_BUILTIN(__builtin_ia32_vpdpbsuds256, "V8iV8iV8iV8i", "ncV:256:", "avxvnniint8")
+TARGET_BUILTIN(__builtin_ia32_vpdpbuud128, "V4iV4iV4iV4i", "ncV:128:", "avxvnniint8")
+TARGET_BUILTIN(__builtin_ia32_vpdpbuud256, "V8iV8iV8iV8i", "ncV:256:", "avxvnniint8")
+TARGET_BUILTIN(__builtin_ia32_vpdpbuuds128, "V4iV4iV4iV4i", "ncV:128:", "avxvnniint8")
+TARGET_BUILTIN(__builtin_ia32_vpdpbuuds256, "V8iV8iV8iV8i", "ncV:256:", "avxvnniint8")
TARGET_BUILTIN(__builtin_ia32_gather3div2df, "V2dV2dvC*V2OiUcIi", "nV:128:", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_gather3div2di, "V2OiV2OivC*V2OiUcIi", "nV:128:", "avx512vl")
@@ -989,31 +950,31 @@ TARGET_BUILTIN(__builtin_ia32_gather3siv4sf, "V4fV4fvC*V4iUcIi", "nV:128:", "avx
TARGET_BUILTIN(__builtin_ia32_gather3siv4si, "V4iV4ivC*V4iUcIi", "nV:128:", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_gather3siv8sf, "V8fV8fvC*V8iUcIi", "nV:256:", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_gather3siv8si, "V8iV8ivC*V8iUcIi", "nV:256:", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_gathersiv8df, "V8dV8dvC*V8iUcIi", "nV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_gathersiv16sf, "V16fV16fvC*V16iUsIi", "nV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_gatherdiv8df, "V8dV8dvC*V8OiUcIi", "nV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_gatherdiv16sf, "V8fV8fvC*V8OiUcIi", "nV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_gathersiv8di, "V8OiV8OivC*V8iUcIi", "nV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_gathersiv16si, "V16iV16ivC*V16iUsIi", "nV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_gatherdiv8di, "V8OiV8OivC*V8OiUcIi", "nV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_gatherdiv16si, "V8iV8ivC*V8OiUcIi", "nV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_scattersiv8df, "vv*UcV8iV8dIi", "nV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_scattersiv16sf, "vv*UsV16iV16fIi", "nV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_scatterdiv8df, "vv*UcV8OiV8dIi", "nV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_scatterdiv16sf, "vv*UcV8OiV8fIi", "nV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_scattersiv8di, "vv*UcV8iV8OiIi", "nV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_scattersiv16si, "vv*UsV16iV16iIi", "nV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_scatterdiv8di, "vv*UcV8OiV8OiIi", "nV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_scatterdiv16si, "vv*UcV8OiV8iIi", "nV:512:", "avx512f")
-
-TARGET_BUILTIN(__builtin_ia32_gatherpfdpd, "vUcV8ivC*IiIi", "nV:512:", "avx512pf")
-TARGET_BUILTIN(__builtin_ia32_gatherpfdps, "vUsV16ivC*IiIi", "nV:512:", "avx512pf")
-TARGET_BUILTIN(__builtin_ia32_gatherpfqpd, "vUcV8OivC*IiIi", "nV:512:", "avx512pf")
-TARGET_BUILTIN(__builtin_ia32_gatherpfqps, "vUcV8OivC*IiIi", "nV:512:", "avx512pf")
-TARGET_BUILTIN(__builtin_ia32_scatterpfdpd, "vUcV8iv*IiIi", "nV:512:", "avx512pf")
-TARGET_BUILTIN(__builtin_ia32_scatterpfdps, "vUsV16iv*IiIi", "nV:512:", "avx512pf")
-TARGET_BUILTIN(__builtin_ia32_scatterpfqpd, "vUcV8Oiv*IiIi", "nV:512:", "avx512pf")
-TARGET_BUILTIN(__builtin_ia32_scatterpfqps, "vUcV8Oiv*IiIi", "nV:512:", "avx512pf")
+TARGET_BUILTIN(__builtin_ia32_gathersiv8df, "V8dV8dvC*V8iUcIi", "nV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_gathersiv16sf, "V16fV16fvC*V16iUsIi", "nV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_gatherdiv8df, "V8dV8dvC*V8OiUcIi", "nV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_gatherdiv16sf, "V8fV8fvC*V8OiUcIi", "nV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_gathersiv8di, "V8OiV8OivC*V8iUcIi", "nV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_gathersiv16si, "V16iV16ivC*V16iUsIi", "nV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_gatherdiv8di, "V8OiV8OivC*V8OiUcIi", "nV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_gatherdiv16si, "V8iV8ivC*V8OiUcIi", "nV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_scattersiv8df, "vv*UcV8iV8dIi", "nV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_scattersiv16sf, "vv*UsV16iV16fIi", "nV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_scatterdiv8df, "vv*UcV8OiV8dIi", "nV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_scatterdiv16sf, "vv*UcV8OiV8fIi", "nV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_scattersiv8di, "vv*UcV8iV8OiIi", "nV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_scattersiv16si, "vv*UsV16iV16iIi", "nV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_scatterdiv8di, "vv*UcV8OiV8OiIi", "nV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_scatterdiv16si, "vv*UcV8OiV8iIi", "nV:512:", "avx512f,evex512")
+
+TARGET_BUILTIN(__builtin_ia32_gatherpfdpd, "vUcV8ivC*IiIi", "nV:512:", "avx512pf,evex512")
+TARGET_BUILTIN(__builtin_ia32_gatherpfdps, "vUsV16ivC*IiIi", "nV:512:", "avx512pf,evex512")
+TARGET_BUILTIN(__builtin_ia32_gatherpfqpd, "vUcV8OivC*IiIi", "nV:512:", "avx512pf,evex512")
+TARGET_BUILTIN(__builtin_ia32_gatherpfqps, "vUcV8OivC*IiIi", "nV:512:", "avx512pf,evex512")
+TARGET_BUILTIN(__builtin_ia32_scatterpfdpd, "vUcV8iv*IiIi", "nV:512:", "avx512pf,evex512")
+TARGET_BUILTIN(__builtin_ia32_scatterpfdps, "vUsV16iv*IiIi", "nV:512:", "avx512pf,evex512")
+TARGET_BUILTIN(__builtin_ia32_scatterpfqpd, "vUcV8Oiv*IiIi", "nV:512:", "avx512pf,evex512")
+TARGET_BUILTIN(__builtin_ia32_scatterpfqps, "vUcV8Oiv*IiIi", "nV:512:", "avx512pf,evex512")
TARGET_BUILTIN(__builtin_ia32_knotqi, "UcUc", "nc", "avx512dq")
TARGET_BUILTIN(__builtin_ia32_knothi, "UsUs", "nc", "avx512f")
@@ -1028,10 +989,10 @@ TARGET_BUILTIN(__builtin_ia32_cmpb256_mask, "UiV32cV32cIiUi", "ncV:256:", "avx51
TARGET_BUILTIN(__builtin_ia32_cmpd256_mask, "UcV8iV8iIiUc", "ncV:256:", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_cmpq256_mask, "UcV4OiV4OiIiUc", "ncV:256:", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_cmpw256_mask, "UsV16sV16sIiUs", "ncV:256:", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_cmpb512_mask, "UOiV64cV64cIiUOi", "ncV:512:", "avx512bw")
-TARGET_BUILTIN(__builtin_ia32_cmpd512_mask, "UsV16iV16iIiUs", "ncV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_cmpq512_mask, "UcV8OiV8OiIiUc", "ncV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_cmpw512_mask, "UiV32sV32sIiUi", "ncV:512:", "avx512bw")
+TARGET_BUILTIN(__builtin_ia32_cmpb512_mask, "UOiV64cV64cIiUOi", "ncV:512:", "avx512bw,evex512")
+TARGET_BUILTIN(__builtin_ia32_cmpd512_mask, "UsV16iV16iIiUs", "ncV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_cmpq512_mask, "UcV8OiV8OiIiUc", "ncV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_cmpw512_mask, "UiV32sV32sIiUi", "ncV:512:", "avx512bw,evex512")
TARGET_BUILTIN(__builtin_ia32_ucmpb128_mask, "UsV16cV16cIiUs", "ncV:128:", "avx512vl,avx512bw")
TARGET_BUILTIN(__builtin_ia32_ucmpd128_mask, "UcV4iV4iIiUc", "ncV:128:", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_ucmpq128_mask, "UcV2OiV2OiIiUc", "ncV:128:", "avx512vl")
@@ -1040,79 +1001,61 @@ TARGET_BUILTIN(__builtin_ia32_ucmpb256_mask, "UiV32cV32cIiUi", "ncV:256:", "avx5
TARGET_BUILTIN(__builtin_ia32_ucmpd256_mask, "UcV8iV8iIiUc", "ncV:256:", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_ucmpq256_mask, "UcV4OiV4OiIiUc", "ncV:256:", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_ucmpw256_mask, "UsV16sV16sIiUs", "ncV:256:", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_ucmpb512_mask, "UOiV64cV64cIiUOi", "ncV:512:", "avx512bw")
-TARGET_BUILTIN(__builtin_ia32_ucmpd512_mask, "UsV16iV16iIiUs", "ncV:512:", "avx512f")
-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")
-TARGET_BUILTIN(__builtin_ia32_packuswb512, "V64cV32sV32s", "ncV:512:", "avx512bw")
-TARGET_BUILTIN(__builtin_ia32_paddsb512, "V64cV64cV64c", "ncV:512:", "avx512bw")
-TARGET_BUILTIN(__builtin_ia32_paddsw512, "V32sV32sV32s", "ncV:512:", "avx512bw")
-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")
-TARGET_BUILTIN(__builtin_ia32_psubusb512, "V64cV64cV64c", "ncV:512:", "avx512bw")
-TARGET_BUILTIN(__builtin_ia32_psubusw512, "V32sV32sV32s", "ncV:512:", "avx512bw")
+TARGET_BUILTIN(__builtin_ia32_ucmpb512_mask, "UOiV64cV64cIiUOi", "ncV:512:", "avx512bw,evex512")
+TARGET_BUILTIN(__builtin_ia32_ucmpd512_mask, "UsV16iV16iIiUs", "ncV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_ucmpq512_mask, "UcV8OiV8OiIiUc", "ncV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_ucmpw512_mask, "UiV32sV32sIiUi", "ncV:512:", "avx512bw,evex512")
+
+TARGET_BUILTIN(__builtin_ia32_packssdw512, "V32sV16iV16i", "ncV:512:", "avx512bw,evex512")
+TARGET_BUILTIN(__builtin_ia32_packsswb512, "V64cV32sV32s", "ncV:512:", "avx512bw,evex512")
+TARGET_BUILTIN(__builtin_ia32_packusdw512, "V32sV16iV16i", "ncV:512:", "avx512bw,evex512")
+TARGET_BUILTIN(__builtin_ia32_packuswb512, "V64cV32sV32s", "ncV:512:", "avx512bw,evex512")
+TARGET_BUILTIN(__builtin_ia32_pavgb512, "V64cV64cV64c", "ncV:512:", "avx512bw,evex512")
+TARGET_BUILTIN(__builtin_ia32_pavgw512, "V32sV32sV32s", "ncV:512:", "avx512bw,evex512")
+TARGET_BUILTIN(__builtin_ia32_pshufb512, "V64cV64cV64c", "ncV:512:", "avx512bw,evex512")
TARGET_BUILTIN(__builtin_ia32_vpconflictdi_128, "V2OiV2Oi", "ncV:128:", "avx512cd,avx512vl")
TARGET_BUILTIN(__builtin_ia32_vpconflictdi_256, "V4OiV4Oi", "ncV:256:", "avx512cd,avx512vl")
TARGET_BUILTIN(__builtin_ia32_vpconflictsi_128, "V4iV4i", "ncV:128:", "avx512cd,avx512vl")
TARGET_BUILTIN(__builtin_ia32_vpconflictsi_256, "V8iV8i", "ncV:256:", "avx512cd,avx512vl")
-TARGET_BUILTIN(__builtin_ia32_vpconflictdi_512, "V8OiV8Oi", "ncV:512:", "avx512cd")
-TARGET_BUILTIN(__builtin_ia32_vpconflictsi_512, "V16iV16i", "ncV:512:", "avx512cd")
-TARGET_BUILTIN(__builtin_ia32_vplzcntd_512, "V16iV16i", "ncV:512:", "avx512cd")
-TARGET_BUILTIN(__builtin_ia32_vplzcntq_512, "V8OiV8Oi", "ncV:512:", "avx512cd")
+TARGET_BUILTIN(__builtin_ia32_vpconflictdi_512, "V8OiV8Oi", "ncV:512:", "avx512cd,evex512")
+TARGET_BUILTIN(__builtin_ia32_vpconflictsi_512, "V16iV16i", "ncV:512:", "avx512cd,evex512")
+TARGET_BUILTIN(__builtin_ia32_vplzcntd_512, "V16iV16i", "ncV:512:", "avx512cd,evex512")
+TARGET_BUILTIN(__builtin_ia32_vplzcntq_512, "V8OiV8Oi", "ncV:512:", "avx512cd,evex512")
TARGET_BUILTIN(__builtin_ia32_vpopcntd_128, "V4iV4i", "ncV:128:", "avx512vpopcntdq,avx512vl")
TARGET_BUILTIN(__builtin_ia32_vpopcntq_128, "V2OiV2Oi", "ncV:128:", "avx512vpopcntdq,avx512vl")
TARGET_BUILTIN(__builtin_ia32_vpopcntd_256, "V8iV8i", "ncV:256:", "avx512vpopcntdq,avx512vl")
TARGET_BUILTIN(__builtin_ia32_vpopcntq_256, "V4OiV4Oi", "ncV:256:", "avx512vpopcntdq,avx512vl")
-TARGET_BUILTIN(__builtin_ia32_vpopcntd_512, "V16iV16i", "ncV:512:", "avx512vpopcntdq")
-TARGET_BUILTIN(__builtin_ia32_vpopcntq_512, "V8OiV8Oi", "ncV:512:", "avx512vpopcntdq")
+TARGET_BUILTIN(__builtin_ia32_vpopcntd_512, "V16iV16i", "ncV:512:", "avx512vpopcntdq,evex512")
+TARGET_BUILTIN(__builtin_ia32_vpopcntq_512, "V8OiV8Oi", "ncV:512:", "avx512vpopcntdq,evex512")
TARGET_BUILTIN(__builtin_ia32_vpopcntb_128, "V16cV16c", "ncV:128:", "avx512vl,avx512bitalg")
TARGET_BUILTIN(__builtin_ia32_vpopcntw_128, "V8sV8s", "ncV:128:", "avx512vl,avx512bitalg")
TARGET_BUILTIN(__builtin_ia32_vpopcntb_256, "V32cV32c", "ncV:256:", "avx512vl,avx512bitalg")
TARGET_BUILTIN(__builtin_ia32_vpopcntw_256, "V16sV16s", "ncV:256:", "avx512vl,avx512bitalg")
-TARGET_BUILTIN(__builtin_ia32_vpopcntb_512, "V64cV64c", "ncV:512:", "avx512bitalg")
-TARGET_BUILTIN(__builtin_ia32_vpopcntw_512, "V32sV32s", "ncV:512:", "avx512bitalg")
+TARGET_BUILTIN(__builtin_ia32_vpopcntb_512, "V64cV64c", "ncV:512:", "avx512bitalg,evex512")
+TARGET_BUILTIN(__builtin_ia32_vpopcntw_512, "V32sV32s", "ncV:512:", "avx512bitalg,evex512")
TARGET_BUILTIN(__builtin_ia32_vpshufbitqmb128_mask, "UsV16cV16cUs", "ncV:128:", "avx512vl,avx512bitalg")
TARGET_BUILTIN(__builtin_ia32_vpshufbitqmb256_mask, "UiV32cV32cUi", "ncV:256:", "avx512vl,avx512bitalg")
-TARGET_BUILTIN(__builtin_ia32_vpshufbitqmb512_mask, "UOiV64cV64cUOi", "ncV:512:", "avx512bitalg")
+TARGET_BUILTIN(__builtin_ia32_vpshufbitqmb512_mask, "UOiV64cV64cUOi", "ncV:512:", "avx512bitalg,evex512")
-TARGET_BUILTIN(__builtin_ia32_pmulhrsw512, "V32sV32sV32s", "ncV:512:", "avx512bw")
-TARGET_BUILTIN(__builtin_ia32_pmulhuw512, "V32sV32sV32s", "ncV:512:", "avx512bw")
-TARGET_BUILTIN(__builtin_ia32_pmulhw512, "V32sV32sV32s", "ncV:512:", "avx512bw")
+TARGET_BUILTIN(__builtin_ia32_pmulhrsw512, "V32sV32sV32s", "ncV:512:", "avx512bw,evex512")
+TARGET_BUILTIN(__builtin_ia32_pmulhuw512, "V32sV32sV32s", "ncV:512:", "avx512bw,evex512")
+TARGET_BUILTIN(__builtin_ia32_pmulhw512, "V32sV32sV32s", "ncV:512:", "avx512bw,evex512")
-TARGET_BUILTIN(__builtin_ia32_addpd512, "V8dV8dV8dIi", "ncV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_addps512, "V16fV16fV16fIi", "ncV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_divpd512, "V8dV8dV8dIi", "ncV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_divps512, "V16fV16fV16fIi", "ncV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_mulpd512, "V8dV8dV8dIi", "ncV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_mulps512, "V16fV16fV16fIi", "ncV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_subpd512, "V8dV8dV8dIi", "ncV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_subps512, "V16fV16fV16fIi", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_addpd512, "V8dV8dV8dIi", "ncV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_addps512, "V16fV16fV16fIi", "ncV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_divpd512, "V8dV8dV8dIi", "ncV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_divps512, "V16fV16fV16fIi", "ncV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_mulpd512, "V8dV8dV8dIi", "ncV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_mulps512, "V16fV16fV16fIi", "ncV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_subpd512, "V8dV8dV8dIi", "ncV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_subps512, "V16fV16fV16fIi", "ncV:512:", "avx512f,evex512")
-TARGET_BUILTIN(__builtin_ia32_pmaddubsw512, "V32sV64cV64c", "ncV:512:", "avx512bw")
-TARGET_BUILTIN(__builtin_ia32_pmaddwd512, "V16iV32sV32s", "ncV:512:", "avx512bw")
+TARGET_BUILTIN(__builtin_ia32_pmaddubsw512, "V32sV64cV64c", "ncV:512:", "avx512bw,evex512")
+TARGET_BUILTIN(__builtin_ia32_pmaddwd512, "V16iV32sV32s", "ncV:512:", "avx512bw,evex512")
TARGET_BUILTIN(__builtin_ia32_addss_round_mask, "V4fV4fV4fV4fUcIi", "ncV:128:", "avx512f")
TARGET_BUILTIN(__builtin_ia32_divss_round_mask, "V4fV4fV4fV4fUcIi", "ncV:128:", "avx512f")
@@ -1198,16 +1141,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")
@@ -1236,66 +1169,66 @@ TARGET_BUILTIN(__builtin_ia32_scattersiv8si, "vv*UcV8iV8iIi", "nV:256:", "avx512
TARGET_BUILTIN(__builtin_ia32_vpermi2vard128, "V4iV4iV4iV4i", "ncV:128:", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_vpermi2vard256, "V8iV8iV8iV8i", "ncV:256:", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_vpermi2vard512, "V16iV16iV16iV16i", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_vpermi2vard512, "V16iV16iV16iV16i", "ncV:512:", "avx512f,evex512")
TARGET_BUILTIN(__builtin_ia32_vpermi2varpd128, "V2dV2dV2OiV2d", "ncV:128:", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_vpermi2varpd256, "V4dV4dV4OiV4d", "ncV:256:", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_vpermi2varpd512, "V8dV8dV8OiV8d", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_vpermi2varpd512, "V8dV8dV8OiV8d", "ncV:512:", "avx512f,evex512")
TARGET_BUILTIN(__builtin_ia32_vpermi2varps128, "V4fV4fV4iV4f", "ncV:128:", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_vpermi2varps256, "V8fV8fV8iV8f", "ncV:256:", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_vpermi2varps512, "V16fV16fV16iV16f", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_vpermi2varps512, "V16fV16fV16iV16f", "ncV:512:", "avx512f,evex512")
TARGET_BUILTIN(__builtin_ia32_vpermi2varq128, "V2OiV2OiV2OiV2Oi", "ncV:128:", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_vpermi2varq256, "V4OiV4OiV4OiV4Oi", "ncV:256:", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_vpermi2varq512, "V8OiV8OiV8OiV8Oi", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_vpermi2varq512, "V8OiV8OiV8OiV8Oi", "ncV:512:", "avx512f,evex512")
TARGET_BUILTIN(__builtin_ia32_vpermi2varqi128, "V16cV16cV16cV16c", "ncV:128:", "avx512vbmi,avx512vl")
TARGET_BUILTIN(__builtin_ia32_vpermi2varqi256, "V32cV32cV32cV32c", "ncV:256:", "avx512vbmi,avx512vl")
-TARGET_BUILTIN(__builtin_ia32_vpermi2varqi512, "V64cV64cV64cV64c", "ncV:512:", "avx512vbmi")
+TARGET_BUILTIN(__builtin_ia32_vpermi2varqi512, "V64cV64cV64cV64c", "ncV:512:", "avx512vbmi,evex512")
TARGET_BUILTIN(__builtin_ia32_vpermi2varhi128, "V8sV8sV8sV8s", "ncV:128:", "avx512vl,avx512bw")
TARGET_BUILTIN(__builtin_ia32_vpermi2varhi256, "V16sV16sV16sV16s", "ncV:256:", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_vpermi2varhi512, "V32sV32sV32sV32s", "ncV:512:", "avx512bw")
+TARGET_BUILTIN(__builtin_ia32_vpermi2varhi512, "V32sV32sV32sV32s", "ncV:512:", "avx512bw,evex512")
TARGET_BUILTIN(__builtin_ia32_vpshldd128, "V4iV4iV4iIi", "ncV:128:", "avx512vl,avx512vbmi2")
TARGET_BUILTIN(__builtin_ia32_vpshldd256, "V8iV8iV8iIi", "ncV:256:", "avx512vl,avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshldd512, "V16iV16iV16iIi", "ncV:512:", "avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_vpshldd512, "V16iV16iV16iIi", "ncV:512:", "avx512vbmi2,evex512")
TARGET_BUILTIN(__builtin_ia32_vpshldq128, "V2OiV2OiV2OiIi", "ncV:128:", "avx512vl,avx512vbmi2")
TARGET_BUILTIN(__builtin_ia32_vpshldq256, "V4OiV4OiV4OiIi", "ncV:256:", "avx512vl,avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshldq512, "V8OiV8OiV8OiIi", "ncV:512:", "avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_vpshldq512, "V8OiV8OiV8OiIi", "ncV:512:", "avx512vbmi2,evex512")
TARGET_BUILTIN(__builtin_ia32_vpshldw128, "V8sV8sV8sIi", "ncV:128:", "avx512vl,avx512vbmi2")
TARGET_BUILTIN(__builtin_ia32_vpshldw256, "V16sV16sV16sIi", "ncV:256:", "avx512vl,avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshldw512, "V32sV32sV32sIi", "ncV:512:", "avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_vpshldw512, "V32sV32sV32sIi", "ncV:512:", "avx512vbmi2,evex512")
TARGET_BUILTIN(__builtin_ia32_vpshldvd128, "V4iV4iV4iV4i", "ncV:128:", "avx512vl,avx512vbmi2")
TARGET_BUILTIN(__builtin_ia32_vpshldvd256, "V8iV8iV8iV8i", "ncV:256:", "avx512vl,avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshldvd512, "V16iV16iV16iV16i", "ncV:512:", "avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_vpshldvd512, "V16iV16iV16iV16i", "ncV:512:", "avx512vbmi2,evex512")
TARGET_BUILTIN(__builtin_ia32_vpshldvq128, "V2OiV2OiV2OiV2Oi", "ncV:128:", "avx512vl,avx512vbmi2")
TARGET_BUILTIN(__builtin_ia32_vpshldvq256, "V4OiV4OiV4OiV4Oi", "ncV:256:", "avx512vl,avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshldvq512, "V8OiV8OiV8OiV8Oi", "ncV:512:", "avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_vpshldvq512, "V8OiV8OiV8OiV8Oi", "ncV:512:", "avx512vbmi2,evex512")
TARGET_BUILTIN(__builtin_ia32_vpshldvw128, "V8sV8sV8sV8s", "ncV:128:", "avx512vl,avx512vbmi2")
TARGET_BUILTIN(__builtin_ia32_vpshldvw256, "V16sV16sV16sV16s", "ncV:256:", "avx512vl,avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshldvw512, "V32sV32sV32sV32s", "ncV:512:", "avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_vpshldvw512, "V32sV32sV32sV32s", "ncV:512:", "avx512vbmi2,evex512")
TARGET_BUILTIN(__builtin_ia32_vpshrdvd128, "V4iV4iV4iV4i", "ncV:128:", "avx512vl,avx512vbmi2")
TARGET_BUILTIN(__builtin_ia32_vpshrdvd256, "V8iV8iV8iV8i", "ncV:256:", "avx512vl,avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshrdvd512, "V16iV16iV16iV16i", "ncV:512:", "avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_vpshrdvd512, "V16iV16iV16iV16i", "ncV:512:", "avx512vbmi2,evex512")
TARGET_BUILTIN(__builtin_ia32_vpshrdvq128, "V2OiV2OiV2OiV2Oi", "ncV:128:", "avx512vl,avx512vbmi2")
TARGET_BUILTIN(__builtin_ia32_vpshrdvq256, "V4OiV4OiV4OiV4Oi", "ncV:256:", "avx512vl,avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshrdvq512, "V8OiV8OiV8OiV8Oi", "ncV:512:", "avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_vpshrdvq512, "V8OiV8OiV8OiV8Oi", "ncV:512:", "avx512vbmi2,evex512")
TARGET_BUILTIN(__builtin_ia32_vpshrdvw128, "V8sV8sV8sV8s", "ncV:128:", "avx512vl,avx512vbmi2")
TARGET_BUILTIN(__builtin_ia32_vpshrdvw256, "V16sV16sV16sV16s", "ncV:256:", "avx512vl,avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshrdvw512, "V32sV32sV32sV32s", "ncV:512:", "avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_vpshrdvw512, "V32sV32sV32sV32s", "ncV:512:", "avx512vbmi2,evex512")
TARGET_BUILTIN(__builtin_ia32_vpshrdd128, "V4iV4iV4iIi", "ncV:128:", "avx512vl,avx512vbmi2")
TARGET_BUILTIN(__builtin_ia32_vpshrdd256, "V8iV8iV8iIi", "ncV:256:", "avx512vl,avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshrdd512, "V16iV16iV16iIi", "ncV:512:", "avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_vpshrdd512, "V16iV16iV16iIi", "ncV:512:", "avx512vbmi2,evex512")
TARGET_BUILTIN(__builtin_ia32_vpshrdq128, "V2OiV2OiV2OiIi", "ncV:128:", "avx512vl,avx512vbmi2")
TARGET_BUILTIN(__builtin_ia32_vpshrdq256, "V4OiV4OiV4OiIi", "ncV:256:", "avx512vl,avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshrdq512, "V8OiV8OiV8OiIi", "ncV:512:", "avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_vpshrdq512, "V8OiV8OiV8OiIi", "ncV:512:", "avx512vbmi2,evex512")
TARGET_BUILTIN(__builtin_ia32_vpshrdw128, "V8sV8sV8sIi", "ncV:128:", "avx512vl,avx512vbmi2")
TARGET_BUILTIN(__builtin_ia32_vpshrdw256, "V16sV16sV16sIi", "ncV:256:", "avx512vl,avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_vpshrdw512, "V32sV32sV32sIi", "ncV:512:", "avx512vbmi2")
+TARGET_BUILTIN(__builtin_ia32_vpshrdw512, "V32sV32sV32sIi", "ncV:512:", "avx512vbmi2,evex512")
-TARGET_BUILTIN(__builtin_ia32_pmovswb512_mask, "V32cV32sV32cUi", "ncV:512:", "avx512bw")
-TARGET_BUILTIN(__builtin_ia32_pmovuswb512_mask, "V32cV32sV32cUi", "ncV:512:", "avx512bw")
-TARGET_BUILTIN(__builtin_ia32_pmovwb512_mask, "V32cV32sV32cUi", "ncV:512:", "avx512bw")
+TARGET_BUILTIN(__builtin_ia32_pmovswb512_mask, "V32cV32sV32cUi", "ncV:512:", "avx512bw,evex512")
+TARGET_BUILTIN(__builtin_ia32_pmovuswb512_mask, "V32cV32sV32cUi", "ncV:512:", "avx512bw,evex512")
+TARGET_BUILTIN(__builtin_ia32_pmovwb512_mask, "V32cV32sV32cUi", "ncV:512:", "avx512bw,evex512")
TARGET_BUILTIN(__builtin_ia32_cvtpd2qq128_mask, "V2OiV2dV2OiUc", "ncV:128:", "avx512vl,avx512dq")
TARGET_BUILTIN(__builtin_ia32_cvtpd2qq256_mask, "V4OiV4dV4OiUc", "ncV:256:", "avx512vl,avx512dq")
TARGET_BUILTIN(__builtin_ia32_cvtpd2uqq128_mask, "V2OiV2dV2OiUc", "ncV:128:", "avx512vl,avx512dq")
@@ -1331,32 +1264,32 @@ TARGET_BUILTIN(__builtin_ia32_pmovswb256_mask, "V16cV16sV16cUs", "ncV:256:", "av
TARGET_BUILTIN(__builtin_ia32_pmovuswb128_mask, "V16cV8sV16cUc", "ncV:128:", "avx512vl,avx512bw")
TARGET_BUILTIN(__builtin_ia32_pmovuswb256_mask, "V16cV16sV16cUs", "ncV:256:", "avx512vl,avx512bw")
TARGET_BUILTIN(__builtin_ia32_pmovwb128_mask, "V16cV8sV16cUc", "ncV:128:", "avx512vl,avx512bw")
-TARGET_BUILTIN(__builtin_ia32_cvtpd2qq512_mask, "V8OiV8dV8OiUcIi", "ncV:512:", "avx512dq")
-TARGET_BUILTIN(__builtin_ia32_cvtpd2uqq512_mask, "V8OiV8dV8OiUcIi", "ncV:512:", "avx512dq")
-TARGET_BUILTIN(__builtin_ia32_cvtps2qq512_mask, "V8OiV8fV8OiUcIi", "ncV:512:", "avx512dq")
-TARGET_BUILTIN(__builtin_ia32_cvtps2uqq512_mask, "V8OiV8fV8OiUcIi", "ncV:512:", "avx512dq")
-TARGET_BUILTIN(__builtin_ia32_cvtqq2pd512_mask, "V8dV8OiV8dUcIi", "ncV:512:", "avx512dq")
-TARGET_BUILTIN(__builtin_ia32_cvtqq2ps512_mask, "V8fV8OiV8fUcIi", "ncV:512:", "avx512dq")
-TARGET_BUILTIN(__builtin_ia32_cvttpd2qq512_mask, "V8OiV8dV8OiUcIi", "ncV:512:", "avx512dq")
-TARGET_BUILTIN(__builtin_ia32_cvttpd2uqq512_mask, "V8OiV8dV8OiUcIi", "ncV:512:", "avx512dq")
-TARGET_BUILTIN(__builtin_ia32_cvttps2qq512_mask, "V8OiV8fV8OiUcIi", "ncV:512:", "avx512dq")
-TARGET_BUILTIN(__builtin_ia32_cvttps2uqq512_mask, "V8OiV8fV8OiUcIi", "ncV:512:", "avx512dq")
-TARGET_BUILTIN(__builtin_ia32_cvtuqq2pd512_mask, "V8dV8OiV8dUcIi", "ncV:512:", "avx512dq")
-TARGET_BUILTIN(__builtin_ia32_cvtuqq2ps512_mask, "V8fV8OiV8fUcIi", "ncV:512:", "avx512dq")
-TARGET_BUILTIN(__builtin_ia32_rangepd512_mask, "V8dV8dV8dIiV8dUcIi", "ncV:512:", "avx512dq")
-TARGET_BUILTIN(__builtin_ia32_rangeps512_mask, "V16fV16fV16fIiV16fUsIi", "ncV:512:", "avx512dq")
-TARGET_BUILTIN(__builtin_ia32_reducepd512_mask, "V8dV8dIiV8dUcIi", "ncV:512:", "avx512dq")
-TARGET_BUILTIN(__builtin_ia32_reduceps512_mask, "V16fV16fIiV16fUsIi", "ncV:512:", "avx512dq")
-TARGET_BUILTIN(__builtin_ia32_prold512, "V16iV16iIi", "ncV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_prolq512, "V8OiV8OiIi", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_cvtpd2qq512_mask, "V8OiV8dV8OiUcIi", "ncV:512:", "avx512dq,evex512")
+TARGET_BUILTIN(__builtin_ia32_cvtpd2uqq512_mask, "V8OiV8dV8OiUcIi", "ncV:512:", "avx512dq,evex512")
+TARGET_BUILTIN(__builtin_ia32_cvtps2qq512_mask, "V8OiV8fV8OiUcIi", "ncV:512:", "avx512dq,evex512")
+TARGET_BUILTIN(__builtin_ia32_cvtps2uqq512_mask, "V8OiV8fV8OiUcIi", "ncV:512:", "avx512dq,evex512")
+TARGET_BUILTIN(__builtin_ia32_cvtqq2pd512_mask, "V8dV8OiV8dUcIi", "ncV:512:", "avx512dq,evex512")
+TARGET_BUILTIN(__builtin_ia32_cvtqq2ps512_mask, "V8fV8OiV8fUcIi", "ncV:512:", "avx512dq,evex512")
+TARGET_BUILTIN(__builtin_ia32_cvttpd2qq512_mask, "V8OiV8dV8OiUcIi", "ncV:512:", "avx512dq,evex512")
+TARGET_BUILTIN(__builtin_ia32_cvttpd2uqq512_mask, "V8OiV8dV8OiUcIi", "ncV:512:", "avx512dq,evex512")
+TARGET_BUILTIN(__builtin_ia32_cvttps2qq512_mask, "V8OiV8fV8OiUcIi", "ncV:512:", "avx512dq,evex512")
+TARGET_BUILTIN(__builtin_ia32_cvttps2uqq512_mask, "V8OiV8fV8OiUcIi", "ncV:512:", "avx512dq,evex512")
+TARGET_BUILTIN(__builtin_ia32_cvtuqq2pd512_mask, "V8dV8OiV8dUcIi", "ncV:512:", "avx512dq,evex512")
+TARGET_BUILTIN(__builtin_ia32_cvtuqq2ps512_mask, "V8fV8OiV8fUcIi", "ncV:512:", "avx512dq,evex512")
+TARGET_BUILTIN(__builtin_ia32_rangepd512_mask, "V8dV8dV8dIiV8dUcIi", "ncV:512:", "avx512dq,evex512")
+TARGET_BUILTIN(__builtin_ia32_rangeps512_mask, "V16fV16fV16fIiV16fUsIi", "ncV:512:", "avx512dq,evex512")
+TARGET_BUILTIN(__builtin_ia32_reducepd512_mask, "V8dV8dIiV8dUcIi", "ncV:512:", "avx512dq,evex512")
+TARGET_BUILTIN(__builtin_ia32_reduceps512_mask, "V16fV16fIiV16fUsIi", "ncV:512:", "avx512dq,evex512")
+TARGET_BUILTIN(__builtin_ia32_prold512, "V16iV16iIi", "ncV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_prolq512, "V8OiV8OiIi", "ncV:512:", "avx512f,evex512")
TARGET_BUILTIN(__builtin_ia32_prold128, "V4iV4iIi", "ncV:128:", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_prold256, "V8iV8iIi", "ncV:256:", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_prolq128, "V2OiV2OiIi", "ncV:128:", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_prolq256, "V4OiV4OiIi", "ncV:256:", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_prolvd512, "V16iV16iV16i", "ncV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_prolvq512, "V8OiV8OiV8Oi", "ncV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_prord512, "V16iV16iIi", "ncV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_prorq512, "V8OiV8OiIi", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_prolvd512, "V16iV16iV16i", "ncV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_prolvq512, "V8OiV8OiV8Oi", "ncV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_prord512, "V16iV16iIi", "ncV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_prorq512, "V8OiV8OiIi", "ncV:512:", "avx512f,evex512")
TARGET_BUILTIN(__builtin_ia32_prolvd128, "V4iV4iV4i", "ncV:128:", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_prolvd256, "V8iV8iV8i", "ncV:256:", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_prolvq128, "V2OiV2OiV2Oi", "ncV:128:", "avx512vl")
@@ -1365,65 +1298,65 @@ TARGET_BUILTIN(__builtin_ia32_prord128, "V4iV4iIi", "ncV:128:", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_prord256, "V8iV8iIi", "ncV:256:", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_prorq128, "V2OiV2OiIi", "ncV:128:", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_prorq256, "V4OiV4OiIi", "ncV:256:", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_prorvd512, "V16iV16iV16i", "ncV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_prorvq512, "V8OiV8OiV8Oi", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_prorvd512, "V16iV16iV16i", "ncV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_prorvq512, "V8OiV8OiV8Oi", "ncV:512:", "avx512f,evex512")
TARGET_BUILTIN(__builtin_ia32_prorvd128, "V4iV4iV4i", "ncV:128:", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_prorvd256, "V8iV8iV8i", "ncV:256:", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_prorvq128, "V2OiV2OiV2Oi", "ncV:128:", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_prorvq256, "V4OiV4OiV4Oi", "ncV:256:", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pshufhw512, "V32sV32sIi", "ncV:512:", "avx512bw")
-TARGET_BUILTIN(__builtin_ia32_pshuflw512, "V32sV32sIi", "ncV:512:", "avx512bw")
-TARGET_BUILTIN(__builtin_ia32_psllv32hi, "V32sV32sV32s", "ncV:512:", "avx512bw")
-TARGET_BUILTIN(__builtin_ia32_psllw512, "V32sV32sV8s", "ncV:512:", "avx512bw")
-TARGET_BUILTIN(__builtin_ia32_psllwi512, "V32sV32si", "ncV:512:", "avx512bw")
+TARGET_BUILTIN(__builtin_ia32_pshufhw512, "V32sV32sIi", "ncV:512:", "avx512bw,evex512")
+TARGET_BUILTIN(__builtin_ia32_pshuflw512, "V32sV32sIi", "ncV:512:", "avx512bw,evex512")
+TARGET_BUILTIN(__builtin_ia32_psllv32hi, "V32sV32sV32s", "ncV:512:", "avx512bw,evex512")
+TARGET_BUILTIN(__builtin_ia32_psllw512, "V32sV32sV8s", "ncV:512:", "avx512bw,evex512")
+TARGET_BUILTIN(__builtin_ia32_psllwi512, "V32sV32si", "ncV:512:", "avx512bw,evex512")
TARGET_BUILTIN(__builtin_ia32_psllv16hi, "V16sV16sV16s", "ncV:256:", "avx512bw,avx512vl")
TARGET_BUILTIN(__builtin_ia32_psllv8hi, "V8sV8sV8s", "ncV:128:", "avx512bw,avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pslldi512, "V16iV16ii", "ncV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_psllqi512, "V8OiV8Oii", "ncV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_psrlv32hi, "V32sV32sV32s", "ncV:512:", "avx512bw")
+TARGET_BUILTIN(__builtin_ia32_pslldi512, "V16iV16ii", "ncV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_psllqi512, "V8OiV8Oii", "ncV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_psrlv32hi, "V32sV32sV32s", "ncV:512:", "avx512bw,evex512")
TARGET_BUILTIN(__builtin_ia32_psrlv16hi, "V16sV16sV16s", "ncV:256:", "avx512bw,avx512vl")
TARGET_BUILTIN(__builtin_ia32_psrlv8hi, "V8sV8sV8s", "ncV:128:", "avx512bw,avx512vl")
-TARGET_BUILTIN(__builtin_ia32_psrldi512, "V16iV16ii", "ncV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_psrlqi512, "V8OiV8Oii", "ncV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_psrav32hi, "V32sV32sV32s", "ncV:512:", "avx512bw")
+TARGET_BUILTIN(__builtin_ia32_psrldi512, "V16iV16ii", "ncV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_psrlqi512, "V8OiV8Oii", "ncV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_psrav32hi, "V32sV32sV32s", "ncV:512:", "avx512bw,evex512")
TARGET_BUILTIN(__builtin_ia32_psrav16hi, "V16sV16sV16s", "ncV:256:", "avx512bw,avx512vl")
TARGET_BUILTIN(__builtin_ia32_psrav8hi, "V8sV8sV8s", "ncV:128:", "avx512bw,avx512vl")
TARGET_BUILTIN(__builtin_ia32_psravq128, "V2OiV2OiV2Oi", "ncV:128:", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_psravq256, "V4OiV4OiV4Oi", "ncV:256:", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_psraw512, "V32sV32sV8s", "ncV:512:", "avx512bw")
-TARGET_BUILTIN(__builtin_ia32_psrawi512, "V32sV32si", "ncV:512:", "avx512bw")
-TARGET_BUILTIN(__builtin_ia32_psrlw512, "V32sV32sV8s", "ncV:512:", "avx512bw")
-TARGET_BUILTIN(__builtin_ia32_psrlwi512, "V32sV32si", "ncV:512:", "avx512bw")
-TARGET_BUILTIN(__builtin_ia32_pslldqi512_byteshift, "V8OiV8OiIi", "ncV:512:", "avx512bw")
-TARGET_BUILTIN(__builtin_ia32_psrldqi512_byteshift, "V8OiV8OiIi", "ncV:512:", "avx512bw")
+TARGET_BUILTIN(__builtin_ia32_psraw512, "V32sV32sV8s", "ncV:512:", "avx512bw,evex512")
+TARGET_BUILTIN(__builtin_ia32_psrawi512, "V32sV32si", "ncV:512:", "avx512bw,evex512")
+TARGET_BUILTIN(__builtin_ia32_psrlw512, "V32sV32sV8s", "ncV:512:", "avx512bw,evex512")
+TARGET_BUILTIN(__builtin_ia32_psrlwi512, "V32sV32si", "ncV:512:", "avx512bw,evex512")
+TARGET_BUILTIN(__builtin_ia32_pslldqi512_byteshift, "V8OiV8OiIi", "ncV:512:", "avx512bw,evex512")
+TARGET_BUILTIN(__builtin_ia32_psrldqi512_byteshift, "V8OiV8OiIi", "ncV:512:", "avx512bw,evex512")
TARGET_BUILTIN(__builtin_ia32_movdqa32load128_mask, "V4iV4iC*V4iUc", "nV:128:", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_movdqa32load256_mask, "V8iV8iC*V8iUc", "nV:256:", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_movdqa32load512_mask, "V16iV16iC*V16iUs", "nV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_movdqa32store512_mask, "vV16i*V16iUs", "nV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_movdqa64load512_mask, "V8OiV8OiC*V8OiUc", "nV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_movdqa64store512_mask, "vV8Oi*V8OiUc", "nV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_movdqa32load512_mask, "V16iV16iC*V16iUs", "nV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_movdqa32store512_mask, "vV16i*V16iUs", "nV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_movdqa64load512_mask, "V8OiV8OiC*V8OiUc", "nV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_movdqa64store512_mask, "vV8Oi*V8OiUc", "nV:512:", "avx512f,evex512")
TARGET_BUILTIN(__builtin_ia32_movdqa32store128_mask, "vV4i*V4iUc", "nV:128:", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_movdqa32store256_mask, "vV8i*V8iUc", "nV:256:", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_movdqa64load128_mask, "V2OiV2OiC*V2OiUc", "nV:128:", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_movdqa64load256_mask, "V4OiV4OiC*V4OiUc", "nV:256:", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_movdqa64store128_mask, "vV2Oi*V2OiUc", "nV:128:", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_movdqa64store256_mask, "vV4Oi*V4OiUc", "nV:256:", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_vpmadd52huq512, "V8OiV8OiV8OiV8Oi", "ncV:512:", "avx512ifma")
-TARGET_BUILTIN(__builtin_ia32_vpmadd52luq512, "V8OiV8OiV8OiV8Oi", "ncV:512:", "avx512ifma")
-TARGET_BUILTIN(__builtin_ia32_vpmadd52huq128, "V2OiV2OiV2OiV2Oi", "ncV:128:", "avx512ifma,avx512vl")
-TARGET_BUILTIN(__builtin_ia32_vpmadd52huq256, "V4OiV4OiV4OiV4Oi", "ncV:256:", "avx512ifma,avx512vl")
-TARGET_BUILTIN(__builtin_ia32_vpmadd52luq128, "V2OiV2OiV2OiV2Oi", "ncV:128:", "avx512ifma,avx512vl")
-TARGET_BUILTIN(__builtin_ia32_vpmadd52luq256, "V4OiV4OiV4OiV4Oi", "ncV:256:", "avx512ifma,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_vpmadd52huq512, "V8OiV8OiV8OiV8Oi", "ncV:512:", "avx512ifma,evex512")
+TARGET_BUILTIN(__builtin_ia32_vpmadd52luq512, "V8OiV8OiV8OiV8Oi", "ncV:512:", "avx512ifma,evex512")
+TARGET_BUILTIN(__builtin_ia32_vpmadd52huq128, "V2OiV2OiV2OiV2Oi", "ncV:128:", "avx512ifma,avx512vl|avxifma")
+TARGET_BUILTIN(__builtin_ia32_vpmadd52huq256, "V4OiV4OiV4OiV4Oi", "ncV:256:", "avx512ifma,avx512vl|avxifma")
+TARGET_BUILTIN(__builtin_ia32_vpmadd52luq128, "V2OiV2OiV2OiV2Oi", "ncV:128:", "avx512ifma,avx512vl|avxifma")
+TARGET_BUILTIN(__builtin_ia32_vpmadd52luq256, "V4OiV4OiV4OiV4Oi", "ncV:256:", "avx512ifma,avx512vl|avxifma")
TARGET_BUILTIN(__builtin_ia32_vcomisd, "iV2dV2dIiIi", "ncV:128:", "avx512f")
TARGET_BUILTIN(__builtin_ia32_vcomiss, "iV4fV4fIiIi", "ncV:128:", "avx512f")
TARGET_BUILTIN(__builtin_ia32_kunpckdi, "UOiUOiUOi", "nc", "avx512bw")
TARGET_BUILTIN(__builtin_ia32_kunpcksi, "UiUiUi", "nc", "avx512bw")
-TARGET_BUILTIN(__builtin_ia32_loaddquhi512_mask, "V32sV32sC*V32sUi", "nV:512:", "avx512bw")
-TARGET_BUILTIN(__builtin_ia32_loaddquqi512_mask, "V64cV64cC*V64cUOi", "nV:512:", "avx512bw")
-TARGET_BUILTIN(__builtin_ia32_fixupimmpd512_mask, "V8dV8dV8dV8OiIiUcIi", "ncV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_fixupimmpd512_maskz, "V8dV8dV8dV8OiIiUcIi", "ncV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_fixupimmps512_mask, "V16fV16fV16fV16iIiUsIi", "ncV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_fixupimmps512_maskz, "V16fV16fV16fV16iIiUsIi", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_loaddquhi512_mask, "V32sV32sC*V32sUi", "nV:512:", "avx512bw,evex512")
+TARGET_BUILTIN(__builtin_ia32_loaddquqi512_mask, "V64cV64cC*V64cUOi", "nV:512:", "avx512bw,evex512")
+TARGET_BUILTIN(__builtin_ia32_fixupimmpd512_mask, "V8dV8dV8dV8OiIiUcIi", "ncV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_fixupimmpd512_maskz, "V8dV8dV8dV8OiIiUcIi", "ncV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_fixupimmps512_mask, "V16fV16fV16fV16iIiUsIi", "ncV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_fixupimmps512_maskz, "V16fV16fV16fV16iIiUsIi", "ncV:512:", "avx512f,evex512")
TARGET_BUILTIN(__builtin_ia32_fixupimmsd_mask, "V2dV2dV2dV2OiIiUcIi", "ncV:128:", "avx512f")
TARGET_BUILTIN(__builtin_ia32_fixupimmsd_maskz, "V2dV2dV2dV2OiIiUcIi", "ncV:128:", "avx512f")
TARGET_BUILTIN(__builtin_ia32_fixupimmss_mask, "V4fV4fV4fV4iIiUcIi", "ncV:128:", "avx512f")
@@ -1458,8 +1391,8 @@ TARGET_BUILTIN(__builtin_ia32_loadupd128_mask, "V2dV2dC*V2dUc", "nV:128:", "avx5
TARGET_BUILTIN(__builtin_ia32_loadupd256_mask, "V4dV4dC*V4dUc", "nV:256:", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_loadups128_mask, "V4fV4fC*V4fUc", "nV:128:", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_loadups256_mask, "V8fV8fC*V8fUc", "nV:256:", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_storedquhi512_mask, "vV32s*V32sUi", "nV:512:", "avx512bw")
-TARGET_BUILTIN(__builtin_ia32_storedquqi512_mask, "vV64c*V64cUOi", "nV:512:", "avx512bw")
+TARGET_BUILTIN(__builtin_ia32_storedquhi512_mask, "vV32s*V32sUi", "nV:512:", "avx512bw,evex512")
+TARGET_BUILTIN(__builtin_ia32_storedquqi512_mask, "vV64c*V64cUOi", "nV:512:", "avx512bw,evex512")
TARGET_BUILTIN(__builtin_ia32_storedquhi128_mask, "vV8s*V8sUc", "nV:128:", "avx512vl,avx512bw")
TARGET_BUILTIN(__builtin_ia32_storedquhi256_mask, "vV16s*V16sUs", "nV:256:", "avx512vl,avx512bw")
TARGET_BUILTIN(__builtin_ia32_storedquqi128_mask, "vV16c*V16cUs", "nV:128:", "avx512vl,avx512bw")
@@ -1494,38 +1427,38 @@ TARGET_BUILTIN(__builtin_ia32_vcvttsd2si32, "iV2dIi", "ncV:128:", "avx512f")
TARGET_BUILTIN(__builtin_ia32_vcvttsd2usi32, "UiV2dIi", "ncV:128:", "avx512f")
TARGET_BUILTIN(__builtin_ia32_vcvttss2si32, "iV4fIi", "ncV:128:", "avx512f")
TARGET_BUILTIN(__builtin_ia32_vcvttss2usi32, "UiV4fIi", "ncV:128:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_vpermilpd512, "V8dV8dIi", "ncV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_vpermilps512, "V16fV16fIi", "ncV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_vpermilvarpd512, "V8dV8dV8Oi", "ncV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_vpermilvarps512, "V16fV16fV16i", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_vpermilpd512, "V8dV8dIi", "ncV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_vpermilps512, "V16fV16fIi", "ncV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_vpermilvarpd512, "V8dV8dV8Oi", "ncV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_vpermilvarps512, "V16fV16fV16i", "ncV:512:", "avx512f,evex512")
TARGET_BUILTIN(__builtin_ia32_rndscalesd_round_mask, "V2dV2dV2dV2dUcIiIi", "ncV:128:", "avx512f")
TARGET_BUILTIN(__builtin_ia32_rndscaless_round_mask, "V4fV4fV4fV4fUcIiIi", "ncV:128:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_scalefpd512_mask, "V8dV8dV8dV8dUcIi", "ncV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_scalefps512_mask, "V16fV16fV16fV16fUsIi", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_scalefpd512_mask, "V8dV8dV8dV8dUcIi", "ncV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_scalefps512_mask, "V16fV16fV16fV16fUsIi", "ncV:512:", "avx512f,evex512")
TARGET_BUILTIN(__builtin_ia32_scalefsd_round_mask, "V2dV2dV2dV2dUcIi", "ncV:128:", "avx512f")
TARGET_BUILTIN(__builtin_ia32_scalefss_round_mask, "V4fV4fV4fV4fUcIi", "ncV:128:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_psradi512, "V16iV16ii", "ncV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_psraqi512, "V8OiV8Oii", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_psradi512, "V16iV16ii", "ncV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_psraqi512, "V8OiV8Oii", "ncV:512:", "avx512f,evex512")
TARGET_BUILTIN(__builtin_ia32_psraq128, "V2OiV2OiV2Oi", "ncV:128:", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_psraq256, "V4OiV4OiV2Oi", "ncV:256:", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_psraqi128, "V2OiV2Oii", "ncV:128:", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_psraqi256, "V4OiV4Oii", "ncV:256:", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pslld512, "V16iV16iV4i", "ncV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_psllq512, "V8OiV8OiV2Oi", "ncV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_psllv16si, "V16iV16iV16i", "ncV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_psllv8di, "V8OiV8OiV8Oi", "ncV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_psrad512, "V16iV16iV4i", "ncV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_psraq512, "V8OiV8OiV2Oi", "ncV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_psrav16si, "V16iV16iV16i", "ncV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_psrav8di, "V8OiV8OiV8Oi", "ncV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_psrld512, "V16iV16iV4i", "ncV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_psrlq512, "V8OiV8OiV2Oi", "ncV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_psrlv16si, "V16iV16iV16i", "ncV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_psrlv8di, "V8OiV8OiV8Oi", "ncV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_pternlogd512_mask, "V16iV16iV16iV16iIiUs", "ncV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_pternlogd512_maskz, "V16iV16iV16iV16iIiUs", "ncV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_pternlogq512_mask, "V8OiV8OiV8OiV8OiIiUc", "ncV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_pternlogq512_maskz, "V8OiV8OiV8OiV8OiIiUc", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_pslld512, "V16iV16iV4i", "ncV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_psllq512, "V8OiV8OiV2Oi", "ncV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_psllv16si, "V16iV16iV16i", "ncV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_psllv8di, "V8OiV8OiV8Oi", "ncV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_psrad512, "V16iV16iV4i", "ncV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_psraq512, "V8OiV8OiV2Oi", "ncV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_psrav16si, "V16iV16iV16i", "ncV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_psrav8di, "V8OiV8OiV8Oi", "ncV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_psrld512, "V16iV16iV4i", "ncV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_psrlq512, "V8OiV8OiV2Oi", "ncV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_psrlv16si, "V16iV16iV16i", "ncV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_psrlv8di, "V8OiV8OiV8Oi", "ncV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_pternlogd512_mask, "V16iV16iV16iV16iIiUs", "ncV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_pternlogd512_maskz, "V16iV16iV16iV16iIiUs", "ncV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_pternlogq512_mask, "V8OiV8OiV8OiV8OiIiUc", "ncV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_pternlogq512_maskz, "V8OiV8OiV8OiV8OiIiUc", "ncV:512:", "avx512f,evex512")
TARGET_BUILTIN(__builtin_ia32_pternlogd128_mask, "V4iV4iV4iV4iIiUc", "ncV:128:", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_pternlogd128_maskz, "V4iV4iV4iV4iIiUc", "ncV:128:", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_pternlogd256_mask, "V8iV8iV8iV8iIiUc", "ncV:256:", "avx512vl")
@@ -1534,12 +1467,12 @@ TARGET_BUILTIN(__builtin_ia32_pternlogq128_mask, "V2OiV2OiV2OiV2OiIiUc", "ncV:12
TARGET_BUILTIN(__builtin_ia32_pternlogq128_maskz, "V2OiV2OiV2OiV2OiIiUc", "ncV:128:", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_pternlogq256_mask, "V4OiV4OiV4OiV4OiIiUc", "ncV:256:", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_pternlogq256_maskz, "V4OiV4OiV4OiV4OiIiUc", "ncV:256:", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_shuf_f32x4, "V16fV16fV16fIi", "ncV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_shuf_f64x2, "V8dV8dV8dIi", "ncV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_shuf_i32x4, "V16iV16iV16iIi", "ncV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_shuf_i64x2, "V8OiV8OiV8OiIi", "ncV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_shufpd512, "V8dV8dV8dIi", "ncV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_shufps512, "V16fV16fV16fIi", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_shuf_f32x4, "V16fV16fV16fIi", "ncV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_shuf_f64x2, "V8dV8dV8dIi", "ncV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_shuf_i32x4, "V16iV16iV16iIi", "ncV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_shuf_i64x2, "V8OiV8OiV8OiIi", "ncV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_shufpd512, "V8dV8dV8dIi", "ncV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_shufps512, "V16fV16fV16fIi", "ncV:512:", "avx512f,evex512")
TARGET_BUILTIN(__builtin_ia32_shuf_f32x4_256, "V8fV8fV8fIi", "ncV:256:", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_shuf_f64x2_256, "V4dV4dV4dIi", "ncV:256:", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_shuf_i32x4_256, "V8iV8iV8iIi", "ncV:256:", "avx512vl")
@@ -1550,13 +1483,13 @@ TARGET_BUILTIN(__builtin_ia32_rsqrt14pd128_mask, "V2dV2dV2dUc", "ncV:128:", "avx
TARGET_BUILTIN(__builtin_ia32_rsqrt14pd256_mask, "V4dV4dV4dUc", "ncV:256:", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_rsqrt14ps128_mask, "V4fV4fV4fUc", "ncV:128:", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_rsqrt14ps256_mask, "V8fV8fV8fUc", "ncV:256:", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_cvtb2mask512, "UOiV64c", "ncV:512:", "avx512bw")
-TARGET_BUILTIN(__builtin_ia32_cvtmask2b512, "V64cUOi", "ncV:512:", "avx512bw")
-TARGET_BUILTIN(__builtin_ia32_cvtmask2w512, "V32sUi", "ncV:512:", "avx512bw")
-TARGET_BUILTIN(__builtin_ia32_cvtd2mask512, "UsV16i", "ncV:512:", "avx512dq")
-TARGET_BUILTIN(__builtin_ia32_cvtmask2d512, "V16iUs", "ncV:512:", "avx512dq")
-TARGET_BUILTIN(__builtin_ia32_cvtmask2q512, "V8OiUc", "ncV:512:", "avx512dq")
-TARGET_BUILTIN(__builtin_ia32_cvtq2mask512, "UcV8Oi", "ncV:512:", "avx512dq")
+TARGET_BUILTIN(__builtin_ia32_cvtb2mask512, "UOiV64c", "ncV:512:", "avx512bw,evex512")
+TARGET_BUILTIN(__builtin_ia32_cvtmask2b512, "V64cUOi", "ncV:512:", "avx512bw,evex512")
+TARGET_BUILTIN(__builtin_ia32_cvtmask2w512, "V32sUi", "ncV:512:", "avx512bw,evex512")
+TARGET_BUILTIN(__builtin_ia32_cvtd2mask512, "UsV16i", "ncV:512:", "avx512dq,evex512")
+TARGET_BUILTIN(__builtin_ia32_cvtmask2d512, "V16iUs", "ncV:512:", "avx512dq,evex512")
+TARGET_BUILTIN(__builtin_ia32_cvtmask2q512, "V8OiUc", "ncV:512:", "avx512dq,evex512")
+TARGET_BUILTIN(__builtin_ia32_cvtq2mask512, "UcV8Oi", "ncV:512:", "avx512dq,evex512")
TARGET_BUILTIN(__builtin_ia32_cvtb2mask128, "UsV16c", "ncV:128:", "avx512bw,avx512vl")
TARGET_BUILTIN(__builtin_ia32_cvtb2mask256, "UiV32c", "ncV:256:", "avx512bw,avx512vl")
TARGET_BUILTIN(__builtin_ia32_cvtmask2b128, "V16cUs", "ncV:128:", "avx512bw,avx512vl")
@@ -1571,17 +1504,17 @@ TARGET_BUILTIN(__builtin_ia32_cvtmask2q128, "V2OiUc", "ncV:128:", "avx512dq,avx5
TARGET_BUILTIN(__builtin_ia32_cvtmask2q256, "V4OiUc", "ncV:256:", "avx512dq,avx512vl")
TARGET_BUILTIN(__builtin_ia32_cvtq2mask128, "UcV2Oi", "ncV:128:", "avx512dq,avx512vl")
TARGET_BUILTIN(__builtin_ia32_cvtq2mask256, "UcV4Oi", "ncV:256:", "avx512dq,avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pmovsdb512_mask, "V16cV16iV16cUs", "ncV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_pmovsdb512mem_mask, "vV16c*V16iUs", "nV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_pmovswb512mem_mask, "vV32c*V32sUi", "nV:512:", "avx512bw")
-TARGET_BUILTIN(__builtin_ia32_pmovsdw512_mask, "V16sV16iV16sUs", "ncV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_pmovsdw512mem_mask, "vV16s*V16iUs", "nV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_pmovsqb512_mask, "V16cV8OiV16cUc", "ncV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_pmovsqb512mem_mask, "vV16c*V8OiUc", "nV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_pmovsqd512_mask, "V8iV8OiV8iUc", "ncV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_pmovsqd512mem_mask, "vV8i*V8OiUc", "nV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_pmovsqw512_mask, "V8sV8OiV8sUc", "ncV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_pmovsqw512mem_mask, "vV8s*V8OiUc", "nV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_pmovsdb512_mask, "V16cV16iV16cUs", "ncV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_pmovsdb512mem_mask, "vV16c*V16iUs", "nV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_pmovswb512mem_mask, "vV32c*V32sUi", "nV:512:", "avx512bw,evex512")
+TARGET_BUILTIN(__builtin_ia32_pmovsdw512_mask, "V16sV16iV16sUs", "ncV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_pmovsdw512mem_mask, "vV16s*V16iUs", "nV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_pmovsqb512_mask, "V16cV8OiV16cUc", "ncV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_pmovsqb512mem_mask, "vV16c*V8OiUc", "nV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_pmovsqd512_mask, "V8iV8OiV8iUc", "ncV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_pmovsqd512mem_mask, "vV8i*V8OiUc", "nV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_pmovsqw512_mask, "V8sV8OiV8sUc", "ncV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_pmovsqw512mem_mask, "vV8s*V8OiUc", "nV:512:", "avx512f,evex512")
TARGET_BUILTIN(__builtin_ia32_pmovsdb128_mask, "V16cV4iV16cUc", "ncV:128:", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_pmovsdb128mem_mask, "vV16c*V4iUc", "nV:128:", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_pmovswb128mem_mask, "vV16c*V8sUc", "nV:128:", "avx512vl,avx512bw")
@@ -1604,17 +1537,17 @@ TARGET_BUILTIN(__builtin_ia32_pmovsqw128_mask, "V8sV2OiV8sUc", "ncV:128:", "avx5
TARGET_BUILTIN(__builtin_ia32_pmovsqw128mem_mask, "vV8s*V2OiUc", "nV:128:", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_pmovsqw256_mask, "V8sV4OiV8sUc", "ncV:256:", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_pmovsqw256mem_mask, "vV8s*V4OiUc", "nV:256:", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pmovusdb512_mask, "V16cV16iV16cUs", "ncV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_pmovusdb512mem_mask, "vV16c*V16iUs", "nV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_pmovuswb512mem_mask, "vV32c*V32sUi", "nV:512:", "avx512bw")
-TARGET_BUILTIN(__builtin_ia32_pmovusdw512_mask, "V16sV16iV16sUs", "ncV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_pmovusdw512mem_mask, "vV16s*V16iUs", "nV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_pmovusqb512_mask, "V16cV8OiV16cUc", "ncV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_pmovusqb512mem_mask, "vV16c*V8OiUc", "nV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_pmovusqd512_mask, "V8iV8OiV8iUc", "ncV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_pmovusqd512mem_mask, "vV8i*V8OiUc", "nV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_pmovusqw512_mask, "V8sV8OiV8sUc", "ncV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_pmovusqw512mem_mask, "vV8s*V8OiUc", "nV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_pmovusdb512_mask, "V16cV16iV16cUs", "ncV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_pmovusdb512mem_mask, "vV16c*V16iUs", "nV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_pmovuswb512mem_mask, "vV32c*V32sUi", "nV:512:", "avx512bw,evex512")
+TARGET_BUILTIN(__builtin_ia32_pmovusdw512_mask, "V16sV16iV16sUs", "ncV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_pmovusdw512mem_mask, "vV16s*V16iUs", "nV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_pmovusqb512_mask, "V16cV8OiV16cUc", "ncV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_pmovusqb512mem_mask, "vV16c*V8OiUc", "nV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_pmovusqd512_mask, "V8iV8OiV8iUc", "ncV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_pmovusqd512mem_mask, "vV8i*V8OiUc", "nV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_pmovusqw512_mask, "V8sV8OiV8sUc", "ncV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_pmovusqw512mem_mask, "vV8s*V8OiUc", "nV:512:", "avx512f,evex512")
TARGET_BUILTIN(__builtin_ia32_pmovusdb128_mask, "V16cV4iV16cUc", "ncV:128:", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_pmovusdb128mem_mask, "vV16c*V4iUc", "nV:128:", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_pmovuswb128mem_mask, "vV16c*V8sUc", "nV:128:", "avx512vl,avx512bw")
@@ -1637,17 +1570,17 @@ TARGET_BUILTIN(__builtin_ia32_pmovusqw128_mask, "V8sV2OiV8sUc", "ncV:128:", "avx
TARGET_BUILTIN(__builtin_ia32_pmovusqw128mem_mask, "vV8s*V2OiUc", "nV:128:", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_pmovusqw256_mask, "V8sV4OiV8sUc", "ncV:256:", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_pmovusqw256mem_mask, "vV8s*V4OiUc", "nV:256:", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_pmovdb512_mask, "V16cV16iV16cUs", "ncV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_pmovdb512mem_mask, "vV16c*V16iUs", "nV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_pmovwb512mem_mask, "vV32c*V32sUi", "nV:512:", "avx512bw")
-TARGET_BUILTIN(__builtin_ia32_pmovdw512_mask, "V16sV16iV16sUs", "ncV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_pmovdw512mem_mask, "vV16s*V16iUs", "nV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_pmovqb512_mask, "V16cV8OiV16cUc", "ncV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_pmovqb512mem_mask, "vV16c*V8OiUc", "nV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_pmovqd512_mask, "V8iV8OiV8iUc", "ncV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_pmovqd512mem_mask, "vV8i*V8OiUc", "nV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_pmovqw512_mask, "V8sV8OiV8sUc", "ncV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_pmovqw512mem_mask, "vV8s*V8OiUc", "nV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_pmovdb512_mask, "V16cV16iV16cUs", "ncV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_pmovdb512mem_mask, "vV16c*V16iUs", "nV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_pmovwb512mem_mask, "vV32c*V32sUi", "nV:512:", "avx512bw,evex512")
+TARGET_BUILTIN(__builtin_ia32_pmovdw512_mask, "V16sV16iV16sUs", "ncV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_pmovdw512mem_mask, "vV16s*V16iUs", "nV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_pmovqb512_mask, "V16cV8OiV16cUc", "ncV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_pmovqb512mem_mask, "vV16c*V8OiUc", "nV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_pmovqd512_mask, "V8iV8OiV8iUc", "ncV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_pmovqd512mem_mask, "vV8i*V8OiUc", "nV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_pmovqw512_mask, "V8sV8OiV8sUc", "ncV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_pmovqw512mem_mask, "vV8s*V8OiUc", "nV:512:", "avx512f,evex512")
TARGET_BUILTIN(__builtin_ia32_pmovdb128_mask, "V16cV4iV16cUc", "ncV:128:", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_pmovwb128mem_mask, "vV16c*V8sUc", "nV:128:", "avx512vl,avx512bw")
TARGET_BUILTIN(__builtin_ia32_pmovdb128mem_mask, "vV16c*V4iUc", "nV:128:", "avx512vl")
@@ -1669,36 +1602,36 @@ TARGET_BUILTIN(__builtin_ia32_pmovqw128_mask, "V8sV2OiV8sUc", "ncV:128:", "avx51
TARGET_BUILTIN(__builtin_ia32_pmovqw128mem_mask, "vV8s*V2OiUc", "nV:128:", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_pmovqw256_mask, "V8sV4OiV8sUc", "ncV:256:", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_pmovqw256mem_mask, "vV8s*V4OiUc", "nV:256:", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_extractf32x8_mask, "V8fV16fIiV8fUc", "ncV:512:", "avx512dq")
-TARGET_BUILTIN(__builtin_ia32_extractf64x2_512_mask, "V2dV8dIiV2dUc", "ncV:512:", "avx512dq")
-TARGET_BUILTIN(__builtin_ia32_extracti32x8_mask, "V8iV16iIiV8iUc", "ncV:512:", "avx512dq")
-TARGET_BUILTIN(__builtin_ia32_extracti64x2_512_mask, "V2OiV8OiIiV2OiUc", "ncV:512:", "avx512dq")
-TARGET_BUILTIN(__builtin_ia32_extracti32x4_mask, "V4iV16iIiV4iUc", "ncV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_extracti64x4_mask, "V4OiV8OiIiV4OiUc", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_extractf32x8_mask, "V8fV16fIiV8fUc", "ncV:512:", "avx512dq,evex512")
+TARGET_BUILTIN(__builtin_ia32_extractf64x2_512_mask, "V2dV8dIiV2dUc", "ncV:512:", "avx512dq,evex512")
+TARGET_BUILTIN(__builtin_ia32_extracti32x8_mask, "V8iV16iIiV8iUc", "ncV:512:", "avx512dq,evex512")
+TARGET_BUILTIN(__builtin_ia32_extracti64x2_512_mask, "V2OiV8OiIiV2OiUc", "ncV:512:", "avx512dq,evex512")
+TARGET_BUILTIN(__builtin_ia32_extracti32x4_mask, "V4iV16iIiV4iUc", "ncV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_extracti64x4_mask, "V4OiV8OiIiV4OiUc", "ncV:512:", "avx512f,evex512")
TARGET_BUILTIN(__builtin_ia32_extractf64x2_256_mask, "V2dV4dIiV2dUc", "ncV:256:", "avx512dq,avx512vl")
TARGET_BUILTIN(__builtin_ia32_extracti64x2_256_mask, "V2OiV4OiIiV2OiUc", "ncV:256:", "avx512dq,avx512vl")
TARGET_BUILTIN(__builtin_ia32_extractf32x4_256_mask, "V4fV8fIiV4fUc", "ncV:256:", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_extracti32x4_256_mask, "V4iV8iIiV4iUc", "ncV:256:", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_insertf32x8, "V16fV16fV8fIi", "ncV:512:", "avx512dq")
-TARGET_BUILTIN(__builtin_ia32_insertf64x2_512, "V8dV8dV2dIi", "ncV:512:", "avx512dq")
-TARGET_BUILTIN(__builtin_ia32_inserti32x8, "V16iV16iV8iIi", "ncV:512:", "avx512dq")
-TARGET_BUILTIN(__builtin_ia32_inserti64x2_512, "V8OiV8OiV2OiIi", "ncV:512:", "avx512dq")
-TARGET_BUILTIN(__builtin_ia32_insertf64x4, "V8dV8dV4dIi", "ncV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_inserti64x4, "V8OiV8OiV4OiIi", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_insertf32x8, "V16fV16fV8fIi", "ncV:512:", "avx512dq,evex512")
+TARGET_BUILTIN(__builtin_ia32_insertf64x2_512, "V8dV8dV2dIi", "ncV:512:", "avx512dq,evex512")
+TARGET_BUILTIN(__builtin_ia32_inserti32x8, "V16iV16iV8iIi", "ncV:512:", "avx512dq,evex512")
+TARGET_BUILTIN(__builtin_ia32_inserti64x2_512, "V8OiV8OiV2OiIi", "ncV:512:", "avx512dq,evex512")
+TARGET_BUILTIN(__builtin_ia32_insertf64x4, "V8dV8dV4dIi", "ncV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_inserti64x4, "V8OiV8OiV4OiIi", "ncV:512:", "avx512f,evex512")
TARGET_BUILTIN(__builtin_ia32_insertf64x2_256, "V4dV4dV2dIi", "ncV:256:", "avx512dq,avx512vl")
TARGET_BUILTIN(__builtin_ia32_inserti64x2_256, "V4OiV4OiV2OiIi", "ncV:256:", "avx512dq,avx512vl")
TARGET_BUILTIN(__builtin_ia32_insertf32x4_256, "V8fV8fV4fIi", "ncV:256:", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_inserti32x4_256, "V8iV8iV4iIi", "ncV:256:", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_insertf32x4, "V16fV16fV4fIi", "ncV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_inserti32x4, "V16iV16iV4iIi", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_insertf32x4, "V16fV16fV4fIi", "ncV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_inserti32x4, "V16iV16iV4iIi", "ncV:512:", "avx512f,evex512")
TARGET_BUILTIN(__builtin_ia32_getmantpd128_mask, "V2dV2dIiV2dUc", "ncV:128:", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_getmantpd256_mask, "V4dV4dIiV4dUc", "ncV:256:", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_getmantps128_mask, "V4fV4fIiV4fUc", "ncV:128:", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_getmantps256_mask, "V8fV8fIiV8fUc", "ncV:256:", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_getmantpd512_mask, "V8dV8dIiV8dUcIi", "ncV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_getmantps512_mask, "V16fV16fIiV16fUsIi", "ncV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_getexppd512_mask, "V8dV8dV8dUcIi", "ncV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_getexpps512_mask, "V16fV16fV16fUsIi", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_getmantpd512_mask, "V8dV8dIiV8dUcIi", "ncV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_getmantps512_mask, "V16fV16fIiV16fUsIi", "ncV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_getexppd512_mask, "V8dV8dV8dUcIi", "ncV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_getexpps512_mask, "V16fV16fV16fUsIi", "ncV:512:", "avx512f,evex512")
TARGET_BUILTIN(__builtin_ia32_vfmaddss3_mask, "V4fV4fV4fV4fUcIi", "ncV:128:", "avx512f")
TARGET_BUILTIN(__builtin_ia32_vfmaddss3_maskz, "V4fV4fV4fV4fUcIi", "ncV:128:", "avx512f")
TARGET_BUILTIN(__builtin_ia32_vfmaddss3_mask3, "V4fV4fV4fV4fUcIi", "ncV:128:", "avx512f")
@@ -1707,14 +1640,14 @@ TARGET_BUILTIN(__builtin_ia32_vfmaddsd3_maskz, "V2dV2dV2dV2dUcIi", "ncV:128:", "
TARGET_BUILTIN(__builtin_ia32_vfmaddsd3_mask3, "V2dV2dV2dV2dUcIi", "ncV:128:", "avx512f")
TARGET_BUILTIN(__builtin_ia32_vfmsubsd3_mask3, "V2dV2dV2dV2dUcIi", "ncV:128:", "avx512f")
TARGET_BUILTIN(__builtin_ia32_vfmsubss3_mask3, "V4fV4fV4fV4fUcIi", "ncV:128:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_permdf512, "V8dV8dIi", "ncV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_permdi512, "V8OiV8OiIi", "ncV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_permvarhi512, "V32sV32sV32s", "ncV:512:", "avx512bw")
-TARGET_BUILTIN(__builtin_ia32_permvardf512, "V8dV8dV8Oi", "ncV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_permvardi512, "V8OiV8OiV8Oi", "ncV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_permvarsf512, "V16fV16fV16i", "ncV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_permvarsi512, "V16iV16iV16i", "ncV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_permvarqi512, "V64cV64cV64c", "ncV:512:", "avx512vbmi")
+TARGET_BUILTIN(__builtin_ia32_permdf512, "V8dV8dIi", "ncV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_permdi512, "V8OiV8OiIi", "ncV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_permvarhi512, "V32sV32sV32s", "ncV:512:", "avx512bw,evex512")
+TARGET_BUILTIN(__builtin_ia32_permvardf512, "V8dV8dV8Oi", "ncV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_permvardi512, "V8OiV8OiV8Oi", "ncV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_permvarsf512, "V16fV16fV16i", "ncV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_permvarsi512, "V16iV16iV16i", "ncV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_permvarqi512, "V64cV64cV64c", "ncV:512:", "avx512vbmi,evex512")
TARGET_BUILTIN(__builtin_ia32_permvarqi128, "V16cV16cV16c", "ncV:128:", "avx512vbmi,avx512vl")
TARGET_BUILTIN(__builtin_ia32_permvarqi256, "V32cV32cV32c", "ncV:256:", "avx512vbmi,avx512vl")
TARGET_BUILTIN(__builtin_ia32_permvarhi128, "V8sV8sV8s", "ncV:128:", "avx512bw,avx512vl")
@@ -1725,8 +1658,8 @@ TARGET_BUILTIN(__builtin_ia32_fpclasspd128_mask, "UcV2dIiUc", "ncV:128:", "avx51
TARGET_BUILTIN(__builtin_ia32_fpclasspd256_mask, "UcV4dIiUc", "ncV:256:", "avx512dq,avx512vl")
TARGET_BUILTIN(__builtin_ia32_fpclassps128_mask, "UcV4fIiUc", "ncV:128:", "avx512dq,avx512vl")
TARGET_BUILTIN(__builtin_ia32_fpclassps256_mask, "UcV8fIiUc", "ncV:256:", "avx512dq,avx512vl")
-TARGET_BUILTIN(__builtin_ia32_fpclassps512_mask, "UsV16fIiUs", "ncV:512:", "avx512dq")
-TARGET_BUILTIN(__builtin_ia32_fpclasspd512_mask, "UcV8dIiUc", "ncV:512:", "avx512dq")
+TARGET_BUILTIN(__builtin_ia32_fpclassps512_mask, "UsV16fIiUs", "ncV:512:", "avx512dq,evex512")
+TARGET_BUILTIN(__builtin_ia32_fpclasspd512_mask, "UcV8dIiUc", "ncV:512:", "avx512dq,evex512")
TARGET_BUILTIN(__builtin_ia32_fpclasssd_mask, "UcV2dIiUc", "ncV:128:", "avx512dq")
TARGET_BUILTIN(__builtin_ia32_fpclassss_mask, "UcV4fIiUc", "ncV:128:", "avx512dq")
TARGET_BUILTIN(__builtin_ia32_kaddqi, "UcUcUc", "nc", "avx512dq")
@@ -1782,120 +1715,321 @@ TARGET_BUILTIN(__builtin_ia32_kmovb, "UcUc", "nc", "avx512dq")
TARGET_BUILTIN(__builtin_ia32_kmovw, "UsUs", "nc", "avx512f")
TARGET_BUILTIN(__builtin_ia32_kmovd, "UiUi", "nc", "avx512bw")
TARGET_BUILTIN(__builtin_ia32_kmovq, "UOiUOi", "nc", "avx512bw")
-TARGET_BUILTIN(__builtin_ia32_palignr512, "V64cV64cV64cIi", "ncV:512:", "avx512bw")
+TARGET_BUILTIN(__builtin_ia32_palignr512, "V64cV64cV64cIi", "ncV:512:", "avx512bw,evex512")
TARGET_BUILTIN(__builtin_ia32_dbpsadbw128, "V8sV16cV16cIi", "ncV:128:", "avx512bw,avx512vl")
TARGET_BUILTIN(__builtin_ia32_dbpsadbw256, "V16sV32cV32cIi", "ncV:256:", "avx512bw,avx512vl")
-TARGET_BUILTIN(__builtin_ia32_dbpsadbw512, "V32sV64cV64cIi", "ncV:512:", "avx512bw")
-TARGET_BUILTIN(__builtin_ia32_psadbw512, "V8OiV64cV64c", "ncV:512:", "avx512bw")
-TARGET_BUILTIN(__builtin_ia32_compressdf512_mask, "V8dV8dV8dUc", "ncV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_compressdi512_mask, "V8OiV8OiV8OiUc", "ncV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_compresshi512_mask, "V32sV32sV32sUi", "ncV:512:", "avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_compressqi512_mask, "V64cV64cV64cUOi", "ncV:512:", "avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_compresssf512_mask, "V16fV16fV16fUs", "ncV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_compresssi512_mask, "V16iV16iV16iUs", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_dbpsadbw512, "V32sV64cV64cIi", "ncV:512:", "avx512bw,evex512")
+TARGET_BUILTIN(__builtin_ia32_psadbw512, "V8OiV64cV64c", "ncV:512:", "avx512bw,evex512")
+TARGET_BUILTIN(__builtin_ia32_compressdf512_mask, "V8dV8dV8dUc", "ncV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_compressdi512_mask, "V8OiV8OiV8OiUc", "ncV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_compresshi512_mask, "V32sV32sV32sUi", "ncV:512:", "avx512vbmi2,evex512")
+TARGET_BUILTIN(__builtin_ia32_compressqi512_mask, "V64cV64cV64cUOi", "ncV:512:", "avx512vbmi2,evex512")
+TARGET_BUILTIN(__builtin_ia32_compresssf512_mask, "V16fV16fV16fUs", "ncV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_compresssi512_mask, "V16iV16iV16iUs", "ncV:512:", "avx512f,evex512")
TARGET_BUILTIN(__builtin_ia32_cmpsd_mask, "UcV2dV2dIiUcIi", "ncV:128:", "avx512f")
TARGET_BUILTIN(__builtin_ia32_cmpss_mask, "UcV4fV4fIiUcIi", "ncV:128:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_pshufd512, "V16iV16iIi", "ncV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_expanddf512_mask, "V8dV8dV8dUc", "ncV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_expanddi512_mask, "V8OiV8OiV8OiUc", "ncV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_expandhi512_mask, "V32sV32sV32sUi", "ncV:512:", "avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_expandqi512_mask, "V64cV64cV64cUOi", "ncV:512:", "avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_expandloaddf512_mask, "V8dV8dC*V8dUc", "nV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_expandloaddi512_mask, "V8OiV8OiC*V8OiUc", "nV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_expandloadhi512_mask, "V32sV32sC*V32sUi", "nV:512:", "avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_expandloadqi512_mask, "V64cV64cC*V64cUOi", "nV:512:", "avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_expandloadsf512_mask, "V16fV16fC*V16fUs", "nV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_expandloadsi512_mask, "V16iV16iC*V16iUs", "nV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_expandsf512_mask, "V16fV16fV16fUs", "ncV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_expandsi512_mask, "V16iV16iV16iUs", "ncV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_cvtps2pd512_mask, "V8dV8fV8dUcIi", "ncV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_compressstoredf512_mask, "vV8d*V8dUc", "nV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_compressstoredi512_mask, "vV8Oi*V8OiUc", "nV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_compressstorehi512_mask, "vV32s*V32sUi", "nV:512:", "avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_compressstoreqi512_mask, "vV64c*V64cUOi", "nV:512:", "avx512vbmi2")
-TARGET_BUILTIN(__builtin_ia32_compressstoresf512_mask, "vV16f*V16fUs", "nV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_compressstoresi512_mask, "vV16i*V16iUs", "nV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_pshufd512, "V16iV16iIi", "ncV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_expanddf512_mask, "V8dV8dV8dUc", "ncV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_expanddi512_mask, "V8OiV8OiV8OiUc", "ncV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_expandhi512_mask, "V32sV32sV32sUi", "ncV:512:", "avx512vbmi2,evex512")
+TARGET_BUILTIN(__builtin_ia32_expandqi512_mask, "V64cV64cV64cUOi", "ncV:512:", "avx512vbmi2,evex512")
+TARGET_BUILTIN(__builtin_ia32_expandloaddf512_mask, "V8dV8dC*V8dUc", "nV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_expandloaddi512_mask, "V8OiV8OiC*V8OiUc", "nV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_expandloadhi512_mask, "V32sV32sC*V32sUi", "nV:512:", "avx512vbmi2,evex512")
+TARGET_BUILTIN(__builtin_ia32_expandloadqi512_mask, "V64cV64cC*V64cUOi", "nV:512:", "avx512vbmi2,evex512")
+TARGET_BUILTIN(__builtin_ia32_expandloadsf512_mask, "V16fV16fC*V16fUs", "nV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_expandloadsi512_mask, "V16iV16iC*V16iUs", "nV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_expandsf512_mask, "V16fV16fV16fUs", "ncV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_expandsi512_mask, "V16iV16iV16iUs", "ncV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_cvtps2pd512_mask, "V8dV8fV8dUcIi", "ncV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_compressstoredf512_mask, "vV8d*V8dUc", "nV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_compressstoredi512_mask, "vV8Oi*V8OiUc", "nV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_compressstorehi512_mask, "vV32s*V32sUi", "nV:512:", "avx512vbmi2,evex512")
+TARGET_BUILTIN(__builtin_ia32_compressstoreqi512_mask, "vV64c*V64cUOi", "nV:512:", "avx512vbmi2,evex512")
+TARGET_BUILTIN(__builtin_ia32_compressstoresf512_mask, "vV16f*V16fUs", "nV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_compressstoresi512_mask, "vV16i*V16iUs", "nV:512:", "avx512f,evex512")
TARGET_BUILTIN(__builtin_ia32_vcvtph2ps_mask, "V4fV8sV4fUc", "ncV:128:", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_vcvtph2ps256_mask, "V8fV8sV8fUc", "ncV:256:", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_vcvtps2ph_mask, "V8sV4fIiV8sUc", "ncV:128:", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_vcvtps2ph256_mask, "V8sV8fIiV8sUc", "ncV:256:", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_cvtw2mask512, "UiV32s", "ncV:512:", "avx512bw")
+TARGET_BUILTIN(__builtin_ia32_cvtw2mask512, "UiV32s", "ncV:512:", "avx512bw,evex512")
TARGET_BUILTIN(__builtin_ia32_cvtw2mask128, "UcV8s", "ncV:128:", "avx512bw,avx512vl")
TARGET_BUILTIN(__builtin_ia32_cvtw2mask256, "UsV16s", "ncV:256:", "avx512bw,avx512vl")
TARGET_BUILTIN(__builtin_ia32_cvtsd2ss_round_mask, "V4fV4fV2dV4fUcIi", "ncV:128:", "avx512f")
TARGET_BUILTIN(__builtin_ia32_cvtsi2ss32, "V4fV4fiIi", "ncV:128:", "avx512f")
TARGET_BUILTIN(__builtin_ia32_cvtss2sd_round_mask, "V2dV2dV4fV2dUcIi", "ncV:128:", "avx512f")
TARGET_BUILTIN(__builtin_ia32_cvtusi2ss32, "V4fV4fUiIi", "ncV:128:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_vpmultishiftqb512, "V64cV64cV64c", "ncV:512:", "avx512vbmi")
+TARGET_BUILTIN(__builtin_ia32_vpmultishiftqb512, "V64cV64cV64c", "ncV:512:", "avx512vbmi,evex512")
TARGET_BUILTIN(__builtin_ia32_vpmultishiftqb128, "V16cV16cV16c", "ncV:128:", "avx512vbmi,avx512vl")
TARGET_BUILTIN(__builtin_ia32_vpmultishiftqb256, "V32cV32cV32c", "ncV:256:", "avx512vbmi,avx512vl")
// bf16 intrinsics
-TARGET_BUILTIN(__builtin_ia32_cvtne2ps2bf16_128, "V8sV4fV4f", "ncV:128:", "avx512bf16,avx512vl")
-TARGET_BUILTIN(__builtin_ia32_cvtne2ps2bf16_256, "V16sV8fV8f", "ncV:256:", "avx512bf16,avx512vl")
-TARGET_BUILTIN(__builtin_ia32_cvtne2ps2bf16_512, "V32sV16fV16f", "ncV:512:", "avx512bf16")
-TARGET_BUILTIN(__builtin_ia32_cvtneps2bf16_128_mask, "V8sV4fV8sUc", "ncV:128:", "avx512bf16,avx512vl")
-TARGET_BUILTIN(__builtin_ia32_cvtneps2bf16_256_mask, "V8sV8fV8sUc", "ncV:256:", "avx512bf16,avx512vl")
-TARGET_BUILTIN(__builtin_ia32_cvtneps2bf16_512_mask, "V16sV16fV16sUs", "ncV:512:", "avx512bf16")
-TARGET_BUILTIN(__builtin_ia32_dpbf16ps_128, "V4fV4fV4iV4i", "ncV:128:", "avx512bf16,avx512vl")
-TARGET_BUILTIN(__builtin_ia32_dpbf16ps_256, "V8fV8fV8iV8i", "ncV:256:", "avx512bf16,avx512vl")
-TARGET_BUILTIN(__builtin_ia32_dpbf16ps_512, "V16fV16fV16iV16i", "ncV:512:", "avx512bf16")
-TARGET_BUILTIN(__builtin_ia32_cvtsbf162ss_32, "fUs", "nc", "avx512bf16")
-
-TARGET_BUILTIN(__builtin_ia32_vp2intersect_q_512, "vV8OiV8OiUc*Uc*", "nV:512:", "avx512vp2intersect")
+TARGET_BUILTIN(__builtin_ia32_cvtne2ps2bf16_128, "V8yV4fV4f", "ncV:128:", "avx512bf16,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_cvtne2ps2bf16_256, "V16yV8fV8f", "ncV:256:", "avx512bf16,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_cvtne2ps2bf16_512, "V32yV16fV16f", "ncV:512:", "avx512bf16,evex512")
+TARGET_BUILTIN(__builtin_ia32_cvtneps2bf16_128_mask, "V8yV4fV8yUc", "ncV:128:", "avx512bf16,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_cvtneps2bf16_256_mask, "V8yV8fV8yUc", "ncV:256:", "avx512bf16,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_cvtneps2bf16_512_mask, "V16yV16fV16yUs", "ncV:512:", "avx512bf16,evex512")
+TARGET_BUILTIN(__builtin_ia32_dpbf16ps_128, "V4fV4fV8yV8y", "ncV:128:", "avx512bf16,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_dpbf16ps_256, "V8fV8fV16yV16y", "ncV:256:", "avx512bf16,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_dpbf16ps_512, "V16fV16fV32yV32y", "ncV:512:", "avx512bf16,evex512")
+TARGET_BUILTIN(__builtin_ia32_cvtsbf162ss_32, "fy", "nc", "avx512bf16")
+
+TARGET_BUILTIN(__builtin_ia32_vp2intersect_q_512, "vV8OiV8OiUc*Uc*", "nV:512:", "avx512vp2intersect,evex512")
TARGET_BUILTIN(__builtin_ia32_vp2intersect_q_256, "vV4OiV4OiUc*Uc*", "nV:256:", "avx512vp2intersect,avx512vl")
TARGET_BUILTIN(__builtin_ia32_vp2intersect_q_128, "vV2OiV2OiUc*Uc*", "nV:128:", "avx512vp2intersect,avx512vl")
-TARGET_BUILTIN(__builtin_ia32_vp2intersect_d_512, "vV16iV16iUs*Us*", "nV:512:", "avx512vp2intersect")
+TARGET_BUILTIN(__builtin_ia32_vp2intersect_d_512, "vV16iV16iUs*Us*", "nV:512:", "avx512vp2intersect,evex512")
TARGET_BUILTIN(__builtin_ia32_vp2intersect_d_256, "vV8iV8iUc*Uc*", "nV:256:", "avx512vp2intersect,avx512vl")
TARGET_BUILTIN(__builtin_ia32_vp2intersect_d_128, "vV4iV4iUc*Uc*", "nV:128:", "avx512vp2intersect,avx512vl")
+// AVX512 fp16 intrinsics
+TARGET_BUILTIN(__builtin_ia32_vcomish, "iV8xV8xIiIi", "ncV:128:", "avx512fp16")
+TARGET_BUILTIN(__builtin_ia32_addph512, "V32xV32xV32xIi", "ncV:512:", "avx512fp16,evex512")
+TARGET_BUILTIN(__builtin_ia32_subph512, "V32xV32xV32xIi", "ncV:512:", "avx512fp16,evex512")
+TARGET_BUILTIN(__builtin_ia32_mulph512, "V32xV32xV32xIi", "ncV:512:", "avx512fp16,evex512")
+TARGET_BUILTIN(__builtin_ia32_divph512, "V32xV32xV32xIi", "ncV:512:", "avx512fp16,evex512")
+TARGET_BUILTIN(__builtin_ia32_maxph512, "V32xV32xV32xIi", "ncV:512:", "avx512fp16,evex512")
+TARGET_BUILTIN(__builtin_ia32_minph512, "V32xV32xV32xIi", "ncV:512:", "avx512fp16,evex512")
+
+TARGET_BUILTIN(__builtin_ia32_minph256, "V16xV16xV16x", "ncV:256:", "avx512fp16,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_minph128, "V8xV8xV8x", "ncV:128:", "avx512fp16,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_maxph256, "V16xV16xV16x", "ncV:256:", "avx512fp16,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_maxph128, "V8xV8xV8x", "ncV:128:", "avx512fp16,avx512vl")
+
+TARGET_BUILTIN(__builtin_ia32_addsh_round_mask, "V8xV8xV8xV8xUcIi", "ncV:128:", "avx512fp16")
+TARGET_BUILTIN(__builtin_ia32_divsh_round_mask, "V8xV8xV8xV8xUcIi", "ncV:128:", "avx512fp16")
+TARGET_BUILTIN(__builtin_ia32_mulsh_round_mask, "V8xV8xV8xV8xUcIi", "ncV:128:", "avx512fp16")
+TARGET_BUILTIN(__builtin_ia32_subsh_round_mask, "V8xV8xV8xV8xUcIi", "ncV:128:", "avx512fp16")
+TARGET_BUILTIN(__builtin_ia32_maxsh_round_mask, "V8xV8xV8xV8xUcIi", "ncV:128:", "avx512fp16")
+TARGET_BUILTIN(__builtin_ia32_minsh_round_mask, "V8xV8xV8xV8xUcIi", "ncV:128:", "avx512fp16")
+TARGET_BUILTIN(__builtin_ia32_cmpph512_mask, "UiV32xV32xIiUiIi", "ncV:512:", "avx512fp16,evex512")
+TARGET_BUILTIN(__builtin_ia32_cmpph256_mask, "UsV16xV16xIiUs", "ncV:256:", "avx512fp16,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_cmpph128_mask, "UcV8xV8xIiUc", "ncV:128:", "avx512fp16,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_cmpsh_mask, "UcV8xV8xIiUcIi", "ncV:128:", "avx512fp16")
+TARGET_BUILTIN(__builtin_ia32_loadsh128_mask, "V8xV8xC*V8xUc", "nV:128:", "avx512fp16")
+TARGET_BUILTIN(__builtin_ia32_storesh128_mask, "vV8x*V8xUc", "nV:128:", "avx512fp16")
+
+TARGET_BUILTIN(__builtin_ia32_rcpph128_mask, "V8xV8xV8xUc", "ncV:128:", "avx512fp16,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_rcpph256_mask, "V16xV16xV16xUs", "ncV:256:", "avx512fp16,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_rcpph512_mask, "V32xV32xV32xUi", "ncV:512:", "avx512fp16,evex512")
+TARGET_BUILTIN(__builtin_ia32_rsqrtph128_mask, "V8xV8xV8xUc", "ncV:128:", "avx512fp16,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_rsqrtph256_mask, "V16xV16xV16xUs", "ncV:256:", "avx512fp16,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_rsqrtph512_mask, "V32xV32xV32xUi", "ncV:512:", "avx512fp16,evex512")
+TARGET_BUILTIN(__builtin_ia32_getmantph128_mask, "V8xV8xIiV8xUc", "ncV:128:", "avx512fp16,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_getmantph256_mask, "V16xV16xIiV16xUs", "ncV:256:", "avx512fp16,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_getmantph512_mask, "V32xV32xIiV32xUiIi", "ncV:512:", "avx512fp16,evex512")
+
+TARGET_BUILTIN(__builtin_ia32_getexpph128_mask, "V8xV8xV8xUc", "ncV:128:", "avx512fp16,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_getexpph256_mask, "V16xV16xV16xUs", "ncV:256:", "avx512fp16,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_getexpph512_mask, "V32xV32xV32xUiIi", "ncV:512:", "avx512fp16,evex512")
+
+TARGET_BUILTIN(__builtin_ia32_scalefph128_mask, "V8xV8xV8xV8xUc", "ncV:128:", "avx512fp16,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_scalefph256_mask, "V16xV16xV16xV16xUs", "ncV:256:", "avx512fp16,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_scalefph512_mask, "V32xV32xV32xV32xUiIi", "ncV:512:", "avx512fp16,evex512")
+
+TARGET_BUILTIN(__builtin_ia32_rndscaleph_128_mask, "V8xV8xIiV8xUc", "ncV:128:", "avx512fp16,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_rndscaleph_256_mask, "V16xV16xIiV16xUs", "ncV:256:", "avx512fp16,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_rndscaleph_mask, "V32xV32xIiV32xUiIi", "ncV:512:", "avx512fp16,evex512")
+TARGET_BUILTIN(__builtin_ia32_reduceph128_mask, "V8xV8xIiV8xUc", "ncV:128:", "avx512fp16,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_reduceph256_mask, "V16xV16xIiV16xUs", "ncV:256:", "avx512fp16,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_reduceph512_mask, "V32xV32xIiV32xUiIi", "ncV:512:", "avx512fp16,evex512")
+TARGET_BUILTIN(__builtin_ia32_rcpsh_mask, "V8xV8xV8xV8xUc", "ncV:128:", "avx512fp16")
+TARGET_BUILTIN(__builtin_ia32_rsqrtsh_mask, "V8xV8xV8xV8xUc", "ncV:128:", "avx512fp16")
+TARGET_BUILTIN(__builtin_ia32_getmantsh_round_mask, "V8xV8xV8xIiV8xUcIi", "ncV:128:", "avx512fp16")
+TARGET_BUILTIN(__builtin_ia32_getexpsh128_round_mask, "V8xV8xV8xV8xUcIi", "ncV:128:", "avx512fp16")
+TARGET_BUILTIN(__builtin_ia32_scalefsh_round_mask, "V8xV8xV8xV8xUcIi", "ncV:128:", "avx512fp16")
+TARGET_BUILTIN(__builtin_ia32_rndscalesh_round_mask, "V8xV8xV8xV8xUcIiIi", "ncV:128:", "avx512fp16")
+TARGET_BUILTIN(__builtin_ia32_reducesh_mask, "V8xV8xV8xV8xUcIiIi", "ncV:128:", "avx512fp16")
+
+TARGET_BUILTIN(__builtin_ia32_sqrtph, "V8xV8x", "ncV:128:", "avx512fp16,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_sqrtph256, "V16xV16x", "ncV:256:", "avx512fp16,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_sqrtph512, "V32xV32xIi", "ncV:512:", "avx512fp16,evex512")
+TARGET_BUILTIN(__builtin_ia32_sqrtsh_round_mask, "V8xV8xV8xV8xUcIi", "ncV:128:", "avx512fp16")
+TARGET_BUILTIN(__builtin_ia32_fpclassph128_mask, "UcV8xIiUc", "ncV:128:", "avx512fp16,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_fpclassph256_mask, "UsV16xIiUs", "ncV:256:", "avx512fp16,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_fpclassph512_mask, "UiV32xIiUi", "ncV:512:", "avx512fp16,evex512")
+TARGET_BUILTIN(__builtin_ia32_fpclasssh_mask, "UcV8xIiUc", "ncV:128:", "avx512fp16")
+
+TARGET_BUILTIN(__builtin_ia32_vcvtpd2ph128_mask, "V8xV2dV8xUc", "ncV:128:", "avx512fp16,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_vcvtpd2ph256_mask, "V8xV4dV8xUc", "ncV:256:", "avx512fp16,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_vcvtpd2ph512_mask, "V8xV8dV8xUcIi", "ncV:512:", "avx512fp16,evex512")
+TARGET_BUILTIN(__builtin_ia32_vcvtph2pd128_mask, "V2dV8xV2dUc", "ncV:128:", "avx512fp16,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_vcvtph2pd256_mask, "V4dV8xV4dUc", "ncV:256:", "avx512fp16,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_vcvtph2pd512_mask, "V8dV8xV8dUcIi", "ncV:512:", "avx512fp16,evex512")
+TARGET_BUILTIN(__builtin_ia32_vcvtsh2ss_round_mask, "V4fV4fV8xV4fUcIi", "ncV:128:", "avx512fp16")
+TARGET_BUILTIN(__builtin_ia32_vcvtss2sh_round_mask, "V8xV8xV4fV8xUcIi", "ncV:128:", "avx512fp16")
+TARGET_BUILTIN(__builtin_ia32_vcvtsd2sh_round_mask, "V8xV8xV2dV8xUcIi", "ncV:128:", "avx512fp16")
+TARGET_BUILTIN(__builtin_ia32_vcvtsh2sd_round_mask, "V2dV2dV8xV2dUcIi", "ncV:128:", "avx512fp16")
+TARGET_BUILTIN(__builtin_ia32_vcvtph2w128_mask, "V8sV8xV8sUc", "ncV:128:", "avx512fp16,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_vcvtph2w256_mask, "V16sV16xV16sUs", "ncV:256:", "avx512fp16,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_vcvtph2w512_mask, "V32sV32xV32sUiIi", "ncV:512:", "avx512fp16,evex512")
+TARGET_BUILTIN(__builtin_ia32_vcvttph2w128_mask, "V8sV8xV8sUc", "ncV:128:", "avx512fp16,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_vcvttph2w256_mask, "V16sV16xV16sUs", "ncV:256:", "avx512fp16,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_vcvttph2w512_mask, "V32sV32xV32sUiIi", "ncV:512:", "avx512fp16,evex512")
+TARGET_BUILTIN(__builtin_ia32_vcvtw2ph128_mask, "V8xV8sV8xUc", "ncV:128:", "avx512fp16,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_vcvtw2ph256_mask, "V16xV16sV16xUs", "ncV:256:", "avx512fp16,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_vcvtw2ph512_mask, "V32xV32sV32xUiIi", "ncV:512:", "avx512fp16,evex512")
+TARGET_BUILTIN(__builtin_ia32_vcvtph2uw128_mask, "V8UsV8xV8UsUc", "ncV:128:", "avx512fp16,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_vcvtph2uw256_mask, "V16UsV16xV16UsUs", "ncV:256:", "avx512fp16,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_vcvtph2uw512_mask, "V32UsV32xV32UsUiIi", "ncV:512:", "avx512fp16,evex512")
+TARGET_BUILTIN(__builtin_ia32_vcvttph2uw128_mask, "V8UsV8xV8UsUc", "ncV:128:", "avx512fp16,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_vcvttph2uw256_mask, "V16UsV16xV16UsUs", "ncV:256:", "avx512fp16,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_vcvttph2uw512_mask, "V32UsV32xV32UsUiIi", "ncV:512:", "avx512fp16,evex512")
+TARGET_BUILTIN(__builtin_ia32_vcvtuw2ph128_mask, "V8xV8UsV8xUc", "ncV:128:", "avx512fp16,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_vcvtuw2ph256_mask, "V16xV16UsV16xUs", "ncV:256:", "avx512fp16,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_vcvtuw2ph512_mask, "V32xV32UsV32xUiIi", "ncV:512:", "avx512fp16,evex512")
+TARGET_BUILTIN(__builtin_ia32_vcvtph2dq128_mask, "V4iV8xV4iUc", "ncV:128:", "avx512fp16,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_vcvtph2dq256_mask, "V8iV8xV8iUc", "ncV:256:", "avx512fp16,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_vcvtph2dq512_mask, "V16iV16xV16iUsIi", "ncV:512:", "avx512fp16,evex512")
+TARGET_BUILTIN(__builtin_ia32_vcvtph2udq128_mask, "V4UiV8xV4UiUc", "ncV:128:", "avx512fp16,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_vcvtph2udq256_mask, "V8UiV8xV8UiUc", "ncV:256:", "avx512fp16,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_vcvtph2udq512_mask, "V16UiV16xV16UiUsIi", "ncV:512:", "avx512fp16,evex512")
+TARGET_BUILTIN(__builtin_ia32_vcvtdq2ph128_mask, "V8xV4iV8xUc", "ncV:128:", "avx512fp16,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_vcvtdq2ph256_mask, "V8xV8iV8xUc", "ncV:256:", "avx512fp16,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_vcvtdq2ph512_mask, "V16xV16iV16xUsIi", "ncV:512:", "avx512fp16,evex512")
+TARGET_BUILTIN(__builtin_ia32_vcvtudq2ph128_mask, "V8xV4UiV8xUc", "ncV:128:", "avx512fp16,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_vcvtudq2ph256_mask, "V8xV8UiV8xUc", "ncV:256:", "avx512fp16,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_vcvtudq2ph512_mask, "V16xV16UiV16xUsIi", "ncV:512:", "avx512fp16,evex512")
+TARGET_BUILTIN(__builtin_ia32_vcvttph2dq128_mask, "V4iV8xV4iUc", "ncV:128:", "avx512fp16,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_vcvttph2dq256_mask, "V8iV8xV8iUc", "ncV:256:", "avx512fp16,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_vcvttph2dq512_mask, "V16iV16xV16iUsIi", "ncV:512:", "avx512fp16,evex512")
+TARGET_BUILTIN(__builtin_ia32_vcvttph2udq128_mask, "V4UiV8xV4UiUc", "ncV:128:", "avx512fp16,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_vcvttph2udq256_mask, "V8UiV8xV8UiUc", "ncV:256:", "avx512fp16,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_vcvttph2udq512_mask, "V16UiV16xV16UiUsIi", "ncV:512:", "avx512fp16,evex512")
+TARGET_BUILTIN(__builtin_ia32_vcvtqq2ph128_mask, "V8xV2OiV8xUc", "ncV:128:", "avx512fp16,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_vcvtqq2ph256_mask, "V8xV4OiV8xUc", "ncV:256:", "avx512fp16,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_vcvtqq2ph512_mask, "V8xV8OiV8xUcIi", "ncV:512:", "avx512fp16,evex512")
+TARGET_BUILTIN(__builtin_ia32_vcvtph2qq128_mask, "V2OiV8xV2OiUc", "ncV:128:", "avx512fp16,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_vcvtph2qq256_mask, "V4OiV8xV4OiUc", "ncV:256:", "avx512fp16,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_vcvtph2qq512_mask, "V8OiV8xV8OiUcIi", "ncV:512:", "avx512fp16,evex512")
+TARGET_BUILTIN(__builtin_ia32_vcvtuqq2ph128_mask, "V8xV2UOiV8xUc", "ncV:128:", "avx512fp16,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_vcvtuqq2ph256_mask, "V8xV4UOiV8xUc", "ncV:256:", "avx512fp16,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_vcvtuqq2ph512_mask, "V8xV8UOiV8xUcIi", "ncV:512:", "avx512fp16,evex512")
+TARGET_BUILTIN(__builtin_ia32_vcvtph2uqq128_mask, "V2UOiV8xV2UOiUc", "ncV:128:", "avx512fp16,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_vcvtph2uqq256_mask, "V4UOiV8xV4UOiUc", "ncV:256:", "avx512fp16,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_vcvtph2uqq512_mask, "V8UOiV8xV8UOiUcIi", "ncV:512:", "avx512fp16,evex512")
+TARGET_BUILTIN(__builtin_ia32_vcvttph2qq128_mask, "V2OiV8xV2OiUc", "ncV:128:", "avx512fp16,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_vcvttph2qq256_mask, "V4OiV8xV4OiUc", "ncV:256:", "avx512fp16,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_vcvttph2qq512_mask, "V8OiV8xV8OiUcIi", "ncV:512:", "avx512fp16,evex512")
+TARGET_BUILTIN(__builtin_ia32_vcvttph2uqq128_mask, "V2UOiV8xV2UOiUc", "ncV:128:", "avx512fp16,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_vcvttph2uqq256_mask, "V4UOiV8xV4UOiUc", "ncV:256:", "avx512fp16,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_vcvttph2uqq512_mask, "V8UOiV8xV8UOiUcIi", "ncV:512:", "avx512fp16,evex512")
+TARGET_BUILTIN(__builtin_ia32_vcvtsh2si32, "iV8xIi", "ncV:128:", "avx512fp16")
+TARGET_BUILTIN(__builtin_ia32_vcvtsh2usi32, "UiV8xIi", "ncV:128:", "avx512fp16")
+TARGET_BUILTIN(__builtin_ia32_vcvtusi2sh, "V8xV8xUiIi", "ncV:128:", "avx512fp16")
+TARGET_BUILTIN(__builtin_ia32_vcvtsi2sh, "V8xV8xiIi", "ncV:128:", "avx512fp16")
+TARGET_BUILTIN(__builtin_ia32_vcvttsh2si32, "iV8xIi", "ncV:128:", "avx512fp16")
+TARGET_BUILTIN(__builtin_ia32_vcvttsh2usi32, "UiV8xIi", "ncV:128:", "avx512fp16")
+
+TARGET_BUILTIN(__builtin_ia32_vcvtph2psx128_mask, "V4fV8xV4fUc", "ncV:128:", "avx512fp16,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_vcvtph2psx256_mask, "V8fV8xV8fUc", "ncV:256:", "avx512fp16,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_vcvtph2psx512_mask, "V16fV16xV16fUsIi", "ncV:512:", "avx512fp16,evex512")
+TARGET_BUILTIN(__builtin_ia32_vcvtps2phx128_mask, "V8xV4fV8xUc", "ncV:128:", "avx512fp16,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_vcvtps2phx256_mask, "V8xV8fV8xUc", "ncV:256:", "avx512fp16,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_vcvtps2phx512_mask, "V16xV16fV16xUsIi", "ncV:512:", "avx512fp16,evex512")
+
+TARGET_BUILTIN(__builtin_ia32_vfmaddph, "V8xV8xV8xV8x", "ncV:128:", "avx512fp16,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_vfmaddph256, "V16xV16xV16xV16x", "ncV:256:", "avx512fp16,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_vfmaddph512_mask, "V32xV32xV32xV32xUiIi", "ncV:512:", "avx512fp16,evex512")
+TARGET_BUILTIN(__builtin_ia32_vfmaddph512_mask3, "V32xV32xV32xV32xUiIi", "ncV:512:", "avx512fp16,evex512")
+TARGET_BUILTIN(__builtin_ia32_vfmaddph512_maskz, "V32xV32xV32xV32xUiIi", "ncV:512:", "avx512fp16,evex512")
+TARGET_BUILTIN(__builtin_ia32_vfmaddsubph, "V8xV8xV8xV8x", "ncV:128:", "avx512fp16,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_vfmaddsubph256, "V16xV16xV16xV16x", "ncV:256:", "avx512fp16,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_vfmaddsubph512_mask, "V32xV32xV32xV32xUiIi", "ncV:512:", "avx512fp16,evex512")
+TARGET_BUILTIN(__builtin_ia32_vfmaddsubph512_maskz, "V32xV32xV32xV32xUiIi", "ncV:512:", "avx512fp16,evex512")
+TARGET_BUILTIN(__builtin_ia32_vfmaddsubph512_mask3, "V32xV32xV32xV32xUiIi", "ncV:512:", "avx512fp16,evex512")
+
+TARGET_BUILTIN(__builtin_ia32_vfmsubaddph512_mask3, "V32xV32xV32xV32xUiIi", "ncV:512:", "avx512fp16,evex512")
+TARGET_BUILTIN(__builtin_ia32_vfmsubph512_mask3, "V32xV32xV32xV32xUiIi", "ncV:512:", "avx512fp16,evex512")
+
+TARGET_BUILTIN(__builtin_ia32_vfmaddsh3_mask, "V8xV8xV8xV8xUcIi", "ncV:128:", "avx512fp16")
+TARGET_BUILTIN(__builtin_ia32_vfmaddsh3_maskz, "V8xV8xV8xV8xUcIi", "ncV:128:", "avx512fp16")
+TARGET_BUILTIN(__builtin_ia32_vfmaddsh3_mask3, "V8xV8xV8xV8xUcIi", "ncV:128:", "avx512fp16")
+TARGET_BUILTIN(__builtin_ia32_vfmsubsh3_mask3, "V8xV8xV8xV8xUcIi", "ncV:128:", "avx512fp16")
+
+TARGET_BUILTIN(__builtin_ia32_vfmaddcph128_mask, "V4fV4fV4fV4fUc", "ncV:128:", "avx512fp16,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_vfmaddcph128_maskz, "V4fV4fV4fV4fUc", "ncV:128:", "avx512fp16,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_vfmaddcph256_mask, "V8fV8fV8fV8fUc", "ncV:256:", "avx512fp16,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_vfmaddcph256_maskz, "V8fV8fV8fV8fUc", "ncV:256:", "avx512fp16,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_vfmaddcph512_mask, "V16fV16fV16fV16fUsIi", "ncV:512:", "avx512fp16,evex512")
+TARGET_BUILTIN(__builtin_ia32_vfmaddcph512_maskz, "V16fV16fV16fV16fUsIi", "ncV:512:", "avx512fp16,evex512")
+TARGET_BUILTIN(__builtin_ia32_vfmaddcph512_mask3, "V16fV16fV16fV16fUsIi", "ncV:512:", "avx512fp16,evex512")
+TARGET_BUILTIN(__builtin_ia32_vfcmaddcph128_mask, "V4fV4fV4fV4fUc", "ncV:128:", "avx512fp16,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_vfcmaddcph128_maskz, "V4fV4fV4fV4fUc", "ncV:128:", "avx512fp16,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_vfcmaddcph256_mask, "V8fV8fV8fV8fUc", "ncV:256:", "avx512fp16,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_vfcmaddcph256_maskz, "V8fV8fV8fV8fUc", "ncV:256:", "avx512fp16,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_vfcmaddcph512_mask, "V16fV16fV16fV16fUsIi", "ncV:512:", "avx512fp16,evex512")
+TARGET_BUILTIN(__builtin_ia32_vfcmaddcph512_maskz, "V16fV16fV16fV16fUsIi", "ncV:512:", "avx512fp16,evex512")
+TARGET_BUILTIN(__builtin_ia32_vfcmaddcph512_mask3, "V16fV16fV16fV16fUsIi", "ncV:512:", "avx512fp16,evex512")
+TARGET_BUILTIN(__builtin_ia32_vfmaddcsh_mask, "V4fV4fV4fV4fUcIi", "ncV:128:", "avx512fp16")
+TARGET_BUILTIN(__builtin_ia32_vfmaddcsh_maskz, "V4fV4fV4fV4fUcIi", "ncV:128:", "avx512fp16")
+TARGET_BUILTIN(__builtin_ia32_vfcmaddcsh_mask, "V4fV4fV4fV4fUcIi", "ncV:128:", "avx512fp16")
+TARGET_BUILTIN(__builtin_ia32_vfcmaddcsh_maskz, "V4fV4fV4fV4fUcIi", "ncV:128:", "avx512fp16")
+TARGET_BUILTIN(__builtin_ia32_vfmaddcsh_round_mask, "V4fV4fV4fV4fUcIi", "ncV:128:", "avx512fp16")
+TARGET_BUILTIN(__builtin_ia32_vfmaddcsh_round_mask3, "V4fV4fV4fV4fUcIi", "ncV:128:", "avx512fp16")
+TARGET_BUILTIN(__builtin_ia32_vfcmaddcsh_round_mask, "V4fV4fV4fV4fUcIi", "ncV:128:", "avx512fp16")
+TARGET_BUILTIN(__builtin_ia32_vfcmaddcsh_round_mask3, "V4fV4fV4fV4fUcIi", "ncV:128:", "avx512fp16")
+
+TARGET_BUILTIN(__builtin_ia32_vfmulcsh_mask, "V4fV4fV4fV4fUcIi", "ncV:128:", "avx512fp16")
+TARGET_BUILTIN(__builtin_ia32_vfcmulcsh_mask, "V4fV4fV4fV4fUcIi", "ncV:128:", "avx512fp16")
+TARGET_BUILTIN(__builtin_ia32_vfmulcph128_mask, "V4fV4fV4fV4fUc", "ncV:128:", "avx512fp16,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_vfmulcph256_mask, "V8fV8fV8fV8fUc", "ncV:256:", "avx512fp16,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_vfmulcph512_mask, "V16fV16fV16fV16fUsIi", "ncV:512:", "avx512fp16,evex512")
+TARGET_BUILTIN(__builtin_ia32_vfcmulcph128_mask, "V4fV4fV4fV4fUc", "ncV:128:", "avx512fp16,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_vfcmulcph256_mask, "V8fV8fV8fV8fUc", "ncV:256:", "avx512fp16,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_vfcmulcph512_mask, "V16fV16fV16fV16fUsIi", "ncV:512:", "avx512fp16,evex512")
+
// generic select intrinsics
TARGET_BUILTIN(__builtin_ia32_selectb_128, "V16cUsV16cV16c", "ncV:128:", "avx512bw,avx512vl")
TARGET_BUILTIN(__builtin_ia32_selectb_256, "V32cUiV32cV32c", "ncV:256:", "avx512bw,avx512vl")
-TARGET_BUILTIN(__builtin_ia32_selectb_512, "V64cUOiV64cV64c", "ncV:512:", "avx512bw")
+TARGET_BUILTIN(__builtin_ia32_selectb_512, "V64cUOiV64cV64c", "ncV:512:", "avx512bw,evex512")
TARGET_BUILTIN(__builtin_ia32_selectw_128, "V8sUcV8sV8s", "ncV:128:", "avx512bw,avx512vl")
TARGET_BUILTIN(__builtin_ia32_selectw_256, "V16sUsV16sV16s", "ncV:256:", "avx512bw,avx512vl")
-TARGET_BUILTIN(__builtin_ia32_selectw_512, "V32sUiV32sV32s", "ncV:512:", "avx512bw")
+TARGET_BUILTIN(__builtin_ia32_selectw_512, "V32sUiV32sV32s", "ncV:512:", "avx512bw,evex512")
TARGET_BUILTIN(__builtin_ia32_selectd_128, "V4iUcV4iV4i", "ncV:128:", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_selectd_256, "V8iUcV8iV8i", "ncV:256:", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_selectd_512, "V16iUsV16iV16i", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_selectd_512, "V16iUsV16iV16i", "ncV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_selectph_128, "V8xUcV8xV8x", "ncV:128:", "avx512fp16,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_selectph_256, "V16xUsV16xV16x", "ncV:256:", "avx512fp16,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_selectph_512, "V32xUiV32xV32x", "ncV:512:", "avx512fp16,evex512")
+TARGET_BUILTIN(__builtin_ia32_selectpbf_128, "V8yUcV8yV8y", "ncV:128:", "avx512bf16,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_selectpbf_256, "V16yUsV16yV16y", "ncV:256:", "avx512bf16,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_selectpbf_512, "V32yUiV32yV32y", "ncV:512:", "avx512bf16,evex512")
TARGET_BUILTIN(__builtin_ia32_selectq_128, "V2OiUcV2OiV2Oi", "ncV:128:", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_selectq_256, "V4OiUcV4OiV4Oi", "ncV:256:", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_selectq_512, "V8OiUcV8OiV8Oi", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_selectq_512, "V8OiUcV8OiV8Oi", "ncV:512:", "avx512f,evex512")
TARGET_BUILTIN(__builtin_ia32_selectps_128, "V4fUcV4fV4f", "ncV:128:", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_selectps_256, "V8fUcV8fV8f", "ncV:256:", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_selectps_512, "V16fUsV16fV16f", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_selectps_512, "V16fUsV16fV16f", "ncV:512:", "avx512f,evex512")
TARGET_BUILTIN(__builtin_ia32_selectpd_128, "V2dUcV2dV2d", "ncV:128:", "avx512vl")
TARGET_BUILTIN(__builtin_ia32_selectpd_256, "V4dUcV4dV4d", "ncV:256:", "avx512vl")
-TARGET_BUILTIN(__builtin_ia32_selectpd_512, "V8dUcV8dV8d", "ncV:512:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_selectpd_512, "V8dUcV8dV8d", "ncV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_selectsh_128, "V8xUcV8xV8x", "ncV:128:", "avx512fp16")
+TARGET_BUILTIN(__builtin_ia32_selectsbf_128, "V8yUcV8yV8y", "ncV:128:", "avx512bf16")
TARGET_BUILTIN(__builtin_ia32_selectss_128, "V4fUcV4fV4f", "ncV:128:", "avx512f")
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_fmax_pd512, "dV8d", "ncV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_reduce_fmax_ps512, "fV16f", "ncV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_reduce_fmin_pd512, "dV8d", "ncV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_reduce_fmin_ps512, "fV16f", "ncV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_reduce_fmul_pd512, "ddV8d", "ncV:512:", "avx512f")
-TARGET_BUILTIN(__builtin_ia32_reduce_fmul_ps512, "ffV16f", "ncV:512:", "avx512f")
-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")
+TARGET_BUILTIN(__builtin_ia32_reduce_fadd_pd512, "ddV8d", "ncV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_reduce_fadd_ps512, "ffV16f", "ncV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_reduce_fadd_ph512, "xxV32x", "ncV:512:", "avx512fp16,evex512")
+TARGET_BUILTIN(__builtin_ia32_reduce_fadd_ph256, "xxV16x", "ncV:256:", "avx512fp16,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_reduce_fadd_ph128, "xxV8x", "ncV:128:", "avx512fp16,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_reduce_fmax_pd512, "dV8d", "ncV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_reduce_fmax_ps512, "fV16f", "ncV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_reduce_fmax_ph512, "xV32x", "ncV:512:", "avx512fp16,evex512")
+TARGET_BUILTIN(__builtin_ia32_reduce_fmax_ph256, "xV16x", "ncV:256:", "avx512fp16,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_reduce_fmax_ph128, "xV8x", "ncV:128:", "avx512fp16,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_reduce_fmin_pd512, "dV8d", "ncV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_reduce_fmin_ps512, "fV16f", "ncV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_reduce_fmin_ph512, "xV32x", "ncV:512:", "avx512fp16,evex512")
+TARGET_BUILTIN(__builtin_ia32_reduce_fmin_ph256, "xV16x", "ncV:256:", "avx512fp16,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_reduce_fmin_ph128, "xV8x", "ncV:128:", "avx512fp16,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_reduce_fmul_pd512, "ddV8d", "ncV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_reduce_fmul_ps512, "ffV16f", "ncV:512:", "avx512f,evex512")
+TARGET_BUILTIN(__builtin_ia32_reduce_fmul_ph512, "xxV32x", "ncV:512:", "avx512fp16,evex512")
+TARGET_BUILTIN(__builtin_ia32_reduce_fmul_ph256, "xxV16x", "ncV:256:", "avx512fp16,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_reduce_fmul_ph128, "xxV8x", "ncV:128:", "avx512fp16,avx512vl")
// MONITORX/MWAITX
TARGET_BUILTIN(__builtin_ia32_monitorx, "vvC*UiUi", "n", "mwaitx")
@@ -1946,41 +2080,96 @@ TARGET_BUILTIN(__builtin_ia32_serialize, "v", "n", "serialize")
TARGET_BUILTIN(__builtin_ia32_xsusldtrk, "v", "n", "tsxldtrk")
TARGET_BUILTIN(__builtin_ia32_xresldtrk, "v", "n", "tsxldtrk")
+// RAO-INT
+TARGET_BUILTIN(__builtin_ia32_aadd32, "vv*Si", "n", "raoint")
+TARGET_BUILTIN(__builtin_ia32_aand32, "vv*Si", "n", "raoint")
+TARGET_BUILTIN(__builtin_ia32_aor32, "vv*Si", "n", "raoint")
+TARGET_BUILTIN(__builtin_ia32_axor32, "vv*Si", "n", "raoint")
+
// MSVC
-TARGET_HEADER_BUILTIN(_BitScanForward, "UcUNi*UNi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_BitScanReverse, "UcUNi*UNi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-
-TARGET_HEADER_BUILTIN(_ReadWriteBarrier, "v", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_ReadBarrier, "v", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_WriteBarrier, "v", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-
-TARGET_HEADER_BUILTIN(__emul, "LLiii", "nch", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(__emulu, "ULLiUiUi", "nch", "intrin.h", ALL_MS_LANGUAGES, "")
-
-TARGET_HEADER_BUILTIN(_AddressOfReturnAddress, "v*", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-
-TARGET_HEADER_BUILTIN(__stosb, "vUc*Ucz", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(__int2c, "v", "nhr", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(__ud2, "v", "nhr", "intrin.h", ALL_MS_LANGUAGES, "")
-
-TARGET_HEADER_BUILTIN(__readfsbyte, "UcUNi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(__readfsword, "UsUNi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(__readfsdword, "UNiUNi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(__readfsqword, "ULLiUNi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-
-TARGET_HEADER_BUILTIN(__readgsbyte, "UcUNi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(__readgsword, "UsUNi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(__readgsdword, "UNiUNi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(__readgsqword, "ULLiUNi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-
-TARGET_HEADER_BUILTIN(_InterlockedAnd64, "WiWiD*Wi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedDecrement64, "WiWiD*", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedExchange64, "WiWiD*Wi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedExchangeAdd64, "WiWiD*Wi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedExchangeSub64, "WiWiD*Wi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedIncrement64, "WiWiD*", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedOr64, "WiWiD*Wi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedXor64, "WiWiD*Wi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_BitScanForward, "UcUNi*UNi", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_BitScanReverse, "UcUNi*UNi", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+
+TARGET_HEADER_BUILTIN(_ReadWriteBarrier, "v", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_ReadBarrier, "v", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_WriteBarrier, "v", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+
+TARGET_HEADER_BUILTIN(__cpuid, "vi*i", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(__cpuidex, "vi*ii", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+
+TARGET_HEADER_BUILTIN(__emul, "LLiii", "nch", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(__emulu, "ULLiUiUi", "nch", INTRIN_H, ALL_MS_LANGUAGES, "")
+
+TARGET_HEADER_BUILTIN(_AddressOfReturnAddress, "v*", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+
+TARGET_HEADER_BUILTIN(__stosb, "vUc*Ucz", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(__int2c, "v", "nhr", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(__ud2, "v", "nhr", INTRIN_H, ALL_MS_LANGUAGES, "")
+
+TARGET_HEADER_BUILTIN(__readfsbyte, "UcUNi", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(__readfsword, "UsUNi", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(__readfsdword, "UNiUNi", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(__readfsqword, "ULLiUNi", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+
+TARGET_HEADER_BUILTIN(__readgsbyte, "UcUNi", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(__readgsword, "UsUNi", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(__readgsdword, "UNiUNi", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(__readgsqword, "ULLiUNi", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+
+// AVX-VNNI-INT16
+TARGET_BUILTIN(__builtin_ia32_vpdpwsud128, "V4iV4iV4iV4i", "nV:128:", "avxvnniint16")
+TARGET_BUILTIN(__builtin_ia32_vpdpwsud256, "V8iV8iV8iV8i", "nV:256:", "avxvnniint16")
+TARGET_BUILTIN(__builtin_ia32_vpdpwsuds128, "V4iV4iV4iV4i", "nV:128:", "avxvnniint16")
+TARGET_BUILTIN(__builtin_ia32_vpdpwsuds256, "V8iV8iV8iV8i", "nV:256:", "avxvnniint16")
+TARGET_BUILTIN(__builtin_ia32_vpdpwusd128, "V4iV4iV4iV4i", "nV:128:", "avxvnniint16")
+TARGET_BUILTIN(__builtin_ia32_vpdpwusd256, "V8iV8iV8iV8i", "nV:256:", "avxvnniint16")
+TARGET_BUILTIN(__builtin_ia32_vpdpwusds128, "V4iV4iV4iV4i", "nV:128:", "avxvnniint16")
+TARGET_BUILTIN(__builtin_ia32_vpdpwusds256, "V8iV8iV8iV8i", "nV:256:", "avxvnniint16")
+TARGET_BUILTIN(__builtin_ia32_vpdpwuud128, "V4iV4iV4iV4i", "nV:128:", "avxvnniint16")
+TARGET_BUILTIN(__builtin_ia32_vpdpwuud256, "V8iV8iV8iV8i", "nV:256:", "avxvnniint16")
+TARGET_BUILTIN(__builtin_ia32_vpdpwuuds128, "V4iV4iV4iV4i", "nV:128:", "avxvnniint16")
+TARGET_BUILTIN(__builtin_ia32_vpdpwuuds256, "V8iV8iV8iV8i", "nV:256:", "avxvnniint16")
+
+// AVX-NE-CONVERT
+TARGET_BUILTIN(__builtin_ia32_vbcstnebf162ps128, "V4fyC*", "nV:128:", "avxneconvert")
+TARGET_BUILTIN(__builtin_ia32_vbcstnebf162ps256, "V8fyC*", "nV:256:", "avxneconvert")
+TARGET_BUILTIN(__builtin_ia32_vbcstnesh2ps128, "V4fxC*", "nV:128:", "avxneconvert")
+TARGET_BUILTIN(__builtin_ia32_vbcstnesh2ps256, "V8fxC*", "nV:256:", "avxneconvert")
+TARGET_BUILTIN(__builtin_ia32_vcvtneebf162ps128, "V4fV8yC*", "nV:128:", "avxneconvert")
+TARGET_BUILTIN(__builtin_ia32_vcvtneebf162ps256, "V8fV16yC*", "nV:256:", "avxneconvert")
+TARGET_BUILTIN(__builtin_ia32_vcvtneeph2ps128, "V4fV8xC*", "nV:128:", "avxneconvert")
+TARGET_BUILTIN(__builtin_ia32_vcvtneeph2ps256, "V8fV16xC*", "nV:256:", "avxneconvert")
+TARGET_BUILTIN(__builtin_ia32_vcvtneobf162ps128, "V4fV8yC*", "nV:128:", "avxneconvert")
+TARGET_BUILTIN(__builtin_ia32_vcvtneobf162ps256, "V8fV16yC*", "nV:256:", "avxneconvert")
+TARGET_BUILTIN(__builtin_ia32_vcvtneoph2ps128, "V4fV8xC*", "nV:128:", "avxneconvert")
+TARGET_BUILTIN(__builtin_ia32_vcvtneoph2ps256, "V8fV16xC*", "nV:256:", "avxneconvert")
+TARGET_BUILTIN(__builtin_ia32_vcvtneps2bf16128, "V8yV4f", "nV:128:", "avx512bf16,avx512vl|avxneconvert")
+TARGET_BUILTIN(__builtin_ia32_vcvtneps2bf16256, "V8yV8f", "nV:256:", "avx512bf16,avx512vl|avxneconvert")
+
+// SHA512
+TARGET_BUILTIN(__builtin_ia32_vsha512msg1, "V4ULLiV4ULLiV2ULLi", "nV:256:", "sha512")
+TARGET_BUILTIN(__builtin_ia32_vsha512msg2, "V4ULLiV4ULLiV4ULLi", "nV:256:", "sha512")
+TARGET_BUILTIN(__builtin_ia32_vsha512rnds2, "V4ULLiV4ULLiV4ULLiV2ULLi", "nV:256:", "sha512")
+
+TARGET_HEADER_BUILTIN(_InterlockedAnd64, "WiWiD*Wi", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedDecrement64, "WiWiD*", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedExchange64, "WiWiD*Wi", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedExchangeAdd64, "WiWiD*Wi", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedExchangeSub64, "WiWiD*Wi", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedIncrement64, "WiWiD*", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedOr64, "WiWiD*Wi", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_InterlockedXor64, "WiWiD*Wi", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+
+// SM3
+TARGET_BUILTIN(__builtin_ia32_vsm3msg1, "V4UiV4UiV4UiV4Ui", "nV:128:", "sm3")
+TARGET_BUILTIN(__builtin_ia32_vsm3msg2, "V4UiV4UiV4UiV4Ui", "nV:128:", "sm3")
+TARGET_BUILTIN(__builtin_ia32_vsm3rnds2, "V4UiV4UiV4UiV4UiIUi", "nV:128:", "sm3")
+
+// SM4
+TARGET_BUILTIN(__builtin_ia32_vsm4key4128, "V4UiV4UiV4Ui", "nV:128:", "sm4")
+TARGET_BUILTIN(__builtin_ia32_vsm4key4256, "V8UiV8UiV8Ui", "nV:256:", "sm4")
+TARGET_BUILTIN(__builtin_ia32_vsm4rnds4128, "V4UiV4UiV4Ui", "nV:128:", "sm4")
+TARGET_BUILTIN(__builtin_ia32_vsm4rnds4256, "V8UiV8UiV8Ui", "nV:256:", "sm4")
#undef BUILTIN
#undef TARGET_BUILTIN
diff --git a/contrib/llvm-project/clang/include/clang/Basic/BuiltinsX86_64.def b/contrib/llvm-project/clang/include/clang/Basic/BuiltinsX86_64.def
index ce2b1decdf6c..5e00916d4b25 100644
--- a/contrib/llvm-project/clang/include/clang/Basic/BuiltinsX86_64.def
+++ b/contrib/llvm-project/clang/include/clang/Basic/BuiltinsX86_64.def
@@ -21,19 +21,19 @@
# define TARGET_HEADER_BUILTIN(ID, TYPE, ATTRS, HEADER, LANG, FEATURE) BUILTIN(ID, TYPE, ATTRS)
#endif
-TARGET_HEADER_BUILTIN(_BitScanForward64, "UcUNi*ULLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_BitScanReverse64, "UcUNi*ULLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_BitScanForward64, "UcUNi*ULLi", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_BitScanReverse64, "UcUNi*ULLi", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(__mulh, "LLiLLiLLi", "nch", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(__umulh, "ULLiULLiULLi", "nch", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_mul128, "LLiLLiLLiLLi*", "nch", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_umul128, "ULLiULLiULLiULLi*", "nch", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(__mulh, "LLiLLiLLi", "nch", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(__umulh, "ULLiULLiULLi", "nch", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_mul128, "LLiLLiLLiLLi*", "nch", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(_umul128, "ULLiULLiULLiULLi*", "nch", INTRIN_H, ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(__faststorefence, "v", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(__shiftleft128, "ULLiULLiULLiUc", "nch", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(__shiftright128, "ULLiULLiULLiUc", "nch", "intrin.h", ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(__faststorefence, "v", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(__shiftleft128, "ULLiULLiULLiUc", "nch", INTRIN_H, ALL_MS_LANGUAGES, "")
+TARGET_HEADER_BUILTIN(__shiftright128, "ULLiULLiULLiUc", "nch", INTRIN_H, ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_InterlockedCompareExchange128, "UcLLiD*LLiLLiLLi*", "nh", "intrin.h", ALL_MS_LANGUAGES, "cx16")
+TARGET_HEADER_BUILTIN(_InterlockedCompareExchange128, "UcLLiD*LLiLLiLLi*", "nh", INTRIN_H, ALL_MS_LANGUAGES, "cx16")
TARGET_BUILTIN(__builtin_ia32_readeflags_u64, "UOi", "n", "")
TARGET_BUILTIN(__builtin_ia32_writeeflags_u64, "vUOi", "n", "")
@@ -42,9 +42,8 @@ TARGET_BUILTIN(__builtin_ia32_cvttss2si64, "OiV4f", "ncV:128:", "sse")
TARGET_BUILTIN(__builtin_ia32_cvtsd2si64, "OiV2d", "ncV:128:", "sse2")
TARGET_BUILTIN(__builtin_ia32_cvttsd2si64, "OiV2d", "ncV:128:", "sse2")
TARGET_BUILTIN(__builtin_ia32_movnti64, "vOi*Oi", "n", "sse2")
-TARGET_BUILTIN(__builtin_ia32_vec_ext_v2di, "OiV2OiIi", "ncV:128:", "sse2")
TARGET_BUILTIN(__builtin_ia32_vec_set_v2di, "V2OiV2OiOiIi", "ncV:128:", "sse4.1")
-TARGET_BUILTIN(__builtin_ia32_crc32di, "UOiUOiUOi", "nc", "sse4.2")
+TARGET_BUILTIN(__builtin_ia32_crc32di, "UOiUOiUOi", "nc", "crc32")
TARGET_BUILTIN(__builtin_ia32_vec_ext_v4di, "OiV4OiIi", "ncV:256:", "avx")
TARGET_BUILTIN(__builtin_ia32_vec_set_v4di, "V4OiV4OiOiIi", "ncV:256:", "avx")
TARGET_BUILTIN(__builtin_ia32_rdfsbase32, "Ui", "n", "fsgsbase")
@@ -92,6 +91,12 @@ TARGET_BUILTIN(__builtin_ia32_cvtsi2sd64, "V2dV2dOiIi", "ncV:128:", "avx512f")
TARGET_BUILTIN(__builtin_ia32_cvtsi2ss64, "V4fV4fOiIi", "ncV:128:", "avx512f")
TARGET_BUILTIN(__builtin_ia32_cvtusi2sd64, "V2dV2dUOiIi", "ncV:128:", "avx512f")
TARGET_BUILTIN(__builtin_ia32_cvtusi2ss64, "V4fV4fUOiIi", "ncV:128:", "avx512f")
+TARGET_BUILTIN(__builtin_ia32_vcvtsh2si64, "OiV8xIi", "ncV:128:", "avx512fp16")
+TARGET_BUILTIN(__builtin_ia32_vcvtsh2usi64, "UOiV8xIi", "ncV:128:", "avx512fp16")
+TARGET_BUILTIN(__builtin_ia32_vcvtusi642sh, "V8xV8xUOiIi", "ncV:128:", "avx512fp16")
+TARGET_BUILTIN(__builtin_ia32_vcvtsi642sh, "V8xV8xOiIi", "ncV:128:", "avx512fp16")
+TARGET_BUILTIN(__builtin_ia32_vcvttsh2si64, "OiV8xIi", "ncV:128:", "avx512fp16")
+TARGET_BUILTIN(__builtin_ia32_vcvttsh2usi64, "UOiV8xIi", "ncV:128:", "avx512fp16")
TARGET_BUILTIN(__builtin_ia32_directstore_u64, "vULi*ULi", "n", "movdiri")
// UINTR
@@ -99,6 +104,9 @@ TARGET_BUILTIN(__builtin_ia32_clui, "v", "n", "uintr")
TARGET_BUILTIN(__builtin_ia32_stui, "v", "n", "uintr")
TARGET_BUILTIN(__builtin_ia32_testui, "Uc", "n", "uintr")
TARGET_BUILTIN(__builtin_ia32_senduipi, "vUWi", "n", "uintr")
+// USERMSR
+TARGET_BUILTIN(__builtin_ia32_urdmsr, "ULLiULLi", "n", "usermsr")
+TARGET_BUILTIN(__builtin_ia32_uwrmsr, "vULLiULLi", "n", "usermsr")
// AMX internal builtin
TARGET_BUILTIN(__builtin_ia32_tile_loadconfig_internal, "vvC*", "n", "amx-tile")
@@ -111,6 +119,9 @@ TARGET_BUILTIN(__builtin_ia32_tdpbuud_internal, "V256iUsUsUsV256iV256iV256i", "n
TARGET_BUILTIN(__builtin_ia32_tilestored64_internal, "vUsUsv*zV256i", "n", "amx-tile")
TARGET_BUILTIN(__builtin_ia32_tilezero_internal, "V256iUsUs", "n", "amx-tile")
TARGET_BUILTIN(__builtin_ia32_tdpbf16ps_internal, "V256iUsUsUsV256iV256iV256i", "n", "amx-bf16")
+TARGET_BUILTIN(__builtin_ia32_tdpfp16ps_internal, "V256iUsUsUsV256iV256iV256i", "n", "amx-fp16")
+TARGET_BUILTIN(__builtin_ia32_tcmmimfp16ps_internal, "V256iUsUsUsV256iV256iV256i", "n", "amx-complex")
+TARGET_BUILTIN(__builtin_ia32_tcmmrlfp16ps_internal, "V256iUsUsUsV256iV256iV256i", "n", "amx-complex")
// AMX
TARGET_BUILTIN(__builtin_ia32_tile_loadconfig, "vvC*", "n", "amx-tile")
TARGET_BUILTIN(__builtin_ia32_tile_storeconfig, "vvC*", "n", "amx-tile")
@@ -128,6 +139,22 @@ TARGET_BUILTIN(__builtin_ia32_tdpbuud, "vIUcIUcIUc", "n", "amx-int8")
TARGET_BUILTIN(__builtin_ia32_tdpbf16ps, "vIUcIUcIUc", "n", "amx-bf16")
TARGET_BUILTIN(__builtin_ia32_ptwrite64, "vUOi", "n", "ptwrite")
+TARGET_BUILTIN(__builtin_ia32_tcmmimfp16ps, "vIUcIUcIUc", "n", "amx-complex")
+TARGET_BUILTIN(__builtin_ia32_tcmmrlfp16ps, "vIUcIUcIUc", "n", "amx-complex")
+
+TARGET_BUILTIN(__builtin_ia32_prefetchi, "vvC*Ui", "nc", "prefetchi")
+TARGET_BUILTIN(__builtin_ia32_cmpccxadd32, "Siv*SiSiIi", "n", "cmpccxadd")
+TARGET_BUILTIN(__builtin_ia32_cmpccxadd64, "SLLiv*SLLiSLLiIi", "n", "cmpccxadd")
+
+// AMX_FP16 FP16
+TARGET_BUILTIN(__builtin_ia32_tdpfp16ps, "vIUcIUcIUc", "n", "amx-fp16")
+
+// RAO-INT
+TARGET_BUILTIN(__builtin_ia32_aadd64, "vv*SOi", "n", "raoint")
+TARGET_BUILTIN(__builtin_ia32_aand64, "vv*SOi", "n", "raoint")
+TARGET_BUILTIN(__builtin_ia32_aor64, "vv*SOi", "n", "raoint")
+TARGET_BUILTIN(__builtin_ia32_axor64, "vv*SOi", "n", "raoint")
+
#undef BUILTIN
#undef TARGET_BUILTIN
#undef TARGET_HEADER_BUILTIN
diff --git a/contrib/llvm-project/clang/include/clang/Basic/CLWarnings.h b/contrib/llvm-project/clang/include/clang/Basic/CLWarnings.h
new file mode 100644
index 000000000000..9b8be93bad3a
--- /dev/null
+++ b/contrib/llvm-project/clang/include/clang/Basic/CLWarnings.h
@@ -0,0 +1,26 @@
+//===--- CLWarnings.h - Maps some cl.exe warning ids -----------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_BASIC_CLWARNINGS_H
+#define LLVM_CLANG_BASIC_CLWARNINGS_H
+
+#include <optional>
+
+namespace clang {
+
+namespace diag {
+enum class Group;
+}
+
+/// For cl.exe warning IDs that cleany map to clang diagnostic groups,
+/// returns the corresponding group. Else, returns an empty Optional.
+std::optional<diag::Group> diagGroupFromCLWarningID(unsigned);
+
+} // end namespace clang
+
+#endif // LLVM_CLANG_BASIC_CLWARNINGS_H
diff --git a/contrib/llvm-project/clang/include/clang/Basic/CharInfo.h b/contrib/llvm-project/clang/include/clang/Basic/CharInfo.h
index 8577475fab06..7d4119383508 100644
--- a/contrib/llvm-project/clang/include/clang/Basic/CharInfo.h
+++ b/contrib/llvm-project/clang/include/clang/Basic/CharInfo.h
@@ -38,15 +38,21 @@ namespace charinfo {
};
} // end namespace charinfo
-/// Returns true if this is an ASCII character.
+/// Returns true if a byte is an ASCII character.
LLVM_READNONE inline bool isASCII(char c) {
return static_cast<unsigned char>(c) <= 127;
}
+LLVM_READNONE inline bool isASCII(unsigned char c) { return c <= 127; }
+
+/// Returns true if a codepoint is an ASCII character.
+LLVM_READNONE inline bool isASCII(uint32_t c) { return c <= 127; }
+LLVM_READNONE inline bool isASCII(int64_t c) { return 0 <= c && c <= 127; }
+
/// Returns true if this is a valid first character of a C identifier,
/// which is [a-zA-Z_].
-LLVM_READONLY inline bool isIdentifierHead(unsigned char c,
- bool AllowDollar = false) {
+LLVM_READONLY inline bool isAsciiIdentifierStart(unsigned char c,
+ bool AllowDollar = false) {
using namespace charinfo;
if (InfoTable[c] & (CHAR_UPPER|CHAR_LOWER|CHAR_UNDER))
return true;
@@ -55,8 +61,8 @@ LLVM_READONLY inline bool isIdentifierHead(unsigned char c,
/// Returns true if this is a body character of a C identifier,
/// which is [a-zA-Z0-9_].
-LLVM_READONLY inline bool isIdentifierBody(unsigned char c,
- bool AllowDollar = false) {
+LLVM_READONLY inline bool isAsciiIdentifierContinue(unsigned char c,
+ bool AllowDollar = false) {
using namespace charinfo;
if (InfoTable[c] & (CHAR_UPPER|CHAR_LOWER|CHAR_DIGIT|CHAR_UNDER))
return true;
@@ -157,6 +163,44 @@ LLVM_READONLY inline bool isRawStringDelimBody(unsigned char c) {
CHAR_DIGIT|CHAR_UNDER|CHAR_RAWDEL)) != 0;
}
+enum class EscapeChar {
+ Single = 1,
+ Double = 2,
+ SingleAndDouble = static_cast<int>(Single) | static_cast<int>(Double),
+};
+
+/// Return C-style escaped string for special characters, or an empty string if
+/// there is no such mapping.
+template <EscapeChar Opt, class CharT>
+LLVM_READONLY inline auto escapeCStyle(CharT Ch) -> StringRef {
+ switch (Ch) {
+ case '\\':
+ return "\\\\";
+ case '\'':
+ if ((static_cast<int>(Opt) & static_cast<int>(EscapeChar::Single)) == 0)
+ break;
+ return "\\'";
+ case '"':
+ if ((static_cast<int>(Opt) & static_cast<int>(EscapeChar::Double)) == 0)
+ break;
+ return "\\\"";
+ case '\a':
+ return "\\a";
+ case '\b':
+ return "\\b";
+ case '\f':
+ return "\\f";
+ case '\n':
+ return "\\n";
+ case '\r':
+ return "\\r";
+ case '\t':
+ return "\\t";
+ case '\v':
+ return "\\v";
+ }
+ return {};
+}
/// Converts the given ASCII character to its lowercase equivalent.
///
@@ -181,13 +225,13 @@ LLVM_READONLY inline char toUppercase(char c) {
///
/// Note that this is a very simple check; it does not accept UCNs as valid
/// identifier characters.
-LLVM_READONLY inline bool isValidIdentifier(StringRef S,
- bool AllowDollar = false) {
- if (S.empty() || !isIdentifierHead(S[0], AllowDollar))
+LLVM_READONLY inline bool isValidAsciiIdentifier(StringRef S,
+ bool AllowDollar = false) {
+ if (S.empty() || !isAsciiIdentifierStart(S[0], AllowDollar))
return false;
for (StringRef::iterator I = S.begin(), E = S.end(); I != E; ++I)
- if (!isIdentifierBody(*I, AllowDollar))
+ if (!isAsciiIdentifierContinue(*I, AllowDollar))
return false;
return true;
diff --git a/contrib/llvm-project/clang/include/clang/Basic/CodeGenOptions.def b/contrib/llvm-project/clang/include/clang/Basic/CodeGenOptions.def
index e3202cf88756..7c0bfe328496 100644
--- a/contrib/llvm-project/clang/include/clang/Basic/CodeGenOptions.def
+++ b/contrib/llvm-project/clang/include/clang/Basic/CodeGenOptions.def
@@ -12,6 +12,9 @@
// that have enumeration type and VALUE_CODEGENOPT is a code
// generation option that describes a value rather than a flag.
//
+// AFFECTING_VALUE_CODEGENOPT is used for code generation options that can
+// affect the AST.
+//
//===----------------------------------------------------------------------===//
#ifndef CODEGENOPT
# error Define the CODEGENOPT macro to handle language options
@@ -27,16 +30,19 @@ CODEGENOPT(Name, Bits, Default)
CODEGENOPT(Name, Bits, Default)
#endif
+#ifndef AFFECTING_VALUE_CODEGENOPT
+# define AFFECTING_VALUE_CODEGENOPT(Name, Bits, Default) \
+VALUE_CODEGENOPT(Name, Bits, Default)
+#endif
+
CODEGENOPT(DisableIntegratedAS, 1, 0) ///< -no-integrated-as
-ENUM_CODEGENOPT(CompressDebugSections, llvm::DebugCompressionType, 2,
- llvm::DebugCompressionType::None)
-CODEGENOPT(RelaxELFRelocations, 1, 0) ///< -Wa,--mrelax-relocations
+CODEGENOPT(RelaxELFRelocations, 1, 1) ///< -Wa,-mrelax-relocations={yes,no}
CODEGENOPT(AsmVerbose , 1, 0) ///< -dA, -fverbose-asm.
-CODEGENOPT(Dwarf64 , 1, 0) ///< -gdwarf64.
-CODEGENOPT(Dwarf32 , 1, 1) ///< -gdwarf32.
CODEGENOPT(PreserveAsmComments, 1, 1) ///< -dA, -fno-preserve-as-comments.
CODEGENOPT(AssumeSaneOperatorNew , 1, 1) ///< implicit __attribute__((malloc)) operator new
+CODEGENOPT(AssumeUniqueVTables , 1, 1) ///< Assume a class has only one vtable.
CODEGENOPT(Autolink , 1, 1) ///< -fno-autolink
+CODEGENOPT(AutoImport , 1, 1) ///< -fno-auto-import
CODEGENOPT(ObjCAutoRefCountExceptions , 1, 0) ///< Whether ARC should be EH-safe.
CODEGENOPT(Backchain , 1, 0) ///< -mbackchain
CODEGENOPT(ControlFlowGuardNoChecks , 1, 0) ///< -cfguard-no-checks
@@ -52,8 +58,10 @@ CODEGENOPT(UniqueBasicBlockSectionNames, 1, 1) ///< Set for -funique-basic-block
///< Produce unique section names with
///< basic block sections.
CODEGENOPT(EnableAIXExtendedAltivecABI, 1, 0) ///< Set for -mabi=vec-extabi. Enables the extended Altivec ABI on AIX.
+CODEGENOPT(XCOFFReadOnlyPointers, 1, 0) ///< Set for -mxcoff-roptr.
ENUM_CODEGENOPT(FramePointer, FramePointerKind, 2, FramePointerKind::None) /// frame-pointer: all,non-leaf,none
+CODEGENOPT(ClearASTBeforeBackend , 1, 0) ///< Free the AST before running backend code generation. Only works with -disable-free.
CODEGENOPT(DisableFree , 1, 0) ///< Don't free memory.
CODEGENOPT(DiscardValueNames , 1, 0) ///< Discard Value Names from the IR (LLVMContext flag)
CODEGENOPT(DisableLLVMPasses , 1, 0) ///< Don't run any LLVM IR passes to get
@@ -64,16 +72,11 @@ CODEGENOPT(DisableO0ImplyOptNone , 1, 0) ///< Don't annonate function with optno
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(LegacyPassManager, 1, 0) ///< Use the legacy pass manager.
CODEGENOPT(DebugPassManager, 1, 0) ///< Prints debug information for the new
///< pass manager.
CODEGENOPT(DisableRedZone , 1, 0) ///< Set when -mno-red-zone is enabled.
CODEGENOPT(EmitCallSiteInfo, 1, 0) ///< Emit call site info only in the case of
///< '-g' + 'O>0' level.
-CODEGENOPT(EnableDIPreservationVerify, 1, 0) ///< Enable di preservation verify
- ///< each (it means check
- ///< the original debug info
- ///< metadata preservation).
CODEGENOPT(IndirectTlsSegRefs, 1, 0) ///< Set when -mno-tls-direct-seg-refs
///< is specified.
CODEGENOPT(DisableTailCalls , 1, 0) ///< Do not emit tail calls.
@@ -84,13 +87,12 @@ CODEGENOPT(EmitDeclMetadata , 1, 0) ///< Emit special metadata indicating what
///< Only useful when running CodeGen as a
///< subroutine.
CODEGENOPT(EmitVersionIdentMetadata , 1, 1) ///< Emit compiler version metadata.
-CODEGENOPT(EmitGcovArcs , 1, 0) ///< Emit coverage data files, aka. GCDA.
-CODEGENOPT(EmitGcovNotes , 1, 0) ///< Emit coverage "notes" files, aka GCNO.
CODEGENOPT(EmitOpenCLArgMetadata , 1, 0) ///< Emit OpenCL kernel arg metadata.
CODEGENOPT(EmulatedTLS , 1, 0) ///< Set by default or -f[no-]emulated-tls.
-CODEGENOPT(ExplicitEmulatedTLS , 1, 0) ///< Set if -f[no-]emulated-tls is used.
/// Embed Bitcode mode (off/all/bitcode/marker).
ENUM_CODEGENOPT(EmbedBitcode, EmbedBitcodeKind, 2, Embed_Off)
+/// Inline asm dialect, -masm=(att|intel)
+ENUM_CODEGENOPT(InlineAsmDialect, InlineAsmDialectKind, 1, IAD_ATT)
CODEGENOPT(ForbidGuardVariables , 1, 0) ///< Issue errors if C++ guard variables
///< are required.
CODEGENOPT(FunctionSections , 1, 0) ///< Set when -ffunction-sections is enabled.
@@ -104,11 +106,16 @@ 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(FunctionReturnThunks, 1, 0) ///< -mfunction-return={keep|thunk-extern}
+CODEGENOPT(IndirectBranchCSPrefix, 1, 0) ///< if -mindirect-branch-cs-prefix
+ ///< is set.
+
CODEGENOPT(XRayInstrumentFunctions , 1, 0) ///< Set when -fxray-instrument is
///< enabled.
CODEGENOPT(StackSizeSection , 1, 0) ///< Set when -fstack-size-section is enabled.
-CODEGENOPT(ForceDwarfFrameSection , 1, 0) ///< Set when -fforce-dwarf-frame is
- ///< enabled.
+
+///< Set when -femit-compact-unwind-non-canonical is enabled.
+CODEGENOPT(EmitCompactUnwindNonCanonical, 1, 0)
///< Set when -fxray-always-emit-customevents is enabled.
CODEGENOPT(XRayAlwaysEmitCustomEvents , 1, 0)
@@ -119,8 +126,8 @@ CODEGENOPT(XRayAlwaysEmitTypedEvents , 1, 0)
///< Set when -fxray-ignore-loops is enabled.
CODEGENOPT(XRayIgnoreLoops , 1, 0)
-///< Set with -fno-xray-function-index to omit the index section.
-CODEGENOPT(XRayOmitFunctionIndex , 1, 0)
+///< Emit the XRay function index section.
+CODEGENOPT(XRayFunctionIndex , 1, 1)
///< Set the minimum number of instructions in a function to determine selective
@@ -136,6 +143,10 @@ 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(JMCInstrument, 1, 0) ///< Set when -fjmc is enabled.
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.
@@ -149,58 +160,66 @@ CODEGENOPT(PrepareForThinLTO , 1, 0) ///< Set when -flto=thin is enabled on the
///< compile step.
CODEGENOPT(LTOUnit, 1, 0) ///< Emit IR to support LTO unit features (CFI, whole
///< program vtable opt).
+CODEGENOPT(FatLTO, 1, 0) ///< Set when -ffat-lto-objects is enabled.
CODEGENOPT(EnableSplitLTOUnit, 1, 0) ///< Enable LTO unit splitting to support
/// CFI and traditional whole program
/// devirtualization that require whole
/// program IR support.
+CODEGENOPT(UnifiedLTO, 1, 0) ///< Use the unified LTO pipeline.
CODEGENOPT(IncrementalLinkerCompatible, 1, 0) ///< Emit an object file which can
///< be used with an incremental
///< linker.
CODEGENOPT(MergeAllConstants , 1, 1) ///< Merge identical constants.
CODEGENOPT(MergeFunctions , 1, 0) ///< Set when -fmerge-functions is enabled.
-CODEGENOPT(MSVolatile , 1, 0) ///< Set when /volatile:ms is enabled.
CODEGENOPT(NoCommon , 1, 0) ///< Set when -fno-common or C++ is enabled.
-CODEGENOPT(NoDwarfDirectoryAsm , 1, 0) ///< Set when -fno-dwarf-directory-asm is
- ///< enabled.
CODEGENOPT(NoExecStack , 1, 0) ///< Set when -Wa,--noexecstack is enabled.
CODEGENOPT(FatalWarnings , 1, 0) ///< Set when -Wa,--fatal-warnings is
///< enabled.
CODEGENOPT(NoWarn , 1, 0) ///< Set when -Wa,--no-warn is enabled.
+CODEGENOPT(NoTypeCheck , 1, 0) ///< Set when -Wa,--no-type-check is enabled.
+CODEGENOPT(MisExpect , 1, 0) ///< Set when -Wmisexpect is enabled
CODEGENOPT(EnableSegmentedStacks , 1, 0) ///< Set when -fsplit-stack is enabled.
-CODEGENOPT(NoInlineLineTables, 1, 0) ///< Whether debug info should contain
- ///< inline line tables.
CODEGENOPT(StackClashProtector, 1, 0) ///< Set when -fstack-clash-protection is enabled.
CODEGENOPT(NoImplicitFloat , 1, 0) ///< Set when -mno-implicit-float is enabled.
CODEGENOPT(NullPointerIsValid , 1, 0) ///< Assume Null pointer deference is defined.
CODEGENOPT(OpenCLCorrectlyRoundedDivSqrt, 1, 0) ///< -cl-fp32-correctly-rounded-divide-sqrt
CODEGENOPT(HIPCorrectlyRoundedDivSqrt, 1, 1) ///< -fno-hip-fp32-correctly-rounded-divide-sqrt
+CODEGENOPT(HIPSaveKernelArgName, 1, 0) ///< Set when -fhip-kernel-arg-name is enabled.
CODEGENOPT(UniqueInternalLinkageNames, 1, 0) ///< Internal Linkage symbols get unique names.
CODEGENOPT(SplitMachineFunctions, 1, 0) ///< Split machine functions using profile information.
+CODEGENOPT(PPCUseFullRegisterNames, 1, 0) ///< Print full register names in assembly
/// When false, this attempts to generate code as if the result of an
/// overflowing conversion matches the overflowing behavior of a target's native
/// float-to-int conversion instructions.
CODEGENOPT(StrictFloatCastOverflow, 1, 1)
-CODEGENOPT(UniformWGSize , 1, 0) ///< -cl-uniform-work-group-size
CODEGENOPT(NoZeroInitializedInBSS , 1, 0) ///< -fno-zero-initialized-in-bss.
/// Method of Objective-C dispatch to use.
ENUM_CODEGENOPT(ObjCDispatchMethod, ObjCDispatchMethodKind, 2, Legacy)
/// Replace certain message sends with calls to ObjC runtime entrypoints
CODEGENOPT(ObjCConvertMessagesToRuntimeCalls , 1, 1)
+CODEGENOPT(ObjCAvoidHeapifyLocalBlocks, 1, 0)
-VALUE_CODEGENOPT(OptimizationLevel, 2, 0) ///< The -O[0-3] option specified.
-VALUE_CODEGENOPT(OptimizeSize, 2, 0) ///< If -Os (==1) or -Oz (==2) is specified.
+
+// The optimization options affect frontend options, whicn in turn do affect the AST.
+AFFECTING_VALUE_CODEGENOPT(OptimizationLevel, 2, 0) ///< The -O[0-3] option specified.
+AFFECTING_VALUE_CODEGENOPT(OptimizeSize, 2, 0) ///< If -Os (==1) or -Oz (==2) is specified.
CODEGENOPT(AtomicProfileUpdate , 1, 0) ///< Set -fprofile-update=atomic
/// Choose profile instrumenation kind or no instrumentation.
ENUM_CODEGENOPT(ProfileInstr, ProfileInstrKind, 2, ProfileNone)
/// Choose profile kind for PGO use compilation.
ENUM_CODEGENOPT(ProfileUse, ProfileInstrKind, 2, ProfileNone)
+/// Partition functions into N groups and select only functions in group i to be
+/// instrumented. Selected group numbers can be 0 to N-1 inclusive.
+VALUE_CODEGENOPT(ProfileTotalFunctionGroups, 32, 1)
+VALUE_CODEGENOPT(ProfileSelectedFunctionGroup, 32, 0)
CODEGENOPT(CoverageMapping , 1, 0) ///< Generate coverage mapping regions to
///< enable code coverage analysis.
CODEGENOPT(DumpCoverageMapping , 1, 0) ///< Dump the generated coverage mapping
///< regions.
+CODEGENOPT(MCDCCoverage , 1, 0) ///< Enable MC/DC code coverage criteria.
/// If -fpcc-struct-return or -freg-struct-return is specified.
ENUM_CODEGENOPT(StructReturnConvention, StructReturnConventionKind, 2, SRCK_Default)
@@ -227,6 +246,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.
@@ -234,6 +256,8 @@ CODEGENOPT(SanitizeMinimalRuntime, 1, 0) ///< Use "_minimal" sanitizer runtime f
///< diagnostics.
CODEGENOPT(SanitizeCfiICallGeneralizePointers, 1, 0) ///< Generalize pointer types in
///< CFI icall function signatures
+CODEGENOPT(SanitizeCfiICallNormalizeIntegers, 1, 0) ///< Normalize integer types in
+ ///< CFI icall function signatures
CODEGENOPT(SanitizeCfiCanonicalJumpTables, 1, 0) ///< Make jump table symbols canonical
///< instead of creating a local jump table.
CODEGENOPT(SanitizeCoverageType, 2, 0) ///< Type of sanitizer coverage
@@ -257,8 +281,15 @@ CODEGENOPT(SanitizeCoverageTracePCGuard, 1, 0) ///< Enable PC tracing with guard
CODEGENOPT(SanitizeCoverageInline8bitCounters, 1, 0) ///< Use inline 8bit counters.
CODEGENOPT(SanitizeCoverageInlineBoolFlag, 1, 0) ///< Use inline bool flag.
CODEGENOPT(SanitizeCoveragePCTable, 1, 0) ///< Create a PC Table.
+CODEGENOPT(SanitizeCoverageControlFlow, 1, 0) ///< Collect control flow
CODEGENOPT(SanitizeCoverageNoPrune, 1, 0) ///< Disable coverage pruning.
CODEGENOPT(SanitizeCoverageStackDepth, 1, 0) ///< Enable max stack depth tracing
+CODEGENOPT(SanitizeCoverageTraceLoads, 1, 0) ///< Enable tracing of loads.
+CODEGENOPT(SanitizeCoverageTraceStores, 1, 0) ///< Enable tracing of stores.
+CODEGENOPT(SanitizeBinaryMetadataCovered, 1, 0) ///< Emit PCs for covered functions.
+CODEGENOPT(SanitizeBinaryMetadataAtomics, 1, 0) ///< Emit PCs for atomic operations.
+CODEGENOPT(SanitizeBinaryMetadataUAR, 1, 0) ///< Emit PCs for start of functions
+ ///< that are subject for use-after-return checking.
CODEGENOPT(SanitizeStats , 1, 0) ///< Collect statistics for sanitizers.
CODEGENOPT(SimplifyLibCalls , 1, 1) ///< Set when -fbuiltin is enabled.
CODEGENOPT(SoftFloat , 1, 0) ///< -soft-float.
@@ -274,7 +305,7 @@ VALUE_CODEGENOPT(TimeTraceGranularity, 32, 500) ///< Minimum time granularity (i
CODEGENOPT(UnrollLoops , 1, 0) ///< Control whether loops are unrolled.
CODEGENOPT(RerollLoops , 1, 0) ///< Control whether loops are rerolled.
CODEGENOPT(NoUseJumpTables , 1, 0) ///< Set when -fno-jump-tables is enabled.
-CODEGENOPT(UnwindTables , 1, 0) ///< Emit unwind tables.
+VALUE_CODEGENOPT(UnwindTables, 2, 0) ///< Unwind tables (1) or asynchronous unwind tables (2)
CODEGENOPT(VectorizeLoop , 1, 0) ///< Run loop vectorizer.
CODEGENOPT(VectorizeSLP , 1, 0) ///< Run SLP vectorizer.
CODEGENOPT(ProfileSampleAccurate, 1, 0) ///< Sample profile is accurate.
@@ -288,35 +319,21 @@ CODEGENOPT(UseRegisterSizedBitfieldAccess , 1, 0)
CODEGENOPT(VerifyModule , 1, 1) ///< Control whether the module should be run
///< through the LLVM Verifier.
+CODEGENOPT(VerifyEach , 1, 1) ///< Control whether the LLVM verifier
+ ///< should run after every pass.
CODEGENOPT(StackRealignment , 1, 0) ///< Control whether to force stack
///< realignment.
CODEGENOPT(UseInitArray , 1, 0) ///< Control whether to use .init_array or
///< .ctors.
+VALUE_CODEGENOPT(LoopAlignment , 32, 0) ///< Overrides default loop
+ ///< alignment, if not 0.
VALUE_CODEGENOPT(StackAlignment , 32, 0) ///< Overrides default stack
///< alignment, if not 0.
VALUE_CODEGENOPT(StackProbeSize , 32, 4096) ///< Overrides default stack
///< probe size, even if 0.
VALUE_CODEGENOPT(WarnStackSize , 32, UINT_MAX) ///< Set via -fwarn-stack-size.
CODEGENOPT(NoStackArgProbe, 1, 0) ///< Set when -mno-stack-arg-probe is used
-CODEGENOPT(DebugStrictDwarf, 1, 1) ///< Whether or not to use strict DWARF info.
-CODEGENOPT(DebugColumnInfo, 1, 0) ///< Whether or not to use column information
- ///< in debug info.
-
-CODEGENOPT(DebugTypeExtRefs, 1, 0) ///< Whether or not debug info should contain
- ///< external references to a PCH or module.
-
-CODEGENOPT(DebugExplicitImport, 1, 0) ///< Whether or not debug info should
- ///< contain explicit imports for
- ///< anonymous namespaces
-
-CODEGENOPT(SplitDwarfInlining, 1, 1) ///< Whether to include inlining info in the
- ///< skeleton CU to allow for symbolication
- ///< of inline stack frames without .dwo files.
-CODEGENOPT(DebugFwdTemplateParams, 1, 0) ///< Whether to emit complete
- ///< template parameter descriptions in
- ///< forward declarations (versus just
- ///< including them in the name).
CODEGENOPT(EmitLLVMUseLists, 1, 0) ///< Control whether to serialize use-lists.
CODEGENOPT(WholeProgramVTables, 1, 0) ///< Whether to apply whole-program
@@ -340,39 +357,21 @@ VALUE_CODEGENOPT(SmallDataLimit, 32, 0)
/// The lower bound for a buffer to be considered for stack protection.
VALUE_CODEGENOPT(SSPBufferSize, 32, 0)
-/// The kind of generated debug info.
-ENUM_CODEGENOPT(DebugInfo, codegenoptions::DebugInfoKind, 4, codegenoptions::NoDebugInfo)
-
-/// Whether to generate macro debug info.
-CODEGENOPT(MacroDebugInfo, 1, 0)
-
-/// Tune the debug info for this debugger.
-ENUM_CODEGENOPT(DebuggerTuning, llvm::DebuggerKind, 3,
- llvm::DebuggerKind::Default)
-
-/// Dwarf version. Version zero indicates to LLVM that no DWARF should be
-/// emitted.
-VALUE_CODEGENOPT(DwarfVersion, 3, 0)
-
-/// Whether to use experimental new variable location tracking.
-CODEGENOPT(ValueTrackingVariableLocations, 1, 0)
-
-/// Whether we should emit CodeView debug information. It's possible to emit
-/// CodeView and DWARF into the same object.
-CODEGENOPT(EmitCodeView, 1, 0)
-
-/// Whether to emit the .debug$H section containing hashes of CodeView types.
-CODEGENOPT(CodeViewGHash, 1, 0)
-
/// The kind of inlining to perform.
ENUM_CODEGENOPT(Inlining, InliningMethod, 2, NormalInlining)
+/// The maximum stack size a function can have to be considered for inlining.
+VALUE_CODEGENOPT(InlineMaxStackSize, 32, UINT_MAX)
+
// Vector functions library to use.
-ENUM_CODEGENOPT(VecLib, VectorLibrary, 3, NoLibrary)
+ENUM_CODEGENOPT(VecLib, llvm::driver::VectorLibrary, 3, llvm::driver::VectorLibrary::NoLibrary)
/// The default TLS model to use.
ENUM_CODEGENOPT(DefaultTLSModel, TLSModel, 2, GeneralDynamicTLSModel)
+/// Whether to enable TLSDESC. AArch64 enables TLSDESC regardless of this value.
+CODEGENOPT(EnableTLSDESC, 1, 0)
+
/// Bit size of immediate TLS offsets (0 == use the default).
VALUE_CODEGENOPT(TLSSize, 8, 0)
@@ -393,26 +392,14 @@ CODEGENOPT(DirectAccessExternalData, 1, 0)
/// paths that reach the end of a function without executing a required return.
CODEGENOPT(StrictReturn, 1, 1)
-/// Whether emit extra debug info for sample pgo profile collection.
-CODEGENOPT(DebugInfoForProfiling, 1, 0)
-
/// Whether emit pseudo probes for sample pgo profile collection.
CODEGENOPT(PseudoProbeForProfiling, 1, 0)
/// Whether 3-component vector type is preserved.
CODEGENOPT(PreserveVec3Type, 1, 0)
-/// Whether to emit .debug_gnu_pubnames section instead of .debug_pubnames.
-CODEGENOPT(DebugNameTable, 2, 0)
-
-/// Whether to use DWARF base address specifiers in .debug_ranges.
-CODEGENOPT(DebugRangesBaseAddress, 1, 0)
-
CODEGENOPT(NoPLT, 1, 0)
-/// Whether to embed source in DWARF debug line section.
-CODEGENOPT(EmbedSource, 1, 0)
-
/// Whether to emit all vtables
CODEGENOPT(ForceEmitVTables, 1, 0)
@@ -422,6 +409,10 @@ CODEGENOPT(Addrsig, 1, 0)
/// Whether to emit unused static constants.
CODEGENOPT(KeepStaticConsts, 1, 0)
+/// Whether to emit all variables that have a persistent storage duration,
+/// including global, static and thread local variables.
+CODEGENOPT(KeepPersistentStorageVariables, 1, 0)
+
/// Whether to follow the AAPCS enforcing at least one read before storing to a volatile bitfield
CODEGENOPT(ForceAAPCSBitfieldLoad, 1, 0)
@@ -437,6 +428,26 @@ CODEGENOPT(AAPCSBitfieldWidth, 1, 1)
/// propagate signaling NaN inputs per IEEE 754-2008 (AMDGPU Only)
CODEGENOPT(EmitIEEENaNCompliantInsts, 1, 1)
+// Whether to emit Swift Async function extended frame information: auto,
+// never, always.
+ENUM_CODEGENOPT(SwiftAsyncFramePointer, SwiftAsyncFramePointerKind, 2,
+ SwiftAsyncFramePointerKind::Always)
+
+/// Whether to skip RAX setup when passing variable arguments (x86 only).
+CODEGENOPT(SkipRaxSetup, 1, 0)
+
+/// Whether to zero out caller-used registers before returning.
+ENUM_CODEGENOPT(ZeroCallUsedRegs, llvm::ZeroCallUsedRegs::ZeroCallUsedRegsKind,
+ 5, llvm::ZeroCallUsedRegs::ZeroCallUsedRegsKind::Skip)
+
+/// Modify C++ ABI to returning `this` pointer from constructors and
+/// non-deleting destructors. (No effect on Microsoft ABI.)
+CODEGENOPT(CtorDtorReturnThis, 1, 0)
+
+/// FIXME: Make DebugOptions its own top-level .def file.
+#include "DebugOptions.def"
+
#undef CODEGENOPT
#undef ENUM_CODEGENOPT
#undef VALUE_CODEGENOPT
+#undef AFFECTING_VALUE_CODEGENOPT
diff --git a/contrib/llvm-project/clang/include/clang/Basic/CodeGenOptions.h b/contrib/llvm-project/clang/include/clang/Basic/CodeGenOptions.h
index 617c255641ef..3f8fe385fef3 100644
--- a/contrib/llvm-project/clang/include/clang/Basic/CodeGenOptions.h
+++ b/contrib/llvm-project/clang/include/clang/Basic/CodeGenOptions.h
@@ -13,10 +13,11 @@
#ifndef LLVM_CLANG_BASIC_CODEGENOPTIONS_H
#define LLVM_CLANG_BASIC_CODEGENOPTIONS_H
-#include "clang/Basic/DebugInfoOptions.h"
#include "clang/Basic/Sanitizers.h"
#include "clang/Basic/XRayInstr.h"
#include "llvm/ADT/FloatingPointMode.h"
+#include "llvm/Frontend/Debug/Options.h"
+#include "llvm/Frontend/Driver/CodeGenOptions.h"
#include "llvm/Support/CodeGen.h"
#include "llvm/Support/Regex.h"
#include "llvm/Target/TargetOptions.h"
@@ -26,12 +27,16 @@
#include <string>
#include <vector>
+namespace llvm {
+class PassBuilder;
+}
namespace clang {
/// Bitfields of CodeGenOptions, split out from CodeGenOptions to ensure
/// that this large collection of bitfields is a trivial class type.
class CodeGenOptionsBase {
friend class CompilerInvocation;
+ friend class CompilerInvocationBase;
public:
#define CODEGENOPT(Name, Bits, Default) unsigned Name : Bits;
@@ -54,15 +59,6 @@ public:
OnlyAlwaysInlining // Only run the always inlining pass.
};
- enum VectorLibrary {
- NoLibrary, // Don't use any vector library.
- Accelerate, // Use the Accelerate framework.
- LIBMVEC, // GLIBC vector math library.
- MASSV, // IBM MASS vector library.
- SVML, // Intel short vector math library.
- Darwin_libsystem_m // Use Darwin's libsytem_m vector functions.
- };
-
enum ObjCDispatchMethodKind {
Legacy = 0,
NonLegacy = 1,
@@ -97,6 +93,17 @@ public:
Embed_Marker // Embed a marker as a placeholder for bitcode.
};
+ enum InlineAsmDialectKind {
+ IAD_ATT,
+ IAD_Intel,
+ };
+
+ enum DebugSrcHashKind {
+ DSH_MD5,
+ DSH_SHA1,
+ DSH_SHA256,
+ };
+
// This field stores one of the allowed values for the option
// -fbasic-block-sections=. The allowed values with this option are:
// {"labels", "all", "list=<file>", "none"}.
@@ -125,15 +132,45 @@ public:
All, // Keep all frame pointers.
};
+ static StringRef getFramePointerKindName(FramePointerKind Kind) {
+ switch (Kind) {
+ case FramePointerKind::None:
+ return "none";
+ case FramePointerKind::NonLeaf:
+ return "non-leaf";
+ case FramePointerKind::All:
+ return "all";
+ }
+
+ llvm_unreachable("invalid FramePointerKind");
+ }
+
+ enum class SwiftAsyncFramePointerKind {
+ Auto, // Choose Swift async extended frame info based on deployment target.
+ Always, // Unconditionally emit Swift async extended frame info.
+ Never, // Don't emit Swift async extended frame info.
+ Default = Always,
+ };
+
enum FiniteLoopsKind {
Language, // Not specified, use language standard.
Always, // All loops are assumed to be finite.
Never, // No loop is assumed to be finite.
};
+ enum AssignmentTrackingOpts {
+ Disabled,
+ Enabled,
+ Forced,
+ };
+
/// The code model to use (-mcmodel).
std::string CodeModel;
+ /// The code model-specific large data threshold to use
+ /// (-mlarge-data-threshold).
+ uint64_t LargeDataThreshold;
+
/// The filename with path we use for coverage data files. The runtime
/// allows further manipulation with the GCOV_PREFIX and GCOV_PREFIX_STRIP
/// environment variables.
@@ -168,8 +205,11 @@ public:
/// if non-empty.
std::string RecordCommandLine;
- std::map<std::string, std::string> DebugPrefixMap;
- std::map<std::string, std::string> CoveragePrefixMap;
+ llvm::SmallVector<std::pair<std::string, std::string>, 0> DebugPrefixMap;
+
+ /// Prefix replacement map for source-based code coverage to remap source
+ /// file paths in coverage mapping.
+ llvm::SmallVector<std::pair<std::string, std::string>, 0> CoveragePrefixMap;
/// The ABI to use for passing floating point arguments.
std::string FloatABI;
@@ -215,6 +255,9 @@ public:
/// Output filename for the split debug info, not used in the skeleton CU.
std::string SplitDwarfOutput;
+ /// Output filename used in the COFF debug information.
+ std::string ObjectFilenameForDebug;
+
/// The name of the relocation model to use.
llvm::Reloc::Model RelocationModel;
@@ -238,6 +281,9 @@ public:
/// Name of the profile file to use as output for with -fmemory-profile.
std::string MemoryProfileOutput;
+ /// Name of the profile file to use as input for -fmemory-profile-use.
+ std::string MemoryProfileUsePath;
+
/// Name of the profile file to use as input for -fprofile-instr-use
std::string ProfileInstrumentUsePath;
@@ -261,6 +307,10 @@ public:
/// CUDA runtime back-end for incorporating them into host-side object file.
std::string CudaGpuBinaryFileName;
+ /// List of filenames passed in using the -fembed-offload-object option. These
+ /// are offloading binaries containing device images and metadata.
+ std::vector<std::string> OffloadObjects;
+
/// The name of the file to which the backend should save YAML optimization
/// records.
std::string OptRecordFile;
@@ -287,12 +337,12 @@ public:
/// Optimization remark with an optional regular expression pattern.
struct OptRemark {
- RemarkKind Kind;
+ RemarkKind Kind = RK_Missing;
std::string Pattern;
std::shared_ptr<llvm::Regex> Regex;
/// By default, optimization remark is missing.
- OptRemark() : Kind(RK_Missing), Pattern(""), Regex(nullptr) {}
+ OptRemark() = default;
/// Returns true iff the optimization remark holds a valid regular
/// expression.
@@ -323,9 +373,6 @@ public:
/// transformation.
OptRemark OptimizationRemarkAnalysis;
- /// Set of files defining the rules for the symbol rewriting.
- std::vector<std::string> RewriteMapFiles;
-
/// Set of sanitizer checks that are non-fatal (i.e. execution should be
/// continued when possible).
SanitizerSet SanitizeRecover;
@@ -354,6 +401,9 @@ public:
/// List of dynamic shared object files to be loaded as pass plugins.
std::vector<std::string> PassPlugins;
+ /// List of pass builder callbacks.
+ std::vector<std::function<void(llvm::PassBuilder &)>> PassBuilderCallbacks;
+
/// Path to allowlist file specifying which objects
/// (files, functions) should exclusively be instrumented
/// by sanitizer coverage pass.
@@ -370,11 +420,19 @@ public:
/// On AArch64 this can only be "sp_el0".
std::string StackProtectorGuardReg;
+ /// Specify a symbol to be the guard value.
+ std::string StackProtectorGuardSymbol;
+
/// Path to ignorelist file specifying which objects
/// (files, functions) listed for instrumentation by sanitizer
/// coverage pass should actually not be instrumented.
std::vector<std::string> SanitizeCoverageIgnorelistFiles;
+ /// Path to ignorelist file specifying which objects
+ /// (files, functions) listed for instrumentation by sanitizer
+ /// binary metadata pass should not be instrumented.
+ std::vector<std::string> SanitizeMetadataIgnorelistFiles;
+
/// Name of the stack usage file (i.e., .su file) if user passes
/// -fstack-usage. If empty, it can be implied that -fstack-usage is not
/// passed on the command line.
@@ -383,7 +441,7 @@ public:
/// Executable and command-line used to create a given CompilerInvocation.
/// Most of the time this will be the full -cc1 command.
const char *Argv0 = nullptr;
- ArrayRef<const char *> CommandLineArgs;
+ std::vector<std::string> CommandLineArgs;
/// The minimum hotness value a diagnostic needs in order to be included in
/// optimization diagnostics.
@@ -398,7 +456,14 @@ public:
/// compilation.
///
/// If threshold option is not specified, it is disabled by default.
- Optional<uint64_t> DiagnosticsHotnessThreshold = 0;
+ std::optional<uint64_t> DiagnosticsHotnessThreshold = 0;
+
+ /// The maximum percentage profiling weights can deviate from the expected
+ /// values in order to be included in misexpect diagnostics.
+ std::optional<uint32_t> DiagnosticsMisExpectTolerance = 0;
+
+ /// The name of a file to use with \c .secure_log_unique directives.
+ std::string AsSecureLogFile;
public:
// Define accessors/mutators for code generation options of enumeration type.
@@ -429,6 +494,9 @@ public:
return getProfileInstr() == ProfileCSIRInstr;
}
+ /// Check if any form of instrumentation is on.
+ bool hasProfileInstr() const { return getProfileInstr() != ProfileNone; }
+
/// Check if Clang profile use is on.
bool hasProfileClangUse() const {
return getProfileUse() == ProfileClangInstr;
@@ -445,19 +513,30 @@ public:
/// Check if type and variable info should be emitted.
bool hasReducedDebugInfo() const {
- return getDebugInfo() >= codegenoptions::DebugInfoConstructor;
+ return getDebugInfo() >= llvm::codegenoptions::DebugInfoConstructor;
}
/// Check if maybe unused type info should be emitted.
bool hasMaybeUnusedDebugInfo() const {
- return getDebugInfo() >= codegenoptions::UnusedTypeInfo;
+ return getDebugInfo() >= llvm::codegenoptions::UnusedTypeInfo;
}
// Check if any one of SanitizeCoverage* is enabled.
bool hasSanitizeCoverage() const {
return SanitizeCoverageType || SanitizeCoverageIndirectCalls ||
- SanitizeCoverageTraceCmp;
+ SanitizeCoverageTraceCmp || SanitizeCoverageTraceLoads ||
+ SanitizeCoverageTraceStores || SanitizeCoverageControlFlow;
}
+
+ // Check if any one of SanitizeBinaryMetadata* is enabled.
+ bool hasSanitizeBinaryMetadata() const {
+ return SanitizeBinaryMetadataCovered || SanitizeBinaryMetadataAtomics ||
+ SanitizeBinaryMetadataUAR;
+ }
+
+ /// Reset all of the options that are not considered when building a
+ /// module.
+ void resetNonModularOptions(StringRef ModuleFormat);
};
} // end namespace clang
diff --git a/contrib/llvm-project/clang/include/clang/Basic/Cuda.h b/contrib/llvm-project/clang/include/clang/Basic/Cuda.h
index aa12724cbf0c..916cb4b7ef34 100644
--- a/contrib/llvm-project/clang/include/clang/Basic/Cuda.h
+++ b/contrib/llvm-project/clang/include/clang/Basic/Cuda.h
@@ -31,8 +31,20 @@ enum class CudaVersion {
CUDA_110,
CUDA_111,
CUDA_112,
- LATEST = CUDA_112,
- LATEST_SUPPORTED = CUDA_101,
+ CUDA_113,
+ CUDA_114,
+ CUDA_115,
+ CUDA_116,
+ CUDA_117,
+ CUDA_118,
+ CUDA_120,
+ CUDA_121,
+ CUDA_122,
+ CUDA_123,
+ FULLY_SUPPORTED = CUDA_123,
+ PARTIALLY_SUPPORTED =
+ CUDA_123, // Partially supported. Proceed with a warning.
+ NEW = 10000, // Too new. Issue a warning, but allow using it.
};
const char *CudaVersionToString(CudaVersion V);
// Input is "Major.Minor"
@@ -58,6 +70,10 @@ enum class CudaArch {
SM_75,
SM_80,
SM_86,
+ SM_87,
+ SM_89,
+ SM_90,
+ SM_90a,
GFX600,
GFX601,
GFX602,
@@ -80,6 +96,9 @@ enum class CudaArch {
GFX909,
GFX90a,
GFX90c,
+ GFX940,
+ GFX941,
+ GFX942,
GFX1010,
GFX1011,
GFX1012,
@@ -90,7 +109,21 @@ enum class CudaArch {
GFX1033,
GFX1034,
GFX1035,
+ GFX1036,
+ GFX1100,
+ GFX1101,
+ GFX1102,
+ GFX1103,
+ GFX1150,
+ GFX1151,
+ GFX1200,
+ GFX1201,
+ Generic, // A processor model named 'generic' if the target backend defines a
+ // public one.
LAST,
+
+ CudaDefault = CudaArch::SM_52,
+ HIPDefault = CudaArch::GFX803,
};
static inline bool IsNVIDIAGpuArch(CudaArch A) {
@@ -98,7 +131,8 @@ static inline bool IsNVIDIAGpuArch(CudaArch A) {
}
static inline bool IsAMDGpuArch(CudaArch A) {
- return A >= CudaArch::GFX600 && A < CudaArch::LAST;
+ // Generic processor model is for testing only.
+ return A >= CudaArch::GFX600 && A < CudaArch::Generic;
}
const char *CudaArchToString(CudaArch A);
diff --git a/contrib/llvm-project/clang/include/clang/Basic/CustomizableOptional.h b/contrib/llvm-project/clang/include/clang/Basic/CustomizableOptional.h
new file mode 100644
index 000000000000..84d40025ee41
--- /dev/null
+++ b/contrib/llvm-project/clang/include/clang/Basic/CustomizableOptional.h
@@ -0,0 +1,280 @@
+//===- CustomizableOptional.h - Optional with custom storage ----*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef CLANG_BASIC_CUSTOMIZABLEOPTIONAL_H
+#define CLANG_BASIC_CUSTOMIZABLEOPTIONAL_H
+
+#include "llvm/ADT/Hashing.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/type_traits.h"
+#include <cassert>
+#include <new>
+#include <optional>
+#include <utility>
+
+namespace clang {
+
+namespace optional_detail {
+template <typename> class OptionalStorage;
+} // namespace optional_detail
+
+// Optional type which internal storage can be specialized by providing
+// OptionalStorage. The interface follows std::optional.
+template <typename T> class CustomizableOptional {
+ optional_detail::OptionalStorage<T> Storage;
+
+public:
+ using value_type = T;
+
+ constexpr CustomizableOptional() = default;
+ constexpr CustomizableOptional(std::nullopt_t) {}
+
+ constexpr CustomizableOptional(const T &y) : Storage(std::in_place, y) {}
+ constexpr CustomizableOptional(const CustomizableOptional &O) = default;
+
+ constexpr CustomizableOptional(T &&y)
+ : Storage(std::in_place, std::move(y)) {}
+ constexpr CustomizableOptional(CustomizableOptional &&O) = default;
+
+ template <typename... ArgTypes>
+ constexpr CustomizableOptional(std::in_place_t, ArgTypes &&...Args)
+ : Storage(std::in_place, std::forward<ArgTypes>(Args)...) {}
+
+ // Allow conversion from std::optional<T>.
+ constexpr CustomizableOptional(const std::optional<T> &y)
+ : CustomizableOptional(y ? *y : CustomizableOptional()) {}
+ constexpr CustomizableOptional(std::optional<T> &&y)
+ : CustomizableOptional(y ? std::move(*y) : CustomizableOptional()) {}
+
+ CustomizableOptional &operator=(T &&y) {
+ Storage = std::move(y);
+ return *this;
+ }
+ CustomizableOptional &operator=(CustomizableOptional &&O) = default;
+
+ /// Create a new object by constructing it in place with the given arguments.
+ template <typename... ArgTypes> void emplace(ArgTypes &&...Args) {
+ Storage.emplace(std::forward<ArgTypes>(Args)...);
+ }
+
+ CustomizableOptional &operator=(const T &y) {
+ Storage = y;
+ return *this;
+ }
+ CustomizableOptional &operator=(const CustomizableOptional &O) = default;
+
+ void reset() { Storage.reset(); }
+
+ LLVM_DEPRECATED("Use &*X instead.", "&*X")
+ constexpr const T *getPointer() const { return &Storage.value(); }
+ LLVM_DEPRECATED("Use &*X instead.", "&*X")
+ T *getPointer() { return &Storage.value(); }
+ LLVM_DEPRECATED("std::optional::value is throwing. Use *X instead", "*X")
+ constexpr const T &value() const & { return Storage.value(); }
+ LLVM_DEPRECATED("std::optional::value is throwing. Use *X instead", "*X")
+ T &value() & { return Storage.value(); }
+
+ constexpr explicit operator bool() const { return has_value(); }
+ constexpr bool has_value() const { return Storage.has_value(); }
+ constexpr const T *operator->() const { return &Storage.value(); }
+ T *operator->() { return &Storage.value(); }
+ constexpr const T &operator*() const & { return Storage.value(); }
+ T &operator*() & { return Storage.value(); }
+
+ template <typename U> constexpr T value_or(U &&alt) const & {
+ return has_value() ? operator*() : std::forward<U>(alt);
+ }
+
+ LLVM_DEPRECATED("std::optional::value is throwing. Use *X instead", "*X")
+ T &&value() && { return std::move(Storage.value()); }
+ T &&operator*() && { return std::move(Storage.value()); }
+
+ template <typename U> T value_or(U &&alt) && {
+ return has_value() ? std::move(operator*()) : std::forward<U>(alt);
+ }
+
+ // Allow conversion to std::optional<T>.
+ explicit operator std::optional<T> &() const & {
+ return *this ? **this : std::optional<T>();
+ }
+ explicit operator std::optional<T> &&() const && {
+ return *this ? std::move(**this) : std::optional<T>();
+ }
+};
+
+template <typename T>
+CustomizableOptional(const T &) -> CustomizableOptional<T>;
+
+template <class T>
+llvm::hash_code hash_value(const CustomizableOptional<T> &O) {
+ return O ? llvm::hash_combine(true, *O) : llvm::hash_value(false);
+}
+
+template <typename T, typename U>
+constexpr bool operator==(const CustomizableOptional<T> &X,
+ const CustomizableOptional<U> &Y) {
+ if (X && Y)
+ return *X == *Y;
+ return X.has_value() == Y.has_value();
+}
+
+template <typename T, typename U>
+constexpr bool operator!=(const CustomizableOptional<T> &X,
+ const CustomizableOptional<U> &Y) {
+ return !(X == Y);
+}
+
+template <typename T, typename U>
+constexpr bool operator<(const CustomizableOptional<T> &X,
+ const CustomizableOptional<U> &Y) {
+ if (X && Y)
+ return *X < *Y;
+ return X.has_value() < Y.has_value();
+}
+
+template <typename T, typename U>
+constexpr bool operator<=(const CustomizableOptional<T> &X,
+ const CustomizableOptional<U> &Y) {
+ return !(Y < X);
+}
+
+template <typename T, typename U>
+constexpr bool operator>(const CustomizableOptional<T> &X,
+ const CustomizableOptional<U> &Y) {
+ return Y < X;
+}
+
+template <typename T, typename U>
+constexpr bool operator>=(const CustomizableOptional<T> &X,
+ const CustomizableOptional<U> &Y) {
+ return !(X < Y);
+}
+
+template <typename T>
+constexpr bool operator==(const CustomizableOptional<T> &X, std::nullopt_t) {
+ return !X;
+}
+
+template <typename T>
+constexpr bool operator==(std::nullopt_t, const CustomizableOptional<T> &X) {
+ return X == std::nullopt;
+}
+
+template <typename T>
+constexpr bool operator!=(const CustomizableOptional<T> &X, std::nullopt_t) {
+ return !(X == std::nullopt);
+}
+
+template <typename T>
+constexpr bool operator!=(std::nullopt_t, const CustomizableOptional<T> &X) {
+ return X != std::nullopt;
+}
+
+template <typename T>
+constexpr bool operator<(const CustomizableOptional<T> &, std::nullopt_t) {
+ return false;
+}
+
+template <typename T>
+constexpr bool operator<(std::nullopt_t, const CustomizableOptional<T> &X) {
+ return X.has_value();
+}
+
+template <typename T>
+constexpr bool operator<=(const CustomizableOptional<T> &X, std::nullopt_t) {
+ return !(std::nullopt < X);
+}
+
+template <typename T>
+constexpr bool operator<=(std::nullopt_t, const CustomizableOptional<T> &X) {
+ return !(X < std::nullopt);
+}
+
+template <typename T>
+constexpr bool operator>(const CustomizableOptional<T> &X, std::nullopt_t) {
+ return std::nullopt < X;
+}
+
+template <typename T>
+constexpr bool operator>(std::nullopt_t, const CustomizableOptional<T> &X) {
+ return X < std::nullopt;
+}
+
+template <typename T>
+constexpr bool operator>=(const CustomizableOptional<T> &X, std::nullopt_t) {
+ return std::nullopt <= X;
+}
+
+template <typename T>
+constexpr bool operator>=(std::nullopt_t, const CustomizableOptional<T> &X) {
+ return X <= std::nullopt;
+}
+
+template <typename T>
+constexpr bool operator==(const CustomizableOptional<T> &X, const T &Y) {
+ return X && *X == Y;
+}
+
+template <typename T>
+constexpr bool operator==(const T &X, const CustomizableOptional<T> &Y) {
+ return Y && X == *Y;
+}
+
+template <typename T>
+constexpr bool operator!=(const CustomizableOptional<T> &X, const T &Y) {
+ return !(X == Y);
+}
+
+template <typename T>
+constexpr bool operator!=(const T &X, const CustomizableOptional<T> &Y) {
+ return !(X == Y);
+}
+
+template <typename T>
+constexpr bool operator<(const CustomizableOptional<T> &X, const T &Y) {
+ return !X || *X < Y;
+}
+
+template <typename T>
+constexpr bool operator<(const T &X, const CustomizableOptional<T> &Y) {
+ return Y && X < *Y;
+}
+
+template <typename T>
+constexpr bool operator<=(const CustomizableOptional<T> &X, const T &Y) {
+ return !(Y < X);
+}
+
+template <typename T>
+constexpr bool operator<=(const T &X, const CustomizableOptional<T> &Y) {
+ return !(Y < X);
+}
+
+template <typename T>
+constexpr bool operator>(const CustomizableOptional<T> &X, const T &Y) {
+ return Y < X;
+}
+
+template <typename T>
+constexpr bool operator>(const T &X, const CustomizableOptional<T> &Y) {
+ return Y < X;
+}
+
+template <typename T>
+constexpr bool operator>=(const CustomizableOptional<T> &X, const T &Y) {
+ return !(X < Y);
+}
+
+template <typename T>
+constexpr bool operator>=(const T &X, const CustomizableOptional<T> &Y) {
+ return !(X < Y);
+}
+
+} // namespace clang
+
+#endif // CLANG_BASIC_CUSTOMIZABLEOPTIONAL_H
diff --git a/contrib/llvm-project/clang/include/clang/Basic/DarwinSDKInfo.h b/contrib/llvm-project/clang/include/clang/Basic/DarwinSDKInfo.h
index 918dc7c8becc..dedfbd934a7b 100644
--- a/contrib/llvm-project/clang/include/clang/Basic/DarwinSDKInfo.h
+++ b/contrib/llvm-project/clang/include/clang/Basic/DarwinSDKInfo.h
@@ -6,15 +6,16 @@
//
//===----------------------------------------------------------------------===//
-#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"
-#include "llvm/ADT/Triple.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/VersionTuple.h"
#include "llvm/Support/VirtualFileSystem.h"
+#include "llvm/TargetParser/Triple.h"
+#include <optional>
namespace llvm {
namespace json {
@@ -57,6 +58,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;
@@ -85,12 +100,12 @@ public:
/// Returns the mapped key, or the appropriate Minimum / MaximumValue if
/// they key is outside of the mapping bounds. If they key isn't mapped, but
- /// within the minimum and maximum bounds, None is returned.
- Optional<VersionTuple> map(const VersionTuple &Key,
- const VersionTuple &MinimumValue,
- Optional<VersionTuple> MaximumValue) const;
+ /// within the minimum and maximum bounds, std::nullopt is returned.
+ std::optional<VersionTuple>
+ map(const VersionTuple &Key, const VersionTuple &MinimumValue,
+ std::optional<VersionTuple> MaximumValue) const;
- static Optional<RelatedTargetVersionMapping>
+ static std::optional<RelatedTargetVersionMapping>
parseJSON(const llvm::json::Object &Obj,
VersionTuple MaximumDeploymentTarget);
@@ -102,12 +117,13 @@ public:
llvm::DenseMap<VersionTuple, VersionTuple> Mapping;
};
- DarwinSDKInfo(VersionTuple Version, VersionTuple MaximumDeploymentTarget,
- llvm::DenseMap<OSEnvPair::StorageType,
- Optional<RelatedTargetVersionMapping>>
- VersionMappings =
- llvm::DenseMap<OSEnvPair::StorageType,
- Optional<RelatedTargetVersionMapping>>())
+ DarwinSDKInfo(
+ VersionTuple Version, VersionTuple MaximumDeploymentTarget,
+ llvm::DenseMap<OSEnvPair::StorageType,
+ std::optional<RelatedTargetVersionMapping>>
+ VersionMappings =
+ llvm::DenseMap<OSEnvPair::StorageType,
+ std::optional<RelatedTargetVersionMapping>>())
: Version(Version), MaximumDeploymentTarget(MaximumDeploymentTarget),
VersionMappings(std::move(VersionMappings)) {}
@@ -128,11 +144,10 @@ public:
auto Mapping = VersionMappings.find(Kind.Value);
if (Mapping == VersionMappings.end())
return nullptr;
- return Mapping->getSecond().hasValue() ? Mapping->getSecond().getPointer()
- : nullptr;
+ return Mapping->getSecond() ? &*Mapping->getSecond() : nullptr;
}
- static Optional<DarwinSDKInfo>
+ static std::optional<DarwinSDKInfo>
parseDarwinSDKSettingsJSON(const llvm::json::Object *Obj);
private:
@@ -141,17 +156,18 @@ private:
// Need to wrap the value in an optional here as the value has to be default
// constructible, and std::unique_ptr doesn't like DarwinSDKInfo being
// Optional as Optional is trying to copy it in emplace.
- llvm::DenseMap<OSEnvPair::StorageType, Optional<RelatedTargetVersionMapping>>
+ llvm::DenseMap<OSEnvPair::StorageType,
+ std::optional<RelatedTargetVersionMapping>>
VersionMappings;
};
/// Parse the SDK information from the SDKSettings.json file.
///
-/// \returns an error if the SDKSettings.json file is invalid, None if the
-/// SDK has no SDKSettings.json, or a valid \c DarwinSDKInfo otherwise.
-Expected<Optional<DarwinSDKInfo>> parseDarwinSDKInfo(llvm::vfs::FileSystem &VFS,
- StringRef SDKRootPath);
+/// \returns an error if the SDKSettings.json file is invalid, std::nullopt if
+/// the SDK has no SDKSettings.json, or a valid \c DarwinSDKInfo otherwise.
+Expected<std::optional<DarwinSDKInfo>>
+parseDarwinSDKInfo(llvm::vfs::FileSystem &VFS, StringRef SDKRootPath);
} // 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/DebugInfoOptions.h b/contrib/llvm-project/clang/include/clang/Basic/DebugInfoOptions.h
deleted file mode 100644
index c1259d7797db..000000000000
--- a/contrib/llvm-project/clang/include/clang/Basic/DebugInfoOptions.h
+++ /dev/null
@@ -1,60 +0,0 @@
-//===--- DebugInfoOptions.h - Debug Info Emission Types ---------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_BASIC_DEBUGINFOOPTIONS_H
-#define LLVM_CLANG_BASIC_DEBUGINFOOPTIONS_H
-
-namespace clang {
-namespace codegenoptions {
-
-enum DebugInfoFormat {
- DIF_DWARF,
- DIF_CodeView,
-};
-
-enum DebugInfoKind {
- /// Don't generate debug info.
- NoDebugInfo,
-
- /// Emit location information but do not generate debug info in the output.
- /// This is useful in cases where the backend wants to track source
- /// locations for instructions without actually emitting debug info for them
- /// (e.g., when -Rpass is used).
- LocTrackingOnly,
-
- /// Emit only debug directives with the line numbers data
- DebugDirectivesOnly,
-
- /// Emit only debug info necessary for generating line number tables
- /// (-gline-tables-only).
- DebugLineTablesOnly,
-
- /// Limit generated debug info for classes to reduce size. This emits class
- /// type info only where the constructor is emitted, if it is a class that
- /// has a constructor.
- /// FIXME: Consider combining this with LimitedDebugInfo.
- DebugInfoConstructor,
-
- /// Limit generated debug info to reduce size (-fno-standalone-debug). This
- /// emits forward decls for types that could be replaced with forward decls in
- /// the source code. For dynamic C++ classes type info is only emitted into
- /// the module that contains the classe's vtable.
- LimitedDebugInfo,
-
- /// Generate complete debug info.
- FullDebugInfo,
-
- /// Generate debug info for types that may be unused in the source
- /// (-fno-eliminate-unused-debug-types).
- UnusedTypeInfo,
-};
-
-} // end namespace codegenoptions
-} // end namespace clang
-
-#endif
diff --git a/contrib/llvm-project/clang/include/clang/Basic/DebugOptions.def b/contrib/llvm-project/clang/include/clang/Basic/DebugOptions.def
new file mode 100644
index 000000000000..7cd3edf08a17
--- /dev/null
+++ b/contrib/llvm-project/clang/include/clang/Basic/DebugOptions.def
@@ -0,0 +1,146 @@
+//===--- DebugOptions.def - Debug option database ----------------- 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 debug-specific codegen options. Users of this file
+// must define the CODEGENOPT macro to make use of this information.
+// Optionally, the user may also define DEBUGOPT (for flags), ENUM_DEBUGOPT (for
+// options that have enumeration type), and VALUE_DEBUGOPT (is a debug option
+// that describes a value rather than a flag).
+//
+// BENIGN_ variants of the macros are used to describe options that do not
+// affect the generated PCM.
+//
+//===----------------------------------------------------------------------===//
+#ifndef DEBUGOPT
+#define DEBUGOPT(Name, Bits, Default) \
+CODEGENOPT(Name, Bits, Default)
+#endif
+
+#ifndef VALUE_DEBUGOPT
+# define VALUE_DEBUGOPT(Name, Bits, Default) \
+VALUE_CODEGENOPT(Name, Bits, Default)
+#endif
+
+#ifndef ENUM_DEBUGOPT
+# define ENUM_DEBUGOPT(Name, Type, Bits, Default) \
+ENUM_CODEGENOPT(Name, Type, Bits, Default)
+#endif
+
+#ifndef BENIGN_DEBUGOPT
+#define BENIGN_DEBUGOPT(Name, Bits, Default) \
+DEBUGOPT(Name, Bits, Default)
+#endif
+
+#ifndef BENIGN_VALUE_DEBUGOPT
+# define BENIGN_VALUE_DEBUGOPT(Name, Bits, Default) \
+VALUE_DEBUGOPT(Name, Bits, Default)
+#endif
+
+#ifndef BENIGN_ENUM_DEBUGOPT
+# define BENIGN_ENUM_DEBUGOPT(Name, Type, Bits, Default) \
+ENUM_DEBUGOPT(Name, Type, Bits, Default)
+#endif
+
+BENIGN_ENUM_DEBUGOPT(CompressDebugSections, llvm::DebugCompressionType, 2,
+ llvm::DebugCompressionType::None)
+DEBUGOPT(Dwarf64, 1, 0) ///< -gdwarf64.
+BENIGN_DEBUGOPT(EnableDIPreservationVerify, 1, 0) ///< Enable di preservation
+ ///< verify each (it means
+ ///< check the original debug
+ ///< info metadata
+ ///< preservation).
+BENIGN_DEBUGOPT(ForceDwarfFrameSection , 1, 0) ///< Set when -fforce-dwarf-frame
+ ///< is enabled.
+
+///< Set when -femit-dwarf-unwind is passed.
+BENIGN_ENUM_DEBUGOPT(EmitDwarfUnwind, llvm::EmitDwarfUnwindType, 2,
+ llvm::EmitDwarfUnwindType::Default)
+
+BENIGN_DEBUGOPT(NoDwarfDirectoryAsm , 1, 0) ///< Set when -fno-dwarf-directory-asm
+ ///< is enabled.
+
+BENIGN_DEBUGOPT(NoInlineLineTables, 1, 0) ///< Whether debug info should contain
+ ///< inline line tables.
+
+DEBUGOPT(DebugStrictDwarf, 1, 1) ///< Whether or not to use strict DWARF info.
+
+/// Control the Assignment Tracking debug info feature.
+BENIGN_ENUM_DEBUGOPT(AssignmentTrackingMode, AssignmentTrackingOpts, 2,
+ AssignmentTrackingOpts::Disabled)
+
+DEBUGOPT(DebugColumnInfo, 1, 0) ///< Whether or not to use column information
+ ///< in debug info.
+
+DEBUGOPT(DebugTypeExtRefs, 1, 0) ///< Whether or not debug info should contain
+ ///< external references to a PCH or module.
+
+DEBUGOPT(DebugExplicitImport, 1, 0) ///< Whether or not debug info should
+ ///< contain explicit imports for
+ ///< anonymous namespaces
+
+/// Set debug info source file hashing algorithm.
+ENUM_DEBUGOPT(DebugSrcHash, DebugSrcHashKind, 2, DSH_MD5)
+
+DEBUGOPT(SplitDwarfInlining, 1, 1) ///< Whether to include inlining info in the
+ ///< skeleton CU to allow for symbolication
+ ///< of inline stack frames without .dwo files.
+DEBUGOPT(DebugFwdTemplateParams, 1, 0) ///< Whether to emit complete
+ ///< template parameter descriptions in
+ ///< forward declarations (versus just
+ ///< including them in the name).
+ENUM_DEBUGOPT(DebugSimpleTemplateNames,
+ llvm::codegenoptions::DebugTemplateNamesKind, 2,
+ llvm::codegenoptions::DebugTemplateNamesKind::Full)
+ ///< Whether to emit template parameters in the textual names of
+ ///< template specializations.
+ ///< Implies DebugFwdTemplateNames to allow decorated names to be
+ ///< reconstructed when needed.
+
+/// The kind of generated debug info.
+ENUM_DEBUGOPT(DebugInfo, llvm::codegenoptions::DebugInfoKind, 4,
+ llvm::codegenoptions::NoDebugInfo)
+
+/// Whether to generate macro debug info.
+DEBUGOPT(MacroDebugInfo, 1, 0)
+
+/// Tune the debug info for this debugger.
+ENUM_DEBUGOPT(DebuggerTuning, llvm::DebuggerKind, 3,
+ llvm::DebuggerKind::Default)
+
+/// Dwarf version. Version zero indicates to LLVM that no DWARF should be
+/// emitted.
+VALUE_DEBUGOPT(DwarfVersion, 3, 0)
+
+/// Whether we should emit CodeView debug information. It's possible to emit
+/// CodeView and DWARF into the same object.
+DEBUGOPT(EmitCodeView, 1, 0)
+
+/// Whether to emit the .debug$H section containing hashes of CodeView types.
+DEBUGOPT(CodeViewGHash, 1, 0)
+
+/// Whether to emit the compiler path and command line into the CodeView debug information.
+DEBUGOPT(CodeViewCommandLine, 1, 0)
+
+/// Whether emit extra debug info for sample pgo profile collection.
+DEBUGOPT(DebugInfoForProfiling, 1, 0)
+
+/// Whether to emit .debug_gnu_pubnames section instead of .debug_pubnames.
+DEBUGOPT(DebugNameTable, 2, 0)
+
+/// Whether to use DWARF base address specifiers in .debug_ranges.
+DEBUGOPT(DebugRangesBaseAddress, 1, 0)
+
+/// Whether to embed source in DWARF debug line section.
+DEBUGOPT(EmbedSource, 1, 0)
+
+#undef DEBUGOPT
+#undef ENUM_DEBUGOPT
+#undef VALUE_DEBUGOPT
+#undef BENIGN_DEBUGOPT
+#undef BENIGN_ENUM_DEBUGOPT
+#undef BENIGN_VALUE_DEBUGOPT
diff --git a/contrib/llvm-project/clang/include/clang/Basic/DeclNodes.td b/contrib/llvm-project/clang/include/clang/Basic/DeclNodes.td
index f8ad6cf5b262..8b1f415dd5fe 100644
--- a/contrib/llvm-project/clang/include/clang/Basic/DeclNodes.td
+++ b/contrib/llvm-project/clang/include/clang/Basic/DeclNodes.td
@@ -41,6 +41,7 @@ def Named : DeclNode<Decl, "named declarations", 1>;
def OMPDeclareReduction : DeclNode<Value>, DeclContext;
def OMPDeclareMapper : DeclNode<Value>, DeclContext;
def MSGuid : DeclNode<Value>;
+ def UnnamedGlobalConstant : DeclNode<Value>;
def TemplateParamObject : DeclNode<Value>;
def Declarator : DeclNode<Value, "declarators", 1>;
def Field : DeclNode<Declarator, "non-static data members">;
@@ -89,17 +90,18 @@ def Named : DeclNode<Decl, "named declarations", 1>;
def ObjCImplementation : DeclNode<ObjCImpl>;
def ObjCProperty : DeclNode<Named, "Objective-C properties">;
def ObjCCompatibleAlias : DeclNode<Named>;
+def ImplicitConceptSpecialization : DeclNode<Decl>;
def LinkageSpec : DeclNode<Decl>, DeclContext;
def Export : DeclNode<Decl>, DeclContext;
def ObjCPropertyImpl : DeclNode<Decl>;
def FileScopeAsm : DeclNode<Decl>;
+def TopLevelStmt : DeclNode<Decl>;
def AccessSpec : DeclNode<Decl>;
def Friend : DeclNode<Decl>;
def FriendTemplate : DeclNode<Decl>;
def StaticAssert : DeclNode<Decl>;
def Block : DeclNode<Decl, "blocks">, DeclContext;
def Captured : DeclNode<Decl>, DeclContext;
-def ClassScopeFunctionSpecialization : DeclNode<Decl>;
def Import : DeclNode<Decl>;
def OMPThreadPrivate : DeclNode<Decl>;
def OMPAllocate : DeclNode<Decl>;
@@ -107,4 +109,4 @@ def OMPRequires : DeclNode<Decl>;
def Empty : DeclNode<Decl>;
def RequiresExprBody : DeclNode<Decl>, DeclContext;
def LifetimeExtendedTemporary : DeclNode<Decl>;
-
+def HLSLBuffer : DeclNode<Named, "HLSLBuffer">, DeclContext;
diff --git a/contrib/llvm-project/clang/include/clang/Basic/Diagnostic.h b/contrib/llvm-project/clang/include/clang/Basic/Diagnostic.h
index 3b915fb15a89..0c7836c2ea56 100644
--- a/contrib/llvm-project/clang/include/clang/Basic/Diagnostic.h
+++ b/contrib/llvm-project/clang/include/clang/Basic/Diagnostic.h
@@ -21,7 +21,6 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/IntrusiveRefCntPtr.h"
-#include "llvm/ADT/Optional.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/iterator_range.h"
@@ -32,6 +31,7 @@
#include <list>
#include <map>
#include <memory>
+#include <optional>
#include <string>
#include <type_traits>
#include <utility>
@@ -39,7 +39,8 @@
namespace llvm {
class Error;
-}
+class raw_ostream;
+} // namespace llvm
namespace clang {
@@ -164,9 +165,9 @@ struct DiagnosticStorage {
/// The values for the various substitution positions.
///
/// This is used when the argument is not an std::string. The specific value
- /// is mangled into an intptr_t and the interpretation depends on exactly
+ /// is mangled into an uint64_t and the interpretation depends on exactly
/// what sort of argument kind it is.
- intptr_t DiagArgumentsVal[MaxArguments];
+ uint64_t DiagArgumentsVal[MaxArguments];
/// The values for the various substitution positions that have
/// string arguments.
@@ -313,18 +314,23 @@ private:
// "Global" configuration state that can actually vary between modules.
// Ignore all warnings: -w
+ LLVM_PREFERRED_TYPE(bool)
unsigned IgnoreAllWarnings : 1;
// Enable all warnings.
+ LLVM_PREFERRED_TYPE(bool)
unsigned EnableAllWarnings : 1;
// Treat warnings like errors.
+ LLVM_PREFERRED_TYPE(bool)
unsigned WarningsAsErrors : 1;
// Treat errors like fatal errors.
+ LLVM_PREFERRED_TYPE(bool)
unsigned ErrorsAsFatal : 1;
// Suppress warnings in system headers.
+ LLVM_PREFERRED_TYPE(bool)
unsigned SuppressSystemWarnings : 1;
// Map extensions to warnings or errors?
@@ -544,6 +550,7 @@ public:
DiagnosticsEngine &operator=(const DiagnosticsEngine &) = delete;
~DiagnosticsEngine();
+ friend void DiagnosticsTestHelper(DiagnosticsEngine &);
LLVM_DUMP_METHOD void dump() const;
LLVM_DUMP_METHOD void dump(StringRef DiagName) const;
@@ -807,6 +814,9 @@ public:
bool setSeverityForGroup(diag::Flavor Flavor, StringRef Group,
diag::Severity Map,
SourceLocation Loc = SourceLocation());
+ bool setSeverityForGroup(diag::Flavor Flavor, diag::Group Group,
+ diag::Severity Map,
+ SourceLocation Loc = SourceLocation());
/// Set the warning-as-error flag for the given diagnostic group.
///
@@ -887,9 +897,9 @@ public:
LastDiagLevel = Other.LastDiagLevel;
}
- /// Reset the state of the diagnostic object to its initial
- /// configuration.
- void Reset();
+ /// Reset the state of the diagnostic object to its initial configuration.
+ /// \param[in] soft - if true, doesn't reset the diagnostic mappings and state
+ void Reset(bool soft = false);
//===--------------------------------------------------------------------===//
// DiagnosticsEngine classification and reporting interfaces.
@@ -1176,7 +1186,7 @@ public:
DiagStorage = nullptr;
}
- void AddTaggedVal(intptr_t V, DiagnosticsEngine::ArgumentKind Kind) const {
+ void AddTaggedVal(uint64_t V, DiagnosticsEngine::ArgumentKind Kind) const {
if (!DiagStorage)
DiagStorage = getStorage();
@@ -1341,8 +1351,8 @@ public:
// It is necessary to limit this to rvalue reference to avoid calling this
// function with a bitfield lvalue argument since non-const reference to
// bitfield is not allowed.
- template <typename T, typename = typename std::enable_if<
- !std::is_lvalue_reference<T>::value>::type>
+ template <typename T,
+ typename = std::enable_if_t<!std::is_lvalue_reference<T>::value>>
const DiagnosticBuilder &operator<<(T &&V) const {
assert(isActive() && "Clients must not add to cleared diagnostic!");
const StreamingDiagnostic &DB = *this;
@@ -1399,6 +1409,18 @@ inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB,
return DB;
}
+inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB,
+ long I) {
+ DB.AddTaggedVal(I, DiagnosticsEngine::ak_sint);
+ return DB;
+}
+
+inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB,
+ long long I) {
+ DB.AddTaggedVal(I, DiagnosticsEngine::ak_sint);
+ return DB;
+}
+
// We use enable_if here to prevent that this overload is selected for
// pointers or other arguments that are implicitly convertible to bool.
template <typename T>
@@ -1416,6 +1438,18 @@ inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB,
}
inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB,
+ unsigned long I) {
+ DB.AddTaggedVal(I, DiagnosticsEngine::ak_uint);
+ return DB;
+}
+
+inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB,
+ unsigned long long I) {
+ DB.AddTaggedVal(I, DiagnosticsEngine::ak_uint);
+ return DB;
+}
+
+inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB,
tok::TokenKind I) {
DB.AddTaggedVal(static_cast<unsigned>(I), DiagnosticsEngine::ak_tokenkind);
return DB;
@@ -1443,6 +1477,12 @@ operator<<(const StreamingDiagnostic &DB, T *DC) {
}
inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB,
+ SourceLocation L) {
+ DB.AddSourceRange(CharSourceRange::getTokenRange(L));
+ return DB;
+}
+
+inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB,
SourceRange R) {
DB.AddSourceRange(CharSourceRange::getTokenRange(R));
return DB;
@@ -1476,7 +1516,7 @@ inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB,
inline const StreamingDiagnostic &
operator<<(const StreamingDiagnostic &DB,
- const llvm::Optional<SourceRange> &Opt) {
+ const std::optional<SourceRange> &Opt) {
if (Opt)
DB << *Opt;
return DB;
@@ -1484,15 +1524,14 @@ operator<<(const StreamingDiagnostic &DB,
inline const StreamingDiagnostic &
operator<<(const StreamingDiagnostic &DB,
- const llvm::Optional<CharSourceRange> &Opt) {
+ const std::optional<CharSourceRange> &Opt) {
if (Opt)
DB << *Opt;
return DB;
}
inline const StreamingDiagnostic &
-operator<<(const StreamingDiagnostic &DB,
- const llvm::Optional<FixItHint> &Opt) {
+operator<<(const StreamingDiagnostic &DB, const std::optional<FixItHint> &Opt) {
if (Opt)
DB << *Opt;
return DB;
@@ -1531,7 +1570,7 @@ inline DiagnosticBuilder DiagnosticsEngine::Report(unsigned DiagID) {
/// currently in-flight diagnostic.
class Diagnostic {
const DiagnosticsEngine *DiagObj;
- StringRef StoredDiagMessage;
+ std::optional<StringRef> StoredDiagMessage;
public:
explicit Diagnostic(const DiagnosticsEngine *DO) : DiagObj(DO) {}
@@ -1577,18 +1616,18 @@ public:
/// Return the specified signed integer argument.
/// \pre getArgKind(Idx) == DiagnosticsEngine::ak_sint
- int getArgSInt(unsigned Idx) const {
+ int64_t getArgSInt(unsigned Idx) const {
assert(getArgKind(Idx) == DiagnosticsEngine::ak_sint &&
"invalid argument accessor!");
- return (int)DiagObj->DiagStorage.DiagArgumentsVal[Idx];
+ return (int64_t)DiagObj->DiagStorage.DiagArgumentsVal[Idx];
}
/// Return the specified unsigned integer argument.
/// \pre getArgKind(Idx) == DiagnosticsEngine::ak_uint
- unsigned getArgUInt(unsigned Idx) const {
+ uint64_t getArgUInt(unsigned Idx) const {
assert(getArgKind(Idx) == DiagnosticsEngine::ak_uint &&
"invalid argument accessor!");
- return (unsigned)DiagObj->DiagStorage.DiagArgumentsVal[Idx];
+ return DiagObj->DiagStorage.DiagArgumentsVal[Idx];
}
/// Return the specified IdentifierInfo argument.
@@ -1602,7 +1641,7 @@ public:
/// Return the specified non-string argument in an opaque form.
/// \pre getArgKind(Idx) != DiagnosticsEngine::ak_std_string
- intptr_t getRawArg(unsigned Idx) const {
+ uint64_t getRawArg(unsigned Idx) const {
assert(getArgKind(Idx) != DiagnosticsEngine::ak_std_string &&
"invalid argument accessor!");
return DiagObj->DiagStorage.DiagArgumentsVal[Idx];
@@ -1687,9 +1726,7 @@ public:
range_iterator range_end() const { return Ranges.end(); }
unsigned range_size() const { return Ranges.size(); }
- ArrayRef<CharSourceRange> getRanges() const {
- return llvm::makeArrayRef(Ranges);
- }
+ ArrayRef<CharSourceRange> getRanges() const { return llvm::ArrayRef(Ranges); }
using fixit_iterator = std::vector<FixItHint>::const_iterator;
@@ -1697,11 +1734,12 @@ public:
fixit_iterator fixit_end() const { return FixIts.end(); }
unsigned fixit_size() const { return FixIts.size(); }
- ArrayRef<FixItHint> getFixIts() const {
- return llvm::makeArrayRef(FixIts);
- }
+ ArrayRef<FixItHint> getFixIts() const { return llvm::ArrayRef(FixIts); }
};
+// Simple debug printing of StoredDiagnostic.
+llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const StoredDiagnostic &);
+
/// Abstract interface, implemented by clients of the front-end, which
/// formats and prints fully processed diagnostics.
class DiagnosticConsumer {
@@ -1789,12 +1827,17 @@ public:
struct TemplateDiffTypes {
intptr_t FromType;
intptr_t ToType;
+ LLVM_PREFERRED_TYPE(bool)
unsigned PrintTree : 1;
+ LLVM_PREFERRED_TYPE(bool)
unsigned PrintFromType : 1;
+ LLVM_PREFERRED_TYPE(bool)
unsigned ElideType : 1;
+ LLVM_PREFERRED_TYPE(bool)
unsigned ShowColors : 1;
// The printer sets this variable to true if the template diff was used.
+ LLVM_PREFERRED_TYPE(bool)
unsigned TemplateDiffUsed : 1;
};
@@ -1807,7 +1850,7 @@ const char ToggleHighlight = 127;
void ProcessWarningOptions(DiagnosticsEngine &Diags,
const DiagnosticOptions &Opts,
bool ReportDiags = true);
-
+void EscapeStringForDiagnostic(StringRef Str, SmallVectorImpl<char> &OutStr);
} // namespace clang
#endif // LLVM_CLANG_BASIC_DIAGNOSTIC_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..8d66e265fbae 100644
--- a/contrib/llvm-project/clang/include/clang/Basic/Diagnostic.td
+++ b/contrib/llvm-project/clang/include/clang/Basic/Diagnostic.td
@@ -55,11 +55,11 @@ class DiagCategory<string Name> {
}
// Diagnostic Groups.
-class DiagGroup<string Name, list<DiagGroup> subgroups = []> {
+class DiagGroup<string Name, list<DiagGroup> subgroups = [], code docs = [{}]> {
string GroupName = Name;
list<DiagGroup> SubGroups = subgroups;
string CategoryName = "";
- code Documentation = [{}];
+ code Documentation = docs;
}
class InGroup<DiagGroup G> { DiagGroup Group = G; }
//class IsGroup<string Name> { DiagGroup Group = DiagGroup<Name>; }
@@ -75,15 +75,16 @@ include "DiagnosticGroups.td"
// All diagnostics emitted by the compiler are an indirect subclass of this.
-class Diagnostic<string text, DiagClass DC, Severity defaultmapping> {
+class Diagnostic<string summary, DiagClass DC, Severity defaultmapping> {
/// Component is specified by the file with a big let directive.
string Component = ?;
- string Text = text;
+ string Summary = summary;
DiagClass Class = DC;
SFINAEResponse SFINAE = SFINAE_Suppress;
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;
}
@@ -148,7 +157,6 @@ class DefaultRemark { Severity DefaultSeverity = SEV_Remark; }
// Definitions for Diagnostics.
include "DiagnosticASTKinds.td"
-include "DiagnosticAnalysisKinds.td"
include "DiagnosticCommentKinds.td"
include "DiagnosticCommonKinds.td"
include "DiagnosticCrossTUKinds.td"
@@ -159,4 +167,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 496d86ee2fe7..c81d17ed6410 100644
--- a/contrib/llvm-project/clang/include/clang/Basic/DiagnosticASTKinds.td
+++ b/contrib/llvm-project/clang/include/clang/Basic/DiagnosticASTKinds.td
@@ -11,9 +11,14 @@ let Component = "AST" in {
// Constant expression diagnostics. These (and their users) belong in Sema.
def note_expr_divide_by_zero : Note<"division by zero">;
def note_constexpr_invalid_cast : Note<
- "%select{reinterpret_cast|dynamic_cast|cast that performs the conversions of"
- " a reinterpret_cast|cast from %1}0 is not allowed in a constant expression"
+ "%select{reinterpret_cast|dynamic_cast|%select{this conversion|cast that"
+ " performs the conversions of a reinterpret_cast}1|cast from %1}0"
+ " is not allowed in a constant expression"
"%select{| in C++ standards before C++20||}0">;
+def note_constexpr_invalid_void_star_cast : Note<
+ "cast from %0 is not allowed in a constant expression "
+ "%select{in C++ standards before C++2c|because the pointed object "
+ "type %2 is not similar to the target type %3}1">;
def note_constexpr_invalid_downcast : Note<
"cannot cast object of dynamic type %0 to type %1">;
def note_constexpr_overflow : Note<
@@ -64,7 +69,11 @@ def note_consteval_address_accessible : Note<
"%select{pointer|reference}0 to a consteval declaration "
"is not a constant expression">;
def note_constexpr_uninitialized : Note<
- "%select{|sub}0object of type %1 is not initialized">;
+ "subobject %select{of type |}0%1 is not initialized">;
+def note_constexpr_uninitialized_base : Note<
+ "constructor of base class %0 is not called">;
+def note_constexpr_static_local : Note<
+ "control flows through the definition of a %select{static|thread_local}0 variable">;
def note_constexpr_subobject_declared_here : Note<
"subobject declared here">;
def note_constexpr_array_index : Note<"cannot refer to element %0 of "
@@ -81,7 +90,23 @@ def note_constexpr_pointer_subtraction_not_same_array : Note<
def note_constexpr_pointer_subtraction_zero_size : Note<
"subtraction of pointers to type %0 of zero size">;
def note_constexpr_pointer_comparison_unspecified : Note<
- "comparison has unspecified value">;
+ "comparison between '%0' and '%1' has unspecified value">;
+def note_constexpr_pointer_constant_comparison : Note<
+ "comparison of numeric address '%0' with pointer '%1' can only be performed "
+ "at runtime">;
+def note_constexpr_literal_comparison : Note<
+ "comparison of addresses of literals has unspecified value">;
+def note_constexpr_pointer_weak_comparison : Note<
+ "comparison against address of weak declaration '%0' can only be performed "
+ "at runtime">;
+def note_constexpr_mem_pointer_weak_comparison : Note<
+ "comparison against pointer to weak member %q0 can only be performed "
+ "at runtime">;
+def note_constexpr_pointer_comparison_past_end : Note<
+ "comparison against pointer '%0' that points past the end of a "
+ "complete object has unspecified value">;
+def note_constexpr_pointer_comparison_zero_sized : Note<
+ "comparison of pointers '%0' and '%1' to unrelated zero-sized objects">;
def note_constexpr_pointer_comparison_base_classes : Note<
"comparison of addresses of subobjects of different base classes "
"has unspecified value">;
@@ -108,6 +133,8 @@ def note_constexpr_null_subobject : Note<
"access array element of|perform pointer arithmetic on|"
"access real component of|"
"access imaginary component of}0 null pointer">;
+def note_constexpr_null_callee : Note<
+ "'%0' evaluates to a null function pointer">;
def note_constexpr_function_param_value_unknown : Note<
"function parameter %0 with unknown value cannot be used in a constant "
"expression">;
@@ -290,7 +317,7 @@ def note_constexpr_memcpy_unsupported : Note<
"source is not a contiguous array of at least %4 elements of type %3|"
"destination is not a contiguous array of at least %4 elements of type %3}2">;
def note_constexpr_bit_cast_unsupported_type : Note<
- "constexpr bit_cast involving type %0 is not yet supported">;
+ "constexpr bit cast involving type %0 is not yet supported">;
def note_constexpr_bit_cast_unsupported_bitfield : Note<
"constexpr bit_cast involving bit-field is not yet supported">;
def note_constexpr_bit_cast_invalid_type : Note<
@@ -299,6 +326,9 @@ def note_constexpr_bit_cast_invalid_type : Note<
"%select{type|member}1 is not allowed in a constant expression">;
def note_constexpr_bit_cast_invalid_subtype : Note<
"invalid type %0 is a %select{member|base}1 of %2">;
+def note_constexpr_bit_cast_invalid_vector : Note<
+ "bit_cast involving type %0 is not allowed in a constant expression; "
+ "element size %1 * element count %2 is not a multiple of the byte size %3">;
def note_constexpr_bit_cast_indet_dest : Note<
"indeterminate value can only initialize an object of type 'unsigned char'"
"%select{, 'char',|}1 or 'std::byte'; %0 is invalid">;
@@ -326,6 +356,9 @@ def note_constexpr_new_negative : Note<
"cannot allocate array; evaluated array bound %0 is negative">;
def note_constexpr_new_too_large : Note<
"cannot allocate array; evaluated array bound %0 is too large">;
+def note_constexpr_new_exceeds_limits : Note<
+ "cannot allocate array; evaluated array bound %0 exceeds the limit (%1); "
+ "use '-fconstexpr-steps' to increase this limit">;
def note_constexpr_new_too_small : Note<
"cannot allocate array; evaluated array bound %0 is too small to hold "
"%1 explicitly initialized elements">;
@@ -362,6 +395,10 @@ def note_constexpr_memory_leak : Note<
"%plural{0:|: (along with %0 other memory leak%s0)}0">;
def note_constexpr_unsupported_layout : Note<
"type %0 has unexpected layout">;
+def note_constexpr_unsupported_flexible_array : Note<
+ "flexible array initialization is not yet supported">;
+def note_constexpr_non_const_vectorelements : Note<
+ "cannot determine number of elements for sizeless vectors in a constant expression">;
def err_experimental_clang_interp_failed : Error<
"the experimental clang interpreter failed to evaluate an expression">;
@@ -371,6 +408,10 @@ def warn_integer_constant_overflow : Warning<
def warn_fixedpoint_constant_overflow : Warning<
"overflow in expression; result is %0 with type %1">,
InGroup<DiagGroup<"fixed-point-overflow">>;
+def warn_constexpr_unscoped_enum_out_of_range : Warning<
+ "integer value %0 is outside the valid range of values [%1, %2] for the "
+ "enumeration type %3">, DefaultError, ShowInSystemHeader, ShowInSystemMacro,
+ InGroup<DiagGroup<"enum-constexpr-conversion">>;
// This is a temporary diagnostic, and shall be removed once our
// implementation is complete, and like the preceding constexpr notes belongs
@@ -439,8 +480,6 @@ def note_odr_tag_kind_here: Note<
def note_odr_field : Note<"field %0 has type %1 here">;
def note_odr_field_name : Note<"field has name %0 here">;
def note_odr_missing_field : Note<"no corresponding field here">;
-def note_odr_bit_field : Note<"bit-field %0 with type %1 and length %2 here">;
-def note_odr_not_bit_field : Note<"field %0 is not a bit-field">;
def note_odr_base : Note<"class has base type %0">;
def note_odr_virtual_base : Note<
"%select{non-virtual|virtual}0 derivation here">;
@@ -561,14 +600,397 @@ def warn_odr_non_type_parameter_type_inconsistent : Warning<
InGroup<ODR>;
def err_unsupported_ast_node: Error<"cannot import unsupported AST node %0">;
+// Compare ODR hashes
+def err_module_odr_violation_different_definitions : Error<
+ "%q0 has different definitions in different modules; "
+ "%select{definition in module '%2' is here|defined here}1">;
+def note_first_module_difference : Note<
+ "in first definition, possible difference is here">;
+def note_module_odr_violation_different_definitions : Note<
+ "definition in module '%0' is here">;
+def note_second_module_difference : Note<
+ "in second definition, possible difference is here">;
+
+def err_module_odr_violation_definition_data : Error <
+ "%q0 has different definitions in different modules; first difference is "
+ "%select{definition in module '%2'|defined here}1 found "
+ "%select{"
+ "%4 base %plural{1:class|:classes}4|"
+ "%4 virtual base %plural{1:class|:classes}4|"
+ "%ordinal4 base class with type %5|"
+ "%ordinal4 %select{non-virtual|virtual}5 base class %6|"
+ "%ordinal4 base class %5 with "
+ "%select{public|protected|private|no}6 access specifier}3">;
+
+def note_module_odr_violation_definition_data : Note <
+ "but in '%0' found "
+ "%select{"
+ "%2 base %plural{1:class|:classes}2|"
+ "%2 virtual base %plural{1:class|:classes}2|"
+ "%ordinal2 base class with different type %3|"
+ "%ordinal2 %select{non-virtual|virtual}3 base class %4|"
+ "%ordinal2 base class %3 with "
+ "%select{public|protected|private|no}4 access specifier}1">;
+
+def err_module_odr_violation_objc_interface : Error <
+ "%0 has different definitions in different modules; first difference is "
+ "%select{definition in module '%2'|defined here}1 found "
+ "%select{"
+ "%select{no super class|super class with type %5}4|"
+ "instance variable '%4' access control is "
+ "%select{|@private|@protected|@public|@package}5"
+ "}3">;
+def note_module_odr_violation_objc_interface : Note <
+ "but in %select{'%1'|definition here}0 found "
+ "%select{"
+ "%select{no super class|super class with type %4}3|"
+ "instance variable '%3' access control is "
+ "%select{|@private|@protected|@public|@package}4"
+ "}2">;
+
+def err_module_odr_violation_template_parameter : Error <
+ "%q0 has different definitions in different modules; first difference is "
+ "%select{definition in module '%2'|defined here}1 found "
+ "%select{"
+ "unnamed template parameter|"
+ "template parameter %5|"
+ "template parameter with %select{no |}4default argument|"
+ "template parameter with default argument}3">;
+
+def note_module_odr_violation_template_parameter : Note <
+ "but in '%0' found "
+ "%select{"
+ "unnamed template parameter %2|"
+ "template parameter %3|"
+ "template parameter with %select{no |}2default argument|"
+ "template parameter with different default argument}1">;
+
+def err_module_odr_violation_mismatch_decl : Error<
+ "%q0 has different definitions in different modules; first difference is "
+ "%select{definition in module '%2'|defined here}1 found "
+ "%select{end of class|public access specifier|private access specifier|"
+ "protected access specifier|static assert|field|method|type alias|typedef|"
+ "data member|friend declaration|function template|method|instance variable|"
+ "property}3">;
+def note_module_odr_violation_mismatch_decl : Note<
+ "but in %select{'%1'|definition here}0 found "
+ "%select{end of class|public access specifier|private access specifier|"
+ "protected access specifier|static assert|field|method|type alias|typedef|"
+ "data member|friend declaration|function template|method|instance variable|"
+ "property}2">;
+
+def err_module_odr_violation_record : Error<
+ "%q0 has different definitions in different modules; first difference is "
+ "%select{definition in module '%2'|defined here}1 found "
+ "%select{"
+ "static assert with condition|"
+ "static assert with message|"
+ "static assert with %select{|no }4message|"
+ "%select{method %5|constructor|destructor}4|"
+ "%select{method %5|constructor|destructor}4 "
+ "is %select{not deleted|deleted}6|"
+ "%select{method %5|constructor|destructor}4 "
+ "is %select{not defaulted|defaulted}6|"
+ "%select{method %5|constructor|destructor}4 "
+ "is %select{|pure }6%select{not virtual|virtual}7|"
+ "%select{method %5|constructor|destructor}4 "
+ "is %select{not static|static}6|"
+ "%select{method %5|constructor|destructor}4 "
+ "is %select{not volatile|volatile}6|"
+ "%select{method %5|constructor|destructor}4 "
+ "is %select{not const|const}6|"
+ "%select{method %5|constructor|destructor}4 "
+ "is %select{not inline|inline}6|"
+ "%select{method %5|constructor|destructor}4 "
+ "with %ordinal6 parameter with%select{out|}7 a default argument|"
+ "%select{method %5|constructor|destructor}4 "
+ "with %ordinal6 parameter with a default argument|"
+ "%select{method %5|constructor|destructor}4 "
+ "with %select{no |}6template arguments|"
+ "%select{method %5|constructor|destructor}4 "
+ "with %6 template argument%s6|"
+ "%select{method %5|constructor|destructor}4 "
+ "with %6 for %ordinal7 template argument|"
+ "%select{method %5|constructor|destructor}4 "
+ "with %select{no body|body}6|"
+ "%select{method %5|constructor|destructor}4 "
+ "with body|"
+ "friend %select{class|function}4|"
+ "friend %4|"
+ "friend function %4|"
+ "function template %4 with %5 template parameter%s5|"
+ "function template %4 with %ordinal5 template parameter being a "
+ "%select{type|non-type|template}6 template parameter|"
+ "function template %4 with %ordinal5 template parameter "
+ "%select{with no name|named %7}6|"
+ "function template %4 with %ordinal5 template parameter with "
+ "%select{no |}6default argument|"
+ "function template %4 with %ordinal5 template parameter with "
+ "default argument %6|"
+ "function template %4 with %ordinal5 template parameter with one type|"
+ "function template %4 with %ordinal5 template parameter %select{not |}6"
+ "being a template parameter pack|"
+ "}3">;
+
+def note_module_odr_violation_record : Note<"but in '%0' found "
+ "%select{"
+ "static assert with different condition|"
+ "static assert with different message|"
+ "static assert with %select{|no }2message|"
+ "%select{method %3|constructor|destructor}2|"
+ "%select{method %3|constructor|destructor}2 "
+ "is %select{not deleted|deleted}4|"
+ "%select{method %3|constructor|destructor}2 "
+ "is %select{not defaulted|defaulted}4|"
+ "%select{method %3|constructor|destructor}2 "
+ "is %select{|pure }4%select{not virtual|virtual}5|"
+ "%select{method %3|constructor|destructor}2 "
+ "is %select{not static|static}4|"
+ "%select{method %3|constructor|destructor}2 "
+ "is %select{not volatile|volatile}4|"
+ "%select{method %3|constructor|destructor}2 "
+ "is %select{not const|const}4|"
+ "%select{method %3|constructor|destructor}2 "
+ "is %select{not inline|inline}4|"
+ "%select{method %3|constructor|destructor}2 "
+ "with %ordinal4 parameter with%select{out|}5 a default argument|"
+ "%select{method %3|constructor|destructor}2 "
+ "with %ordinal4 parameter with a different default argument|"
+ "%select{method %3|constructor|destructor}2 "
+ "with %select{no |}4template arguments|"
+ "%select{method %3|constructor|destructor}2 "
+ "with %4 template argument%s4|"
+ "%select{method %3|constructor|destructor}2 "
+ "with %4 for %ordinal5 template argument|"
+ "%select{method %3|constructor|destructor}2 "
+ "with %select{no body|body}4|"
+ "%select{method %3|constructor|destructor}2 "
+ "with different body|"
+ "friend %select{class|function}2|"
+ "friend %2|"
+ "friend function %2|"
+ "function template %2 with %3 template parameter%s3|"
+ "function template %2 with %ordinal3 template paramter being a "
+ "%select{type|non-type|template}4 template parameter|"
+ "function template %2 with %ordinal3 template parameter "
+ "%select{with no name|named %5}4|"
+ "function template %2 with %ordinal3 template parameter with "
+ "%select{no |}4default argument|"
+ "function template %2 with %ordinal3 template parameter with "
+ "default argument %4|"
+ "function template %2 with %ordinal3 template parameter with different type|"
+ "function template %2 with %ordinal3 template parameter %select{not |}4"
+ "being a template parameter pack|"
+ "}1">;
+
+def err_module_odr_violation_field : Error<
+ "%q0 has different definitions in different modules; first difference is "
+ "%select{definition in module '%2'|defined here}1 found "
+ "%select{"
+ "field %4|"
+ "field %4 with type %5|"
+ "%select{non-|}5bitfield %4|"
+ "bitfield %4 with one width expression|"
+ "%select{non-|}5mutable field %4|"
+ "field %4 with %select{no|an}5 initializer|"
+ "field %4 with an initializer"
+ "}3">;
+def note_module_odr_violation_field : Note<
+ "but in %select{'%1'|definition here}0 found "
+ "%select{"
+ "field %3|"
+ "field %3 with type %4|"
+ "%select{non-|}4bitfield %3|"
+ "bitfield %3 with different width expression|"
+ "%select{non-|}4mutable field %3|"
+ "field %3 with %select{no|an}4 initializer|"
+ "field %3 with a different initializer"
+ "}2">;
+
+def err_module_odr_violation_typedef : Error<
+ "%q0 has different definitions in different modules; first difference is "
+ "%select{definition in module '%2'|defined here}1 found "
+ "%select{"
+ "%select{typedef|type alias}4 name %5|"
+ "%select{typedef|type alias}4 %5 with underlying type %6"
+ "}3">;
+def note_module_odr_violation_typedef : Note<"but in '%0' found "
+ "%select{"
+ "%select{typedef|type alias}2 name %3|"
+ "%select{typedef|type alias}2 %3 with different underlying type %4"
+ "}1">;
+
+def err_module_odr_violation_variable : Error<
+ "%q0 has different definitions in different modules; first difference is "
+ "%select{definition in module '%2'|defined here}1 found "
+ "%select{"
+ "data member with name %4|"
+ "data member %4 with type %5|"
+ "data member %4 with%select{out|}5 an initializer|"
+ "data member %4 with an initializer|"
+ "data member %4 %select{is constexpr|is not constexpr}5"
+ "}3">;
+def note_module_odr_violation_variable : Note<"but in '%0' found "
+ "%select{"
+ "data member with name %2|"
+ "data member %2 with different type %3|"
+ "data member %2 with%select{out|}3 an initializer|"
+ "data member %2 with a different initializer|"
+ "data member %2 %select{is constexpr|is not constexpr}3"
+ "}1">;
+
+def err_module_odr_violation_function : Error<
+ "%q0 has different definitions in different modules; "
+ "%select{definition in module '%2'|defined here}1 "
+ "first difference is "
+ "%select{"
+ "return type is %4|"
+ "%ordinal4 parameter with name %5|"
+ "%ordinal4 parameter with type %5%select{| decayed from %7}6|"
+ "%ordinal4 parameter with%select{out|}5 a default argument|"
+ "%ordinal4 parameter with a default argument|"
+ "function body"
+ "}3">;
+
+def note_module_odr_violation_function : Note<"but in '%0' found "
+ "%select{"
+ "different return type %2|"
+ "%ordinal2 parameter with name %3|"
+ "%ordinal2 parameter with type %3%select{| decayed from %5}4|"
+ "%ordinal2 parameter with%select{out|}3 a default argument|"
+ "%ordinal2 parameter with a different default argument|"
+ "a different body"
+ "}1">;
+
+def err_module_odr_violation_enum : Error<
+ "%q0 has different definitions in different modules; "
+ "%select{definition in module '%2'|defined here}1 "
+ "first difference is "
+ "%select{"
+ "enum that is %select{not scoped|scoped}4|"
+ "enum scoped with keyword %select{struct|class}4|"
+ "enum %select{without|with}4 specified type|"
+ "enum with specified type %4|"
+ "enum with %4 element%s4|"
+ "%ordinal4 element has name %5|"
+ "%ordinal4 element %5 %select{has|does not have}6 an initializer|"
+ "%ordinal4 element %5 has an initializer|"
+ "}3">;
+
+def note_module_odr_violation_enum : Note<"but in '%0' found "
+ "%select{"
+ "enum that is %select{not scoped|scoped}2|"
+ "enum scoped with keyword %select{struct|class}2|"
+ "enum %select{without|with}2 specified type|"
+ "enum with specified type %2|"
+ "enum with %2 element%s2|"
+ "%ordinal2 element has name %3|"
+ "%ordinal2 element %3 %select{has|does not have}4 an initializer|"
+ "%ordinal2 element %3 has different initializer|"
+ "}1">;
+
+def err_module_odr_violation_referenced_protocols : Error <
+ "%q0 has different definitions in different modules; first difference is "
+ "%select{definition in module '%2'|defined here}1 found "
+ "%select{"
+ "%4 referenced %plural{1:protocol|:protocols}4|"
+ "%ordinal4 referenced protocol with name %5"
+ "}3">;
+def note_module_odr_violation_referenced_protocols : Note <
+ "but in %select{'%1'|definition here}0 found "
+ "%select{"
+ "%3 referenced %plural{1:protocol|:protocols}3|"
+ "%ordinal3 referenced protocol with different name %4"
+ "}2">;
+
+def err_module_odr_violation_objc_method : Error<
+ "%q0 has different definitions in different modules; first difference is "
+ "%select{definition in module '%2'|defined here}1 found "
+ "%select{"
+ "method %4 with return type %5|"
+ "%select{class|instance}5 method %4|"
+ "%select{no|'required'|'optional'}4 method control|"
+ "method %4 with %select{no designated initializer|designated initializer}5|"
+ "%select{regular|direct}5 method %4|"
+ "method %4"
+ "}3">;
+def note_module_odr_violation_objc_method : Note<
+ "but in %select{'%1'|definition here}0 found "
+ "%select{"
+ "method %3 with different return type %4|"
+ "method %3 as %select{class|instance}4 method|"
+ "%select{no|'required'|'optional'}3 method control|"
+ "method %3 with %select{no designated initializer|designated initializer}4|"
+ "%select{regular|direct}4 method %3|"
+ "different method %3"
+ "}2">;
+
+def err_module_odr_violation_method_params : Error<
+ "%q0 has different definitions in different modules; first difference is "
+ "%select{definition in module '%2'|defined here}1 found "
+ "%select{"
+ "%select{method %5|constructor|destructor}4 "
+ "that has %6 parameter%s6|"
+ "%select{method %5|constructor|destructor}4 "
+ "with %ordinal6 parameter of type %7%select{| decayed from %9}8|"
+ "%select{method %5|constructor|destructor}4 "
+ "with %ordinal6 parameter named %7"
+ "}3">;
+def note_module_odr_violation_method_params : Note<
+ "but in %select{'%1'|definition here}0 found "
+ "%select{"
+ "%select{method %4|constructor|destructor}3 "
+ "that has %5 parameter%s5|"
+ "%select{method %4|constructor|destructor}3 "
+ "with %ordinal5 parameter of type %6%select{| decayed from %8}7|"
+ "%select{method %4|constructor|destructor}3 "
+ "with %ordinal5 parameter named %6"
+ "}2">;
+
+def err_module_odr_violation_objc_property : Error<
+ "%q0 has different definitions in different modules; first difference is "
+ "%select{definition in module '%2'|defined here}1 found "
+ "%select{"
+ "property %4|"
+ "property %4 with type %5|"
+ "%select{no|'required'|'optional'}4 property control|"
+ "property %4 with %select{default |}6'%select{none|readonly|getter|assign|"
+ "readwrite|retain|copy|nonatomic|setter|atomic|weak|strong|"
+ "unsafe_unretained|nullability|null_resettable|class|direct}5' attribute"
+ "}3">;
+def note_module_odr_violation_objc_property : Note<
+ "but in %select{'%1'|definition here}0 found "
+ "%select{"
+ "property %3|"
+ "property %3 with type %4|"
+ "%select{no|'required'|'optional'}3 property control|"
+ "property %3 with different '%select{none|readonly|getter|assign|"
+ "readwrite|retain|copy|nonatomic|setter|atomic|weak|strong|"
+ "unsafe_unretained|nullability|null_resettable|class|direct}4' attribute"
+ "}2">;
+
+def err_module_odr_violation_mismatch_decl_unknown : Error<
+ "%q0 %select{with definition in module '%2'|defined here}1 has different "
+ "definitions in different modules; first difference is this "
+ "%select{||||static assert|field|method|type alias|typedef|data member|"
+ "friend declaration|function template|method|instance variable|"
+ "property|unexpected decl}3">;
+def note_module_odr_violation_mismatch_decl_unknown : Note<
+ "but in %select{'%1'|definition here}0 found "
+ "%select{||||different static assert|different field|different method|"
+ "different type alias|different typedef|different data member|"
+ "different friend declaration|different function template|different method|"
+ "different instance variable|different property|another unexpected decl}2">;
+
+
def remark_sanitize_address_insert_extra_padding_accepted : Remark<
"-fsanitize-address-field-padding applied to %0">, ShowInSystemHeader,
InGroup<SanitizeAddressRemarks>;
def remark_sanitize_address_insert_extra_padding_rejected : Remark<
"-fsanitize-address-field-padding ignored for %0 because it "
"%select{is not C++|is packed|is a union|is trivially copyable|"
- "has trivial destructor|is standard layout|is in a blacklisted file|"
- "is blacklisted}1">, ShowInSystemHeader,
+ "has trivial destructor|is standard layout|is in a ignorelisted file|"
+ "is ignorelisted}1">, ShowInSystemHeader,
InGroup<SanitizeAddressRemarks>;
def warn_npot_ms_struct : Warning<
@@ -576,6 +998,16 @@ def warn_npot_ms_struct : Warning<
"data types with sizes that aren't a power of two">,
DefaultError, InGroup<IncompatibleMSStruct>;
+// -Wpadded-bitfield
+def warn_padded_struct_bitfield : Warning<
+ "padding %select{struct|interface|class}0 %1 with %2 "
+ "%select{byte|bit}3%s2 to align %4">,
+ InGroup<PaddedBitField>, DefaultIgnore;
+def warn_padded_struct_anon_bitfield : Warning<
+ "padding %select{struct|interface|class}0 %1 with %2 "
+ "%select{byte|bit}3%s2 to align anonymous bit-field">,
+ InGroup<PaddedBitField>, DefaultIgnore;
+
// -Wpadded, -Wpacked
def warn_padded_struct_field : Warning<
"padding %select{struct|interface|class}0 %1 with %2 "
@@ -583,11 +1015,21 @@ def warn_padded_struct_field : Warning<
InGroup<Padded>, DefaultIgnore;
def warn_padded_struct_anon_field : Warning<
"padding %select{struct|interface|class}0 %1 with %2 "
- "%select{byte|bit}3%s2 to align anonymous bit-field">,
+ "%select{byte|bit}3%s2 to align anonymous field">,
InGroup<Padded>, DefaultIgnore;
def warn_padded_struct_size : Warning<
"padding size of %0 with %1 %select{byte|bit}2%s1 to alignment boundary">,
InGroup<Padded>, DefaultIgnore;
def warn_unnecessary_packed : Warning<
"packed attribute is unnecessary for %0">, InGroup<Packed>, DefaultIgnore;
+def warn_unpacked_field
+ : Warning<
+ "not packing field %0 as it is non-POD for the purposes of layout">,
+ InGroup<PackedNonPod>,
+ 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/DiagnosticAnalysisKinds.td b/contrib/llvm-project/clang/include/clang/Basic/DiagnosticAnalysisKinds.td
deleted file mode 100644
index 20efd96b85fd..000000000000
--- a/contrib/llvm-project/clang/include/clang/Basic/DiagnosticAnalysisKinds.td
+++ /dev/null
@@ -1,11 +0,0 @@
-//==--- DiagnosticAnalysisKinds.td - libanalysis diagnostics --------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-
-let Component = "Analysis" in {
-
-}
diff --git a/contrib/llvm-project/clang/include/clang/Basic/DiagnosticCategories.h b/contrib/llvm-project/clang/include/clang/Basic/DiagnosticCategories.h
index 0decf15080a0..14be326f7515 100644
--- a/contrib/llvm-project/clang/include/clang/Basic/DiagnosticCategories.h
+++ b/contrib/llvm-project/clang/include/clang/Basic/DiagnosticCategories.h
@@ -19,6 +19,14 @@ namespace clang {
#undef GET_CATEGORY_TABLE
DiagCat_NUM_CATEGORIES
};
+
+ enum class Group {
+#define DIAG_ENTRY(GroupName, FlagNameOffset, Members, SubGroups, Docs) \
+ GroupName,
+#include "clang/Basic/DiagnosticGroups.inc"
+#undef CATEGORY
+#undef DIAG_ENTRY
+ };
} // end namespace diag
} // end namespace clang
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/DiagnosticCommentKinds.td b/contrib/llvm-project/clang/include/clang/Basic/DiagnosticCommentKinds.td
index ae63bb623ed3..1122ace3027d 100644
--- a/contrib/llvm-project/clang/include/clang/Basic/DiagnosticCommentKinds.td
+++ b/contrib/llvm-project/clang/include/clang/Basic/DiagnosticCommentKinds.td
@@ -155,8 +155,8 @@ def note_add_deprecation_attr : Note<
// inline contents commands
-def warn_doc_inline_contents_no_argument : Warning<
- "'%select{\\|@}0%1' command does not have a valid word argument">,
+def warn_doc_inline_command_not_enough_arguments : Warning<
+ "'%select{\\|@}0%1' command has %plural{0:no|:%2}2 word argument%s2, expected %3">,
InGroup<Documentation>, DefaultIgnore;
// verbatim block commands
diff --git a/contrib/llvm-project/clang/include/clang/Basic/DiagnosticCommonKinds.td b/contrib/llvm-project/clang/include/clang/Basic/DiagnosticCommonKinds.td
index 4dff3379ed35..08bb1d81ba29 100644
--- a/contrib/llvm-project/clang/include/clang/Basic/DiagnosticCommonKinds.td
+++ b/contrib/llvm-project/clang/include/clang/Basic/DiagnosticCommonKinds.td
@@ -55,15 +55,25 @@ def err_expected_colon_after_setter_name : Error<
def err_expected_string_literal : Error<"expected string literal "
"%select{in %1|for diagnostic message in static_assert|"
"for optional message in 'availability' attribute|"
- "for %select{language|source container}1 name in "
- "'external_source_symbol' attribute}0">;
+ "for %select{language name|source container name|USR}1 in "
+ "'external_source_symbol' attribute|"
+ "as argument of '%1' attribute}0">;
+
def err_invalid_string_udl : Error<
"string literal with user-defined suffix cannot be used here">;
def err_invalid_character_udl : Error<
"character literal with user-defined suffix cannot be used here">;
def err_invalid_numeric_udl : Error<
"numeric literal with user-defined suffix cannot be used here">;
-
+def warn_pragma_debug_missing_argument : Warning<
+ "missing argument to debug command '%0'">, InGroup<IgnoredPragmas>;
+def warn_pragma_debug_unexpected_argument : Warning<
+ "unexpected argument to debug command">, InGroup<IgnoredPragmas>;
+
+def warn_fp_nan_inf_when_disabled : Warning<
+ "use of %select{infinity|NaN}0%select{| via a macro}1 is undefined behavior "
+ "due to the currently enabled floating-point options">,
+ InGroup<DiagGroup<"nan-infinity-disabled", [], NanInfDisabledDocs>>;
}
// Parse && Sema
@@ -117,13 +127,21 @@ def note_pragma_entered_here : Note<"#pragma entered here">;
def note_decl_hiding_tag_type : Note<
"%1 %0 is hidden by a non-type declaration of %0 here">;
def err_attribute_not_type_attr : Error<
- "%0 attribute cannot be applied to types">;
+ "%0%select{ attribute|}1 cannot be applied to types">;
def err_enum_template : Error<"enumeration cannot be a template">;
def warn_cxx20_compat_consteval : Warning<
"'consteval' specifier is incompatible with C++ standards before C++20">,
InGroup<CXX20Compat>, DefaultIgnore;
-
+def warn_missing_type_specifier : Warning<
+ "type specifier missing, defaults to 'int'">,
+ InGroup<ImplicitInt>, DefaultIgnore;
+
+def ext_c_empty_initializer : Extension<
+ "use of an empty initializer is a C23 extension">, InGroup<C23>;
+def warn_c23_compat_empty_initializer : Warning<
+ "use of an empty initializer is incompatible with C standards before C23">,
+ InGroup<CPre23Compat>, DefaultIgnore;
}
let CategoryName = "Nullability Issue" in {
@@ -145,15 +163,26 @@ def warn_conflicting_nullability_attr_overriding_param_types : Warning<
def err_nullability_conflicting : Error<
"nullability specifier %0 conflicts with existing specifier %1">;
+def warn_incompatible_branch_protection_option: Warning <
+ "'-mbranch-protection=' option is incompatible with the '%0' architecture">,
+ InGroup<BranchProtection>;
+
+def warn_target_unsupported_branch_protection_attribute: Warning <
+ "ignoring the 'branch-protection' attribute because the '%0' architecture does not support it">,
+ InGroup<BranchProtection>;
}
// OpenCL Section 6.8.g
def err_opencl_unknown_type_specifier : Error<
- "%select{OpenCL C|C++ for OpenCL}0 version %1 does not support the "
- "'%2' %select{type qualifier|storage class specifier}3">;
+ "%0 does not support the '%1' "
+ "%select{type qualifier|storage class specifier}2">;
def warn_unknown_attribute_ignored : Warning<
"unknown attribute %0 ignored">, InGroup<UnknownAttributes>;
+def warn_attribute_ignored : Warning<"%0 attribute ignored">,
+ InGroup<IgnoredAttributes>;
+def err_keyword_not_supported_on_target : Error<
+ "%0 is not supported on this target">;
def err_use_of_tag_name_without_tag : Error<
"must use '%1' tag to refer to type %0%select{| in this scope}2">;
@@ -189,17 +218,23 @@ def ext_cxx11_longlong : Extension<
def warn_cxx98_compat_longlong : Warning<
"'long long' is incompatible with C++98">,
InGroup<CXX98CompatPedantic>, DefaultIgnore;
-def ext_cxx2b_size_t_suffix : ExtWarn<
- "'size_t' suffix for literals is a C++2b extension">,
- InGroup<CXX2b>;
+def ext_cxx23_size_t_suffix : ExtWarn<
+ "'size_t' suffix for literals is a C++23 extension">,
+ InGroup<CXX23>;
def warn_cxx20_compat_size_t_suffix : Warning<
"'size_t' suffix for literals is incompatible with C++ standards before "
- "C++2b">, InGroup<CXXPre2bCompat>, DefaultIgnore;
-def err_cxx2b_size_t_suffix: Error<
- "'size_t' suffix for literals is a C++2b feature">;
+ "C++23">, InGroup<CXXPre23Compat>, DefaultIgnore;
+def err_cxx23_size_t_suffix: Error<
+ "'size_t' suffix for literals is a C++23 feature">;
def err_size_t_literal_too_large: Error<
"%select{signed |}0'size_t' literal is out of range of possible "
"%select{signed |}0'size_t' values">;
+def ext_c23_bitint_suffix : ExtWarn<
+ "'_BitInt' suffix for literals is a C23 extension">,
+ InGroup<C23>;
+def warn_c23_compat_bitint_suffix : Warning<
+ "'_BitInt' suffix for literals is incompatible with C standards before C23">,
+ InGroup<CPre23Compat>, DefaultIgnore;
def err_integer_literal_too_large : Error<
"integer literal is too large to be represented in any %select{signed |}0"
"integer type">;
@@ -229,8 +264,6 @@ def ext_clang_diagnose_if : Extension<"'diagnose_if' is a clang extension">,
InGroup<GccCompat>;
def err_too_large_for_fixed_point : Error<
"this value is too large for this fixed point type">;
-def err_fixed_point_not_enabled : Error<"compile with "
- "'-ffixed-point' to enable fixed point types">;
def err_unimplemented_conversion_with_fixed_point_type : Error<
"conversion between fixed point and %0 is not yet supported">;
@@ -252,34 +285,37 @@ def note_constexpr_invalid_template_arg : Note<
"%select{type_info object|string literal|temporary object|"
"predefined '%3' variable}2 is not allowed in a template argument">;
def err_constexpr_invalid_template_arg : Error<
- note_constexpr_invalid_template_arg.Text>;
+ note_constexpr_invalid_template_arg.Summary>;
// Sema && Frontend
let CategoryName = "Inline Assembly Issue" in {
- def err_asm_invalid_type_in_input : Error<
- "invalid type %0 in asm input for constraint '%1'">;
+def err_asm_invalid_type_in_input : Error<
+ "invalid type %0 in asm input for constraint '%1'">;
- def err_asm_invalid_type : Error<
- "invalid type %0 in asm %select{input|output}1">;
+def err_asm_invalid_type : Error<
+ "invalid type %0 in asm %select{input|output}1">;
- def warn_stack_clash_protection_inline_asm : Warning<
- "Unable to protect inline asm that clobbers stack pointer against stack clash">,
- InGroup<DiagGroup<"stack-protector">>;
+def err_ms_asm_bitfield_unsupported : Error<
+ "an inline asm block cannot have an operand which is a bit-field">;
- def warn_slh_does_not_support_asm_goto
- : Warning<"Speculative load hardening does not protect functions with "
- "asm goto">,
- InGroup<DiagGroup<"slh-asm-goto">>;
+def warn_stack_clash_protection_inline_asm : Warning<
+ "unable to protect inline asm that clobbers stack pointer against stack "
+ "clash">, InGroup<DiagGroup<"stack-protector">>;
+
+def warn_slh_does_not_support_asm_goto : Warning<
+ "speculative load hardening does not protect functions with asm goto">,
+ InGroup<DiagGroup<"slh-asm-goto">>;
}
// Sema && Serialization
def warn_dup_category_def : Warning<
- "duplicate definition of category %1 on interface %0">;
+ "duplicate definition of category %1 on interface %0">,
+ InGroup<DiagGroup<"objc-duplicate-category-definition">>;
// Targets
def err_target_unknown_triple : Error<
- "unknown target triple '%0', please use -triple or -arch">;
+ "unknown target triple '%0'">;
def err_target_unknown_cpu : Error<"unknown target CPU '%0'">;
def note_valid_options : Note<"valid target CPU values are: %0">;
def err_target_unsupported_cpu_for_micromips : Error<
@@ -298,30 +334,54 @@ def err_target_unsupported_unaligned : Error<
"the %0 sub-architecture does not support unaligned accesses">;
def err_target_unsupported_execute_only : Error<
"execute only is not supported for the %0 sub-architecture">;
+def err_target_unsupported_tp_hard : Error<
+ "hardware TLS register is not supported for the %0 sub-architecture">;
def err_target_unsupported_mcmse : Error<
"-mcmse is not supported for %0">;
def err_opt_not_valid_with_opt : Error<
"option '%0' cannot be specified with '%1'">;
+def err_opt_not_valid_with_opt_on_target : Error<
+ "option '%0' cannot be specified with '%1' for the %2 sub-architecture">;
def err_opt_not_valid_without_opt : Error<
"option '%0' cannot be specified without '%1'">;
def err_opt_not_valid_on_target : Error<
"option '%0' cannot be specified on this target">;
+def err_invalid_feature_combination : Error<
+ "invalid feature combination: %0">;
+def warn_invalid_feature_combination : Warning<
+ "invalid feature combination: %0">, InGroup<DiagGroup<"invalid-feature-combination">>;
+def warn_target_unrecognized_env : Warning<
+ "mismatch between architecture and environment in target triple '%0'; did you mean '%1'?">,
+ InGroup<InvalidCommandLineArgument>;
+def warn_knl_knm_isa_support_removed : Warning<
+ "KNL, KNM related Intel Xeon Phi CPU's specific ISA's supports will be removed in LLVM 19.">,
+ InGroup<DiagGroup<"knl-knm-isa-support-removed">>;
// Source manager
def err_cannot_open_file : Error<"cannot open file '%0': %1">, DefaultFatal;
def err_file_modified : Error<
"file '%0' modified since it was first processed">, DefaultFatal;
def err_file_too_large : Error<
- "sorry, unsupported: file '%0' is too large for Clang to process">;
-def err_include_too_large : Error<
- "sorry, this include generates a translation unit too large for"
- " Clang to process.">, DefaultFatal;
+ "file '%0' is too large for Clang to process">;
+def err_sloc_space_too_large : Error<
+ "translation unit is too large for Clang to process: ran out of source locations">, DefaultFatal;
def err_unsupported_bom : Error<"%0 byte order mark detected in '%1', but "
"encoding is not supported">, DefaultFatal;
def err_unable_to_rename_temp : Error<
"unable to rename temporary '%0' to output file '%1': '%2'">;
def err_unable_to_make_temp : Error<
"unable to make temporary file: %0">;
+def remark_sloc_usage : Remark<
+ "source manager location address space usage:">,
+ InGroup<DiagGroup<"sloc-usage">>, DefaultRemark, ShowInSystemHeader;
+def note_total_sloc_usage : Note<
+ "%0B in local locations, %1B in locations loaded from AST files, for a total "
+ "of %2B (%3%% of available space)">;
+def note_file_sloc_usage : Note<
+ "file entered %0 time%s0 using %1B of space"
+ "%plural{0:|: plus %2B for macro expansions}2">;
+def note_file_misc_sloc_usage : Note<
+ "%0 additional files entered using a total of %1B of space">;
// Modules
def err_module_format_unhandled : Error<
@@ -337,6 +397,19 @@ def note_mt_message : Note<"[rewriter] %0">;
def warn_arcmt_nsalloc_realloc : Warning<"[rewriter] call returns pointer to GC managed memory; it will become unmanaged in ARC">;
def err_arcmt_nsinvocation_ownership : Error<"NSInvocation's %0 is not safe to be used with an object with ownership other than __unsafe_unretained">;
+// API notes
+def err_apinotes_message : Error<"%0">;
+def warn_apinotes_message : Warning<"%0">, InGroup<DiagGroup<"apinotes">>;
+def note_apinotes_message : Note<"%0">;
+
+class NonportablePrivateAPINotesPath : Warning<
+ "private API notes file for module '%0' should be named "
+ "'%0_private.apinotes', not '%1'">;
+def warn_apinotes_private_case : NonportablePrivateAPINotesPath,
+ InGroup<DiagGroup<"nonportable-private-apinotes-path">>;
+def warn_apinotes_private_case_system : NonportablePrivateAPINotesPath,
+ DefaultIgnore, InGroup<DiagGroup<"nonportable-private-system-apinotes-path">>;
+
// C++ for OpenCL.
def err_openclcxx_not_supported : Error<
"'%0' is not supported in C++ for OpenCL">;
@@ -371,4 +444,13 @@ def err_opencl_extension_and_feature_differs : Error<
"options %0 and %1 are set to different values">;
def err_opencl_feature_requires : Error<
"feature %0 requires support of %1 feature">;
+
+def warn_throw_not_valid_on_target : Warning<
+ "target '%0' does not support exception handling;"
+ " 'throw' is assumed to be never reached">,
+ InGroup<OpenMPTargetException>;
+def warn_try_not_valid_on_target : Warning<
+ "target '%0' does not support exception handling;"
+ " 'catch' block is ignored">,
+ InGroup<OpenMPTargetException>;
}
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/DiagnosticCrossTUKinds.td b/contrib/llvm-project/clang/include/clang/Basic/DiagnosticCrossTUKinds.td
index 4277a3173203..e6ea1956f98a 100644
--- a/contrib/llvm-project/clang/include/clang/Basic/DiagnosticCrossTUKinds.td
+++ b/contrib/llvm-project/clang/include/clang/Basic/DiagnosticCrossTUKinds.td
@@ -12,8 +12,8 @@ def err_ctu_error_opening : Error<
"error opening '%0': required by the CrossTU functionality">;
def err_extdefmap_parsing : Error<
- "error parsing index file: '%0' line: %1 'UniqueID filename' format "
- "expected">;
+ "error parsing index file: '%0' line: %1 '<USR-Length>:<USR> <File-Path>' "
+ "format expected">;
def err_multiple_def_index : Error<
"multiple definitions are found for the same key in index ">;
diff --git a/contrib/llvm-project/clang/include/clang/Basic/DiagnosticDocs.td b/contrib/llvm-project/clang/include/clang/Basic/DiagnosticDocs.td
index bf88d5d04567..8c024b5cad74 100644
--- a/contrib/llvm-project/clang/include/clang/Basic/DiagnosticDocs.td
+++ b/contrib/llvm-project/clang/include/clang/Basic/DiagnosticDocs.td
@@ -81,3 +81,18 @@ Diagnostic flags
}];
}
+defvar GCCWriteStringsDocs = [{
+**Note:** enabling this warning in C will change the semantic behavior of the
+program by treating all string literals as having type ``const char *``
+instead of ``char *``. This can cause unexpected behaviors with type-sensitive
+constructs like ``_Generic``.
+}];
+
+defvar NanInfDisabledDocs = [{
+This warning is enabled when source code using the macros ``INFINITY`` or ``NAN``
+is compiled with floating-point options preventing these two values. This can
+lead to undefined behavior. Check the order of command line arguments that modify
+this behavior, such as ``-ffast-math``, ``-fhonor-infinities``, and
+``-fhonor-nans`` (etc), as well as ``#pragma`` directives if this diagnostic is
+generated unexpectedly.
+}];
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 fc3704303a95..094fe1950941 100644
--- a/contrib/llvm-project/clang/include/clang/Basic/DiagnosticDriverKinds.td
+++ b/contrib/llvm-project/clang/include/clang/Basic/DiagnosticDriverKinds.td
@@ -16,8 +16,12 @@ def err_drv_unsupported_opt_with_suggestion : Error<
"unsupported option '%0'; did you mean '%1'?">;
def err_drv_unsupported_opt_for_target : Error<
"unsupported option '%0' for target '%1'">;
+def err_drv_unsupported_opt_for_language_mode : Error<
+ "unsupported option '%0' for language mode '%1'">;
def err_drv_unsupported_option_argument : Error<
"unsupported argument '%1' to option '%0'">;
+def err_drv_unsupported_option_argument_for_target : Error<
+ "unsupported argument '%1' to option '%0' for target '%2'">;
def err_drv_unknown_stdin_type : Error<
"-E or -x required when input is from standard input">;
def err_drv_unknown_stdin_type_clang_cl : Error<
@@ -27,16 +31,15 @@ def err_drv_invalid_arch_name : Error<
"invalid arch name '%0'">;
def err_drv_invalid_riscv_arch_name : Error<
"invalid arch name '%0', %1">;
-def err_drv_invalid_riscv_ext_arch_name : Error<
- "invalid arch name '%0', %1 '%2'">;
+def err_drv_invalid_riscv_cpu_name_for_target : Error<
+ "cpu '%0' does not support rv%select{32|64}1">;
+def warn_drv_invalid_arch_name_with_suggestion : Warning<
+ "ignoring invalid /arch: argument '%0'; for %select{64|32}1-bit expected one of %2">,
+ InGroup<UnusedCommandLineArgument>;
def warn_drv_avr_mcu_not_specified : Warning<
"no target microcontroller specified on command line, cannot "
"link standard libraries, please pass -mmcu=<mcu name>">,
InGroup<AVRRtlibLinkingQuirks>;
-def warn_drv_avr_gcc_not_found: Warning<
- "no avr-gcc installation can be found on the system, "
- "cannot link standard libraries">,
- InGroup<AVRRtlibLinkingQuirks>;
def warn_drv_avr_libc_not_found: Warning<
"no avr-libc installation can be found on the system, "
"cannot link standard libraries">,
@@ -52,38 +55,88 @@ def warn_drv_avr_stdlib_not_linked: Warning<
"standard library not linked and so no interrupt vector table or "
"compiler runtime routines will be linked">,
InGroup<AVRRtlibLinkingQuirks>;
-def err_drv_cuda_bad_gpu_arch : Error<"Unsupported CUDA gpu architecture: %0">;
+def err_drv_cuda_bad_gpu_arch : Error<"unsupported CUDA gpu architecture: %0">;
+def err_drv_offload_bad_gpu_arch : Error<"unsupported %0 gpu architecture: %1">;
def err_drv_no_cuda_installation : Error<
- "cannot find CUDA installation. Provide its path via --cuda-path, or pass "
- "-nocudainc to build without CUDA includes.">;
+ "cannot find CUDA installation; provide its path via '--cuda-path', or pass "
+ "'-nocudainc' to build without CUDA includes">;
def err_drv_no_cuda_libdevice : Error<
- "cannot find libdevice for %0. Provide path to different CUDA installation "
- "via --cuda-path, or pass -nocudalib to build without linking with libdevice.">;
+ "cannot find libdevice for %0; provide path to different CUDA installation "
+ "via '--cuda-path', or pass '-nocudalib' to build without linking with "
+ "libdevice">;
def err_drv_no_rocm_device_lib : Error<
- "cannot find ROCm device library%select{| for %1}0. Provide its path via --rocm-path or "
- "--rocm-device-lib-path, or pass -nogpulib to build without ROCm device library.">;
+ "cannot find ROCm device library%select{| for %1|for ABI version %1}0; provide its path via "
+ "'--rocm-path' or '--rocm-device-lib-path', or pass '-nogpulib' to build "
+ "without ROCm device library">;
def err_drv_no_hip_runtime : Error<
- "cannot find HIP runtime. Provide its path via --rocm-path, or pass "
- "-nogpuinc to build without HIP runtime.">;
-
-def err_drv_undetermined_amdgpu_arch : Error<
- "Cannot determine AMDGPU architecture: %0. Consider passing it via --march.">;
+ "cannot find HIP runtime; provide its path via '--rocm-path', or pass "
+ "'-nogpuinc' to build without HIP runtime">;
+def err_drv_no_hipstdpar_lib : Error<
+ "cannot find HIP Standard Parallelism Acceleration library; provide it via "
+ "'--hipstdpar-path'">;
+def err_drv_no_hipstdpar_thrust_lib : Error<
+ "cannot find rocThrust, which is required by the HIP Standard Parallelism "
+ "Acceleration library; provide it via "
+ "'--hipstdpar-thrust-path'">;
+def err_drv_no_hipstdpar_prim_lib : Error<
+ "cannot find rocPrim, which is required by the HIP Standard Parallelism "
+ "Acceleration library; provide it via '--hipstdpar-prim-path'">;
+
+def err_drv_no_hipspv_device_lib : Error<
+ "cannot find HIP device library%select{| for %1}0; provide its path via "
+ "'--hip-path' or '--hip-device-lib-path', or pass '-nogpulib' to build "
+ "without HIP device library">;
+def err_drv_hipspv_no_hip_path : Error<
+ "'--hip-path' must be specified when offloading to "
+ "SPIR-V%select{| unless %1 is given}0.">;
+
+def err_drv_undetermined_gpu_arch : Error<
+ "cannot determine %0 architecture: %1; consider passing it via "
+ "'%2'">;
+def warn_drv_multi_gpu_arch : Warning<
+ "multiple %0 architectures are detected: %1; only the first one is used for "
+ "'%2'">, InGroup<MultiGPU>;
def err_drv_cuda_version_unsupported : Error<
"GPU arch %0 is supported by CUDA versions between %1 and %2 (inclusive), "
- "but installation at %3 is %4. Use --cuda-path to specify a different CUDA "
- "install, pass a different GPU arch with --cuda-gpu-arch, or pass "
- "--no-cuda-version-check.">;
-def warn_drv_unknown_cuda_version: Warning<
- "Unknown CUDA version. %0 Assuming the latest supported version %1">,
+ "but installation at %3 is %4; use '--cuda-path' to specify a different CUDA "
+ "install, pass a different GPU arch with '--cuda-gpu-arch', or pass "
+ "'--no-cuda-version-check'">;
+def warn_drv_new_cuda_version: Warning<
+ "CUDA version%0 is newer than the latest%select{| partially}1 supported version %2">,
+ InGroup<CudaUnknownVersion>;
+def warn_drv_partially_supported_cuda_version: Warning<
+ "CUDA version %0 is only partially supported">,
InGroup<CudaUnknownVersion>;
-def err_drv_cuda_host_arch : Error<"unsupported architecture '%0' for host compilation.">;
-def err_drv_mix_cuda_hip : Error<"Mixed Cuda and HIP compilation is not supported.">;
-def err_drv_bad_target_id : Error<"Invalid target ID: %0 (A target ID is a processor name "
- "followed by an optional list of predefined features post-fixed by a plus or minus sign deliminated "
- "by colon, e.g. 'gfx908:sramecc+:xnack-')">;
-def err_drv_bad_offload_arch_combo : Error<"Invalid offload arch combinations: %0 and %1 (For a specific "
- "processor, a feature should either exist in all offload archs, or not exist in any offload archs)">;
+def err_drv_cuda_host_arch : Error<
+ "unsupported architecture '%0' for host compilation">;
+def err_drv_mix_cuda_hip : Error<
+ "mixed CUDA and HIP compilation is not supported">;
+def err_drv_bad_target_id : Error<
+ "invalid target ID '%0'; format is a processor name followed by an optional "
+ "colon-delimited list of features followed by an enable/disable sign (e.g., "
+ "'gfx908:sramecc+:xnack-')">;
+def err_drv_bad_offload_arch_combo : Error<
+ "invalid offload arch combinations: '%0' and '%1' (for a specific processor, "
+ "a feature should either exist in all offload archs, or not exist in any "
+ "offload archs)">;
+def warn_drv_unsupported_option_for_offload_arch_req_feature : Warning<
+ "ignoring '%0' option for offload arch '%1' as it is not currently supported "
+ "there. Use it with an offload arch containing '%2' instead">,
+ InGroup<OptionIgnored>;
+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_unsupported_option_for_flang : Warning<
+ "the argument '%0' is not supported for option '%1'. Mapping to '%1%2'">,
+ InGroup<OptionIgnored>;
+def warn_drv_unsupported_diag_option_for_flang : Warning<
+ "The warning option '-%0' is not supported">,
+ InGroup<OptionIgnored>;
+def warn_drv_unsupported_option_for_processor : Warning<
+ "ignoring '%0' option as it is not currently supported for processor '%1'">,
+ 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<
@@ -96,13 +149,13 @@ def err_drv_invalid_unwindlib_name : Error<
"invalid unwind library name in argument '%0'">;
def err_drv_incompatible_unwindlib : Error<
"--rtlib=libgcc requires --unwindlib=libgcc">;
+def err_drv_incompatible_options : Error<
+ "the combination of '%0' and '%1' is incompatible">;
def err_drv_invalid_stdlib_name : Error<
"invalid library name in argument '%0'">;
def err_drv_invalid_output_with_multiple_archs : Error<
"cannot use '%0' output with multiple -arch options">;
def err_drv_no_input_files : Error<"no input files">;
-def err_drv_use_of_Z_option : Error<
- "unsupported use of internal gcc -Z option '%0'">;
def err_drv_output_argument_with_multiple_files : Error<
"cannot specify -o when generating multiple output files">;
def err_drv_out_file_argument_with_multiple_sources : Error<
@@ -119,6 +172,8 @@ def err_drv_invalid_darwin_version : Error<
"invalid Darwin version number: %0">;
def err_drv_invalid_diagnotics_hotness_threshold : Error<
"invalid argument in '%0', only integer or 'auto' is supported">;
+def err_drv_invalid_diagnotics_misexpect_tolerance : Error<
+ "invalid argument in '%0', only integers are supported">;
def err_drv_missing_argument : Error<
"argument to '%0' is missing (expected %1 value%s1)">;
def err_drv_invalid_Xarch_argument_with_args : Error<
@@ -129,10 +184,14 @@ def err_drv_invalid_Xopenmp_target_with_args : Error<
"invalid -Xopenmp-target argument: '%0', options requiring arguments are unsupported">;
def err_drv_argument_only_allowed_with : Error<
"invalid argument '%0' only allowed with '%1'">;
+def err_drv_opt_unsupported_input_type : Error<
+ "'%0' invalid for input of type %1">;
def err_drv_amdgpu_ieee_without_no_honor_nans : Error<
"invalid argument '-mno-amdgpu-ieee' only allowed with relaxed NaN handling">;
def err_drv_argument_not_allowed_with : Error<
"invalid argument '%0' not allowed with '%1'">;
+def err_drv_cannot_open_randomize_layout_seed_file : Error<
+ "cannot read randomize layout seed file '%0'">;
def err_drv_invalid_version_number : Error<
"invalid version number in '%0'">;
def err_drv_no_linker_llvm_support : Error<
@@ -163,28 +222,36 @@ def err_drv_invalid_mtp : Error<
"invalid thread pointer reading mode '%0'">;
def err_drv_missing_arg_mtp : Error<
"missing argument to '%0'">;
-def err_drv_invalid_libcxx_deployment : Error<
- "invalid deployment target for -stdlib=libc++ (requires %0 or later)">;
+def warn_drv_missing_plugin_name : Warning<
+ "missing plugin name in %0">,
+ InGroup<InvalidCommandLineArgument>;
+def warn_drv_missing_plugin_arg : Warning<
+ "missing plugin argument for plugin %0 in %1">,
+ InGroup<InvalidCommandLineArgument>;
def err_drv_invalid_argument_to_option : Error<
"invalid argument '%0' to -%1">;
+def err_drv_missing_sanitizer_ignorelist : Error<
+ "missing sanitizer ignorelist: '%0'">;
def err_drv_malformed_sanitizer_ignorelist : Error<
"malformed sanitizer ignorelist: '%0'">;
-def err_drv_malformed_sanitizer_coverage_whitelist : Error<
- "malformed sanitizer coverage whitelist: '%0'">;
+def err_drv_malformed_sanitizer_coverage_allowlist : Error<
+ "malformed sanitizer coverage allowlist: '%0'">;
def err_drv_malformed_sanitizer_coverage_ignorelist : Error<
"malformed sanitizer coverage ignorelist: '%0'">;
+def err_drv_malformed_sanitizer_metadata_ignorelist : Error<
+ "malformed sanitizer metadata ignorelist: '%0'">;
+def err_drv_unsupported_static_sanitizer_darwin : Error<
+ "static %0 runtime is not supported on darwin">;
def err_drv_duplicate_config : Error<
"no more than one option '--config' is allowed">;
-def err_drv_config_file_not_exist : Error<
- "configuration file '%0' does not exist">;
+def err_drv_cannot_open_config_file : Error<
+ "configuration file '%0' cannot be opened: %1">;
def err_drv_config_file_not_found : Error<
"configuration file '%0' cannot be found">;
def note_drv_config_file_searched_in : Note<
"was searched for in the directory: %0">;
def err_drv_cannot_read_config_file : Error<
- "cannot read configuration file '%0'">;
-def err_drv_nested_config_file: Error<
- "option '--config' is not allowed inside configuration file">;
+ "cannot read configuration file '%0': %1">;
def err_drv_arg_requires_bitcode_input: Error<
"option '%0' requires input to be LLVM bitcode">;
@@ -193,7 +260,7 @@ def err_target_unsupported_arch
def err_cpu_unsupported_isa
: Error<"CPU '%0' does not support '%1' execution mode">;
def err_arch_unsupported_isa
- : Error<"Architecture '%0' does not support '%1' execution mode">;
+ : Error<"architecture '%0' does not support '%1' execution mode">;
def err_drv_I_dash_not_supported : Error<
"'%0' not supported, please use -iquote instead">;
@@ -206,6 +273,7 @@ def warn_drv_unknown_argument_clang_cl : Warning<
def warn_drv_unknown_argument_clang_cl_with_suggestion : Warning<
"unknown argument ignored in clang-cl '%0'; did you mean '%1'?">,
InGroup<UnknownArgument>;
+def err_drv_unknown_target_triple : Error<"unknown target triple '%0'">;
def warn_drv_ycyu_different_arg_clang_cl : Warning<
"support for '/Yc' and '/Yu' with different filenames not implemented yet; flags ignored">,
@@ -214,12 +282,17 @@ def warn_drv_yc_multiple_inputs_clang_cl : Warning<
"support for '/Yc' with more than one source file not implemented yet; flag ignored">,
InGroup<ClangClPch>;
+def warn_drv_potentially_misspelled_joined_argument : Warning<
+ "joined argument treated as '%0'; did you mean '%1'?">, InGroup<UnknownArgument>;
+
def err_drv_invalid_value : Error<"invalid value '%1' in '%0'">;
def err_drv_invalid_int_value : Error<"invalid integral value '%1' in '%0'">;
def err_drv_invalid_value_with_suggestion : Error<
"invalid value '%1' in '%0', expected one of: %2">;
+def err_drv_alignment_not_power_of_two : Error<"alignment is not a power of 2 in '%0'">;
def err_drv_invalid_remap_file : Error<
"invalid option '%0' not of the form <from-file>;<to-file>">;
+def err_drv_invalid_gcc_install_dir : Error<"'%0' does not contain a GCC installation">;
def err_drv_invalid_gcc_output_type : Error<
"invalid output type '%0' for use with gcc tool">;
def err_drv_cc_print_options_failure : Error<
@@ -227,12 +300,15 @@ def err_drv_cc_print_options_failure : Error<
def err_drv_lto_without_lld : Error<"LTO requires -fuse-ld=lld">;
def err_drv_preamble_format : Error<
"incorrect format for -preamble-bytes=N,END">;
+def err_drv_header_unit_extra_inputs : Error<
+ "multiple inputs are not valid for header units (first extra '%0')">;
def warn_invalid_ios_deployment_target : Warning<
"invalid iOS deployment version '%0', iOS 10 is the maximum deployment "
"target for 32-bit targets">, InGroup<InvalidIOSDeploymentTarget>,
DefaultError;
def err_invalid_macos_32bit_deployment_target : Error<
"32-bit targets are not supported when building for Mac Catalyst">;
+def err_drv_invalid_os_in_arg : Error<"invalid OS value '%0' in '%1'">;
def err_drv_conflicting_deployment_targets : Error<
"conflicting deployment targets, both '%0' and '%1' are present in environment">;
def err_arc_unsupported_on_runtime : Error<
@@ -262,30 +338,45 @@ def err_drv_no_neon_modifier : Error<"[no]neon is not accepted as modifier, plea
def err_drv_invalid_omp_target : Error<"OpenMP target is invalid: '%0'">;
def err_drv_incompatible_omp_arch : Error<"OpenMP target architecture '%0' pointer size is incompatible with host '%1'">;
def err_drv_omp_host_ir_file_not_found : Error<
- "The provided host compiler IR file '%0' is required to generate code for OpenMP target regions but cannot be found.">;
+ "provided host compiler IR file '%0' is required to generate code for OpenMP "
+ "target regions but cannot be found">;
def err_drv_omp_host_target_not_supported : Error<
- "The target '%0' is not a supported OpenMP host target.">;
+ "target '%0' is not a supported OpenMP host target">;
def err_drv_expecting_fopenmp_with_fopenmp_targets : Error<
- "The option -fopenmp-targets must be used in conjunction with a -fopenmp option compatible with offloading, please use -fopenmp=libomp or -fopenmp=libiomp5.">;
+ "'-fopenmp-targets' must be used in conjunction with a '-fopenmp' option "
+ "compatible with offloading; e.g., '-fopenmp=libomp' or '-fopenmp=libiomp5'">;
+def err_drv_failed_to_deduce_target_from_arch : Error<
+ "failed to deduce triple for target architecture '%0'; specify the triple "
+ "using '-fopenmp-targets' and '-Xopenmp-target' instead.">;
def err_drv_omp_offload_target_missingbcruntime : Error<
- "No library '%0' found in the default clang lib directory or in LIBRARY_PATH. Please use --libomptarget-%1-bc-path to specify %1 bitcode library.">;
-def err_drv_omp_offload_target_bcruntime_not_found : Error<"Bitcode library '%0' does not exist.">;
-def err_drv_omp_offload_target_cuda_version_not_support : Error<"NVPTX target requires CUDA 9.2 or above. CUDA %0 is detected.">;
+ "no library '%0' found in the default clang lib directory or in LIBRARY_PATH"
+ "; use '--libomptarget-%1-bc-path' to specify %1 bitcode library">;
+def err_drv_omp_offload_target_bcruntime_not_found : Error<
+ "bitcode library '%0' does not exist">;
+def err_drv_omp_offload_target_cuda_version_not_support : Error<
+ "NVPTX target requires CUDA 9.2 or above; CUDA %0 detected">;
def warn_drv_omp_offload_target_duplicate : Warning<
- "The OpenMP offloading target '%0' is similar to target '%1' already specified - will be ignored.">,
- InGroup<OpenMPTarget>;
+ "OpenMP offloading target '%0' is similar to target '%1' already specified; "
+ "will be ignored">, InGroup<OpenMPTarget>;
def err_drv_unsupported_embed_bitcode
: Error<"%0 is not supported with -fembed-bitcode">;
def err_drv_bitcode_unsupported_on_toolchain : Error<
"-fembed-bitcode is not supported on versions of iOS prior to 6.0">;
def err_drv_negative_columns : Error<
- "invalid value '%1' in '%0', value must be 'none' or a positive integer">;
+ "invalid value '%1' in '%0', value must be 'none' or a positive integer">;
def err_drv_small_columns : Error<
- "invalid value '%1' in '%0', value must be '%2' or greater">;
+ "invalid value '%1' in '%0', value must be '%2' or greater">;
def err_drv_invalid_malign_branch_EQ : Error<
"invalid argument '%0' to -malign-branch=; each element must be one of: %1">;
+def err_drv_print_header_env_var : Error<
+ "environment variable CC_PRINT_HEADERS_%select{FORMAT|FILTERING}0 has invalid value %1">;
+def err_drv_print_header_env_var_combination : Error<
+ "unsupported combination: CC_PRINT_HEADERS_FORMAT=%0 and CC_PRINT_HEADERS_FILTERING=%1">;
+def err_drv_print_header_env_var_combination_cc1 : Error<
+ "unsupported combination: -header-include-format=%0 and -header-include-filtering=%1">;
+
def warn_O4_is_O3 : Warning<"-O4 is equivalent to -O3">, InGroup<Deprecated>;
def warn_drv_optimization_value : Warning<"optimization level '%0' is not supported; using '%1%2' instead">,
InGroup<InvalidCommandLineArgument>;
@@ -300,7 +391,8 @@ def warn_drv_unsupported_debug_info_opt_for_target : Warning<
"debug information option '%0' is not supported for target '%1'">,
InGroup<UnsupportedTargetOpt>;
def warn_drv_dwarf_version_limited_by_target : Warning<
- "debug information option '%0' is not supported. It needs DWARF-%2 but target '%1' only provides DWARF-%3.">,
+ "debug information option '%0' is not supported; requires DWARF-%2 but "
+ "target '%1' only provides DWARF-%3">,
InGroup<UnsupportedTargetOpt>;
def warn_c_kext : Warning<
"ignoring -fapple-kext which is valid for C++ and Objective-C++ only">;
@@ -319,33 +411,53 @@ def warn_drv_preprocessed_input_file_unused : Warning<
def warn_drv_unused_argument : Warning<
"argument unused during compilation: '%0'">,
InGroup<UnusedCommandLineArgument>;
+def warn_drv_unused_x : Warning<
+ "'-x %0' after last input file has no effect">,
+ InGroup<UnusedCommandLineArgument>;
def warn_drv_empty_joined_argument : Warning<
"joined argument expects additional value: '%0'">,
InGroup<UnusedCommandLineArgument>;
def warn_drv_diagnostics_hotness_requires_pgo : Warning<
"argument '%0' requires profile-guided optimization information">,
InGroup<UnusedCommandLineArgument>;
+def warn_drv_diagnostics_misexpect_requires_pgo : Warning<
+ "argument '%0' requires profile-guided optimization information">,
+ InGroup<UnusedCommandLineArgument>;
def warn_drv_clang_unsupported : Warning<
"the clang compiler does not support '%0'">;
def warn_drv_deprecated_arg : Warning<
"argument '%0' is deprecated, use '%1' instead">, InGroup<Deprecated>;
+def warn_drv_deprecated_custom : Warning<
+ "argument '%0' is deprecated, %1">, 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<UnsupportedABI>;
+def warn_drv_no_floating_point_registers: Warning<
+ "'%0': selected processor lacks floating point registers">,
+ InGroup<UnsupportedABI>;
def warn_ignoring_ftabstop_value : Warning<
"ignoring invalid -ftabstop value '%0', using default value %1">;
-def warn_drv_overriding_flag_option : Warning<
+def warn_drv_overriding_option : Warning<
"overriding '%0' option with '%1'">,
- InGroup<DiagGroup<"overriding-t-option">>;
+ InGroup<DiagGroup<"overriding-option">>;
def warn_drv_treating_input_as_cxx : Warning<
"treating '%0' input as '%1' when in C++ mode, this behavior is deprecated">,
InGroup<Deprecated>;
def warn_drv_pch_not_first_include : Warning<
"precompiled header '%0' was ignored because '%1' is not first '-include'">;
+def warn_drv_pch_ignoring_gch_file : Warning<
+ "precompiled header '%0' was ignored because it is not a clang PCH file">,
+ InGroup<IgnoredGCH>;
+def warn_drv_pch_ignoring_gch_dir : Warning<
+ "precompiled header directory '%0' was ignored because it contains no clang PCH files">,
+ InGroup<IgnoredGCH>;
def warn_missing_sysroot : Warning<"no such sysroot directory: '%0'">,
InGroup<DiagGroup<"missing-sysroot">>;
def warn_incompatible_sysroot : Warning<"using sysroot for '%0' but targeting '%1'">,
InGroup<DiagGroup<"incompatible-sysroot">>;
-def warn_debug_compression_unavailable : Warning<"cannot compress debug sections (zlib not installed)">,
+def warn_debug_compression_unavailable : Warning<"cannot compress debug sections (%0 not enabled)">,
InGroup<DiagGroup<"debug-compression-unavailable">>;
def warn_drv_disabling_vptr_no_rtti_default : Warning<
"implicitly disabling vptr sanitizer because rtti wasn't enabled">,
@@ -357,17 +469,18 @@ def warn_ignoring_verify_debuginfo_preserve_export : Warning<
"ignoring -fverify-debuginfo-preserve-export=%0 because "
"-fverify-debuginfo-preserve wasn't enabled">,
InGroup<UnusedCommandLineArgument>;
-def err_invalid_branch_protection: Error <
- "invalid branch protection option '%0' in '%1'">;
-def err_invalid_sls_hardening : Error<
- "invalid sls hardening option '%0' in '%1'">;
+def warn_unsupported_branch_protection: Warning <
+ "invalid branch protection option '%0' in '%1'">, InGroup<BranchProtection>;
def err_sls_hardening_arm_not_supported : Error<
"-mharden-sls is only supported on armv7-a or later">;
+def warn_drv_large_data_threshold_invalid_code_model: Warning<
+ "'%0' only applies to medium and large code models">,
+ InGroup<UnusedCommandLineArgument>;
def note_drv_command_failed_diag_msg : Note<
"diagnostic msg: %0">;
def note_drv_t_option_is_global : Note<
- "The last /TC or /TP option takes precedence over earlier instances">;
+ "the last '/TC' or '/TP' option takes precedence over earlier instances">;
def note_drv_address_sanitizer_debug_runtime : Note<
"AddressSanitizer doesn't support linking with debug runtime libraries yet">;
def note_drv_use_standard : Note<"use '%0'"
@@ -387,12 +500,25 @@ def err_analyzer_checker_option_invalid_input : Error<
"invalid input for checker option '%0', that expects %1">;
def err_analyzer_checker_incompatible_analyzer_option : Error<
"checker cannot be enabled with analyzer option '%0' == %1">;
-
-def err_drv_invalid_hvx_length : Error<
- "-mhvx-length is not supported without a -mhvx/-mhvx= flag">;
-def warn_drv_vectorize_needs_hvx : Warning<
- "auto-vectorization requires HVX, use -mhvx to enable it">,
+def err_analyzer_not_built_with_z3 : Error<
+ "analyzer constraint manager 'z3' is only available if LLVM was built with "
+ "-DLLVM_ENABLE_Z3_SOLVER=ON">;
+def warn_analyzer_deprecated_option : Warning<
+ "analyzer option '%0' is deprecated. This flag will be removed in %1, and "
+ "passing this option will be an error.">,
+ InGroup<DeprecatedStaticAnalyzerFlag>;
+def warn_analyzer_deprecated_option_with_alternative : Warning<
+ "analyzer option '%0' is deprecated. This flag will be removed in %1, and "
+ "passing this option will be an error. Use '%2' instead.">,
+ InGroup<DeprecatedStaticAnalyzerFlag>;
+
+def warn_drv_needs_hvx : Warning<
+ "%0 requires HVX, use -mhvx/-mhvx= to enable it">,
InGroup<OptionIgnored>;
+def err_drv_needs_hvx : Error<
+ "%0 requires HVX, use -mhvx/-mhvx= to enable it">;
+def err_drv_needs_hvx_version : Error<
+ "%0 is not supported on HVX %1">;
def err_drv_module_header_wrong_kind : Error<
"header file '%0' input type '%1' does not match type of prior input "
@@ -405,9 +531,21 @@ def err_test_module_file_extension_format : Error<
"-ftest-module-file-extension argument '%0' is not of the required form "
"'blockname:major:minor:hashed:user info'">;
+def err_drv_module_output_with_multiple_arch : Error<
+ "option '-fmodule-output' can't be used with multiple arch options">;
+
+def warn_drv_delayed_template_parsing_after_cxx20 : Warning<
+ "-fdelayed-template-parsing is deprecated after C++20">,
+ InGroup<DiagGroup<"delayed-template-parsing-in-cxx20">>;
+
+def err_drv_extract_api_wrong_kind : Error<
+ "header file '%0' input '%1' does not match the type of prior input "
+ "in api extraction; use '-x %2' to override">;
+
def warn_slash_u_filename : Warning<"'/U%0' treated as the '/U' option">,
InGroup<DiagGroup<"slash-u-filename">>;
-def note_use_dashdash : Note<"Use '--' to treat subsequent arguments as filenames">;
+def note_use_dashdash : Note<
+ "use '--' to treat subsequent arguments as filenames">;
def err_drv_ropi_rwpi_incompatible_with_pic : Error<
"embedded and GOT-based position independence are incompatible">;
@@ -415,7 +553,8 @@ def err_drv_ropi_incompatible_with_cxx : Error<
"ROPI is not compatible with c++">;
def err_stack_tagging_requires_hardware_feature : Error<
- "'-fsanitize=memtag' requires hardware support (+memtag)">;
+ "'-fsanitize=memtag-stack' requires hardware support (+memtag). For Armv8 or "
+ "Armv9, try compiling with -march=armv8a+memtag or -march=armv9a+memtag">;
def err_cmse_pi_are_incompatible : Error<
"cmse is not compatible with %select{RWPI|ROPI}0">;
@@ -463,27 +602,22 @@ def err_drv_unsupported_fpatchable_function_entry_argument : Error<
"the second argument of '-fpatchable-function-entry' must be smaller than the first argument">;
def warn_drv_unable_to_find_directory_expected : Warning<
- "unable to find %0 directory, expected to be in '%1'">,
+ "unable to find %0 directory, expected to be in '%1' found via %2">,
InGroup<InvalidOrNonExistentDirectory>, DefaultIgnore;
-def warn_drv_ps4_force_pic : Warning<
- "option '%0' was ignored by the PS4 toolchain, using '-fPIC'">,
+def warn_drv_ps_force_pic : Warning<
+ "option '%0' was ignored by the %1 toolchain, using '-fPIC'">,
InGroup<OptionIgnored>;
-def warn_drv_ps4_sdk_dir : Warning<
- "environment variable SCE_ORBIS_SDK_DIR is set, but points to invalid or nonexistent directory '%0'">,
- InGroup<InvalidOrNonExistentDirectory>;
-
-def err_drv_unsupported_linker : Error<"unsupported value '%0' for -linker option">;
def err_drv_defsym_invalid_format : Error<"defsym must be of the form: sym=value: %0">;
-def err_drv_defsym_invalid_symval : Error<"Value is not an integer: %0">;
+def err_drv_defsym_invalid_symval : Error<"value is not an integer: %0">;
def warn_drv_msvc_not_found : Warning<
"unable to find a Visual Studio installation; "
"try running Clang from a developer command prompt">,
InGroup<DiagGroup<"msvc-not-found">>;
def warn_drv_fuse_ld_path : Warning<
- "'-fuse-ld=' taking a path is deprecated. Use '--ld-path=' instead">,
+ "'-fuse-ld=' taking a path is deprecated; use '--ld-path=' instead">,
InGroup<FUseLdPath>, DefaultIgnore;
def warn_drv_fine_grained_bitfield_accesses_ignored : Warning<
@@ -503,37 +637,45 @@ def warn_drv_global_isel_incomplete_opt : Warning<
InGroup<GlobalISel>;
def warn_drv_moutline_unsupported_opt : Warning<
- "The '%0' architecture does not support -moutline; flag ignored">,
+ "'%0' does not support '-moutline'; flag ignored">,
InGroup<OptionIgnored>;
def warn_drv_moutline_atomics_unsupported_opt : Warning<
- "The '%0' architecture does not support -moutline-atomics; flag ignored">,
+ "'%0' does not support '-%1'; flag ignored">,
InGroup<OptionIgnored>;
def warn_drv_darwin_sdk_invalid_settings : Warning<
"SDK settings were ignored as 'SDKSettings.json' could not be parsed">,
InGroup<DiagGroup<"darwin-sdk-settings">>;
-def err_drv_trivial_auto_var_init_zero_disabled : Error<
- "-ftrivial-auto-var-init=zero hasn't been enabled. Enable it at your own peril for benchmarking purpose only with "
- "-enable-trivial-auto-var-init-zero-knowing-it-will-be-removed-from-clang">;
+def err_drv_darwin_sdk_missing_arclite : Error<
+ "SDK does not contain 'libarclite' at the path '%0'; try increasing the minimum deployment target">;
def err_drv_trivial_auto_var_init_stop_after_missing_dependency : Error<
- "-ftrivial-auto-var-init-stop-after=* is used without -ftrivial-auto-var-init=zero or -ftrivial-auto-var-init=pattern.">;
+ "'-ftrivial-auto-var-init-stop-after=*' is used without "
+ "'-ftrivial-auto-var-init=zero' or '-ftrivial-auto-var-init=pattern'">;
def err_drv_trivial_auto_var_init_stop_after_invalid_value : Error<
- "-ftrivial-auto-var-init-stop-after=* only accepts positive integers.">;
+ "'-ftrivial-auto-var-init-stop-after=*' only accepts positive integers">;
-def warn_drv_msp430_hwmult_unsupported : Warning<"the given MCU does not "
- "support hardware multiply, but -mhwmult is set to %0.">,
- InGroup<InvalidCommandLineArgument>;
-def warn_drv_msp430_hwmult_mismatch : Warning<"the given MCU supports %0 "
- "hardware multiply, but -mhwmult is set to %1.">,
+def err_drv_trivial_auto_var_init_max_size_missing_dependency : Error<
+ "'-ftrivial-auto-var-init-max-size=*' is used without "
+ "'-ftrivial-auto-var-init=zero' or '-ftrivial-auto-var-init=pattern'">;
+
+def err_drv_trivial_auto_var_init_max_size_invalid_value : Error<
+ "'-ftrivial-auto-var-init-max-size=*' only accepts positive integers (in bytes)">;
+
+def warn_drv_msp430_hwmult_unsupported : Warning<
+ "the given MCU does not support hardware multiply, but '-mhwmult' is set to "
+ "%0">, InGroup<InvalidCommandLineArgument>;
+def warn_drv_msp430_hwmult_mismatch : Warning<
+ "the given MCU supports %0 hardware multiply, but '-mhwmult' is set to %1">,
InGroup<InvalidCommandLineArgument>;
-def warn_drv_msp430_hwmult_no_device : Warning<"no MCU device specified, but "
- "'-mhwmult' is set to 'auto', assuming no hardware multiply. Use -mmcu to "
- "specify a MSP430 device, or -mhwmult to set hardware multiply type "
- "explicitly.">, InGroup<InvalidCommandLineArgument>;
+def warn_drv_msp430_hwmult_no_device : Warning<
+ "no MCU device specified, but '-mhwmult' is set to 'auto', assuming no "
+ "hardware multiply; use '-mmcu' to specify an MSP430 device, or '-mhwmult' "
+ "to set the hardware multiply type explicitly">,
+ InGroup<InvalidCommandLineArgument>;
def warn_drv_libstdcxx_not_found : Warning<
"include path for libstdc++ headers not found; pass '-stdlib=libc++' on the "
@@ -542,17 +684,118 @@ def warn_drv_libstdcxx_not_found : Warning<
def err_drv_cannot_mix_options : Error<"cannot specify '%1' along with '%0'">;
-def err_drv_invalid_object_mode : Error<"OBJECT_MODE setting %0 is not recognized and is not a valid setting.">;
+def err_drv_invalid_object_mode : Error<
+ "OBJECT_MODE setting %0 is not recognized and is not a valid setting">;
def err_aix_unsupported_tls_model : Error<"TLS model '%0' is not yet supported on AIX">;
+def err_roptr_requires_data_sections: Error<"-mxcoff-roptr is supported only with -fdata-sections">;
+def err_roptr_cannot_build_shared: Error<"-mxcoff-roptr is not supported with -shared">;
-def err_invalid_cxx_abi : Error<"Invalid C++ ABI name '%0'">;
+def err_invalid_cxx_abi : Error<"invalid C++ ABI name '%0'">;
def err_unsupported_cxx_abi : Error<"C++ ABI '%0' is not supported on target triple '%1'">;
-def note_cc1_round_trip_original : Note<"Original arguments in round-trip: %0">;
-def note_cc1_round_trip_generated : Note<"Generated arguments #%0 in round-trip: %1">;
-def remark_cc1_round_trip_generated : Remark<"Generated arguments #%0 in round-trip: %1">, InGroup<RoundTripCC1Args>;
-def err_cc1_round_trip_fail_then_ok : Error<"Original arguments parse failed, then succeeded in round-trip">;
-def err_cc1_round_trip_ok_then_fail : Error<"Generated arguments parse failed in round-trip">;
-def err_cc1_round_trip_mismatch : Error<"Generated arguments do not match in round-trip">;
+def note_cc1_round_trip_original : Note<"original arguments in round-trip: %0">;
+def note_cc1_round_trip_generated : Note<
+ "generated arguments #%0 in round-trip: %1">;
+def remark_cc1_round_trip_generated : Remark<
+ "generated arguments #%0 in round-trip: %1">, InGroup<RoundTripCC1Args>;
+def err_cc1_round_trip_fail_then_ok : Error<
+ "original arguments parse failed, then succeeded in round-trip">;
+def err_cc1_round_trip_ok_then_fail : Error<
+ "generated arguments parse failed in round-trip">;
+def err_cc1_round_trip_mismatch : Error<
+ "generated arguments do not match in round-trip">;
+def err_cc1_unbounded_vscale_min : Error<
+ "minimum vscale must be an unsigned integer greater than 0">;
+
+def err_drv_using_omit_rtti_component_without_no_rtti : Error<
+ "-fexperimental-omit-vtable-rtti call only be used with -fno-rtti">;
+
+def err_drv_ssp_missing_offset_argument : Error<
+ "'%0' is used without '-mstack-protector-guard-offset', and there is no default">;
+
+def err_drv_only_one_offload_target_supported : Error<
+ "only one offload target is supported">;
+def err_drv_invalid_or_unsupported_offload_target : Error<
+ "invalid or unsupported offload target: '%0'">;
+def err_drv_cuda_offload_only_emit_bc : Error<
+ "CUDA offload target is supported only along with --emit-llvm">;
+
+def warn_drv_jmc_requires_debuginfo : Warning<
+ "%0 requires debug info. Use %1 or debug options that enable debugger's "
+ "stepping function; option ignored">,
+ InGroup<OptionIgnored>;
+
+def warn_drv_fjmc_for_elf_only : Warning<
+ "-fjmc works only for ELF; option ignored">,
+ InGroup<OptionIgnored>;
+
+def warn_target_override_arm64ec : Warning<
+ "/arm64EC has been overridden by specified target: %0; option ignored">,
+ InGroup<OptionIgnored>;
+
+def err_drv_target_variant_invalid : Error<
+ "unsupported '%0' value '%1'; use 'ios-macabi' instead">;
+
+def err_drv_invalid_directx_shader_module : Error<
+ "invalid profile : %0">;
+def err_drv_dxc_missing_target_profile : Error<
+ "target profile option (-T) is missing">;
+def err_drv_hlsl_unsupported_target : Error<
+ "HLSL code generation is unsupported for target '%0'">;
+def err_drv_hlsl_bad_shader_required_in_target : Error<
+ "%select{shader model|Vulkan environment|shader stage}0 is required as %select{OS|environment}1 in target '%2' for HLSL code generation">;
+
+def err_drv_hlsl_bad_shader_unsupported : Error<
+ "%select{shader model|Vulkan environment|shader stage}0 '%1' in target '%2' is invalid for HLSL code generation">;
+def warn_drv_dxc_missing_dxv : Warning<"dxv not found. "
+ "Resulting DXIL will not be validated or signed for use in release environments.">,
+ InGroup<DXILValidation>;
+
+def err_drv_invalid_range_dxil_validator_version : Error<
+ "invalid validator version : %0\n"
+ "Validator version must be less than or equal to current internal version.">;
+def err_drv_invalid_format_dxil_validator_version : Error<
+ "invalid validator version : %0\n"
+ "Format of validator version is \"<major>.<minor>\" (ex:\"1.4\").">;
+def err_drv_invalid_empty_dxil_validator_version : Error<
+ "invalid validator version : %0\n"
+ "If validator major version is 0, minor version must also be 0.">;
+
+def warn_drv_sarif_format_unstable : Warning<
+ "diagnostic formatting in SARIF mode is currently unstable">,
+ InGroup<DiagGroup<"sarif-format-unstable">>;
+
+def err_drv_riscv_unsupported_with_linker_relaxation : Error<
+ "%0 is unsupported with RISC-V linker relaxation (-mrelax)">;
+
+def warn_drv_loongarch_conflicting_implied_val : Warning<
+ "ignoring '%0' as it conflicts with that implied by '%1' (%2)">,
+ InGroup<OptionIgnored>;
+def err_drv_loongarch_invalid_mfpu_EQ : Error<
+ "invalid argument '%0' to -mfpu=; must be one of: 64, 32, none, 0 (alias for none)">;
+def err_drv_loongarch_wrong_fpu_width_for_lsx : Error<
+ "wrong fpu width; LSX depends on 64-bit FPU.">;
+def err_drv_loongarch_wrong_fpu_width_for_lasx : Error<
+ "wrong fpu width; LASX depends on 64-bit FPU.">;
+def err_drv_loongarch_invalid_simd_option_combination : Error<
+ "invalid option combination; LASX depends on LSX.">;
+
+def err_drv_expand_response_file : Error<
+ "failed to expand response file: %0">;
+
+def warn_drv_missing_multilib : Warning<
+ "no multilib found matching flags: %0">,
+ InGroup<DiagGroup<"missing-multilib">>;
+def note_drv_available_multilibs : Note<
+ "available multilibs are:%0">;
+
+def warn_android_unversioned_fallback : Warning<
+ "Using unversioned Android target directory %0 for target %1. Unversioned"
+ " directories will not be used in Clang 19. Provide a versioned directory"
+ " for the target version or lower instead.">,
+ InGroup<DiagGroup<"android-unversioned-fallback">>;
+
+def err_drv_triple_version_invalid : Error<
+ "version '%0' in target triple '%1' is invalid">;
}
diff --git a/contrib/llvm-project/clang/include/clang/Basic/DiagnosticError.h b/contrib/llvm-project/clang/include/clang/Basic/DiagnosticError.h
index 430da6f724ed..744f7fe19db7 100644
--- a/contrib/llvm-project/clang/include/clang/Basic/DiagnosticError.h
+++ b/contrib/llvm-project/clang/include/clang/Basic/DiagnosticError.h
@@ -6,11 +6,12 @@
//
//===----------------------------------------------------------------------===//
-#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"
+#include <optional>
namespace clang {
@@ -34,10 +35,10 @@ public:
}
/// Extracts and returns the diagnostic payload from the given \c Error if
- /// the error is a \c DiagnosticError. Returns none if the given error is not
- /// a \c DiagnosticError.
- static Optional<PartialDiagnosticAt> take(llvm::Error &Err) {
- Optional<PartialDiagnosticAt> Result;
+ /// the error is a \c DiagnosticError. Returns std::nullopt if the given error
+ /// is not a \c DiagnosticError.
+ static std::optional<PartialDiagnosticAt> take(llvm::Error &Err) {
+ std::optional<PartialDiagnosticAt> Result;
Err = llvm::handleErrors(std::move(Err), [&](DiagnosticError &E) {
Result = std::move(E.getDiagnostic());
});
@@ -57,4 +58,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/DiagnosticFrontendKinds.td b/contrib/llvm-project/clang/include/clang/Basic/DiagnosticFrontendKinds.td
index 0f4ccec38550..85ecfdf9de62 100644
--- a/contrib/llvm-project/clang/include/clang/Basic/DiagnosticFrontendKinds.td
+++ b/contrib/llvm-project/clang/include/clang/Basic/DiagnosticFrontendKinds.td
@@ -11,7 +11,7 @@ class BackendInfo : CatBackend, ShowInSystemHeader;
let Component = "Frontend" in {
def err_fe_error_opening : Error<"error opening '%0': %1">;
-def err_fe_error_reading : Error<"error reading '%0'">;
+def err_fe_error_reading : Error<"error reading '%0': %1">;
def err_fe_error_reading_stdin : Error<"error reading stdin: %0">;
def err_fe_error_backend : Error<"error in backend: %0">, DefaultFatal;
@@ -22,10 +22,11 @@ def note_fe_inline_asm_here : Note<"instantiated into assembly here">;
def err_fe_source_mgr : Error<"%0">, CatSourceMgr;
def warn_fe_source_mgr : Warning<"%0">, CatSourceMgr, InGroup<BackendSourceMgr>;
def note_fe_source_mgr : Note<"%0">, CatSourceMgr;
-def err_fe_cannot_link_module : Error<"cannot link module '%0': %1">,
- DefaultFatal;
+def err_fe_linking_module : Error<"cannot link module '%0': %1">, DefaultFatal;
+def warn_fe_linking_module : Warning<"linking module '%0': %1">, InGroup<LinkerWarnings>;
+def note_fe_linking_module : Note<"linking module '%0': %1">;
-def warn_fe_frame_larger_than : Warning<"stack frame size (%0) exceeds limit (%1) in %q2">,
+def warn_fe_frame_larger_than : Warning<"stack frame size (%0) exceeds limit (%1) in '%2'">,
BackendInfo, InGroup<BackendFrameLargerThan>;
def warn_fe_backend_frame_larger_than: Warning<"%0">,
BackendInfo, InGroup<BackendFrameLargerThan>;
@@ -34,6 +35,11 @@ def note_fe_backend_frame_larger_than: Note<"%0">, BackendInfo;
def warn_fe_backend_plugin: Warning<"%0">, BackendInfo, InGroup<BackendPlugin>;
def err_fe_backend_plugin: Error<"%0">, BackendInfo;
+
+def warn_fe_backend_resource_limit: Warning<"%0 (%1) exceeds limit (%2) in '%3'">, BackendInfo, InGroup<BackendPlugin>;
+def err_fe_backend_resource_limit: Error<"%0 (%1) exceeds limit (%2) in '%3'">, BackendInfo;
+def note_fe_backend_resource_limit: Note<"%0 (%1) exceeds limit (%2) in '%3'">, BackendInfo;
+
def remark_fe_backend_plugin: Remark<"%0">, BackendInfo, InGroup<RemarkBackendPlugin>;
def note_fe_backend_plugin: Note<"%0">, BackendInfo;
@@ -46,6 +52,16 @@ def warn_fe_backend_unsupported_fp_rounding : Warning<
def warn_fe_backend_unsupported_fp_exceptions : Warning<
"overriding currently unsupported use of floating point exceptions "
"on this target">, InGroup<UnsupportedFPOpt>;
+def warn_fe_backend_invalid_feature_flag : Warning<
+ "feature flag '%0' must start with either '+' to enable the feature or '-'"
+ " to disable it; flag ignored">, InGroup<InvalidCommandLineArgument>;
+def warn_fe_backend_readonly_feature_flag : Warning<
+ "feature flag '%0' is ignored since the feature is read only">,
+ InGroup<InvalidCommandLineArgument>;
+
+def err_incompatible_fp_eval_method_options : Error<
+ "option 'ffp-eval-method' cannot be used with option "
+ "%select{'fapprox-func'|'mreassociate'|'freciprocal'}0">;
def remark_fe_backend_optimization_remark : Remark<"%0">, BackendInfo,
InGroup<BackendOptimizationRemark>;
@@ -64,6 +80,7 @@ def remark_fe_backend_optimization_remark_analysis_aliasing : Remark<"%0; "
"the '__restrict__' qualifier with the independent array arguments. "
"Erroneous results will occur if these options are incorrectly applied!">,
BackendInfo, InGroup<BackendOptimizationRemarkAnalysis>;
+
def warn_fe_backend_optimization_failure : Warning<"%0">, BackendInfo,
InGroup<BackendOptimizationFailure>, DefaultWarn;
def note_fe_backend_invalid_loc : Note<"could "
@@ -72,6 +89,12 @@ def note_fe_backend_invalid_loc : Note<"could "
def err_fe_backend_unsupported : Error<"%0">, BackendInfo;
def warn_fe_backend_unsupported : Warning<"%0">, BackendInfo;
+def err_fe_backend_error_attr :
+ Error<"call to '%0' declared with 'error' attribute: %1">, BackendInfo;
+def warn_fe_backend_warning_attr :
+ Warning<"call to '%0' declared with 'warning' attribute: %1">, BackendInfo,
+ InGroup<BackendWarningAttributes>;
+
def err_fe_invalid_code_complete_file : Error<
"cannot locate code-completion file %0">, DefaultFatal;
def err_fe_dependency_file_requires_MT : Error<
@@ -113,9 +136,8 @@ def err_fe_invalid_alignment : Error<
"invalid value '%1' in '%0'; alignment must be a power of 2">;
def err_fe_invalid_exception_model
: Error<"invalid exception model '%select{none|sjlj|seh|dwarf|wasm}0' for target '%1'">;
-def warn_fe_concepts_ts_flag : Warning<
- "-fconcepts-ts is deprecated - use '-std=c++20' for Concepts support">,
- InGroup<Deprecated>;
+def err_fe_invalid_source_date_epoch : Error<
+ "environment variable 'SOURCE_DATE_EPOCH' ('%0') must be a non-negative decimal integer <= %1">;
def err_fe_unable_to_load_basic_block_sections_file : Error<
"unable to load basic block sections function list: '%0'">;
@@ -145,7 +167,7 @@ def err_verify_no_such_marker : Error<
def err_verify_missing_start : Error<
"cannot find start ('{{') of expected %0">;
def err_verify_missing_end : Error<
- "cannot find end ('}}') of expected %0">;
+ "cannot find end ('%1') of expected %0">;
def err_verify_invalid_content : Error<
"invalid expected %0: %1">;
def err_verify_missing_regex : Error<
@@ -191,10 +213,7 @@ def note_incompatible_analyzer_plugin_api : Note<
def err_module_build_requires_fmodules : Error<
"module compilation requires '-fmodules'">;
def err_module_interface_requires_cpp_modules : Error<
- "module interface compilation requires '-std=c++20' or '-fmodules-ts'">;
-def err_header_module_requires_modules : Error<
- "header module compilation requires '-fmodules', '-std=c++20', or "
- "'-fmodules-ts'">;
+ "module interface compilation requires '-std=c++20'">;
def warn_module_config_mismatch : Warning<
"module file %0 cannot be loaded due to a configuration mismatch with the current "
"compilation">, InGroup<DiagGroup<"module-file-config-mismatch">>, DefaultError;
@@ -226,9 +245,13 @@ def warn_module_config_macro_undef : Warning<
def note_module_def_undef_here : Note<
"macro was %select{defined|#undef'd}0 here">;
def remark_module_build : Remark<"building module '%0' as '%1'">,
+ ShowInSystemHeader,
InGroup<ModuleBuild>;
def remark_module_build_done : Remark<"finished building module '%0'">,
+ ShowInSystemHeader,
InGroup<ModuleBuild>;
+def remark_module_lock : Remark<"locking '%0' to build module '%1'">,
+ InGroup<ModuleLock>;
def err_modules_embed_file_not_found :
Error<"file '%0' specified by '-fmodules-embed-file=' not found">,
DefaultFatal;
@@ -239,13 +262,18 @@ def err_test_module_file_extension_version : Error<
"test module file extension '%0' has different version (%1.%2) than expected "
"(%3.%4)">;
+def warn_eagerly_load_for_standard_cplusplus_modules : Warning<
+ "the form '-fmodule-file=<BMI-path>' is deprecated for standard C++ named modules;"
+ "consider to use '-fmodule-file=<module-name>=<BMI-path>' instead">,
+ InGroup<DiagGroup<"eager-load-cxx-named-modules">>;
+
def err_missing_vfs_overlay_file : Error<
"virtual filesystem overlay file '%0' not found">, DefaultFatal;
def err_invalid_vfs_overlay : Error<
"invalid virtual filesystem overlay file '%0'">, DefaultFatal;
def warn_option_invalid_ocl_version : Warning<
- "OpenCL version %0 does not support the option '%1'">, InGroup<Deprecated>;
+ "%0 does not support the option '%1'">, InGroup<Deprecated>;
def err_builtin_needs_feature : Error<"%0 needs target feature %1">;
def err_function_needs_feature : Error<
@@ -256,11 +284,17 @@ def warn_avx_calling_convention
: Warning<"AVX vector %select{return|argument}0 of type %1 without '%2' "
"enabled changes the ABI">,
InGroup<DiagGroup<"psabi">>;
-def err_avx_calling_convention : Error<warn_avx_calling_convention.Text>;
+def err_avx_calling_convention : Error<warn_avx_calling_convention.Summary>;
def err_alias_to_undefined : Error<
"%select{alias|ifunc}0 must point to a defined "
"%select{variable or |}1function">;
+def err_alias_to_common : Error<
+ "alias to a variable in a common section is not allowed">;
+def note_alias_requires_mangled_name : Note<
+ "the %select{function or variable|function}0 specified in an %select{alias|ifunc}1 must refer to its mangled name">;
+def note_alias_mangled_name_alternative: Note<
+ "function by that name is mangled as \"%0\"">;
def warn_alias_to_weak_alias : Warning<
"%select{alias|ifunc}2 will always resolve to %0 even if weak definition of "
"%1 is overridden">,
@@ -269,6 +303,10 @@ def err_duplicate_mangled_name : Error<
"definition with same mangled name '%0' as another definition">;
def err_cyclic_alias : Error<
"%select{alias|ifunc}0 definition is part of a cycle">;
+def err_hidden_visibility_dllexport : Error<
+ "hidden visibility cannot be applied to 'dllexport' declaration">;
+def err_non_default_visibility_dllimport : Error<
+ "non-default visibility cannot be applied to 'dllimport' declaration">;
def err_ifunc_resolver_return : Error<
"ifunc resolver function must return a pointer">;
@@ -284,6 +322,10 @@ def warn_atomic_op_oversized : Warning<
"; the access size (%0 bytes) exceeds the max lock-free size (%1 bytes)">,
InGroup<AtomicAlignment>;
+def warn_sync_op_misaligned : Warning<
+ "__sync builtin operation MUST have natural alignment (consider using __atomic).">,
+ InGroup<SyncAlignment>;
+
def warn_alias_with_section : Warning<
"%select{alias|ifunc}1 will not be in section '%0' but in the same section "
"as the %select{aliasee|resolver}2">,
@@ -302,6 +344,14 @@ def warn_profile_data_missing : Warning<
def warn_profile_data_unprofiled : Warning<
"no profile data available for file \"%0\"">,
InGroup<ProfileInstrUnprofiled>;
+def warn_profile_data_misexpect : Warning<
+ "Potential performance regression from use of __builtin_expect(): "
+ "Annotation was correct on %0 of profiled executions.">,
+ BackendInfo,
+ InGroup<MisExpect>;
} // end of instrumentation issue category
+def err_extract_api_ignores_file_not_found :
+ Error<"file '%0' specified by '--extract-api-ignores=' not found">, DefaultFatal;
+
}
diff --git a/contrib/llvm-project/clang/include/clang/Basic/DiagnosticGroups.td b/contrib/llvm-project/clang/include/clang/Basic/DiagnosticGroups.td
index 4b4928a7a00e..6765721ae700 100644
--- a/contrib/llvm-project/clang/include/clang/Basic/DiagnosticGroups.td
+++ b/contrib/llvm-project/clang/include/clang/Basic/DiagnosticGroups.td
@@ -15,9 +15,12 @@ def Implicit : DiagGroup<"implicit", [
ImplicitInt
]>;
+def DeprecatedStaticAnalyzerFlag : DiagGroup<"deprecated-static-analyzer-flag">;
+
// Empty DiagGroups are recognized by clang but ignored.
def ODR : DiagGroup<"odr">;
def : DiagGroup<"abi">;
+def : DiagGroup<"gnu-empty-initializer">; // Now a C extension, not GNU.
def AbsoluteValue : DiagGroup<"absolute-value">;
def MisspelledAssumption : DiagGroup<"misspelled-assumption">;
def UnknownAssumption : DiagGroup<"unknown-assumption">;
@@ -29,13 +32,15 @@ def GNUAnonymousStruct : DiagGroup<"gnu-anonymous-struct">;
def GNUAutoType : DiagGroup<"gnu-auto-type">;
def ArrayBounds : DiagGroup<"array-bounds">;
def ArrayBoundsPointerArithmetic : DiagGroup<"array-bounds-pointer-arithmetic">;
+def ArrayParameter : DiagGroup<"array-parameter">;
def AutoDisableVptrSanitizer : DiagGroup<"auto-disable-vptr-sanitizer">;
def Availability : DiagGroup<"availability">;
def Section : DiagGroup<"section">;
-def AutoImport : DiagGroup<"auto-import">;
+def : DiagGroup<"auto-import">;
def FrameworkHdrQuotedInclude : DiagGroup<"quoted-include-in-framework-header">;
def FrameworkIncludePrivateFromPublic :
DiagGroup<"framework-include-private-from-public">;
+def DeprecatedModuleDotMap : DiagGroup<"deprecated-module-dot-map">;
def FrameworkHdrAtImport : DiagGroup<"atimport-in-framework-header">;
def CXX14BinaryLiteral : DiagGroup<"c++14-binary-literal">;
def CXXPre14CompatBinaryLiteral : DiagGroup<"c++98-c++11-compat-binary-literal">;
@@ -44,7 +49,10 @@ def BinaryLiteral : DiagGroup<"binary-literal", [CXX14BinaryLiteral,
CXXPre14CompatBinaryLiteral,
GNUBinaryLiteral]>;
def GNUCompoundLiteralInitializer : DiagGroup<"gnu-compound-literal-initializer">;
-def BitFieldConstantConversion : DiagGroup<"bitfield-constant-conversion">;
+def SingleBitBitFieldConstantConversion :
+ DiagGroup<"single-bit-bitfield-constant-conversion">;
+def BitFieldConstantConversion : DiagGroup<"bitfield-constant-conversion",
+ [SingleBitBitFieldConstantConversion]>;
def BitFieldEnumConversion : DiagGroup<"bitfield-enum-conversion">;
def BitFieldWidth : DiagGroup<"bitfield-width">;
def CompoundTokenSplitByMacro : DiagGroup<"compound-token-split-by-macro">;
@@ -54,7 +62,14 @@ def CompoundTokenSplit : DiagGroup<"compound-token-split",
CompoundTokenSplitBySpace]>;
def CoroutineMissingUnhandledException :
DiagGroup<"coroutine-missing-unhandled-exception">;
-def Coroutine : DiagGroup<"coroutine", [CoroutineMissingUnhandledException]>;
+def DeprecatedCoroutine :
+ DiagGroup<"deprecated-coroutine">;
+def AlwaysInlineCoroutine :
+ DiagGroup<"always-inline-coroutine">;
+def CoroNonAlignedAllocationFunction :
+ DiagGroup<"coro-non-aligned-allocation-function">;
+def Coroutine : DiagGroup<"coroutine", [CoroutineMissingUnhandledException, DeprecatedCoroutine,
+ AlwaysInlineCoroutine, CoroNonAlignedAllocationFunction]>;
def ObjCBoolConstantConversion : DiagGroup<"objc-bool-constant-conversion">;
def ConstantConversion : DiagGroup<"constant-conversion",
[BitFieldConstantConversion,
@@ -64,6 +79,8 @@ def StringConversion : DiagGroup<"string-conversion">;
def SignConversion : DiagGroup<"sign-conversion">;
def PointerBoolConversion : DiagGroup<"pointer-bool-conversion">;
def UndefinedBoolConversion : DiagGroup<"undefined-bool-conversion">;
+def BitwiseInsteadOfLogical : DiagGroup<"bitwise-instead-of-logical">;
+def BoolOperation : DiagGroup<"bool-operation", [BitwiseInsteadOfLogical]>;
def BoolConversion : DiagGroup<"bool-conversion", [PointerBoolConversion,
UndefinedBoolConversion]>;
def IntConversion : DiagGroup<"int-conversion">;
@@ -128,6 +145,9 @@ def MacroRedefined : DiagGroup<"macro-redefined">;
def BuiltinMacroRedefined : DiagGroup<"builtin-macro-redefined">;
def BuiltinRequiresHeader : DiagGroup<"builtin-requires-header">;
def C99Compat : DiagGroup<"c99-compat">;
+def C23Compat : DiagGroup<"c23-compat">;
+def : DiagGroup<"c2x-compat", [C23Compat]>;
+
def CXXCompat: DiagGroup<"c++-compat">;
def ExternCCompat : DiagGroup<"extern-c-compat">;
def KeywordCompat : DiagGroup<"keyword-compat">;
@@ -155,6 +175,7 @@ def DeleteNonVirtualDtor : DiagGroup<"delete-non-virtual-dtor",
DeleteAbstractNonVirtualDtor]>;
def AbstractFinalClass : DiagGroup<"abstract-final-class">;
def FinalDtorNonFinalClass : DiagGroup<"final-dtor-non-final-class">;
+def GNUOffsetofExtensions : DiagGroup<"gnu-offsetof-extensions">;
def CXX11CompatDeprecatedWritableStr :
DiagGroup<"c++11-compat-deprecated-writable-strings">;
@@ -166,9 +187,11 @@ def DeprecatedCopyWithUserProvidedCopy : DiagGroup<"deprecated-copy-with-user-pr
def DeprecatedCopyWithUserProvidedDtor : DiagGroup<"deprecated-copy-with-user-provided-dtor">;
def DeprecatedCopy : DiagGroup<"deprecated-copy", [DeprecatedCopyWithUserProvidedCopy]>;
def DeprecatedCopyWithDtor : DiagGroup<"deprecated-copy-with-dtor", [DeprecatedCopyWithUserProvidedDtor]>;
+def DeprecatedLiteralOperator : DiagGroup<"deprecated-literal-operator">;
// For compatibility with GCC.
def : DiagGroup<"deprecated-copy-dtor", [DeprecatedCopyWithDtor]>;
def DeprecatedDeclarations : DiagGroup<"deprecated-declarations">;
+def DeprecatedRedundantConstexprStaticDef : DiagGroup<"deprecated-redundant-constexpr-static-def">;
def UnavailableDeclarations : DiagGroup<"unavailable-declarations">;
def UnguardedAvailabilityNew : DiagGroup<"unguarded-availability-new">;
def UnguardedAvailability : DiagGroup<"unguarded-availability",
@@ -177,6 +200,7 @@ def UnguardedAvailability : DiagGroup<"unguarded-availability",
def : DiagGroup<"partial-availability", [UnguardedAvailability]>;
def DeprecatedDynamicExceptionSpec
: DiagGroup<"deprecated-dynamic-exception-spec">;
+def DeprecatedBuiltins : DiagGroup<"deprecated-builtins">;
def DeprecatedImplementations :DiagGroup<"deprecated-implementations">;
def DeprecatedIncrementBool : DiagGroup<"deprecated-increment-bool">;
def DeprecatedRegister : DiagGroup<"deprecated-register">;
@@ -184,6 +208,8 @@ def DeprecatedThisCapture : DiagGroup<"deprecated-this-capture">;
def DeprecatedVolatile : DiagGroup<"deprecated-volatile">;
def DeprecatedWritableStr : DiagGroup<"deprecated-writable-strings",
[CXX11CompatDeprecatedWritableStr]>;
+def DeprecatedPragma : DiagGroup<"deprecated-pragma">;
+def DeprecatedType : DiagGroup<"deprecated-type">;
// FIXME: Why is DeprecatedImplementations not in this group?
def Deprecated : DiagGroup<"deprecated", [DeprecatedAnonEnumEnumConversion,
DeprecatedArrayCompare,
@@ -197,11 +223,17 @@ def Deprecated : DiagGroup<"deprecated", [DeprecatedAnonEnumEnumConversion,
DeprecatedEnumCompareConditional,
DeprecatedEnumEnumConversion,
DeprecatedEnumFloatConversion,
+ DeprecatedBuiltins,
DeprecatedIncrementBool,
+ DeprecatedLiteralOperator,
+ DeprecatedPragma,
DeprecatedRegister,
DeprecatedThisCapture,
+ DeprecatedType,
DeprecatedVolatile,
- DeprecatedWritableStr]>,
+ DeprecatedWritableStr,
+ DeprecatedRedundantConstexprStaticDef
+ ]>,
DiagCategory<"Deprecations">;
def CXX20Designator : DiagGroup<"c++20-designator">;
@@ -231,8 +263,8 @@ 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">;
def ExtraTokens : DiagGroup<"extra-tokens">;
def CXX98CompatExtraSemi : DiagGroup<"c++98-compat-extra-semi">;
@@ -258,9 +290,11 @@ def : DiagGroup<"c++1z-compat-mangling", [CXX17CompatMangling]>;
def NoexceptType : DiagGroup<"noexcept-type", [CXX17CompatMangling]>;
// Warnings for C code which is not compatible with previous C standards.
-def CPre2xCompat : DiagGroup<"pre-c2x-compat">;
-def CPre2xCompatPedantic : DiagGroup<"pre-c2x-compat-pedantic",
- [CPre2xCompat]>;
+def CPre23Compat : DiagGroup<"pre-c23-compat">;
+def CPre23CompatPedantic : DiagGroup<"pre-c23-compat-pedantic",
+ [CPre23Compat]>;
+def : DiagGroup<"pre-c2x-compat", [CPre23Compat]>;
+def : DiagGroup<"pre-c2x-compat-pedantic", [CPre23CompatPedantic]>;
// Warnings for C++ code which is not compatible with previous C++ standards.
def CXXPre14Compat : DiagGroup<"pre-c++14-compat">;
@@ -281,9 +315,14 @@ def CXXPre20CompatPedantic : DiagGroup<"pre-c++20-compat-pedantic",
[CXXPre20Compat]>;
def : DiagGroup<"c++98-c++11-c++14-c++17-compat-pedantic",
[CXXPre20CompatPedantic]>;
-def CXXPre2bCompat : DiagGroup<"pre-c++2b-compat">;
-def CXXPre2bCompatPedantic :
- DiagGroup<"pre-c++2b-compat-pedantic", [CXXPre2bCompat]>;
+def CXXPre23Compat : DiagGroup<"pre-c++23-compat">;
+def CXXPre23CompatPedantic :
+ DiagGroup<"pre-c++23-compat-pedantic", [CXXPre23Compat]>;
+def CXXPre26Compat : DiagGroup<"pre-c++26-compat">;
+def CXXPre26CompatPedantic :
+ DiagGroup<"pre-c++26-compat-pedantic", [CXXPre26Compat]>;
+def : DiagGroup<"pre-c++2c-compat", [CXXPre26Compat]>;
+def : DiagGroup<"pre-c++2c-compat-pedantic", [CXXPre26CompatPedantic]>;
def CXX98CompatBindToTemporaryCopy :
DiagGroup<"c++98-compat-bind-to-temporary-copy">;
@@ -298,7 +337,7 @@ def CXX98Compat : DiagGroup<"c++98-compat",
CXXPre14Compat,
CXXPre17Compat,
CXXPre20Compat,
- CXXPre2bCompat]>;
+ CXXPre23Compat]>;
// Warnings for C++11 features which are Extensions in C++98 mode.
def CXX98CompatPedantic : DiagGroup<"c++98-compat-pedantic",
[CXX98Compat,
@@ -307,9 +346,10 @@ def CXX98CompatPedantic : DiagGroup<"c++98-compat-pedantic",
CXXPre14CompatPedantic,
CXXPre17CompatPedantic,
CXXPre20CompatPedantic,
- CXXPre2bCompatPedantic]>;
+ CXXPre23CompatPedantic]>;
-def CXX11Narrowing : DiagGroup<"c++11-narrowing">;
+def CXX11NarrowingConstReference : DiagGroup<"c++11-narrowing-const-reference">;
+def CXX11Narrowing : DiagGroup<"c++11-narrowing", [CXX11NarrowingConstReference]>;
def CXX11WarnInconsistentOverrideDestructor :
DiagGroup<"inconsistent-missing-destructor-override">;
@@ -337,46 +377,50 @@ def CXX11Compat : DiagGroup<"c++11-compat",
CXXPre14Compat,
CXXPre17Compat,
CXXPre20Compat,
- CXXPre2bCompat]>;
+ CXXPre23Compat]>;
def : DiagGroup<"c++0x-compat", [CXX11Compat]>;
def CXX11CompatPedantic : DiagGroup<"c++11-compat-pedantic",
[CXX11Compat,
CXXPre14CompatPedantic,
CXXPre17CompatPedantic,
CXXPre20CompatPedantic,
- CXXPre2bCompatPedantic]>;
+ CXXPre23CompatPedantic]>;
def CXX14Compat : DiagGroup<"c++14-compat", [CXXPre17Compat,
CXXPre20Compat,
- CXXPre2bCompat]>;
+ CXXPre23Compat]>;
def CXX14CompatPedantic : DiagGroup<"c++14-compat-pedantic",
[CXX14Compat,
CXXPre17CompatPedantic,
CXXPre20CompatPedantic,
- CXXPre2bCompatPedantic]>;
+ CXXPre23CompatPedantic]>;
def CXX17Compat : DiagGroup<"c++17-compat", [DeprecatedRegister,
DeprecatedIncrementBool,
CXX17CompatMangling,
CXXPre20Compat,
- CXXPre2bCompat]>;
+ CXXPre23Compat]>;
def CXX17CompatPedantic : DiagGroup<"c++17-compat-pedantic",
[CXX17Compat,
CXXPre20CompatPedantic,
- CXXPre2bCompatPedantic]>;
+ CXXPre23CompatPedantic]>;
def : DiagGroup<"c++1z-compat", [CXX17Compat]>;
-def CXX20Compat : DiagGroup<"c++20-compat", [CXXPre2bCompat]>;
+def CXX20Compat : DiagGroup<"c++20-compat", [CXXPre23Compat]>;
def CXX20CompatPedantic : DiagGroup<"c++20-compat-pedantic",
[CXX20Compat,
- CXXPre2bCompatPedantic]>;
+ CXXPre23CompatPedantic]>;
def : DiagGroup<"c++2a-compat", [CXX20Compat]>;
def : DiagGroup<"c++2a-compat-pedantic", [CXX20CompatPedantic]>;
def ExitTimeDestructors : DiagGroup<"exit-time-destructors">;
def FlexibleArrayExtensions : DiagGroup<"flexible-array-extensions">;
def FourByteMultiChar : DiagGroup<"four-char-constants">;
-def GlobalConstructors : DiagGroup<"global-constructors">;
+def GlobalConstructors : DiagGroup<"global-constructors"> {
+ code Documentation = [{
+Emit a warning for each variable declaration that generates code run at startup.
+ }];
+}
def BitwiseConditionalParentheses: DiagGroup<"bitwise-conditional-parentheses">;
def BitwiseOpParentheses: DiagGroup<"bitwise-op-parentheses">;
def LogicalOpParentheses: DiagGroup<"logical-op-parentheses">;
@@ -388,11 +432,14 @@ def DanglingField : DiagGroup<"dangling-field">;
def DanglingInitializerList : DiagGroup<"dangling-initializer-list">;
def DanglingGsl : DiagGroup<"dangling-gsl">;
def ReturnStackAddress : DiagGroup<"return-stack-address">;
+// Name of this warning in GCC
+def : DiagGroup<"return-local-addr", [ReturnStackAddress]>;
def Dangling : DiagGroup<"dangling", [DanglingField,
DanglingInitializerList,
DanglingGsl,
ReturnStackAddress]>;
def DistributedObjectModifiers : DiagGroup<"distributed-object-modifiers">;
+def DllexportExplicitInstantiationDecl : DiagGroup<"dllexport-explicit-instantiation-decl">;
def ExcessInitializers : DiagGroup<"excess-initializers">;
def ExpansionToDefined : DiagGroup<"expansion-to-defined">;
def FlagEnum : DiagGroup<"flag-enum">;
@@ -400,10 +447,13 @@ def IncrementBool : DiagGroup<"increment-bool", [DeprecatedIncrementBool]>;
def InfiniteRecursion : DiagGroup<"infinite-recursion">;
def PureVirtualCallFromCtorDtor: DiagGroup<"call-to-pure-virtual-from-ctor-dtor">;
def GNUImaginaryConstant : DiagGroup<"gnu-imaginary-constant">;
-def IgnoredQualifiers : DiagGroup<"ignored-qualifiers">;
+def IgnoredGCH : DiagGroup<"ignored-gch">;
+def IgnoredReferenceQualifiers : DiagGroup<"ignored-reference-qualifiers">;
+def IgnoredQualifiers : DiagGroup<"ignored-qualifiers", [IgnoredReferenceQualifiers]>;
def : DiagGroup<"import">;
def GNUIncludeNext : DiagGroup<"gnu-include-next">;
def IncompatibleMSStruct : DiagGroup<"incompatible-ms-struct">;
+def IncompatibleMSPragmaSection : DiagGroup<"incompatible-ms-pragma-section">;
def IncompatiblePointerTypesDiscardsQualifiers
: DiagGroup<"incompatible-pointer-types-discards-qualifiers">;
def IncompatibleFunctionPointerTypes
@@ -429,10 +479,13 @@ def InlineNamespaceReopenedNoninline
def InvalidNoreturn : DiagGroup<"invalid-noreturn">;
def InvalidSourceEncoding : DiagGroup<"invalid-source-encoding">;
def KNRPromotedParameter : DiagGroup<"knr-promoted-parameter">;
+def DeprecatedNonPrototype : DiagGroup<"deprecated-non-prototype">;
+def StrictPrototypes : DiagGroup<"strict-prototypes", [DeprecatedNonPrototype]>;
def : DiagGroup<"init-self">;
def : DiagGroup<"inline">;
def : DiagGroup<"invalid-pch">;
def GNULabelsAsValue : DiagGroup<"gnu-label-as-value">;
+def GNULineMarker : DiagGroup<"gnu-line-marker">;
def LiteralRange : DiagGroup<"literal-range">;
def LocalTypeTemplateArgs : DiagGroup<"local-type-template-args",
[CXX98CompatLocalTypeTemplateArgs]>;
@@ -462,10 +515,12 @@ def MismatchedParameterTypes : DiagGroup<"mismatched-parameter-types">;
def MismatchedReturnTypes : DiagGroup<"mismatched-return-types">;
def MismatchedTags : DiagGroup<"mismatched-tags">;
def MissingFieldInitializers : DiagGroup<"missing-field-initializers">;
+def ModuleLock : DiagGroup<"module-lock">;
def ModuleBuild : DiagGroup<"module-build">;
def ModuleImport : DiagGroup<"module-import">;
def ModuleConflict : DiagGroup<"module-conflict">;
def ModuleFileExtension : DiagGroup<"module-file-extension">;
+def ModuleIncludeDirectiveTranslation : DiagGroup<"module-include-translation">;
def RoundTripCC1Args : DiagGroup<"round-trip-cc1-args">;
def NewlineEOF : DiagGroup<"newline-eof">;
def Nullability : DiagGroup<"nullability">;
@@ -486,7 +541,9 @@ def NonPODVarargs : DiagGroup<"non-pod-varargs">;
def ClassVarargs : DiagGroup<"class-varargs", [NonPODVarargs]>;
def : DiagGroup<"nonportable-cfstrings">;
def NonVirtualDtor : DiagGroup<"non-virtual-dtor">;
-def NullPointerArithmetic : DiagGroup<"null-pointer-arithmetic">;
+def GNUNullPointerArithmetic : DiagGroup<"gnu-null-pointer-arithmetic">;
+def NullPointerArithmetic
+ : DiagGroup<"null-pointer-arithmetic", [GNUNullPointerArithmetic]>;
def NullPointerSubtraction : DiagGroup<"null-pointer-subtraction">;
def : DiagGroup<"effc++", [NonVirtualDtor]>;
def OveralignedType : DiagGroup<"over-aligned">;
@@ -504,7 +561,8 @@ def PrivateExtern : DiagGroup<"private-extern">;
def SelTypeCast : DiagGroup<"cast-of-sel-type">;
def FunctionDefInObjCContainer : DiagGroup<"function-def-in-objc-container">;
def BadFunctionCast : DiagGroup<"bad-function-cast">;
-def CastFunctionType : DiagGroup<"cast-function-type">;
+def CastFunctionTypeStrict : DiagGroup<"cast-function-type-strict">;
+def CastFunctionType : DiagGroup<"cast-function-type", [CastFunctionTypeStrict]>;
def ObjCPropertyImpl : DiagGroup<"objc-property-implementation">;
def ObjCPropertyNoAttribute : DiagGroup<"objc-property-no-attribute">;
def ObjCPropertyAssignOnObjectType : DiagGroup<"objc-property-assign-on-object-type">;
@@ -527,13 +585,18 @@ def UnderalignedExceptionObject : DiagGroup<"underaligned-exception-object">;
def DeprecatedObjCIsaUsage : DiagGroup<"deprecated-objc-isa-usage">;
def ExplicitInitializeCall : DiagGroup<"explicit-initialize-call">;
def OrderedCompareFunctionPointers : DiagGroup<"ordered-compare-function-pointers">;
-def Packed : DiagGroup<"packed">;
-def Padded : DiagGroup<"padded">;
+def PackedNonPod : DiagGroup<"packed-non-pod">;
+def Packed : DiagGroup<"packed", [PackedNonPod]>;
+def PaddedBitField : DiagGroup<"padded-bitfield">;
+def Padded : DiagGroup<"padded", [PaddedBitField]>;
+def UnalignedAccess : DiagGroup<"unaligned-access">;
def PessimizingMove : DiagGroup<"pessimizing-move">;
def ReturnStdMove : DiagGroup<"return-std-move">;
-def PointerArith : DiagGroup<"pointer-arith">;
+def GNUPointerArith : DiagGroup<"gnu-pointer-arith">;
+def PointerArith : DiagGroup<"pointer-arith", [GNUPointerArith]>;
+
def PoundWarning : DiagGroup<"#warnings">;
def PoundPragmaMessage : DiagGroup<"#pragma-messages">,
DiagCategory<"#pragma message Directive">;
@@ -571,7 +634,7 @@ def ShadowAll : DiagGroup<"shadow-all", [Shadow, ShadowFieldInConstructor,
def Shorten64To32 : DiagGroup<"shorten-64-to-32">;
def : DiagGroup<"sign-promo">;
def SignCompare : DiagGroup<"sign-compare">;
-def : DiagGroup<"switch-default">;
+def SwitchDefault : DiagGroup<"switch-default">;
def : DiagGroup<"synth">;
def SizeofArrayArgument : DiagGroup<"sizeof-array-argument">;
def SizeofArrayDecay : DiagGroup<"sizeof-array-decay">;
@@ -587,7 +650,12 @@ def StaticInInline : DiagGroup<"static-in-inline">;
def StaticLocalInInline : DiagGroup<"static-local-in-inline">;
def GNUStaticFloatInit : DiagGroup<"gnu-static-float-init">;
def StaticFloatInit : DiagGroup<"static-float-init", [GNUStaticFloatInit]>;
-def GNUStatementExpression : DiagGroup<"gnu-statement-expression">;
+// Allow differentiation between GNU statement expressions in a macro versus
+// written directly in source.
+def GNUStatementExpressionFromMacroExpansion :
+ DiagGroup<"gnu-statement-expression-from-macro-expansion">;
+def GNUStatementExpression : DiagGroup<"gnu-statement-expression",
+ [GNUStatementExpressionFromMacroExpansion]>;
def StringConcatation : DiagGroup<"string-concatenation">;
def StringCompare : DiagGroup<"string-compare">;
def StringPlusInt : DiagGroup<"string-plus-int">;
@@ -618,13 +686,15 @@ def TautologicalOverlapCompare : DiagGroup<"tautological-overlap-compare">;
def TautologicalBitwiseCompare : DiagGroup<"tautological-bitwise-compare">;
def TautologicalUndefinedCompare : DiagGroup<"tautological-undefined-compare">;
def TautologicalObjCBoolCompare : DiagGroup<"tautological-objc-bool-compare">;
+def TautologicalNegationCompare : DiagGroup<"tautological-negation-compare">;
def TautologicalCompare : DiagGroup<"tautological-compare",
[TautologicalConstantCompare,
TautologicalPointerCompare,
TautologicalOverlapCompare,
TautologicalBitwiseCompare,
TautologicalUndefinedCompare,
- TautologicalObjCBoolCompare]>;
+ TautologicalObjCBoolCompare,
+ TautologicalNegationCompare]>;
def HeaderHygiene : DiagGroup<"header-hygiene">;
def DuplicateDeclSpecifier : DiagGroup<"duplicate-decl-specifier">;
def CompareDistinctPointerType : DiagGroup<"compare-distinct-pointer-types">;
@@ -642,6 +712,8 @@ def AmbiguousMacro : DiagGroup<"ambiguous-macro">;
def KeywordAsMacro : DiagGroup<"keyword-macro">;
def ReservedIdAsMacro : DiagGroup<"reserved-macro-identifier">;
def ReservedIdAsMacroAlias : DiagGroup<"reserved-id-macro", [ReservedIdAsMacro]>;
+def RestrictExpansionMacro : DiagGroup<"restrict-expansion">;
+def FinalMacro : DiagGroup<"final-macro">;
// Just silence warnings about -Wstrict-aliasing for now.
def : DiagGroup<"strict-aliasing=0">;
@@ -742,6 +814,7 @@ def UnusedLocalTypedef : DiagGroup<"unused-local-typedef">;
def UnusedPropertyIvar : DiagGroup<"unused-property-ivar">;
def UnusedGetterReturnValue : DiagGroup<"unused-getter-return-value">;
def UsedButMarkedUnused : DiagGroup<"used-but-marked-unused">;
+def UsedSearchPath : DiagGroup<"search-path-usage">;
def UserDefinedLiterals : DiagGroup<"user-defined-literals">;
def UserDefinedWarnings : DiagGroup<"user-defined-warnings">;
def ReorderCtor : DiagGroup<"reorder-ctor">;
@@ -753,6 +826,7 @@ def AtomicAlignment : DiagGroup<"atomic-alignment">;
def CustomAtomic : DiagGroup<"custom-atomic-properties">;
def AtomicProperties : DiagGroup<"atomic-properties",
[ImplicitAtomic, CustomAtomic]>;
+def SyncAlignment : DiagGroup<"sync-alignment">;
def ARCUnsafeRetainedAssign : DiagGroup<"arc-unsafe-retained-assign">;
def ARCRetainCycles : DiagGroup<"arc-retain-cycles">;
def ARCNonPodMemAccess : DiagGroup<"arc-non-pod-memaccess">;
@@ -779,7 +853,9 @@ def OverridingMethodMismatch : DiagGroup<"overriding-method-mismatch">;
def VariadicMacros : DiagGroup<"variadic-macros">;
def VectorConversion : DiagGroup<"vector-conversion">; // clang specific
def VexingParse : DiagGroup<"vexing-parse">;
-def VLAExtension : DiagGroup<"vla-extension">;
+def VLAUseStaticAssert : DiagGroup<"vla-extension-static-assert">;
+def VLACxxExtension : DiagGroup<"vla-cxx-extension", [VLAUseStaticAssert]>;
+def VLAExtension : DiagGroup<"vla-extension", [VLACxxExtension]>;
def VLA : DiagGroup<"vla", [VLAExtension]>;
def VolatileRegisterVar : DiagGroup<"volatile-register-var">;
def Visibility : DiagGroup<"visibility">;
@@ -799,15 +875,17 @@ def WritableStrings : DiagGroup<"writable-strings", [DeprecatedWritableStr]>;
//
// FIXME: Should this affect C++11 (where this is an error,
// not just deprecated) or not?
-def GCCWriteStrings : DiagGroup<"write-strings" , [WritableStrings]>;
+def GCCWriteStrings : DiagGroup<"write-strings" , [WritableStrings],
+ GCCWriteStringsDocs>;
def CharSubscript : DiagGroup<"char-subscripts">;
def LargeByValueCopy : DiagGroup<"large-by-value-copy">;
def DuplicateArgDecl : DiagGroup<"duplicate-method-arg">;
def SignedEnumBitfield : DiagGroup<"signed-enum-bitfield">;
+def ReservedModuleIdentifier : DiagGroup<"reserved-module-identifier">;
def ReservedIdentifier : DiagGroup<"reserved-identifier",
- [ReservedIdAsMacro]>;
+ [ReservedIdAsMacro, ReservedModuleIdentifier, UserDefinedLiterals]>;
// Unreachable code warning groups.
//
@@ -816,8 +894,12 @@ def ReservedIdentifier : DiagGroup<"reserved-identifier",
// under separate flags.
//
def UnreachableCodeLoopIncrement : DiagGroup<"unreachable-code-loop-increment">;
+def UnreachableCodeFallthrough : DiagGroup<"unreachable-code-fallthrough">;
+def UnreachableCodeGenericAssoc : DiagGroup<"unreachable-code-generic-assoc">;
def UnreachableCode : DiagGroup<"unreachable-code",
- [UnreachableCodeLoopIncrement]>;
+ [UnreachableCodeLoopIncrement,
+ UnreachableCodeFallthrough,
+ UnreachableCodeGenericAssoc]>;
def UnreachableCodeBreak : DiagGroup<"unreachable-code-break">;
def UnreachableCodeReturn : DiagGroup<"unreachable-code-return">;
def UnreachableCodeAggressive : DiagGroup<"unreachable-code-aggressive",
@@ -889,10 +971,16 @@ def FormatNonStandard : DiagGroup<"format-non-iso">;
def FormatY2K : DiagGroup<"format-y2k">;
def FormatPedantic : DiagGroup<"format-pedantic">;
def FormatTypeConfusion : DiagGroup<"format-type-confusion">;
+
+def FormatOverflowNonKprintf: DiagGroup<"format-overflow-non-kprintf">;
+def FormatOverflow: DiagGroup<"format-overflow", [FormatOverflowNonKprintf]>;
+def FormatTruncationNonKprintf: DiagGroup<"format-truncation-non-kprintf">;
+def FormatTruncation: DiagGroup<"format-truncation", [FormatTruncationNonKprintf]>;
+
def Format : DiagGroup<"format",
[FormatExtraArgs, FormatZeroLength, NonNull,
FormatSecurity, FormatY2K, FormatInvalidSpecifier,
- FormatInsufficientArgs]>,
+ FormatInsufficientArgs, FormatOverflow, FormatTruncation]>,
DiagCategory<"Format String Issue">;
def FormatNonLiteral : DiagGroup<"format-nonliteral">;
def Format2 : DiagGroup<"format=2",
@@ -912,6 +1000,7 @@ def PointerToEnumCast : DiagGroup<"pointer-to-enum-cast",
[VoidPointerToEnumCast]>;
def PointerToIntCast : DiagGroup<"pointer-to-int-cast",
[PointerToEnumCast, VoidPointerToIntCast]>;
+def VoidPointerDeref : DiagGroup<"void-ptr-dereference">;
def FUseLdPath : DiagGroup<"fuse-ld-path">;
@@ -940,6 +1029,8 @@ def Extra : DiagGroup<"extra", [
]>;
def Most : DiagGroup<"most", [
+ ArrayParameter,
+ BoolOperation,
CharSubscript,
Comment,
DeleteNonVirtualDtor,
@@ -981,7 +1072,9 @@ def Most : DiagGroup<"most", [
def ThreadSafetyAttributes : DiagGroup<"thread-safety-attributes">;
def ThreadSafetyAnalysis : DiagGroup<"thread-safety-analysis">;
def ThreadSafetyPrecise : DiagGroup<"thread-safety-precise">;
-def ThreadSafetyReference : DiagGroup<"thread-safety-reference">;
+def ThreadSafetyReferenceReturn : DiagGroup<"thread-safety-reference-return">;
+def ThreadSafetyReference : DiagGroup<"thread-safety-reference",
+ [ThreadSafetyReferenceReturn]>;
def ThreadSafetyNegative : DiagGroup<"thread-safety-negative">;
def ThreadSafety : DiagGroup<"thread-safety",
[ThreadSafetyAttributes,
@@ -998,7 +1091,8 @@ def Consumed : DiagGroup<"consumed">;
// warning should be active _only_ when -Wall is passed in, mark it as
// DefaultIgnore in addition to putting it here.
def All : DiagGroup<"all", [Most, Parentheses, Switch, SwitchBool,
- MisleadingIndentation]>;
+ MisleadingIndentation, PackedNonPod,
+ VLACxxExtension]>;
// Warnings that should be in clang-cl /w4.
def : DiagGroup<"CL4", [All, Extra]>;
@@ -1027,6 +1121,15 @@ def : DiagGroup<"unused-local-typedefs", [UnusedLocalTypedef]>;
def NonGCC : DiagGroup<"non-gcc",
[SignCompare, Conversion, LiteralRange]>;
+def CXX14Attrs : DiagGroup<"c++14-attribute-extensions">;
+def CXX17Attrs : DiagGroup<"c++17-attribute-extensions">;
+def CXX20Attrs : DiagGroup<"c++20-attribute-extensions">;
+def FutureAttrs : DiagGroup<"future-attribute-extensions", [CXX14Attrs,
+ CXX17Attrs,
+ CXX20Attrs]>;
+
+def CXX23AttrsOnLambda : DiagGroup<"c++23-lambda-attributes">;
+
// A warning group for warnings about using C++11 features as extensions in
// earlier C++ versions.
def CXX11 : DiagGroup<"c++11-extensions", [CXX11ExtraSemi, CXX11InlineNamespace,
@@ -1034,24 +1137,30 @@ def CXX11 : DiagGroup<"c++11-extensions", [CXX11ExtraSemi, CXX11InlineNamespace,
// A warning group for warnings about using C++14 features as extensions in
// earlier C++ versions.
-def CXX14 : DiagGroup<"c++14-extensions", [CXX14BinaryLiteral]>;
+def CXX14 : DiagGroup<"c++14-extensions", [CXX14BinaryLiteral, CXX14Attrs]>;
// A warning group for warnings about using C++17 features as extensions in
// earlier C++ versions.
-def CXX17 : DiagGroup<"c++17-extensions">;
+def CXX17 : DiagGroup<"c++17-extensions", [CXX17Attrs]>;
// A warning group for warnings about using C++20 features as extensions in
// earlier C++ versions.
-def CXX20 : DiagGroup<"c++20-extensions", [CXX20Designator]>;
+def CXX20 : DiagGroup<"c++20-extensions", [CXX20Designator, CXX20Attrs]>;
-// A warning group for warnings about using C++2b features as extensions in
+// A warning group for warnings about using C++23 features as extensions in
// earlier C++ versions.
-def CXX2b : DiagGroup<"c++2b-extensions">;
+def CXX23 : DiagGroup<"c++23-extensions", [CXX23AttrsOnLambda]>;
+
+// A warning group for warnings about using C++26 features as extensions in
+// earlier C++ versions.
+def CXX26 : DiagGroup<"c++26-extensions">;
def : DiagGroup<"c++0x-extensions", [CXX11]>;
def : DiagGroup<"c++1y-extensions", [CXX14]>;
def : DiagGroup<"c++1z-extensions", [CXX17]>;
def : DiagGroup<"c++2a-extensions", [CXX20]>;
+def : DiagGroup<"c++2b-extensions", [CXX23]>;
+def : DiagGroup<"c++2c-extensions", [CXX26]>;
def DelegatingCtorCycles :
DiagGroup<"delegating-ctor-cycles">;
@@ -1062,8 +1171,10 @@ def C11 : DiagGroup<"c11-extensions">;
// A warning group for warnings about using C99 features as extensions.
def C99 : DiagGroup<"c99-extensions", [C99Designator]>;
-// A warning group for warnings about using C2x features as extensions.
-def C2x : DiagGroup<"c2x-extensions">;
+// A warning group for warnings about using C23 features as extensions.
+def C23 : DiagGroup<"c23-extensions">;
+
+def : DiagGroup<"c2x-extensions", [C23]>;
// A warning group for warnings about GCC extensions.
def GNU : DiagGroup<"gnu", [GNUAlignofExpression, GNUAnonymousStruct,
@@ -1071,16 +1182,17 @@ def GNU : DiagGroup<"gnu", [GNUAlignofExpression, GNUAnonymousStruct,
GNUBinaryLiteral, GNUCaseRange,
GNUComplexInteger, GNUCompoundLiteralInitializer,
GNUConditionalOmittedOperand, GNUDesignator,
- GNUEmptyInitializer, GNUEmptyStruct,
+ GNUEmptyStruct,
VLAExtension, GNUFlexibleArrayInitializer,
GNUFlexibleArrayUnionMember, GNUFoldingConstant,
GNUImaginaryConstant, GNUIncludeNext,
- GNULabelsAsValue,
+ GNULabelsAsValue, GNULineMarker, GNUNullPointerArithmetic,
+ GNUOffsetofExtensions, GNUPointerArith,
RedeclaredClassMember, GNURedeclaredEnum,
GNUStatementExpression, GNUStaticFloatInit,
- GNUStringLiteralOperatorTemplate,
- GNUUnionCast, GNUVariableSizedTypeNotAtEnd,
- ZeroLengthArray, GNUZeroLineDirective,
+ GNUStringLiteralOperatorTemplate, GNUUnionCast,
+ GNUVariableSizedTypeNotAtEnd, ZeroLengthArray,
+ GNUZeroLineDirective,
GNUZeroVariadicMacroArguments]>;
// A warning group for warnings about code that clang accepts but gcc doesn't.
def GccCompat : DiagGroup<"gcc-compat">;
@@ -1125,6 +1237,9 @@ def MicrosoftCommentPaste : DiagGroup<"microsoft-comment-paste">;
def MicrosoftEndOfFile : DiagGroup<"microsoft-end-of-file">;
def MicrosoftInaccessibleBase : DiagGroup<"microsoft-inaccessible-base">;
def MicrosoftStaticAssert : DiagGroup<"microsoft-static-assert">;
+def MicrosoftInitFromPredefined : DiagGroup<"microsoft-init-from-predefined">;
+def MicrosoftStringLiteralFromPredefined : DiagGroup<
+ "microsoft-string-literal-from-predefined">;
// Aliases.
def : DiagGroup<"msvc-include", [MicrosoftInclude]>;
@@ -1142,6 +1257,7 @@ def Microsoft : DiagGroup<"microsoft",
MicrosoftFlexibleArray, MicrosoftExtraQualification, MicrosoftCast,
MicrosoftConstInit, MicrosoftVoidPseudoDtor, MicrosoftAnonTag,
MicrosoftCommentPaste, MicrosoftEndOfFile, MicrosoftStaticAssert,
+ MicrosoftInitFromPredefined, MicrosoftStringLiteralFromPredefined,
MicrosoftInconsistentDllImport]>;
def ClangClPch : DiagGroup<"clang-cl-pch">;
@@ -1185,6 +1301,9 @@ def ASM : DiagGroup<"asm", [
ASMOperandWidths
]>;
+// Linker warnings.
+def LinkerWarnings : DiagGroup<"linker-warnings">;
+
// OpenMP warnings.
def SourceUsesOpenMP : DiagGroup<"source-uses-openmp">;
def OpenMPClauses : DiagGroup<"openmp-clauses">;
@@ -1193,15 +1312,41 @@ def OpenMPMapping : DiagGroup<"openmp-mapping">;
def OpenMPTarget : DiagGroup<"openmp-target", [OpenMPMapping]>;
def OpenMPPre51Compat : DiagGroup<"pre-openmp-51-compat">;
def OpenMP51Ext : DiagGroup<"openmp-51-extensions">;
+def OpenMPExtensions : DiagGroup<"openmp-extensions">;
+def OpenMPTargetException : DiagGroup<"openmp-target-exception">;
def OpenMP : DiagGroup<"openmp", [
SourceUsesOpenMP, OpenMPClauses, OpenMPLoopForm, OpenMPTarget,
- OpenMPMapping, OpenMP51Ext
+ OpenMPMapping, OpenMP51Ext, OpenMPExtensions, OpenMPTargetException
]>;
+// OpenACC warnings.
+def SourceUsesOpenACC : DiagGroup<"source-uses-openacc">;
+def OpenACC : DiagGroup<"openacc", [SourceUsesOpenACC]>;
+
// Backend warnings.
def BackendInlineAsm : DiagGroup<"inline-asm">;
def BackendSourceMgr : DiagGroup<"source-mgr">;
-def BackendFrameLargerThan : DiagGroup<"frame-larger-than">;
+def BackendFrameLargerThan : DiagGroup<"frame-larger-than">{
+ code Documentation = [{
+More fine grained information about the stack layout is available by adding the
+`-Rpass-analysis=stack-frame-layout` command-line flag to the compiler
+invocation.
+
+The diagnostic information can be saved to a file in a machine readable format,
+like YAML by adding the `-foptimization-record-file=<file>` command-line flag.
+
+Results can be filtered by function name by passing
+`-mllvm -filter-print-funcs=foo`, where `foo` is the target function's name.
+
+ .. code-block:: console
+
+ clang -c a.cpp -Rpass-analysis=stack-frame-layout -mllvm -filter-print-funcs=foo
+
+ .. code-block:: console
+
+ clang -c a.cpp -Rpass-analysis=stack-frame-layout -foptimization-record-file=<file>
+}];
+}
// Compatibility flag name from old versions of Clang.
def : DiagGroup<"frame-larger-than=", [BackendFrameLargerThan]>;
def BackendPlugin : DiagGroup<"backend-plugin">;
@@ -1210,11 +1355,13 @@ def BackendOptimizationRemark : DiagGroup<"pass">;
def BackendOptimizationRemarkMissed : DiagGroup<"pass-missed">;
def BackendOptimizationRemarkAnalysis : DiagGroup<"pass-analysis">;
def BackendOptimizationFailure : DiagGroup<"pass-failed">;
+def BackendWarningAttributes : DiagGroup<"attribute-warning">;
// Instrumentation based profiling warnings.
def ProfileInstrMissing : DiagGroup<"profile-instr-missing">;
def ProfileInstrOutOfDate : DiagGroup<"profile-instr-out-of-date">;
def ProfileInstrUnprofiled : DiagGroup<"profile-instr-unprofiled">;
+def MisExpect : DiagGroup<"misexpect">;
// AddressSanitizer frontend instrumentation remarks.
def SanitizeAddressRemarks : DiagGroup<"sanitize-address">;
@@ -1233,6 +1380,12 @@ def CudaUnknownVersion: DiagGroup<"unknown-cuda-version">;
// ignored by CUDA.
def HIPOnly : DiagGroup<"hip-only">;
+// Warning about mixed HIP and OpenMP compilation / target offloading.
+def HIPOpenMPOffloading: DiagGroup<"hip-omp-target-directives">;
+
+// Warning about multiple GPUs are detected.
+def MultiGPU: DiagGroup<"multi-gpu">;
+
// Warnings which cause linking of the runtime libraries like
// libc and the CRT to be skipped.
def AVRRtlibLinkingQuirks : DiagGroup<"avr-rtlib-linking-quirks">;
@@ -1246,16 +1399,24 @@ def OptionIgnored : DiagGroup<"option-ignored">;
def UnknownArgument : DiagGroup<"unknown-argument">;
+def UnsupportedABI : DiagGroup<"unsupported-abi">;
+
// A warning group for warnings about code that clang accepts when
-// compiling OpenCL C/C++ but which is not compatible with the SPIR spec.
+// compiling OpenCL C/C++ but which is not compatible with the SPIR(-V) spec.
def SpirCompat : DiagGroup<"spir-compat">;
+def : DiagGroup<"spirv-compat", [SpirCompat]>; // Alias.
// Warning for the GlobalISel options.
def GlobalISel : DiagGroup<"global-isel">;
+// A warning group for the GNU extension to allow mixed specifier types for
+// target-clones multiversioning.
+def TargetClonesMixedSpecifiers : DiagGroup<"target-clones-mixed-specifiers">;
+
// A warning group specifically for warnings related to function
// multiversioning.
-def FunctionMultiVersioning : DiagGroup<"function-multiversion">;
+def FunctionMultiVersioning
+ : DiagGroup<"function-multiversion", [TargetClonesMixedSpecifiers]>;
def NoDeref : DiagGroup<"noderef">;
@@ -1264,7 +1425,7 @@ def CrossTU : DiagGroup<"ctu">;
def CTADMaybeUnsupported : DiagGroup<"ctad-maybe-unsupported">;
-def FortifySource : DiagGroup<"fortify-source">;
+def FortifySource : DiagGroup<"fortify-source", [FormatOverflow, FormatTruncation]>;
def MaxTokens : DiagGroup<"max-tokens"> {
code Documentation = [{
@@ -1274,19 +1435,22 @@ the token limit, which can be set in three ways:
1. As a limit at a specific point in a file, using the ``clang max_tokens_here``
pragma:
- .. code-block: c++
+ .. code-block:: c++
+
#pragma clang max_tokens_here 1234
2. As a per-translation unit limit, using the ``-fmax-tokens=`` command-line
flag:
- .. code-block: console
+ .. code-block:: console
+
clang -c a.cpp -fmax-tokens=1234
3. As a per-translation unit limit using the ``clang max_tokens_total`` pragma,
which works like and overrides the ``-fmax-tokens=`` flag:
- .. code-block: c++
+ .. code-block:: c++
+
#pragma clang max_tokens_total 1234
These limits can be helpful in limiting code growth through included files.
@@ -1303,3 +1467,27 @@ def WebAssemblyExceptionSpec : DiagGroup<"wasm-exception-spec">;
def RTTI : DiagGroup<"rtti">;
def OpenCLCoreFeaturesDiagGroup : DiagGroup<"pedantic-core-features">;
+
+// Warnings and extensions to make preprocessor macro usage pedantic.
+def PedanticMacros : DiagGroup<"pedantic-macros",
+ [DeprecatedPragma,
+ MacroRedefined,
+ BuiltinMacroRedefined,
+ RestrictExpansionMacro,
+ FinalMacro]>;
+
+def BranchProtection : DiagGroup<"branch-protection">;
+
+// HLSL diagnostic groups
+// Warnings for HLSL Clang extensions
+def HLSLExtension : DiagGroup<"hlsl-extensions">;
+
+// Warnings for DXIL validation
+def DXILValidation : DiagGroup<"dxil-validation">;
+
+// Warnings and notes related to const_var_decl_type attribute checks
+def ReadOnlyPlacementChecks : DiagGroup<"read-only-types">;
+
+// Warnings and fixes to support the "safe buffers" programming model.
+def UnsafeBufferUsageInContainer : DiagGroup<"unsafe-buffer-usage-in-container">;
+def UnsafeBufferUsage : DiagGroup<"unsafe-buffer-usage", [UnsafeBufferUsageInContainer]>;
diff --git a/contrib/llvm-project/clang/include/clang/Basic/DiagnosticIDs.h b/contrib/llvm-project/clang/include/clang/Basic/DiagnosticIDs.h
index 288504def5eb..0cdda42793f6 100644
--- a/contrib/llvm-project/clang/include/clang/Basic/DiagnosticIDs.h
+++ b/contrib/llvm-project/clang/include/clang/Basic/DiagnosticIDs.h
@@ -17,6 +17,7 @@
#include "clang/Basic/LLVM.h"
#include "llvm/ADT/IntrusiveRefCntPtr.h"
#include "llvm/ADT/StringRef.h"
+#include <optional>
#include <vector>
namespace clang {
@@ -25,15 +26,17 @@ namespace clang {
// Import the diagnostic enums themselves.
namespace diag {
+ enum class Group;
+
// Size of each of the diagnostic categories.
enum {
DIAG_SIZE_COMMON = 300,
- DIAG_SIZE_DRIVER = 250,
+ DIAG_SIZE_DRIVER = 400,
DIAG_SIZE_FRONTEND = 150,
DIAG_SIZE_SERIALIZATION = 120,
DIAG_SIZE_LEX = 400,
- DIAG_SIZE_PARSE = 600,
- DIAG_SIZE_AST = 250,
+ DIAG_SIZE_PARSE = 700,
+ DIAG_SIZE_AST = 300,
DIAG_SIZE_COMMENT = 100,
DIAG_SIZE_CROSSTU = 100,
DIAG_SIZE_SEMA = 4500,
@@ -43,18 +46,18 @@ namespace clang {
// Start position for diagnostics.
enum {
DIAG_START_COMMON = 0,
- DIAG_START_DRIVER = DIAG_START_COMMON + DIAG_SIZE_COMMON,
- DIAG_START_FRONTEND = DIAG_START_DRIVER + DIAG_SIZE_DRIVER,
- DIAG_START_SERIALIZATION = DIAG_START_FRONTEND + DIAG_SIZE_FRONTEND,
- DIAG_START_LEX = DIAG_START_SERIALIZATION + DIAG_SIZE_SERIALIZATION,
- DIAG_START_PARSE = DIAG_START_LEX + DIAG_SIZE_LEX,
- DIAG_START_AST = DIAG_START_PARSE + DIAG_SIZE_PARSE,
- DIAG_START_COMMENT = DIAG_START_AST + DIAG_SIZE_AST,
- DIAG_START_CROSSTU = DIAG_START_COMMENT + DIAG_SIZE_COMMENT,
- DIAG_START_SEMA = DIAG_START_CROSSTU + DIAG_SIZE_CROSSTU,
- DIAG_START_ANALYSIS = DIAG_START_SEMA + DIAG_SIZE_SEMA,
- DIAG_START_REFACTORING = DIAG_START_ANALYSIS + DIAG_SIZE_ANALYSIS,
- DIAG_UPPER_LIMIT = DIAG_START_REFACTORING + DIAG_SIZE_REFACTORING
+ DIAG_START_DRIVER = DIAG_START_COMMON + static_cast<int>(DIAG_SIZE_COMMON),
+ DIAG_START_FRONTEND = DIAG_START_DRIVER + static_cast<int>(DIAG_SIZE_DRIVER),
+ DIAG_START_SERIALIZATION = DIAG_START_FRONTEND + static_cast<int>(DIAG_SIZE_FRONTEND),
+ DIAG_START_LEX = DIAG_START_SERIALIZATION + static_cast<int>(DIAG_SIZE_SERIALIZATION),
+ DIAG_START_PARSE = DIAG_START_LEX + static_cast<int>(DIAG_SIZE_LEX),
+ DIAG_START_AST = DIAG_START_PARSE + static_cast<int>(DIAG_SIZE_PARSE),
+ DIAG_START_COMMENT = DIAG_START_AST + static_cast<int>(DIAG_SIZE_AST),
+ DIAG_START_CROSSTU = DIAG_START_COMMENT + static_cast<int>(DIAG_SIZE_COMMENT),
+ DIAG_START_SEMA = DIAG_START_CROSSTU + static_cast<int>(DIAG_SIZE_CROSSTU),
+ DIAG_START_ANALYSIS = DIAG_START_SEMA + static_cast<int>(DIAG_SIZE_SEMA),
+ DIAG_START_REFACTORING = DIAG_START_ANALYSIS + static_cast<int>(DIAG_SIZE_ANALYSIS),
+ DIAG_UPPER_LIMIT = DIAG_START_REFACTORING + static_cast<int>(DIAG_SIZE_REFACTORING)
};
class CustomDiagInfo;
@@ -65,7 +68,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"
@@ -97,11 +100,17 @@ namespace clang {
}
class DiagnosticMapping {
+ LLVM_PREFERRED_TYPE(diag::Severity)
unsigned Severity : 3;
+ LLVM_PREFERRED_TYPE(bool)
unsigned IsUser : 1;
+ LLVM_PREFERRED_TYPE(bool)
unsigned IsPragma : 1;
+ LLVM_PREFERRED_TYPE(bool)
unsigned HasNoWarningAsError : 1;
+ LLVM_PREFERRED_TYPE(bool)
unsigned HasNoErrorAsFatal : 1;
+ LLVM_PREFERRED_TYPE(bool)
unsigned WasUpgradedFromWarning : 1;
public:
@@ -156,6 +165,10 @@ public:
Result.Severity = Bits & 0x7;
return Result;
}
+
+ bool operator==(DiagnosticMapping Other) const {
+ return serialize() == Other.serialize();
+ }
};
/// Used for handling and querying diagnostic IDs.
@@ -205,6 +218,9 @@ public:
/// default.
static bool isDefaultMappingAsError(unsigned DiagID);
+ /// Get the default mapping for this diagnostic.
+ static DiagnosticMapping getDefaultMapping(unsigned DiagID);
+
/// Determine whether the given built-in diagnostic ID is a Note.
static bool isBuiltinNote(unsigned DiagID);
@@ -224,6 +240,21 @@ public:
///
static bool isBuiltinExtensionDiag(unsigned DiagID, bool &EnabledByDefault);
+ /// Given a group ID, returns the flag that toggles the group.
+ /// For example, for Group::DeprecatedDeclarations, returns
+ /// "deprecated-declarations".
+ static StringRef getWarningOptionForGroup(diag::Group);
+
+ /// Given a diagnostic group ID, return its documentation.
+ static StringRef getWarningOptionDocumentation(diag::Group GroupID);
+
+ /// Given a group ID, returns the flag that toggles the group.
+ /// For example, for "deprecated-declarations", returns
+ /// Group::DeprecatedDeclarations.
+ static std::optional<diag::Group> getGroupForWarningOption(StringRef);
+
+ /// Return the lowest-level group that contains the specified diagnostic.
+ static std::optional<diag::Group> getGroupForDiag(unsigned DiagID);
/// Return the lowest-level warning option that enables the specified
/// diagnostic.
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/DiagnosticLexKinds.td b/contrib/llvm-project/clang/include/clang/Basic/DiagnosticLexKinds.td
index bdf5d263fa92..75ca2fa16d34 100644
--- a/contrib/llvm-project/clang/include/clang/Basic/DiagnosticLexKinds.td
+++ b/contrib/llvm-project/clang/include/clang/Basic/DiagnosticLexKinds.td
@@ -80,6 +80,10 @@ def warn_cxx11_keyword : Warning<"'%0' is a keyword in C++11">,
InGroup<CXX11Compat>, DefaultIgnore;
def warn_cxx20_keyword : Warning<"'%0' is a keyword in C++20">,
InGroup<CXX20Compat>, DefaultIgnore;
+def warn_c99_keyword : Warning<"'%0' is a keyword in C99">,
+ InGroup<C99Compat>, DefaultIgnore;
+def warn_c23_keyword : Warning<"'%0' is a keyword in C23">,
+ InGroup<C23Compat>, DefaultIgnore;
def ext_unterminated_char_or_string : ExtWarn<
"missing terminating %select{'|'\"'}0 character">, InGroup<InvalidPPToken>;
@@ -113,25 +117,61 @@ def warn_four_char_character_literal : Warning<
// Unicode and UCNs
def err_invalid_utf8 : Error<
"source file is not valid UTF-8">;
-def err_non_ascii : Error<
- "non-ASCII characters are not allowed outside of literals and identifiers">;
+def warn_invalid_utf8_in_comment : Extension<
+ "invalid UTF-8 in comment">, InGroup<DiagGroup<"invalid-utf8">>;
+def err_character_not_allowed : Error<
+ "unexpected character <U+%0>">;
+def err_character_not_allowed_identifier : Error<
+ "character <U+%0> not allowed %select{in|at the start of}1 an identifier">;
def ext_unicode_whitespace : ExtWarn<
"treating Unicode character as whitespace">,
InGroup<DiagGroup<"unicode-whitespace">>;
def warn_utf8_symbol_homoglyph : Warning<
- "treating Unicode character <U+%0> as identifier character rather than "
+ "treating Unicode character <U+%0> as an identifier character rather than "
"as '%1' symbol">, InGroup<DiagGroup<"unicode-homoglyph">>;
def warn_utf8_symbol_zero_width : Warning<
"identifier contains Unicode character <U+%0> that is invisible in "
"some environments">, InGroup<DiagGroup<"unicode-zero-width">>;
-
+def ext_mathematical_notation : ExtWarn<
+ "mathematical notation character <U+%0> in an identifier is a Clang extension">,
+ InGroup<DiagGroup<"mathematical-notation-identifier-extension">>;
+
+def ext_delimited_escape_sequence : Extension<
+ "%select{delimited|named}0 escape sequences are a "
+ "%select{Clang|C++23}1 extension">,
+ InGroup<DiagGroup<"delimited-escape-sequence-extension">>;
+
+def warn_cxx23_delimited_escape_sequence : Warning<
+ "%select{delimited|named}0 escape sequences are "
+ "incompatible with C++ standards before C++23">,
+ InGroup<CXXPre23Compat>, DefaultIgnore;
+
+def err_delimited_escape_empty : Error<
+ "delimited escape sequence cannot be empty">;
+def err_delimited_escape_missing_brace: Error<
+ "expected '{' after '\\%0' escape sequence">;
+def err_delimited_escape_invalid : Error<
+ "invalid digit '%0' in escape sequence">;
def err_hex_escape_no_digits : Error<
"\\%0 used with no following hex digits">;
+def err_invalid_ucn_name : Error<
+ "'%0' is not a valid Unicode character name">;
+def note_invalid_ucn_name_loose_matching : Note<
+ "characters names in Unicode escape sequences are sensitive to case and whitespaces">;
+def note_invalid_ucn_name_candidate : Note<
+ "did you mean %0 ('%2' U+%1)?">;
+
def warn_ucn_escape_no_digits : Warning<
"\\%0 used with no following hex digits; "
"treating as '\\' followed by identifier">, InGroup<Unicode>;
def err_ucn_escape_incomplete : Error<
"incomplete universal character name">;
+def warn_delimited_ucn_incomplete : Warning<
+ "incomplete delimited universal character name; "
+ "treating as '\\' '%0' '{' identifier">, InGroup<Unicode>;
+def warn_delimited_ucn_empty : Warning<
+ "empty delimited universal character name; "
+ "treating as '\\' '%0' '{' '}'">, InGroup<Unicode>;
def warn_ucn_escape_incomplete : Warning<
"incomplete universal character name; "
"treating as '\\' followed by identifier">, InGroup<Unicode>;
@@ -150,9 +190,6 @@ def warn_c99_compat_unicode_id : Warning<
"%select{using this character in an identifier|starting an identifier with "
"this character}0 is incompatible with C99">,
InGroup<C99Compat>, DefaultIgnore;
-def warn_cxx98_compat_unicode_id : Warning<
- "using this character in an identifier is incompatible with C++98">,
- InGroup<CXX98Compat>, DefaultIgnore;
def warn_cxx98_compat_literal_ucn_escape_basic_scs : Warning<
"specifying character '%0' with a universal character name "
@@ -160,6 +197,14 @@ def warn_cxx98_compat_literal_ucn_escape_basic_scs : Warning<
def warn_cxx98_compat_literal_ucn_control_character : Warning<
"universal character name referring to a control character "
"is incompatible with C++98">, InGroup<CXX98Compat>, DefaultIgnore;
+def warn_c23_compat_literal_ucn_escape_basic_scs : Warning<
+ "specifying character '%0' with a universal character name is "
+ "incompatible with C standards before C23">,
+ InGroup<CPre23Compat>, DefaultIgnore;
+def warn_c23_compat_literal_ucn_control_character : Warning<
+ "universal character name referring to a control character "
+ "is incompatible with C standards before C23">,
+ InGroup<CPre23Compat>, DefaultIgnore;
def warn_ucn_not_valid_in_c89 : Warning<
"universal character names are only valid in C99 or C++; "
"treating as '\\' followed by identifier">, InGroup<Unicode>;
@@ -179,17 +224,15 @@ def err_invalid_suffix_constant : Error<
def warn_cxx11_compat_digit_separator : Warning<
"digit separators are incompatible with C++ standards before C++14">,
InGroup<CXXPre14Compat>, DefaultIgnore;
-def warn_c2x_compat_digit_separator : Warning<
- "digit separators are incompatible with C standards before C2x">,
- InGroup<CPre2xCompat>, DefaultIgnore;
+def warn_c23_compat_digit_separator : Warning<
+ "digit separators are incompatible with C standards before C23">,
+ InGroup<CPre23Compat>, DefaultIgnore;
def err_digit_separator_not_between_digits : Error<
"digit separator cannot appear at %select{start|end}0 of digit sequence">;
-def warn_extraneous_char_constant : Warning<
- "extraneous characters in character constant ignored">;
def warn_char_constant_too_large : Warning<
"character constant too long for its type">;
-def err_multichar_utf_character_literal : Error<
- "Unicode character literals may not contain multiple characters">;
+def err_multichar_character_literal : Error<
+ "%select{wide|Unicode}0 character literals may not contain multiple characters">;
def err_exponent_has_no_digits : Error<"exponent has no digits">;
def err_hex_constant_requires : Error<
"hexadecimal floating %select{constant|literal}0 requires "
@@ -241,6 +284,17 @@ def ext_ms_reserved_user_defined_literal : ExtWarn<
"identifier">, InGroup<ReservedUserDefinedLiteral>;
def err_unsupported_string_concat : Error<
"unsupported non-standard concatenation of string literals">;
+
+def warn_unevaluated_string_prefix : Warning<
+ "encoding prefix '%0' on an unevaluated string literal has no effect"
+ "%select{| and is incompatible with c++2c}1">,
+ InGroup<DiagGroup<"invalid-unevaluated-string">>;
+def err_unevaluated_string_prefix : Error<
+ "an unevaluated string literal cannot have an encoding prefix">;
+def err_unevaluated_string_udl : Error<
+ "an unevaluated string literal cannot be a user-defined literal">;
+def err_unevaluated_string_invalid_escape_sequence : Error<
+ "invalid escape sequence '%0' in an unevaluated string literal">;
def err_string_concat_mixed_suffix : Error<
"differing user-defined suffixes ('%0' and '%1') in string literal "
"concatenation">;
@@ -257,7 +311,9 @@ def err_bad_character_encoding : Error<
def warn_bad_character_encoding : ExtWarn<
"illegal character encoding in character literal">,
InGroup<InvalidSourceEncoding>;
-def err_lexing_string : Error<"failure when lexing a string">;
+def err_lexing_string : Error<"failure when lexing a string literal">;
+def err_lexing_char : Error<"failure when lexing a character literal">;
+def err_lexing_numeric : Error<"failure when lexing a numeric literal">;
def err_placeholder_in_source : Error<"editor placeholder in source file">;
//===----------------------------------------------------------------------===//
@@ -301,11 +357,9 @@ def pp_pragma_sysheader_in_main_file : Warning<
"#pragma system_header ignored in main file">,
InGroup<DiagGroup<"pragma-system-header-outside-header">>;
-def err_pragma_include_instead_not_sysheader : Error<
- "'#pragma clang include_instead' cannot be used outside of system headers">;
-def err_pragma_include_instead_system_reserved : Error<
- "header '%0' is an implementation detail; #include %select{'%2'|either '%2' "
- "or '%3'|one of %2}1 instead">;
+def err_illegal_use_of_flt_eval_macro : Error<
+ "'__FLT_EVAL_METHOD__' cannot be expanded inside a scope containing "
+ "'#pragma clang fp eval_method'">;
def pp_poisoning_existing_macro : Warning<"poisoning existing macro">;
def pp_out_of_date_dependency : Warning<
@@ -359,7 +413,15 @@ def ext_pp_include_search_ms : ExtWarn<
def ext_pp_ident_directive : Extension<"#ident is a language extension">;
def ext_pp_include_next_directive : Extension<
"#include_next is a language extension">, InGroup<GNUIncludeNext>;
-def ext_pp_warning_directive : Extension<"#warning is a language extension">;
+
+def ext_pp_warning_directive : Extension<
+ "#warning is a %select{C23|C++23}0 extension">;
+def warn_cxx23_compat_warning_directive : Warning<
+ "#warning is incompatible with C++ standards before C++23">,
+ InGroup<CXXPre23Compat>, DefaultIgnore;
+def warn_c23_compat_warning_directive : Warning<
+ "#warning is incompatible with C standards before C23">,
+ InGroup<CPre23Compat>, DefaultIgnore;
def ext_pp_extra_tokens_at_eol : ExtWarn<
"extra tokens at end of #%0 directive">, InGroup<ExtraTokens>;
@@ -400,6 +462,10 @@ def ext_embedded_directive : Extension<
def ext_missing_varargs_arg : Extension<
"must specify at least one argument for '...' parameter of variadic macro">,
InGroup<GNUZeroVariadicMacroArguments>;
+def warn_cxx17_compat_missing_varargs_arg : Warning<
+ "passing no argument for the '...' parameter of a variadic macro is "
+ "incompatible with C++ standards before C++20">,
+ InGroup<CXXPre20Compat>, DefaultIgnore;
def ext_empty_fnmacro_arg : Extension<
"empty macro arguments are a C99 feature">, InGroup<C99>;
def warn_cxx98_compat_empty_fnmacro_arg : Warning<
@@ -411,7 +477,13 @@ def note_macro_expansion_here : Note<"expansion of macro %0 requested here">;
def ext_pp_opencl_variadic_macros : Extension<
"variadic macros are a Clang extension in OpenCL">;
-def err_pp_invalid_directive : Error<"invalid preprocessing directive">;
+def ext_pp_gnu_line_directive : Extension<
+ "this style of line directive is a GNU extension">,
+ InGroup<GNULineMarker>;
+def err_pp_invalid_directive : Error<
+ "invalid preprocessing directive%select{|, did you mean '#%1'?}0">;
+def warn_pp_invalid_directive : Warning<
+ err_pp_invalid_directive.Summary>, InGroup<DiagGroup<"unknown-directives">>;
def err_pp_directive_required : Error<
"%0 must be used within a preprocessing directive">;
def err_pp_file_not_found : Error<"'%0' file not found">, DefaultFatal;
@@ -430,6 +502,9 @@ def warn_pp_hdrstop_filename_ignored : Warning<
"#pragma hdrstop filename not supported, "
"/Fp can be used to specify precompiled header filename">,
InGroup<ClangClPch>;
+def remark_pp_search_path_usage : Remark<
+ "search path used: '%0'">,
+ InGroup<UsedSearchPath>;
def err_pp_file_not_found_angled_include_not_fatal : Error<
"'%0' file not found with <angled> %select{include|import}1; "
"use \"quotes\" instead">;
@@ -526,6 +601,27 @@ def warn_pragma_warning_expected_number :
ExtWarn<"#pragma warning expected a warning number">,
InGroup<UnknownPragmas>;
+// - #pragma deprecated(...)
+def warn_pragma_deprecated_macro_use :
+ ExtWarn<"macro %0 has been marked as deprecated%select{|: %2}1">,
+ InGroup<DeprecatedPragma>;
+
+// - #pragma clang restrict_expansion(...)
+def warn_pragma_restrict_expansion_macro_use :
+ ExtWarn<"macro %0 has been marked as unsafe for use in headers"
+ "%select{|: %2}1">,
+ InGroup<RestrictExpansionMacro>;
+
+// - Note for macro annotations.
+def note_pp_macro_annotation :
+ Note<"macro marked '%select{deprecated|restrict_expansion|final}0' here">;
+
+// - #pragma clang final(...)
+def warn_pragma_final_macro :
+ ExtWarn<"macro %0 has been marked as final and should not be "
+ "%select{undefined|redefined}1">,
+ InGroup<FinalMacro>, ShowInSystemHeader;
+
// - #pragma execution_character_set(...)
def warn_pragma_exec_charset_expected :
ExtWarn<"#pragma execution_character_set expected '%0'">,
@@ -574,10 +670,10 @@ def warn_pragma_diagnostic_unknown_warning :
ExtWarn<"unknown warning group '%0', ignored">,
InGroup<UnknownWarningOption>;
// - #pragma __debug
+def warn_pragma_debug_missing_command : Warning<
+ "missing debug command">, InGroup<IgnoredPragmas>;
def warn_pragma_debug_unexpected_command : Warning<
"unexpected debug command '%0'">, InGroup<IgnoredPragmas>;
-def warn_pragma_debug_missing_argument : Warning<
- "missing argument to debug command '%0'">, InGroup<IgnoredPragmas>;
def warn_pragma_debug_unknown_module : Warning<
"unknown module '%0'">, InGroup<IgnoredPragmas>;
// #pragma module
@@ -626,7 +722,7 @@ def ext_pp_bad_paste_ms : ExtWarn<
def err_pp_operator_used_as_macro_name : Error<
"C++ operator %0 (aka %1) used as a macro name">;
def ext_pp_operator_used_as_macro_name : Extension<
- err_pp_operator_used_as_macro_name.Text>, InGroup<MicrosoftCppMacro>;
+ err_pp_operator_used_as_macro_name.Summary>, InGroup<MicrosoftCppMacro>;
def err_pp_illegal_floating_literal : Error<
"floating point literal in preprocessor expression">;
def err_pp_line_requires_integer : Error<
@@ -654,6 +750,23 @@ def warn_cxx98_compat_pp_line_too_big : Warning<
"#line number greater than 32767 is incompatible with C++98">,
InGroup<CXX98CompatPedantic>, DefaultIgnore;
+def warn_c23_compat_pp_directive : Warning<
+ "use of a '#%select{<BUG IF SEEN>|elifdef|elifndef}0' directive "
+ "is incompatible with C standards before C23">,
+ InGroup<CPre23Compat>, DefaultIgnore;
+def ext_c23_pp_directive : ExtWarn<
+ "use of a '#%select{<BUG IF SEEN>|elifdef|elifndef}0' directive "
+ "is a C23 extension">,
+ InGroup<C23>;
+def warn_cxx23_compat_pp_directive : Warning<
+ "use of a '#%select{<BUG IF SEEN>|elifdef|elifndef}0' directive "
+ "is incompatible with C++ standards before C++23">,
+ InGroup<CXXPre23Compat>, DefaultIgnore;
+def ext_cxx23_pp_directive : ExtWarn<
+ "use of a '#%select{<BUG IF SEEN>|elifdef|elifndef}0' directive "
+ "is a C++23 extension">,
+ InGroup<CXX23>;
+
def err_pp_visibility_non_macro : Error<"no macro named %0">;
def err_pp_arc_cf_code_audited_syntax : Error<"expected 'begin' or 'end'">;
@@ -771,10 +884,13 @@ def warn_quoted_include_in_framework_header : Warning<
def warn_framework_include_private_from_public : Warning<
"public framework header includes private framework header '%0'"
>, InGroup<FrameworkIncludePrivateFromPublic>;
+def warn_deprecated_module_dot_map : Warning<
+ "'%0' as a module map name is deprecated, rename it to %select{module.modulemap|module.private.modulemap}1%select{| in the 'Modules' directory of the framework}2">,
+ InGroup<DeprecatedModuleDotMap>;
-def warn_auto_module_import : Warning<
+def remark_pp_include_directive_modular_translation : Remark<
"treating #%select{include|import|include_next|__include_macros}0 as an "
- "import of module '%1'">, InGroup<AutoImport>, DefaultIgnore;
+ "import of module '%1'">, InGroup<ModuleIncludeDirectiveTranslation>;
def note_implicit_top_level_module_import_here : Note<
"submodule of top-level module '%0' implicitly imported here">;
def warn_uncovered_module_header : Warning<
@@ -790,6 +906,8 @@ def warn_use_of_private_header_outside_module : Warning<
InGroup<DiagGroup<"private-header">>, DefaultError;
def err_undeclared_use_of_module : Error<
"module %0 does not depend on a module exporting '%1'">;
+def err_undeclared_use_of_module_indirect : Error<
+ "module %0 does not directly depend on a module exporting '%1', which is part of indirectly-used module %2">;
def warn_non_modular_include_in_framework_module : Warning<
"include of non-modular header inside framework module '%0': '%1'">,
InGroup<NonModularIncludeInFrameworkModule>, DefaultIgnore;
@@ -807,6 +925,11 @@ def err_header_import_semi_in_macro : Error<
def err_header_import_not_header_unit : Error<
"header file %0 (aka '%1') cannot be imported because "
"it is not known to be a header unit">;
+def warn_pp_include_angled_in_module_purview : Warning<
+ "'#include <filename>' attaches the declarations to the named module '%0'"
+ ", which is not usually intended; consider moving that directive before "
+ "the module declaration">,
+ InGroup<DiagGroup<"include-angled-in-module-purview">>;
def warn_header_guard : Warning<
"%0 is used as a header guard here, followed by #define of a different macro">,
@@ -836,13 +959,24 @@ def err_pp_eof_in_assume_nonnull : Error<
}
-let CategoryName = "Dependency Directive Source Minimization Issue" in {
+let CategoryName = "Dependency Directive Source Scanner Issue" in {
-def err_dep_source_minimizer_missing_sema_after_at_import : Error<
+def err_dep_source_scanner_missing_semi_after_at_import : Error<
"could not find ';' after @import">;
-def err_dep_source_minimizer_unexpected_tokens_at_import : Error<
+def err_dep_source_scanner_unexpected_tokens_at_import : Error<
"unexpected extra tokens at end of @import declaration">;
}
+def err_pp_double_begin_pragma_unsafe_buffer_usage :
+Error<"already inside '#pragma unsafe_buffer_usage'">;
+
+def err_pp_unmatched_end_begin_pragma_unsafe_buffer_usage :
+Error<"not currently inside '#pragma unsafe_buffer_usage'">;
+
+def err_pp_unclosed_pragma_unsafe_buffer_usage :
+Error<"'#pragma unsafe_buffer_usage' was not ended">;
+
+def err_pp_pragma_unsafe_buffer_usage_syntax :
+Error<"Expected 'begin' or 'end'">;
}
diff --git a/contrib/llvm-project/clang/include/clang/Basic/DiagnosticOptions.def b/contrib/llvm-project/clang/include/clang/Basic/DiagnosticOptions.def
index 7be81f6b6a95..6d0c1b14acc1 100644
--- a/contrib/llvm-project/clang/include/clang/Basic/DiagnosticOptions.def
+++ b/contrib/llvm-project/clang/include/clang/Basic/DiagnosticOptions.def
@@ -90,11 +90,15 @@ VALUE_DIAGOPT(ConstexprBacktraceLimit, 32, DefaultConstexprBacktraceLimit)
VALUE_DIAGOPT(SpellCheckingLimit, 32, DefaultSpellCheckingLimit)
/// Limit number of lines shown in a snippet.
VALUE_DIAGOPT(SnippetLineLimit, 32, DefaultSnippetLineLimit)
+/// Show line number column on the left of snippets.
+VALUE_DIAGOPT(ShowLineNumbers, 1, DefaultShowLineNumbers)
VALUE_DIAGOPT(TabStop, 32, DefaultTabStop) /// The distance between tab stops.
/// Column limit for formatting message diagnostics, or 0 if unused.
VALUE_DIAGOPT(MessageLength, 32, 0)
+DIAGOPT(ShowSafeBufferUsageSuggestions, 1, 0)
+
#undef DIAGOPT
#undef ENUM_DIAGOPT
#undef VALUE_DIAGOPT
diff --git a/contrib/llvm-project/clang/include/clang/Basic/DiagnosticOptions.h b/contrib/llvm-project/clang/include/clang/Basic/DiagnosticOptions.h
index 17533b38ff5f..099982c3bdd5 100644
--- a/contrib/llvm-project/clang/include/clang/Basic/DiagnosticOptions.h
+++ b/contrib/llvm-project/clang/include/clang/Basic/DiagnosticOptions.h
@@ -46,20 +46,20 @@ enum class DiagnosticLevelMask : unsigned {
};
inline DiagnosticLevelMask operator~(DiagnosticLevelMask M) {
- using UT = std::underlying_type<DiagnosticLevelMask>::type;
+ using UT = std::underlying_type_t<DiagnosticLevelMask>;
return static_cast<DiagnosticLevelMask>(~static_cast<UT>(M));
}
inline DiagnosticLevelMask operator|(DiagnosticLevelMask LHS,
DiagnosticLevelMask RHS) {
- using UT = std::underlying_type<DiagnosticLevelMask>::type;
+ using UT = std::underlying_type_t<DiagnosticLevelMask>;
return static_cast<DiagnosticLevelMask>(
static_cast<UT>(LHS) | static_cast<UT>(RHS));
}
inline DiagnosticLevelMask operator&(DiagnosticLevelMask LHS,
DiagnosticLevelMask RHS) {
- using UT = std::underlying_type<DiagnosticLevelMask>::type;
+ using UT = std::underlying_type_t<DiagnosticLevelMask>;
return static_cast<DiagnosticLevelMask>(
static_cast<UT>(LHS) & static_cast<UT>(RHS));
}
@@ -72,9 +72,10 @@ class DiagnosticOptions : public RefCountedBase<DiagnosticOptions>{
clang::DiagnosticsEngine *, bool);
friend class CompilerInvocation;
+ friend class CompilerInvocationBase;
public:
- enum TextDiagnosticFormat { Clang, MSVC, Vi };
+ enum TextDiagnosticFormat { Clang, MSVC, Vi, SARIF };
// Default values.
enum {
@@ -84,7 +85,8 @@ public:
DefaultTemplateBacktraceLimit = 10,
DefaultConstexprBacktraceLimit = 10,
DefaultSpellCheckingLimit = 50,
- DefaultSnippetLineLimit = 1,
+ DefaultSnippetLineLimit = 16,
+ DefaultShowLineNumbers = 1,
};
// Define simple diagnostic options (with no accessors).
@@ -122,6 +124,10 @@ public:
/// default).
std::vector<std::string> VerifyPrefixes;
+ /// The list of -Wsystem-header-in-module=... options used to override
+ /// whether -Wsystem-headers is enabled on a per-module basis.
+ std::vector<std::string> SystemHeaderWarningsModules;
+
public:
// Define accessors/mutators for diagnostic options of enumeration type.
#define DIAGOPT(Name, Bits, Default)
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 7e4b0841e06b..a30ab27566ec 100644
--- a/contrib/llvm-project/clang/include/clang/Basic/DiagnosticParseKinds.td
+++ b/contrib/llvm-project/clang/include/clang/Basic/DiagnosticParseKinds.td
@@ -157,11 +157,17 @@ def err_duplicate_default_assoc : Error<
"duplicate default generic association">;
def note_previous_default_assoc : Note<
"previous default generic association is here">;
+def ext_generic_with_type_arg : Extension<
+ "passing a type argument as the first operand to '_Generic' is a Clang "
+ "extension">, InGroup<DiagGroup<"generic-type-extension">>;
def ext_c99_feature : Extension<
"'%0' is a C99 extension">, InGroup<C99>;
def ext_c11_feature : Extension<
"'%0' is a C11 extension">, InGroup<C11>;
+def warn_c23_compat_keyword : Warning<
+ "'%0' is incompatible with C standards before C23">,
+ InGroup<CPre23Compat>, DefaultIgnore;
def err_c11_noreturn_misplaced : Error<
"'_Noreturn' keyword must precede function declarator">;
@@ -174,10 +180,11 @@ def err_stmtexpr_file_scope : Error<
"statement expression not allowed at file scope">;
def ext_gnu_statement_expr : Extension<
"use of GNU statement expression extension">, InGroup<GNUStatementExpression>;
+def ext_gnu_statement_expr_macro : Extension<
+ "use of GNU statement expression extension from macro expansion">,
+ InGroup<GNUStatementExpressionFromMacroExpansion>;
def ext_gnu_conditional_expr : Extension<
"use of GNU ?: conditional expression extension, omitting middle operand">, InGroup<GNUConditionalOmittedOperand>;
-def ext_gnu_empty_initializer : Extension<
- "use of GNU empty initializer extension">, InGroup<GNUEmptyInitializer>;
def ext_gnu_array_range : Extension<"use of GNU array range extension">,
InGroup<GNUDesignator>;
def ext_gnu_missing_equal_designator : ExtWarn<
@@ -279,7 +286,7 @@ def err_inline_nested_namespace_definition : Error<
def err_expected_semi_after_attribute_list : Error<
"expected ';' after attribute list">;
def err_expected_semi_after_static_assert : Error<
- "expected ';' after static_assert">;
+ "expected ';' after '%0'">;
def err_expected_semi_for : Error<"expected ';' in 'for' statement specifier">;
def err_single_decl_assign_in_for_range : Error<
"range-based 'for' statement uses ':', not '='">;
@@ -292,8 +299,24 @@ def note_missing_selector_name : Note<
def note_force_empty_selector_name : Note<
"or insert whitespace before ':' to use %0 as parameter name "
"and have an empty entry in the selector">;
-def err_label_end_of_compound_statement : Error<
- "label at end of compound statement: expected statement">;
+def ext_c_label_followed_by_declaration : ExtWarn<
+ "label followed by a declaration is a C23 extension">,
+ InGroup<C23>;
+def warn_c23_compat_label_followed_by_declaration : Warning<
+ "label followed by a declaration is incompatible with C standards before "
+ "C23">, InGroup<CPre23Compat>, DefaultIgnore;
+def ext_c_label_end_of_compound_statement : ExtWarn<
+ "label at end of compound statement is a C23 extension">,
+ InGroup<C23>;
+def ext_cxx_label_end_of_compound_statement : ExtWarn<
+ "label at end of compound statement is a C++23 extension">,
+ InGroup<CXX23>;
+def warn_c23_compat_label_end_of_compound_statement : Warning<
+ "label at end of compound statement is incompatible with C standards before C23">,
+ InGroup<CPre23Compat>, DefaultIgnore;
+def warn_cxx20_compat_label_end_of_compound_statement : Warning<
+ "label at end of compound statement is incompatible with C++ standards before C++23">,
+ InGroup<CXXPre23Compat>, DefaultIgnore;
def err_address_of_label_outside_fn : Error<
"use of address-of-label extension outside of a function body">;
def err_asm_operand_wide_string_literal : Error<
@@ -422,7 +445,7 @@ def err_unexpected_token_in_nested_name_spec : Error<
def err_bool_redeclaration : Error<
"redeclaration of C++ built-in type 'bool'">;
def warn_cxx98_compat_static_assert : Warning<
- "static_assert declarations are incompatible with C++98">,
+ "'static_assert' declarations are incompatible with C++98">,
InGroup<CXX98Compat>, DefaultIgnore;
def ext_ms_static_assert : ExtWarn<
"use of 'static_assert' without inclusion of <assert.h> is a Microsoft "
@@ -430,15 +453,15 @@ def ext_ms_static_assert : ExtWarn<
def ext_cxx_static_assert_no_message : ExtWarn<
"'static_assert' with no message is a C++17 extension">, InGroup<CXX17>;
def ext_c_static_assert_no_message : ExtWarn<
- "'_Static_assert' with no message is a C2x extension">, InGroup<C2x>;
+ "'_Static_assert' with no message is a C23 extension">, InGroup<C23>;
def warn_cxx14_compat_static_assert_no_message : Warning<
"'static_assert' with no message is incompatible with C++ standards before "
"C++17">,
DefaultIgnore, InGroup<CXXPre17Compat>;
def warn_c17_compat_static_assert_no_message : Warning<
"'_Static_assert' with no message is incompatible with C standards before "
- "C2x">,
- DefaultIgnore, InGroup<CPre2xCompat>;
+ "C23">,
+ DefaultIgnore, InGroup<CPre23Compat>;
def err_function_definition_not_allowed : Error<
"function definition is not allowed here">;
def err_expected_end_of_enumerator : Error<
@@ -535,6 +558,8 @@ def err_invalid_operator_on_type : Error<
"cannot use %select{dot|arrow}0 operator on a type">;
def err_expected_unqualified_id : Error<
"expected %select{identifier|unqualified-id}0">;
+def err_while_loop_outside_of_a_function : Error<
+ "while loop outside of a function">;
def err_brackets_go_after_unqualified_id : Error<
"brackets are not allowed here; to declare an array, "
"place the brackets after the %select{identifier|name}0">;
@@ -549,6 +574,12 @@ def err_expected_init_in_condition_lparen : Error<
"variable declaration in condition cannot have a parenthesized initializer">;
def err_extraneous_rparen_in_condition : Error<
"extraneous ')' after condition, expected a statement">;
+def ext_alias_in_init_statement : ExtWarn<
+ "alias declaration in this context is a C++23 extension">,
+ InGroup<CXX23>;
+def warn_cxx20_alias_in_init_statement : Warning<
+ "alias declaration in this context is incompatible with C++ standards before C++23">,
+ DefaultIgnore, InGroup<CXXPre23Compat>;
def warn_dangling_else : Warning<
"add explicit braces to avoid dangling else">,
InGroup<DanglingElse>;
@@ -586,6 +617,9 @@ def warn_cxx17_compat_using_enum_declaration : Warning<
def ext_using_enum_declaration : ExtWarn<
"using enum declaration is a C++20 extension">,
InGroup<CXX20>;
+def err_using_enum_expect_identifier : Error<
+ "using enum %select{requires an enum or typedef name|"
+ "does not permit an elaborated enum specifier}0">;
def err_constructor_bad_name : Error<
"missing return type for function %0; did you mean the constructor name %1?">;
def err_destructor_tilde_identifier : Error<
@@ -626,6 +660,13 @@ def ext_constexpr_if : ExtWarn<
def warn_cxx14_compat_constexpr_if : Warning<
"constexpr if is incompatible with C++ standards before C++17">,
DefaultIgnore, InGroup<CXXPre17Compat>;
+def ext_consteval_if : ExtWarn<
+ "consteval if is a C++23 extension">,
+ InGroup<CXX23>;
+def warn_cxx20_compat_consteval_if : Warning<
+ "consteval if is incompatible with C++ standards before C++23">,
+ InGroup<CXXPre23Compat>, DefaultIgnore;
+
def ext_init_statement : ExtWarn<
"'%select{if|switch}0' initialization statements are a C++17 extension">,
InGroup<CXX17>;
@@ -668,6 +709,8 @@ def warn_cxx98_compat_noexcept_expr : Warning<
InGroup<CXX98Compat>, DefaultIgnore;
def warn_cxx98_compat_nullptr : Warning<
"'nullptr' is incompatible with C++98">, InGroup<CXX98Compat>, DefaultIgnore;
+def ext_c_nullptr : Extension<
+ "'nullptr' is a C23 extension">, InGroup<C23>;
def warn_wrong_clang_attr_namespace : Warning<
"'__clang__' is a predefined macro name, not an attribute scope specifier; "
@@ -682,8 +725,17 @@ def warn_cxx14_compat_ns_enum_attribute : Warning<
def warn_cxx98_compat_alignas : Warning<"'alignas' is incompatible with C++98">,
InGroup<CXX98Compat>, DefaultIgnore;
def warn_cxx98_compat_attribute : Warning<
- "C++11 attribute syntax is incompatible with C++98">,
+ "[[]] attributes are incompatible with C++ standards before C++11">,
InGroup<CXX98Compat>, DefaultIgnore;
+def warn_ext_cxx11_attributes : Extension<
+ "[[]] attributes are a C++11 extension">,
+ InGroup<CXX11>;
+def warn_pre_c23_compat_attributes : Warning<
+ "[[]] attributes are incompatible with C standards before C23">,
+ DefaultIgnore, InGroup<CPre23Compat>;
+def warn_ext_c23_attributes : Extension<
+ "[[]] attributes are a C23 extension">,
+ InGroup<C23>;
def err_cxx11_attribute_forbids_arguments : Error<
"attribute %0 cannot have an argument list">;
def err_attribute_requires_arguments : Error<
@@ -699,13 +751,17 @@ def ext_using_attribute_ns : ExtWarn<
def err_using_attribute_ns_conflict : Error<
"attribute with scope specifier cannot follow default scope specifier">;
def err_attributes_not_allowed : Error<"an attribute list cannot appear here">;
+def err_keyword_not_allowed : Error<"%0 cannot appear here">;
def ext_cxx11_attr_placement : ExtWarn<
- "ISO C++ does not allow an attribute list to appear here">,
+ "ISO C++ does not allow %select{an attribute list|%0}1 to appear here">,
InGroup<DiagGroup<"cxx-attribute-extension">>;
def err_attributes_misplaced : Error<"misplaced attributes; expected attributes here">;
+def err_keyword_misplaced : Error<"misplaced %0; expected %0 here">;
def err_l_square_l_square_not_attribute : Error<
"C++11 only allows consecutive left square brackets when "
"introducing an attribute">;
+def err_attribute_argument_parm_pack_not_supported : Error<
+ "attribute %0 does not support argument pack expansion">;
def err_ms_declspec_type : Error<
"__declspec attributes must be an identifier or string literal">;
def err_ms_property_no_getter_or_putter : Error<
@@ -742,8 +798,9 @@ def err_unknown_template_name : Error<
"unknown template name %0">;
def err_expected_comma_greater : Error<
"expected ',' or '>' in template-parameter-list">;
-def err_class_on_template_template_param : Error<
- "template template parameter requires 'class' after the parameter list">;
+def err_class_on_template_template_param
+ : Error<"template template parameter requires 'class'%select{| or "
+ "'typename'}0 after the parameter list">;
def ext_template_template_param_typename : ExtWarn<
"template template parameter using 'typename' is a C++17 extension">,
InGroup<CXX17>;
@@ -754,7 +811,8 @@ def warn_cxx14_compat_template_template_param_typename : Warning<
def err_template_spec_syntax_non_template : Error<
"identifier followed by '<' indicates a class template specialization but "
"%0 %select{does not refer to a template|refers to a function template|"
- "<unused>|refers to a variable template|<unused>|refers to a concept}1">;
+ "<unused>|refers to a variable template|<unused>|<unused>|"
+ "refers to a concept}1">;
def err_id_after_template_in_nested_name_spec : Error<
"expected template name after 'template' keyword in nested name specifier">;
def err_unexpected_template_in_unqualified_id : Error<
@@ -806,10 +864,10 @@ def err_requires_expr_expected_type_constraint : Error<
def err_requires_expr_simple_requirement_noexcept : Error<
"'noexcept' can only be used in a compound requirement (with '{' '}' around "
"the expression)">;
-def warn_requires_expr_in_simple_requirement : Warning<
- "this requires expression will only be checked for syntactic validity; did "
+def err_requires_expr_in_simple_requirement : Error<
+ "requires expression in requirement body; did "
"you intend to place it in a nested requirement? (add another 'requires' "
- "before the expression)">, InGroup<DiagGroup<"requires-expression">>;
+ "before the expression)">;
def err_missing_dependent_template_keyword : Error<
"use 'template' keyword to treat '%0' as a dependent template name">;
@@ -944,6 +1002,9 @@ def err_duplicate_class_virt_specifier : Error<
def err_duplicate_virt_specifier : Error<
"class member already marked '%0'">;
+def err_virt_specifier_outside_class : Error<
+ "'%0' specifier is not allowed outside a class definition">;
+
def err_expected_parameter_pack : Error<
"expected the name of a parameter pack">;
def err_paren_sizeof_parameter_pack : Error<
@@ -963,7 +1024,8 @@ def warn_cxx98_compat_lambda : Warning<
"lambda expressions are incompatible with C++98">,
InGroup<CXX98Compat>, DefaultIgnore;
def err_lambda_decl_specifier_repeated : Error<
- "%select{'mutable'|'constexpr'|'consteval'}0 cannot appear multiple times in a lambda declarator">;
+ "%select{'mutable'|'static'|'constexpr'|'consteval'}0 cannot "
+ "appear multiple times in a lambda declarator">;
def err_lambda_capture_misplaced_ellipsis : Error<
"ellipsis in pack %select{|init-}0capture must appear %select{after|before}0 "
"the name of the capture">;
@@ -972,14 +1034,15 @@ def err_lambda_capture_multiple_ellipses : Error<
def err_capture_default_first : Error<
"capture default must be first">;
def ext_decl_attrs_on_lambda : ExtWarn<
- "an attribute specifier sequence in this position is a C++2b extension">,
- InGroup<CXX2b>;
+ "%select{an attribute specifier sequence|%0}1 in this position "
+ "is a C++23 extension">, InGroup<CXX23AttrsOnLambda>;
def ext_lambda_missing_parens : ExtWarn<
- "lambda without a parameter clause is a C++2b extension">,
- InGroup<CXX2b>;
+ "lambda without a parameter clause is a C++23 extension">,
+ InGroup<CXX23>;
def warn_cxx20_compat_decl_attrs_on_lambda : Warning<
- "an attribute specifier sequence in this position is incompatible with C++ "
- "standards before C++2b">, InGroup<CXXPre2bCompat>, DefaultIgnore;
+ "%select{an attribute specifier sequence|%1}0 in this position "
+ "is incompatible with C++ standards before C++23">,
+ InGroup<CXXPre23Compat>, DefaultIgnore;
// C++17 lambda expressions
def err_expected_star_this_capture : Error<
@@ -1002,6 +1065,17 @@ def warn_cxx17_compat_lambda_template_parameter_list: Warning<
def err_lambda_template_parameter_list_empty : Error<
"lambda template parameter list cannot be empty">;
+// C++23 static lambdas
+def err_static_lambda: ExtWarn<
+ "static lambdas are a C++23 extension">, InGroup<CXX23>;
+def warn_cxx20_compat_static_lambda : Warning<
+ "static lambdas are incompatible with C++ standards before C++23">,
+ InGroup<CXXPre23Compat>, DefaultIgnore;
+def err_static_mutable_lambda : Error<
+ "lambda cannot be both mutable and static">;
+def err_static_lambda_captures : Error<
+ "a static lambda cannot have any captures">;
+
// Availability attribute
def err_expected_version : Error<
"expected a version of the form 'major[.minor[.subminor]]'">;
@@ -1046,7 +1120,7 @@ def err_availability_query_repeated_star : Error<
// External source symbol attribute
def err_external_source_symbol_expected_keyword : Error<
- "expected 'language', 'defined_in', or 'generated_declaration'">;
+ "expected 'language', 'defined_in', 'generated_declaration', or 'USR'">;
def err_external_source_symbol_duplicate_clause : Error<
"duplicate %0 clause in an 'external_source_symbol' attribute">;
@@ -1102,6 +1176,9 @@ def warn_pragma_expected_integer : Warning<
def warn_pragma_ms_struct : Warning<
"incorrect use of '#pragma ms_struct on|off' - ignored">,
InGroup<IgnoredPragmas>;
+def warn_pragma_ms_fenv_access : Warning<
+ "incorrect use of '#pragma fenv_access (on|off)' - ignored">,
+ InGroup<IgnoredPragmas>;
def warn_pragma_extra_tokens_at_eol : Warning<
"extra tokens at end of '#pragma %0' - ignored">,
InGroup<IgnoredPragmas>;
@@ -1144,10 +1221,6 @@ def warn_pragma_pack_malformed : Warning<
def warn_pragma_intrinsic_builtin : Warning<
"%0 is not a recognized builtin%select{|; consider including <intrin.h> to access non-builtin intrinsics}1">,
InGroup<IgnoredPragmaIntrinsic>;
-// - #pragma optimize
-def warn_pragma_optimize : Warning<
- "'#pragma optimize' is not supported">,
- InGroup<IgnoredPragmaOptimize>;
// - #pragma unused
def warn_pragma_unused_expected_var : Warning<
"expected '#pragma unused' argument to be a variable name">,
@@ -1167,9 +1240,6 @@ def ext_stdc_pragma_ignored : ExtWarn<"unknown pragma in STDC namespace">,
// The C standard 7.6.1p2 says "The [FENV_ACCESS] pragma shall occur either
// outside external declarations or preceding all explicit declarations and
// statements inside a compound statement.
-def err_pragma_stdc_fenv_access_scope : Error<
- "'#pragma STDC FENV_ACCESS' can only appear at file scope or at the start of"
- " a compound statement">;
def warn_stdc_fenv_round_not_supported :
Warning<"pragma STDC FENV_ROUND is not supported">,
InGroup<UnknownPragmas>;
@@ -1218,8 +1288,6 @@ def err_pragma_attribute_extra_tokens_after_attribute : Error<
"extra tokens after attribute in a '#pragma clang attribute push'">;
def err_pragma_attribute_unsupported_attribute : Error<
"attribute %0 is not supported by '#pragma clang attribute'">;
-def err_pragma_attribute_multiple_attributes : Error<
- "more than one attribute specified in '#pragma clang attribute push'">;
def err_pragma_attribute_expected_attribute_syntax : Error<
"expected an attribute that is specified using the GNU, C++11 or '__declspec'"
" syntax">;
@@ -1248,6 +1316,13 @@ def err_pragma_attribute_namespace_on_attribute : Error<
def note_pragma_attribute_namespace_on_attribute : Note<
"omit the namespace to add attributes to the most-recently"
" pushed attribute group">;
+def warn_no_support_for_eval_method_source_on_m32 : Warning<
+ "Setting the floating point evaluation method to `source` on a target"
+ " without SSE is not supported.">, InGroup<Pragmas>;
+// - #pragma __debug
+def warn_pragma_debug_dependent_argument : Warning<
+ "%select{value|type}0-dependent expression passed as an argument to debug "
+ "command">, InGroup<IgnoredPragmas>;
// OpenCL EXTENSION pragma (OpenCL 1.1 [9.1])
def warn_pragma_expected_colon : Warning<
@@ -1255,12 +1330,13 @@ def warn_pragma_expected_colon : Warning<
def warn_pragma_expected_predicate : Warning<
"expected %select{'enable', 'disable', 'begin' or 'end'|'disable'}0 - ignoring">, InGroup<IgnoredPragmas>;
def warn_pragma_unknown_extension : Warning<
- "unknown OpenCL extension %0 - ignoring">, InGroup<IgnoredPragmas>;
+ "OpenCL extension %0 unknown or does not require pragma - ignoring">, InGroup<IgnoredPragmas>;
def warn_pragma_unsupported_extension : Warning<
"unsupported OpenCL extension %0 - ignoring">, InGroup<IgnoredPragmas>;
def warn_pragma_extension_is_core : Warning<
"OpenCL extension %0 is core feature or supported optional core feature - ignoring">,
InGroup<OpenCLCoreFeaturesDiagGroup>, DefaultIgnore;
+def err_modifier_expected_colon : Error<"missing ':' after %0 modifier">;
// OpenCL errors.
def err_opencl_taking_function_address_parser : Error<
@@ -1272,12 +1348,44 @@ def err_opencl_logical_exclusive_or : Error<
def err_openclcxx_virtual_function : Error<
"virtual functions are not supported in C++ for OpenCL">;
+// OpenACC Support.
+def warn_pragma_acc_ignored
+ : Warning<"unexpected '#pragma acc ...' in program">,
+ InGroup<SourceUsesOpenACC>,
+ DefaultIgnore;
+def err_acc_unexpected_directive
+ : Error<"unexpected OpenACC directive %select{|'#pragma acc %1'}0">;
+def warn_pragma_acc_unimplemented
+ : Warning<"OpenACC directives not yet implemented, pragma ignored">,
+ InGroup<SourceUsesOpenACC>;
+def err_acc_invalid_directive
+ : Error<"invalid OpenACC directive %select{%1|'%1 %2'}0">;
+def err_acc_invalid_clause : Error<"invalid OpenACC clause %0">;
+def err_acc_missing_directive : Error<"expected OpenACC directive">;
+def err_acc_invalid_open_paren
+ : Error<"expected clause-list or newline in OpenACC directive">;
+def err_acc_invalid_default_clause_kind
+ : Error<"invalid value for 'default' clause; expected 'present' or 'none'">;
+def err_acc_invalid_tag_kind
+ : Error<"invalid tag %0 on '%1' %select{directive|clause}2">;
+def err_acc_expected_reduction_operator
+ : Error<"missing reduction operator, expected '+', '*', 'max', 'min', '&', "
+ "'|', '^', '&&', or '||', follwed by a ':'">;
+def err_acc_invalid_reduction_operator
+ : Error<"invalid reduction operator, expected '+', '*', 'max', 'min', "
+ "'&', '|', '^', '&&', or '||'">;
+def err_acc_incorrect_bind_arg : Error<"expected identifier or string literal">;
+
// OpenMP support.
def warn_pragma_omp_ignored : Warning<
"unexpected '#pragma omp ...' in program">, InGroup<SourceUsesOpenMP>, DefaultIgnore;
def warn_omp_extra_tokens_at_eol : Warning<
"extra tokens at the end of '#pragma omp %0' are ignored">,
InGroup<ExtraTokens>;
+def err_omp_multiple_step_or_linear_modifier : Error<
+ "multiple %select{'step size'|'linear modifier'}0 found in linear clause">;
+def err_omp_deprecate_old_syntax: Error<
+ "old syntax '%0' on '%1' clause was deprecated, use new syntax '%2'">;
def warn_pragma_expected_colon_r_paren : Warning<
"missing ':' or ')' after %0 - ignoring">, InGroup<IgnoredPragmas>;
def err_omp_unknown_directive : Error<
@@ -1286,8 +1394,12 @@ def err_omp_unexpected_directive : Error<
"unexpected OpenMP directive %select{|'#pragma omp %1'}0">;
def err_omp_expected_punc : Error<
"expected ',' or ')' in '%0' %select{clause|directive}1">;
+def warn_clause_expected_string : Warning<
+ "expected string literal in 'clause %0' - ignoring">, InGroup<IgnoredPragmas>;
def err_omp_unexpected_clause : Error<
"unexpected OpenMP clause '%0' in directive '#pragma omp %1'">;
+def err_omp_unexpected_clause_extension_only : Error<
+ "OpenMP clause '%0' is only available as extension, use '-fopenmp-extensions'">;
def err_omp_immediate_directive : Error<
"'#pragma omp %0' %select{|with '%2' clause }1cannot be an immediate substatement">;
def err_omp_expected_identifier_for_critical : Error<
@@ -1300,17 +1412,21 @@ def err_omp_expected_punc_after_iterator : Error<
"expected ',' or ')' after iterator specifier">;
def err_omp_decl_in_declare_simd_variant : Error<
"function declaration is expected after 'declare %select{simd|variant}0' directive">;
+def err_omp_sink_and_source_iteration_not_allowd: Error<" '%0 %select{sink:|source:}1' must be with '%select{omp_cur_iteration - 1|omp_cur_iteration}1'">;
def err_omp_unknown_map_type : Error<
"incorrect map type, expected one of 'to', 'from', 'tofrom', 'alloc', 'release', or 'delete'">;
def err_omp_unknown_map_type_modifier : Error<
- "incorrect map type modifier, expected 'always', 'close', "
- "%select{or 'mapper'|'mapper', or 'present'}0">;
+ "incorrect map type modifier, expected one of: 'always', 'close', 'mapper'"
+ "%select{|, 'present'|, 'present', 'iterator'}0%select{|, 'ompx_hold'}1">;
def err_omp_map_type_missing : Error<
"missing map type">;
def err_omp_map_type_modifier_missing : Error<
"missing map type modifier">;
def err_omp_declare_simd_inbranch_notinbranch : Error<
"unexpected '%0' clause, '%1' is specified already">;
+def err_omp_expected_clause_argument
+ : Error<"expected '%0' clause with an argument on '#pragma omp %1' "
+ "construct">;
def err_expected_end_declare_target_or_variant : Error<
"expected '#pragma omp end declare %select{target|variant}0'">;
def err_expected_begin_declare_variant
@@ -1327,23 +1443,40 @@ 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_declare_target_unexpected_clause_52: Error<
+ "unexpected '%0' clause, only %select{'device_type'|'enter' or 'link'|'enter', 'link' or 'device_type'|'device_type', 'indirect'|'enter', '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<
+def err_omp_declare_target_wrong_clause_after_implicit_to: Error<
"unexpected clause after an implicit 'to' clause">;
+def err_omp_declare_target_wrong_clause_after_implicit_enter: Error<
+ "unexpected clause after an implicit 'enter' 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_missing_enter_or_link_clause: Error<
+ "expected at least one %select{'enter' or 'link'|'enter', 'link' or 'indirect'}0 clause">;
+def err_omp_declare_target_unexpected_to_clause: Error<
+ "unexpected 'to' clause, use 'enter' instead">;
+def err_omp_declare_target_unexpected_enter_clause: Error<
+ "unexpected 'enter' clause, use 'to' instead">;
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<
"illegal OpenMP user-defined mapper identifier">;
def err_omp_mapper_expected_declarator : Error<
"expected declarator on 'omp declare mapper' directive">;
+def err_omp_unexpected_append_op : Error<
+ "unexpected operation specified in 'append_args' clause, expected 'interop'">;
+def err_omp_unexpected_execution_modifier : Error<
+ "unexpected 'execution' modifier in non-executable context">;
def err_omp_declare_variant_wrong_clause : Error<
- "expected '%0' clause on 'omp declare variant' directive">;
+ "expected %select{'match'|'match', 'adjust_args', or 'append_args'}0 clause "
+ "on 'omp declare variant' directive">;
def err_omp_declare_variant_duplicate_nested_trait : Error<
"nested OpenMP context selector contains duplicated trait '%0'"
" in selector '%1' and set '%2' with different score">;
@@ -1354,11 +1487,13 @@ 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">,
InGroup<SourceUsesOpenMP>;
+def note_ompx_bare_clause : Note<
+ "OpenMP extension clause '%0' only allowed with '#pragma omp %1'">;
def note_omp_declare_variant_ctx_options
: Note<"context %select{set|selector|property}0 options are: %1">;
def warn_omp_declare_variant_expected
@@ -1436,6 +1571,21 @@ def warn_omp51_compat_attributes : Warning<
"specifying OpenMP directives with [[]] is incompatible with OpenMP "
"standards before OpenMP 5.1">,
InGroup<OpenMPPre51Compat>, DefaultIgnore;
+def err_omp_expected_colon : Error<"missing ':' in %0">;
+def err_omp_missing_comma : Error< "missing ',' after %0">;
+def err_omp_expected_context_selector
+ : Error<"expected valid context selector in %0">;
+def err_omp_requires_out_inout_depend_type : Error<
+ "reserved locator 'omp_all_memory' requires 'out' or 'inout' "
+ "dependency types">;
+def warn_omp_more_one_omp_all_memory : Warning<
+ "reserved locator 'omp_all_memory' cannot be specified more than once">,
+ InGroup<OpenMPClauses>;
+def warn_omp_depend_in_ordered_deprecated : Warning<"'depend' clause for"
+ " 'ordered' is deprecated; use 'doacross' instead">, InGroup<Deprecated>;
+def warn_omp_invalid_attribute_for_ompx_attributes : Warning<"'ompx_attribute' clause only allows "
+ "'amdgpu_flat_work_group_size', 'amdgpu_waves_per_eu', and 'launch_bounds'; "
+ "%0 is ignored">, InGroup<OpenMPExtensions>;
// Pragma loop support.
def err_pragma_loop_missing_argument : Error<
@@ -1453,26 +1603,31 @@ def note_pragma_loop_invalid_vectorize_option : Note<
"vectorize_width(X, scalable) where X is an integer, or vectorize_width('fixed' or 'scalable')">;
def err_pragma_fp_invalid_option : Error<
- "%select{invalid|missing}0 option%select{ %1|}0; expected 'contract', 'reassociate' or 'exceptions'">;
+ "%select{invalid|missing}0 option%select{ %1|}0; expected 'contract', 'reassociate', 'reciprocal', or 'exceptions'">;
def err_pragma_fp_invalid_argument : Error<
"unexpected argument '%0' to '#pragma clang fp %1'; expected "
"%select{"
"'fast' or 'on' or 'off'|"
"'on' or 'off'|"
- "'ignore', 'maytrap' or 'strict'}2">;
+ "'on' or 'off'|"
+ "'ignore', 'maytrap' or 'strict'|"
+ "'source', 'double' or 'extended'}2">;
def err_pragma_invalid_keyword : Error<
"invalid argument; expected 'enable'%select{|, 'full'}0%select{|, 'assume_safety'}1 or 'disable'">;
def err_pragma_pipeline_invalid_keyword : Error<
"invalid argument; expected 'disable'">;
+// API notes.
+def err_type_unparsed : Error<"unparsed tokens following type">;
+
// Pragma unroll support.
def warn_pragma_unroll_cuda_value_in_parens : Warning<
"argument to '#pragma unroll' should not be in parentheses in CUDA C/C++">,
InGroup<CudaCompat>;
def warn_cuda_attr_lambda_position : Warning<
- "nvcc does not allow '__%0__' to appear after '()' in lambdas">,
+ "nvcc does not allow '__%0__' to appear after the parameter list in lambdas">,
InGroup<CudaCompat>;
def warn_pragma_force_cuda_host_device_bad_arg : Warning<
"incorrect use of #pragma clang force_cuda_host_device begin|end">,
@@ -1480,6 +1635,12 @@ def warn_pragma_force_cuda_host_device_bad_arg : Warning<
def err_pragma_cannot_end_force_cuda_host_device : Error<
"force_cuda_host_device end pragma without matching "
"force_cuda_host_device begin">;
+
+def warn_ext_int_deprecated : Warning<
+ "'_ExtInt' is deprecated; use '_BitInt' instead">, InGroup<DeprecatedType>;
+def ext_bit_int : Extension<
+ "'_BitInt' in %select{C17 and earlier|C++}0 is a Clang extension">,
+ InGroup<DiagGroup<"bit-int-extension">>;
} // end of Parse Issue category.
let CategoryName = "Modules Issue" in {
@@ -1489,8 +1650,12 @@ def err_module_expected_ident : Error<
"expected a module name after '%select{module|import}0'">;
def err_attribute_not_module_attr : Error<
"%0 attribute cannot be applied to a module">;
+def err_keyword_not_module_attr : Error<
+ "%0 cannot be applied to a module">;
def err_attribute_not_import_attr : Error<
"%0 attribute cannot be applied to a module import">;
+def err_keyword_not_import_attr : Error<
+ "%0 cannot be applied to a module import">;
def err_module_expected_semi : Error<
"expected ';' after module name">;
def err_global_module_introducer_not_at_start : Error<
@@ -1502,7 +1667,13 @@ def err_private_module_fragment_expected_semi : Error<
"expected ';' after private module fragment declaration">;
def err_missing_before_module_end : Error<"expected %0 at end of module">;
def err_unsupported_module_partition : Error<
- "sorry, module partitions are not yet supported">;
+ "module partitions are only supported for C++20 onwards">;
+def err_import_not_allowed_here : Error<
+ "imports must immediately follow the module declaration">;
+def err_partition_import_outside_module : Error<
+ "module partition imports must be within a module purview">;
+def err_import_in_wrong_fragment : Error<
+ "module%select{| partition}0 imports cannot be in the %select{global|private}1 module fragment">;
def err_export_empty : Error<"export declaration cannot be empty">;
}
@@ -1525,14 +1696,16 @@ def note_meant_to_use_typename : Note<
let CategoryName = "Coroutines Issue" in {
def err_for_co_await_not_range_for : Error<
"'co_await' modifier can only be applied to range-based for loop">;
+def warn_deprecated_for_co_await : Warning<
+ "'for co_await' belongs to CoroutineTS instead of C++20, which is deprecated">,
+ InGroup<DeprecatedCoroutine>;
}
let CategoryName = "Concepts Issue" in {
def err_concept_definition_not_identifier : Error<
"name defined in concept definition must be an identifier">;
-def ext_concept_legacy_bool_keyword : ExtWarn<
- "ISO C++20 does not permit the 'bool' keyword after 'concept'">,
- InGroup<DiagGroup<"concepts-ts-compat">>;
+def err_concept_legacy_bool_keyword : Error<
+ "ISO C++ does not permit the 'bool' keyword after 'concept'">;
def err_placeholder_expected_auto_or_decltype_auto : Error<
"expected 'auto' or 'decltype(auto)' after concept name">;
}
@@ -1547,4 +1720,16 @@ def warn_max_tokens_total : Warning<
def note_max_tokens_total_override : Note<"total token limit set here">;
+// HLSL Parser Diagnostics
+
+def err_expected_semantic_identifier : Error<
+ "expected HLSL Semantic identifier">;
+def err_invalid_declaration_in_hlsl_buffer : Error<
+ "invalid declaration inside %select{tbuffer|cbuffer}0">;
+def err_unknown_hlsl_semantic : Error<"unknown HLSL semantic %0">;
+def err_hlsl_separate_attr_arg_and_number : Error<"wrong argument format for hlsl attribute, use %0 instead">;
+def ext_hlsl_access_specifiers : ExtWarn<
+ "access specifiers are a clang HLSL extension">,
+ InGroup<HLSLExtension>;
+
} // end of Parser diagnostics
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 c57b8eca7deb..07ba4ecf7e12 100644
--- a/contrib/llvm-project/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/contrib/llvm-project/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -66,6 +66,7 @@ def warn_infinite_recursive_function : Warning<
def warn_comma_operator : Warning<"possible misuse of comma operator here">,
InGroup<DiagGroup<"comma">>, DefaultIgnore;
def note_cast_to_void : Note<"cast expression to void to silence warning">;
+def note_cast_operand_to_int : Note<"cast one or both operands to int to silence this warning">;
// Constant expressions
def err_expr_not_ice : Error<
@@ -82,11 +83,11 @@ def err_typecheck_converted_constant_expression_indirect : Error<
"bind reference to a temporary">;
def err_expr_not_cce : Error<
"%select{case value|enumerator value|non-type template argument|"
- "array size|explicit specifier argument}0 "
- "is not a constant expression">;
+ "array size|explicit specifier argument|noexcept specifier argument|"
+ "call to 'size()'|call to 'data()'}0 is not a constant expression">;
def ext_cce_narrowing : ExtWarn<
"%select{case value|enumerator value|non-type template argument|"
- "array size|explicit specifier argument}0 "
+ "array size|explicit specifier argument|noexcept specifier argument}0 "
"%select{cannot be narrowed from type %2 to %3|"
"evaluates to %2, which cannot be narrowed to type %3}1">,
InGroup<CXX11Narrowing>, DefaultError, SFINAEFailure;
@@ -111,12 +112,22 @@ def err_expr_not_string_literal : Error<"expression is not a string literal">;
def ext_predef_outside_function : Warning<
"predefined identifier is only valid inside function">,
InGroup<DiagGroup<"predefined-identifier-outside-function">>;
+def ext_init_from_predefined : ExtWarn<
+ "initializing an array from a '%0' predefined identifier is a Microsoft extension">,
+ InGroup<MicrosoftInitFromPredefined>;
+def ext_string_literal_from_predefined : ExtWarn<
+ "expansion of predefined identifier '%0' to a string literal is a Microsoft extension">,
+ InGroup<MicrosoftStringLiteralFromPredefined>;
def warn_float_overflow : Warning<
"magnitude of floating-point constant too large for type %0; maximum is %1">,
InGroup<LiteralRange>;
def warn_float_underflow : Warning<
"magnitude of floating-point constant too small for type %0; minimum is %1">,
InGroup<LiteralRange>;
+def warn_float_compare_literal : Warning<
+ "floating-point comparison is always %select{true|false}0; "
+ "constant cannot be represented exactly in type %1">,
+ InGroup<LiteralRange>;
def warn_double_const_requires_fp64 : Warning<
"double precision constant requires %select{cl_khr_fp64|cl_khr_fp64 and __opencl_c_fp64}0, "
"casting to single precision">;
@@ -126,6 +137,18 @@ def err_half_const_requires_fp16 : Error<
// C99 variable-length arrays
def ext_vla : Extension<"variable length arrays are a C99 feature">,
InGroup<VLAExtension>;
+// In C++ language modes, we warn by default as an extension, while in GNU++
+// language modes, we warn as an extension but add the warning group to -Wall.
+def ext_vla_cxx : ExtWarn<
+ "variable length arrays in C++ are a Clang extension">,
+ InGroup<VLACxxExtension>;
+def ext_vla_cxx_in_gnu_mode : Extension<ext_vla_cxx.Summary>,
+ InGroup<VLACxxExtension>;
+def ext_vla_cxx_static_assert : ExtWarn<
+ "variable length arrays in C++ are a Clang extension; did you mean to use "
+ "'static_assert'?">, InGroup<VLAUseStaticAssert>;
+def ext_vla_cxx_in_gnu_mode_static_assert : Extension<
+ ext_vla_cxx_static_assert.Summary>, InGroup<VLAUseStaticAssert>;
def warn_vla_used : Warning<"variable length array used">,
InGroup<VLA>, DefaultIgnore;
def err_vla_in_sfinae : Error<
@@ -142,7 +165,9 @@ def ext_vla_folded_to_constant : ExtWarn<
"variable length array folded to constant array as an extension">,
InGroup<GNUFoldingConstant>;
def err_vla_unsupported : Error<
- "variable length arrays are not supported for the current target">;
+ "variable length arrays are not supported for %select{the current target|'%1'}0">;
+def err_vla_in_coroutine_unsupported : Error<
+ "variable length arrays in a coroutine are not supported">;
def note_vla_unsupported : Note<
"variable length arrays are not supported for the current target">;
@@ -179,8 +204,10 @@ def err_designator_for_scalar_or_sizeless_init : Error<
def warn_initializer_overrides : Warning<
"initializer %select{partially |}0overrides prior initialization of "
"this subobject">, InGroup<InitializerOverrides>;
-def ext_initializer_overrides : ExtWarn<warn_initializer_overrides.Text>,
+def ext_initializer_overrides : ExtWarn<warn_initializer_overrides.Summary>,
InGroup<InitializerOverrides>, SFINAEFailure;
+def ext_initializer_union_overrides : ExtWarn<warn_initializer_overrides.Summary>,
+ InGroup<InitializerOverrides>, DefaultError, SFINAEFailure;
def err_initializer_overrides_destructed : Error<
"initializer would partially override prior initialization of object of "
"type %1 with non-trivial destruction">;
@@ -196,7 +223,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;
@@ -226,6 +254,10 @@ def ext_imaginary_constant : Extension<
"imaginary constants are a GNU extension">, InGroup<GNUImaginaryConstant>;
def ext_integer_complex : Extension<
"complex integer types are a GNU extension">, InGroup<GNUComplexInteger>;
+def ext_c23_auto_non_plain_identifier : Extension<
+ "type inference of a declaration other than a plain identifier with optional "
+ "trailing attributes is a Clang extension">,
+ InGroup<DiagGroup<"auto-decl-extensions">>;
def err_invalid_saturation_spec : Error<"'_Sat' specifier is only valid on "
"'_Fract' or '_Accum', not '%0'">;
@@ -267,10 +299,12 @@ def err_invalid_vector_double_decl_spec : Error <
def err_invalid_vector_bool_int128_decl_spec : Error <
"use of '__int128' with '__vector bool' requires VSX support enabled (on "
"POWER10 or later)">;
+def err_invalid_vector_int128_decl_spec : Error<
+ "use of '__int128' with '__vector' requires extended Altivec support"
+ " (available on POWER8 or later)">;
def err_invalid_vector_long_long_decl_spec : Error <
- "use of 'long long' with '__vector bool' requires VSX support (available on "
- "POWER7 or later) or extended Altivec support (available on POWER8 or later) "
- "to be enabled">;
+ "use of 'long long' with '__vector' requires VSX support (available on "
+ "POWER7 or later) to be enabled">;
def err_invalid_vector_long_double_decl_spec : Error<
"cannot use 'long double' with '__vector'">;
def warn_vector_long_decl_spec_combination : Warning<
@@ -284,9 +318,9 @@ def err_bad_parameter_name : Error<
"%0 cannot be the name of a parameter">;
def err_bad_parameter_name_template_id : Error<
"parameter name cannot have template arguments">;
-def ext_parameter_name_omitted_c2x : ExtWarn<
- "omitting the parameter name in a function definition is a C2x extension">,
- InGroup<C2x>;
+def ext_parameter_name_omitted_c23 : ExtWarn<
+ "omitting the parameter name in a function definition is a C23 extension">,
+ InGroup<C23>;
def err_anyx86_interrupt_attribute : Error<
"%select{x86|x86-64}0 'interrupt' attribute only applies to functions that "
"have %select{a 'void' return type|"
@@ -294,10 +328,12 @@ def err_anyx86_interrupt_attribute : Error<
"a pointer as the first parameter|a %2 type as the second parameter}1">;
def err_anyx86_interrupt_called : Error<
"interrupt service routine cannot be called directly">;
-def warn_anyx86_interrupt_regsave : Warning<
- "interrupt service routine should only call a function"
- " with attribute 'no_caller_saved_registers'">,
- InGroup<DiagGroup<"interrupt-service-routine">>;
+def warn_anyx86_excessive_regsave : Warning<
+ "%select{interrupt service routine|function with attribute"
+ " 'no_caller_saved_registers'}0 should only call a function"
+ " with attribute 'no_caller_saved_registers'"
+ " or be compiled with '-mgeneral-regs-only'">,
+ InGroup<DiagGroup<"excessive-regsave">>;
def warn_arm_interrupt_calling_convention : Warning<
"call to function without interrupt attribute could clobber interruptee's VFP registers">,
InGroup<Extra>;
@@ -388,10 +424,16 @@ def warn_reserved_extern_symbol: Warning<
"identifier %0 is reserved because %select{"
"<ERROR>|" // ReservedIdentifierStatus::NotReserved
"it starts with '_' at global scope|"
+ "it starts with '_' and has C language linkage|"
"it starts with '__'|"
"it starts with '_' followed by a capital letter|"
"it contains '__'}1">,
InGroup<ReservedIdentifier>, DefaultIgnore;
+def warn_deprecated_literal_operator_id: Warning<
+ "identifier %0 preceded by whitespace in a literal operator declaration "
+ "is deprecated">, InGroup<DeprecatedLiteralOperator>, DefaultIgnore;
+def warn_reserved_module_name : Warning<
+ "%0 is a reserved name for a module">, InGroup<ReservedModuleIdentifier>;
def warn_parameter_size: Warning<
"%0 is a large (%1 bytes) pass-by-value argument; "
@@ -408,18 +450,15 @@ def warn_return_value_udt_incomplete: Warning<
def warn_implicit_function_decl : Warning<
"implicit declaration of function %0">,
InGroup<ImplicitFunctionDeclare>, DefaultIgnore;
-def ext_implicit_function_decl : ExtWarn<
- "implicit declaration of function %0 is invalid in C99">,
- InGroup<ImplicitFunctionDeclare>;
+def ext_implicit_function_decl_c99 : ExtWarn<
+ "call to undeclared function %0; ISO C99 and later do not support implicit "
+ "function declarations">, InGroup<ImplicitFunctionDeclare>;
def note_function_suggestion : Note<"did you mean %0?">;
def err_ellipsis_first_param : Error<
"ISO C requires a named parameter before '...'">;
def err_declarator_need_ident : Error<"declarator requires an identifier">;
def err_language_linkage_spec_unknown : Error<"unknown linkage language">;
-def err_language_linkage_spec_not_ascii : Error<
- "string literal in language linkage specifier cannot have an "
- "encoding-prefix">;
def ext_use_out_of_scope_declaration : ExtWarn<
"use of out-of-scope declaration of %0%select{| whose type is not "
"compatible with that of an implicit declaration}1">,
@@ -434,7 +473,7 @@ def warn_qual_return_type : Warning<
def warn_deprecated_redundant_constexpr_static_def : Warning<
"out-of-line definition of constexpr static data member is redundant "
"in C++17 and is deprecated">,
- InGroup<Deprecated>, DefaultIgnore;
+ InGroup<DeprecatedRedundantConstexprStaticDef>, DefaultIgnore;
def warn_decl_shadow :
Warning<"declaration shadows a %select{"
@@ -445,9 +484,9 @@ 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>,
+ Warning<warn_decl_shadow.Summary>,
InGroup<ShadowUncapturedLocal>, DefaultIgnore;
def warn_ctor_parm_shadows_field:
Warning<"constructor parameter %0 shadows the field %1 of %2">,
@@ -483,6 +522,8 @@ def warn_cxx17_compat_decomp_decl_spec : Warning<
def err_decomp_decl_type : Error<
"decomposition declaration cannot be declared with type %0; "
"declared type must be 'auto' or reference to 'auto'">;
+def err_decomp_decl_constraint : Error<
+ "decomposition declaration cannot be declared with constrained 'auto'">;
def err_decomp_decl_parens : Error<
"decomposition declaration cannot be declared with parentheses">;
def err_decomp_decl_template : Error<
@@ -551,11 +592,10 @@ def err_using_decl_can_not_refer_to_class_member : Error<
def warn_cxx17_compat_using_decl_class_member_enumerator : Warning<
"member using declaration naming a non-member enumerator is incompatible "
"with C++ standards before C++20">, InGroup<CXXPre20Compat>, DefaultIgnore;
-def ext_using_decl_class_member_enumerator : ExtWarn<
- "member using declaration naming a non-member enumerator is "
- "a C++20 extension">, InGroup<CXX20>;
def err_using_enum_is_dependent : Error<
"using-enum cannot name a dependent type">;
+def err_using_enum_not_enum : Error<
+ "%0 is not an enumerated type">;
def err_ambiguous_inherited_constructor : Error<
"constructor of %0 inherited from multiple base class subobjects">;
def note_ambiguous_inherited_constructor_using : Note<
@@ -652,6 +692,13 @@ def warn_maybe_falloff_nonvoid_function : Warning<
def warn_falloff_nonvoid_function : Warning<
"non-void function does not return a value">,
InGroup<ReturnType>;
+def warn_const_attr_with_pure_attr : Warning<
+ "'const' attribute imposes more restrictions; 'pure' attribute ignored">,
+ InGroup<IgnoredAttributes>;
+def warn_pure_function_returns_void : Warning<
+ "'%select{pure|const}0' attribute on function returning 'void'; attribute ignored">,
+ InGroup<IgnoredAttributes>;
+
def err_maybe_falloff_nonvoid_block : Error<
"non-void block does not return a value in all control paths">;
def err_falloff_nonvoid_block : Error<
@@ -682,13 +729,24 @@ def warn_unreachable_return : Warning<
def warn_unreachable_loop_increment : Warning<
"loop will run at most once (loop increment never executed)">,
InGroup<UnreachableCodeLoopIncrement>, DefaultIgnore;
+def warn_unreachable_fallthrough_attr : Warning<
+ "fallthrough annotation in unreachable code">,
+ InGroup<UnreachableCodeFallthrough>, DefaultIgnore;
def note_unreachable_silence : Note<
"silence by adding parentheses to mark code as explicitly dead">;
+def warn_unreachable_association : Warning<
+ "due to lvalue conversion of the controlling expression, association of type "
+ "%0 will never be selected because it is %select{of array type|qualified}1">,
+ InGroup<UnreachableCodeGenericAssoc>;
/// Built-in functions.
def ext_implicit_lib_function_decl : ExtWarn<
"implicitly declaring library function '%0' with type %1">,
InGroup<ImplicitFunctionDeclare>;
+def ext_implicit_lib_function_decl_c99 : ExtWarn<
+ "call to undeclared library function '%0' with type %1; ISO C99 and later "
+ "do not support implicit function declarations">,
+ InGroup<ImplicitFunctionDeclare>;
def note_include_header_or_declare : Note<
"include the header <%0> or explicitly provide a declaration for '%1'">;
def note_previous_builtin_declaration : Note<"%0 is a builtin with type %1">;
@@ -811,16 +869,47 @@ def warn_builtin_chk_overflow : Warning<
InGroup<DiagGroup<"builtin-memcpy-chk-size">>;
def warn_fortify_source_overflow
- : Warning<warn_builtin_chk_overflow.Text>, InGroup<FortifySource>;
+ : Warning<warn_builtin_chk_overflow.Summary>, InGroup<FortifySource>;
def warn_fortify_source_size_mismatch : Warning<
"'%0' size argument is too large; destination buffer has size %1,"
" but size argument is %2">, InGroup<FortifySource>;
-def warn_fortify_source_format_overflow : Warning<
+def warn_fortify_strlen_overflow: Warning<
+ "'%0' will always overflow; destination buffer has size %1,"
+ " but the source string has length %2 (including NUL byte)">,
+ InGroup<FortifySource>;
+
+def subst_format_overflow : TextSubstitution<
"'%0' will always overflow; destination buffer has size %1,"
- " but format string expands to at least %2">,
+ " but format string expands to at least %2">;
+
+def warn_format_overflow : Warning<
+ "%sub{subst_format_overflow}0,1,2">,
+ InGroup<FormatOverflow>;
+
+def warn_format_overflow_non_kprintf : Warning<
+ "%sub{subst_format_overflow}0,1,2">,
+ InGroup<FormatOverflowNonKprintf>;
+
+def subst_format_truncation: TextSubstitution<
+ "'%0' will always be truncated; specified size is %1,"
+ " but format string expands to at least %2">;
+
+def warn_format_truncation: Warning<
+ "%sub{subst_format_truncation}0,1,2">,
+ InGroup<FormatTruncation>;
+
+def warn_format_truncation_non_kprintf: Warning<
+ "%sub{subst_format_truncation}0,1,2">,
+ InGroup<FormatTruncationNonKprintf>;
+
+def warn_fortify_scanf_overflow : Warning<
+ "'%0' may overflow; destination buffer in argument %1 has size "
+ "%2, but the corresponding specifier may require size %3">,
InGroup<FortifySource>;
+def err_function_start_invalid_type: Error<
+ "argument must be a function">;
/// main()
// static main() is not an error in C, just in C++.
@@ -908,11 +997,14 @@ def warn_pragma_options_align_reset_failed : Warning<
InGroup<IgnoredPragmas>;
def err_pragma_options_align_mac68k_target_unsupported : Error<
"mac68k alignment pragma is not supported on this target">;
+def warn_pragma_align_not_xl_compatible : Warning<
+ "#pragma align(packed) may not be compatible with objects generated with AIX XL C/C++">,
+ InGroup<AIXCompat>;
def warn_pragma_pack_invalid_alignment : Warning<
"expected #pragma pack parameter to be '1', '2', '4', '8', or '16'">,
InGroup<IgnoredPragmas>;
def err_pragma_pack_invalid_alignment : Error<
- warn_pragma_pack_invalid_alignment.Text>;
+ warn_pragma_pack_invalid_alignment.Summary>;
def warn_pragma_pack_non_default_at_include : Warning<
"non-default #pragma pack value changes the alignment of struct or union "
"members in the included file">, InGroup<PragmaPackSuspiciousInclude>,
@@ -933,7 +1025,8 @@ def warn_pragma_pack_pop_identifier_and_alignment : Warning<
def warn_pragma_pop_failed : Warning<"#pragma %0(pop, ...) failed: %1">,
InGroup<IgnoredPragmas>;
def err_pragma_fc_pp_scope : Error<
- "'#pragma float_control push/pop' can only appear at file scope or namespace scope">;
+ "'#pragma float_control push/pop' can only appear at file or namespace scope "
+ "or within a language linkage specification">;
def err_pragma_fc_noprecise_requires_nofenv : Error<
"'#pragma float_control(precise, off)' is illegal when fenv_access is enabled">;
def err_pragma_fc_except_requires_precise : Error<
@@ -949,12 +1042,22 @@ def warn_cxx_ms_struct :
def err_pragma_pack_identifer_not_supported : Error<
"specifying an identifier within `#pragma pack` is not supported on this target">;
def err_section_conflict : Error<"%0 causes a section type conflict with %1">;
+def warn_section_msvc_compat : Warning<"`#pragma const_seg` for section %1 will"
+ " not apply to %0 due to the presence of a %select{mutable field||non-trivial constructor|non-trivial destructor}2">,
+ InGroup<IncompatibleMSPragmaSection>;
def err_no_base_classes : Error<"invalid use of '__super', %0 has no base classes">;
def err_invalid_super_scope : Error<"invalid use of '__super', "
"this keyword can only be used inside class or member function scope">;
def err_super_in_lambda_unsupported : Error<
"use of '__super' inside a lambda is unsupported">;
+def err_pragma_expected_file_scope : Error<
+ "'#pragma %0' can only appear at file scope">;
+def err_pragma_alloc_text_c_linkage: Error<
+ "'#pragma alloc_text' is applicable only to functions with C linkage">;
+def err_pragma_alloc_text_not_function: Error<
+ "'#pragma alloc_text' is applicable only to functions">;
+
def warn_pragma_unused_undeclared_var : Warning<
"undeclared variable %0 used as an argument for '#pragma unused'">,
InGroup<IgnoredPragmas>;
@@ -1041,7 +1144,7 @@ def warn_protocol_property_mismatch : Warning<
"property %select{of type %1|with attribute '%1'|without attribute '%1'|with "
"getter %1|with setter %1}0 was selected for synthesis">,
InGroup<DiagGroup<"protocol-property-synthesis-ambiguity">>;
-def err_protocol_property_mismatch: Error<warn_protocol_property_mismatch.Text>;
+def err_protocol_property_mismatch: Error<warn_protocol_property_mismatch.Summary>;
def err_undef_interface : Error<"cannot find interface declaration for %0">;
def err_category_forward_interface : Error<
"cannot define %select{category|class extension}0 for undefined class %1">;
@@ -1258,7 +1361,7 @@ def warn_objc_pointer_masking : Warning<
"bitmasking for introspection of Objective-C object pointers is strongly "
"discouraged">,
InGroup<ObjCPointerIntrospect>;
-def warn_objc_pointer_masking_performSelector : Warning<warn_objc_pointer_masking.Text>,
+def warn_objc_pointer_masking_performSelector : Warning<warn_objc_pointer_masking.Summary>,
InGroup<ObjCPointerIntrospectPerformSelector>;
def warn_objc_property_default_assign_on_object : Warning<
"default property attribute 'assign' not appropriate for object">,
@@ -1284,7 +1387,7 @@ def warn_atomic_property_rule : Warning<
"with a user defined %select{getter|setter}2">,
InGroup<DiagGroup<"atomic-property-with-user-defined-accessor">>;
def note_atomic_property_fixup_suggest : Note<"setter and getter must both be "
- "synthesized, or both be user defined,or the property must be nonatomic">;
+ "synthesized, or both be user defined, or the property must be nonatomic">;
def err_atomic_property_nontrivial_assign_op : Error<
"atomic property of reference type %0 cannot have non-trivial assignment"
" operator">;
@@ -1462,7 +1565,7 @@ def warn_potentially_direct_selector_expression : Warning<
"@selector expression formed with potentially direct selector %0">,
InGroup<ObjCPotentiallyDirectSelector>;
def warn_strict_potentially_direct_selector_expression : Warning<
- warn_potentially_direct_selector_expression.Text>,
+ warn_potentially_direct_selector_expression.Summary>,
InGroup<ObjCStrictPotentiallyDirectSelector>, DefaultIgnore;
def err_objc_kindof_nonobject : Error<
@@ -1486,12 +1589,36 @@ def err_messaging_class_with_direct_method : Error<
// C++ declarations
def err_static_assert_expression_is_not_constant : Error<
- "static_assert expression is not an integral constant expression">;
+ "static assertion expression is not an integral constant expression">;
def err_constexpr_if_condition_expression_is_not_constant : Error<
"constexpr if condition is not a constant expression">;
-def err_static_assert_failed : Error<"static_assert failed%select{ %1|}0">;
+def err_static_assert_failed : Error<"static assertion failed%select{: %1|}0">;
def err_static_assert_requirement_failed : Error<
- "static_assert failed due to requirement '%0'%select{ %2|}1">;
+ "static assertion failed due to requirement '%0'%select{: %2|}1">;
+def note_expr_evaluates_to : Note<
+ "expression evaluates to '%0 %1 %2'">;
+def err_static_assert_invalid_message : Error<
+ "the message in a static assertion must be a string literal or an "
+ "object with 'data()' and 'size()' member functions">;
+def err_static_assert_missing_member_function : Error<
+ "the message object in this static assertion is missing %select{"
+ "a 'size()' member function|"
+ "a 'data()' member function|"
+ "'data()' and 'size()' member functions}0">;
+def err_static_assert_invalid_mem_fn_ret_ty : Error<
+ "the message in a static assertion must have a '%select{size|data}0()' member "
+ "function returning an object convertible to '%select{std::size_t|const char *}0'">;
+def warn_static_assert_message_constexpr : Warning<
+ "the message in this static assertion is not a "
+ "constant expression">,
+ DefaultError, InGroup<DiagGroup<"invalid-static-assert-message">>;
+def err_static_assert_message_constexpr : Error<
+ "the message in a static assertion must be produced by a "
+ "constant expression">;
+
+def warn_consteval_if_always_true : Warning<
+ "consteval if is always true in an %select{unevaluated|immediate}0 context">,
+ InGroup<DiagGroup<"redundant-consteval-if">>;
def ext_inline_variable : ExtWarn<
"inline variables are a C++17 extension">, InGroup<CXX17>;
@@ -1504,6 +1631,8 @@ def warn_inline_namespace_reopened_noninline : Warning<
InGroup<InlineNamespaceReopenedNoninline>;
def err_inline_namespace_mismatch : Error<
"non-inline namespace cannot be reopened as inline">;
+def err_inline_namespace_std : Error<
+ "cannot declare the namespace 'std' to be inline">;
def err_unexpected_friend : Error<
"friends can only be classes or functions">;
@@ -1547,6 +1676,8 @@ def err_qualified_friend_def : Error<
"friend function definition cannot be qualified with '%0'">;
def err_friend_def_in_local_class : Error<
"friend function cannot be defined in a local class">;
+def err_friend_specialization_def : Error<
+ "friend function specialization cannot be defined">;
def err_friend_not_first_in_declaration : Error<
"'friend' must appear first in a non-function declaration">;
def err_using_decl_friend : Error<
@@ -1600,6 +1731,9 @@ def err_type_defined_in_condition : Error<
"%0 cannot be defined in a condition">;
def err_type_defined_in_enum : Error<
"%0 cannot be defined in an enumeration">;
+def ext_type_defined_in_offsetof : Extension<
+ "defining a type within '%select{__builtin_offsetof|offsetof}0' is a Clang "
+ "extension">, InGroup<GNUOffsetofExtensions>;
def note_pure_virtual_function : Note<
"unimplemented pure virtual method %0 in %1">;
@@ -1624,8 +1758,7 @@ def warn_weak_vtable : Warning<
"emitted in every translation unit">,
InGroup<DiagGroup<"weak-vtables">>, DefaultIgnore;
def warn_weak_template_vtable : Warning<
- "explicit template instantiation %0 will emit a vtable in every "
- "translation unit">,
+ "this warning is no longer in use and will be removed in the next release">,
InGroup<DiagGroup<"weak-template-vtables">>, DefaultIgnore;
def ext_using_undefined_std : ExtWarn<
@@ -1643,37 +1776,32 @@ def err_incomplete_in_exception_spec : Error<
def err_sizeless_in_exception_spec : Error<
"%select{|reference to }0sizeless type %1 is not allowed "
"in exception specification">;
-def ext_incomplete_in_exception_spec : ExtWarn<err_incomplete_in_exception_spec.Text>,
+def ext_incomplete_in_exception_spec : ExtWarn<err_incomplete_in_exception_spec.Summary>,
InGroup<MicrosoftExceptionSpec>;
def err_rref_in_exception_spec : Error<
"rvalue reference type %0 is not allowed in exception specification">;
def err_mismatched_exception_spec : Error<
"exception specification in declaration does not match previous declaration">;
-def ext_mismatched_exception_spec : ExtWarn<err_mismatched_exception_spec.Text>,
+def ext_mismatched_exception_spec : ExtWarn<err_mismatched_exception_spec.Summary>,
InGroup<MicrosoftExceptionSpec>;
def err_override_exception_spec : Error<
"exception specification of overriding function is more lax than "
"base version">;
-def ext_override_exception_spec : ExtWarn<err_override_exception_spec.Text>,
+def ext_override_exception_spec : ExtWarn<err_override_exception_spec.Summary>,
InGroup<MicrosoftExceptionSpec>;
def err_incompatible_exception_specs : Error<
"target exception specification is not superset of source">;
def warn_incompatible_exception_specs : Warning<
- err_incompatible_exception_specs.Text>, InGroup<IncompatibleExceptionSpec>;
+ err_incompatible_exception_specs.Summary>, InGroup<IncompatibleExceptionSpec>;
def err_deep_exception_specs_differ : Error<
"exception specifications of %select{return|argument}0 types differ">;
def warn_deep_exception_specs_differ : Warning<
- err_deep_exception_specs_differ.Text>, InGroup<IncompatibleExceptionSpec>;
+ err_deep_exception_specs_differ.Summary>, InGroup<IncompatibleExceptionSpec>;
def err_missing_exception_specification : Error<
"%0 is missing exception specification '%1'">;
def ext_missing_exception_specification : ExtWarn<
- err_missing_exception_specification.Text>,
+ err_missing_exception_specification.Summary>,
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<
"exception specification is not available until end of class definition">;
def err_exception_spec_cycle : Error<
@@ -1833,7 +1961,7 @@ def err_static_not_bitfield : Error<"static member %0 cannot be a bit-field">;
def err_static_out_of_line : Error<
"'static' can only be specified inside the class definition">;
def ext_static_out_of_line : ExtWarn<
- err_static_out_of_line.Text>,
+ err_static_out_of_line.Summary>,
InGroup<MicrosoftTemplate>;
def err_storage_class_for_static_member : Error<
"static data member definition cannot specify a storage class">;
@@ -1961,6 +2089,10 @@ def err_different_return_type_for_overriding_virtual_function : Error<
"than the function it overrides}1,2">;
def note_overridden_virtual_function : Note<
"overridden virtual function is here">;
+def err_conflicting_overriding_attributes : Error<
+ "virtual function %0 has different attributes "
+ "%diff{($) than the function it overrides (which has $)|"
+ "than the function it overrides}1,2">;
def err_conflicting_overriding_cc_attributes : Error<
"virtual function %0 has different calling convention attributes "
"%diff{($) than the function it overrides (which has calling convention $)|"
@@ -2077,7 +2209,8 @@ def err_init_conversion_failed : Error<
"exception object|a member subobject|an array element|a new value|a value|a "
"base class|a constructor delegation|a vector element|a block element|a "
"block element|a complex element|a lambda capture|a compound literal "
- "initializer|a related result|a parameter of CF audited function}0 "
+ "initializer|a related result|a parameter of CF audited function|a "
+ "structured binding|a member subobject}0 "
"%diff{of type $ with an %select{rvalue|lvalue}2 of type $|"
"with an %select{rvalue|lvalue}2 of incompatible type}1,3"
"%select{|: different classes%diff{ ($ vs $)|}5,6"
@@ -2120,10 +2253,15 @@ def err_init_list_bad_dest_type : Error<
def warn_cxx20_compat_aggregate_init_with_ctors : Warning<
"aggregate initialization of type %0 with user-declared constructors "
"is incompatible with C++20">, DefaultIgnore, InGroup<CXX20Compat>;
+def warn_cxx17_compat_aggregate_init_paren_list : Warning<
+ "aggregate initialization of type %0 from a parenthesized list of values "
+ "is a C++20 extension">, DefaultIgnore, InGroup<CXX20>;
def err_reference_bind_to_bitfield : Error<
"%select{non-const|volatile}0 reference cannot bind to "
"bit-field%select{| %1}2">;
+def err_reference_bind_to_bitfield_in_cce : Error<
+ "reference cannot bind to bit-field in converted constant expression">;
def err_reference_bind_to_vector_element : Error<
"%select{non-const|volatile}0 reference cannot bind to vector element">;
def err_reference_bind_to_matrix_element : Error<
@@ -2138,6 +2276,8 @@ def err_reference_has_multiple_inits : Error<
"reference cannot be initialized with multiple values">;
def err_init_non_aggr_init_list : Error<
"initialization of non-aggregate type %0 with an initializer list">;
+def err_designated_init_for_non_aggregate : Error<
+ "initialization of non-aggregate type %0 with a designated initializer list">;
def err_init_reference_member_uninitialized : Error<
"reference member of type %0 uninitialized">;
def note_uninit_reference_member : Note<
@@ -2260,8 +2400,6 @@ def err_auto_variable_cannot_appear_in_own_initializer : Error<
def err_binding_cannot_appear_in_own_initializer : Error<
"binding %0 cannot appear in the initializer of its own "
"decomposition declaration">;
-def err_illegal_decl_array_of_auto : Error<
- "'%0' declared as array of %1">;
def err_new_array_of_auto : Error<
"cannot allocate array of 'auto'">;
def err_auto_not_allowed : Error<
@@ -2279,7 +2417,9 @@ def err_auto_not_allowed : Error<
"|in conversion function type|here|in lambda parameter"
"|in type allocated by 'new'|in K&R-style function parameter"
"|in template parameter|in friend declaration|in function prototype that is "
- "not a function declaration|in requires expression parameter}1">;
+ "not a function declaration|in requires expression parameter"
+ "|in array declaration"
+ "|in declaration of conversion function template}1">;
def err_dependent_deduced_tst : Error<
"typename specifier refers to "
"%select{class template|function template|variable template|alias template|"
@@ -2301,13 +2441,23 @@ def ext_auto_new_list_init : Extension<
"type %0 to use list-initialization">, InGroup<CXX17>;
def err_auto_var_init_no_expression : Error<
"initializer for variable %0 with type %1 is empty">;
+def err_auto_expr_init_no_expression : Error<
+ "initializer for functional-style cast to %0 is empty">;
def err_auto_var_init_multiple_expressions : Error<
"initializer for variable %0 with type %1 contains multiple expressions">;
+def err_auto_expr_init_multiple_expressions : Error<
+ "initializer for functional-style cast to %0 contains multiple expressions">;
def err_auto_var_init_paren_braces : Error<
"cannot deduce type for variable %1 with type %2 from "
"%select{parenthesized|nested}0 initializer list">;
def err_auto_new_ctor_multiple_expressions : Error<
"new expression for type %0 contains multiple constructor arguments">;
+def err_auto_expr_init_paren_braces : Error<
+ "cannot deduce actual type for %1 from "
+ "%select{parenthesized|nested}0 initializer list">;
+def warn_cxx20_compat_auto_expr : Warning<
+ "'auto' as a functional-style cast is incompatible with C++ standards "
+ "before C++23">, InGroup<CXXPre23Compat>, DefaultIgnore;
def err_auto_missing_trailing_return : Error<
"'auto' return without trailing return type; deduced return types are a "
"C++14 extension">;
@@ -2321,6 +2471,8 @@ def err_auto_var_deduction_failure : Error<
"variable %0 with type %1 has incompatible initializer of type %2">;
def err_auto_var_deduction_failure_from_init_list : Error<
"cannot deduce actual type for variable %0 with type %1 from initializer list">;
+def err_auto_expr_deduction_failure : Error<
+ "functional-style cast to %0 has incompatible initializer of type %1">;
def err_auto_new_deduction_failure : Error<
"new expression for type %0 has incompatible constructor argument of type %1">;
def err_auto_inconsistent_deduction : Error<
@@ -2340,7 +2492,8 @@ def err_implied_std_initializer_list_not_found : Error<
def err_malformed_std_initializer_list : Error<
"std::initializer_list must be a class template with a single type parameter">;
def err_auto_init_list_from_c : Error<
- "cannot use __auto_type with initializer list in C">;
+ "cannot use %select{'auto'|<ERROR>|'__auto_type'}0 with "
+ "%select{initializer list|array}1 in C">;
def err_auto_bitfield : Error<
"cannot pass bit-field as __auto_type initializer in C">;
@@ -2486,7 +2639,7 @@ def err_final_function_overridden : Error<
// C++11 scoped enumerations
def err_enum_invalid_underlying : Error<
- "non-integral type %0 is an invalid underlying type">;
+ "%select{non-integral type %0|%0}1 is an invalid underlying type">;
def err_enumerator_too_large : Error<
"enumerator value is not representable in the underlying type %0">;
def ext_enumerator_too_large : Extension<
@@ -2586,10 +2739,28 @@ def warn_cxx14_compat_constexpr_not_const : Warning<
"in C++14; add 'const' to avoid a change in behavior">,
InGroup<DiagGroup<"constexpr-not-const">>;
def err_invalid_consteval_take_address : Error<
- "cannot take address of consteval function %0 outside"
+ "cannot take address of %select{immediate|consteval}2 "
+ "%select{function|call operator of}1 %0 outside"
" of an immediate invocation">;
def err_invalid_consteval_call : Error<
- "call to consteval function %q0 is not a constant expression">;
+ "call to %select{immediate|consteval}1 function "
+ "%q0 is not a constant expression">;
+
+def err_immediate_function_used_before_definition : Error<
+ "immediate function %0 used before it is defined">;
+
+def note_immediate_function_reason : Note<
+ "%0 is an immediate %select{function|constructor}5 because "
+ "%select{its body|the%select{| default}7 initializer of %8}6 "
+ "%select{evaluates the address of %select{an immediate|a consteval}2 "
+ "function %1|contains a call to %select{an immediate|a consteval}2 "
+ "%select{function|constructor}4 %1 and that call is not a constant "
+ "expression}3">;
+
+def note_invalid_consteval_initializer : Note<
+ "in the default initializer of %0">;
+def note_invalid_consteval_initializer_here : Note<
+ "initialized here %0">;
def err_invalid_consteval_decl_kind : Error<
"%0 cannot be declared consteval">;
def err_invalid_constexpr : Error<
@@ -2598,7 +2769,7 @@ def err_invalid_constexpr : Error<
def err_invalid_constexpr_member : Error<"non-static data member cannot be "
"constexpr%select{; did you intend to make it %select{const|static}0?|}1">;
def err_constexpr_tag : Error<
- "%select{class|struct|interface|union|enum}0 "
+ "%select{class|struct|interface|union|enum|enum class|enum struct}0 "
"cannot be marked %sub{select_constexpr_spec_kind}1">;
def err_constexpr_dtor : Error<
"destructor cannot be declared %sub{select_constexpr_spec_kind}0">;
@@ -2658,6 +2829,13 @@ def warn_cxx17_compat_constexpr_body_invalid_stmt : Warning<
"use of this statement in a constexpr %select{function|constructor}0 "
"is incompatible with C++ standards before C++20">,
InGroup<CXXPre20Compat>, DefaultIgnore;
+def ext_constexpr_body_invalid_stmt_cxx23 : ExtWarn<
+ "use of this statement in a constexpr %select{function|constructor}0 "
+ "is a C++23 extension">, InGroup<CXX23>;
+def warn_cxx20_compat_constexpr_body_invalid_stmt : Warning<
+ "use of this statement in a constexpr %select{function|constructor}0 "
+ "is incompatible with C++ standards before C++23">,
+ InGroup<CXXPre23Compat>, DefaultIgnore;
def ext_constexpr_type_definition : ExtWarn<
"type definition in a constexpr %select{function|constructor}0 "
"is a C++14 extension">, InGroup<CXX14>;
@@ -2675,12 +2853,18 @@ def warn_cxx11_compat_constexpr_local_var : Warning<
"variable declaration in a constexpr %select{function|constructor}0 "
"is incompatible with C++ standards before C++14">,
InGroup<CXXPre14Compat>, DefaultIgnore;
-def err_constexpr_local_var_static : Error<
- "%select{static|thread_local}1 variable not permitted in a constexpr "
- "%select{function|constructor}0">;
+def ext_constexpr_static_var : ExtWarn<
+ "definition of a %select{static|thread_local}1 variable "
+ "in a constexpr %select{function|constructor}0 "
+ "is a C++23 extension">, InGroup<CXX23>;
+def warn_cxx20_compat_constexpr_var : Warning<
+ "definition of a %select{static variable|thread_local variable|variable "
+ "of non-literal type}1 in a constexpr %select{function|constructor}0 "
+ "is incompatible with C++ standards before C++23">,
+ InGroup<CXXPre23Compat>, DefaultIgnore;
def err_constexpr_local_var_non_literal_type : Error<
"variable of non-literal type %1 cannot be defined in a constexpr "
- "%select{function|constructor}0">;
+ "%select{function|constructor}0 before C++23">;
def ext_constexpr_local_var_no_init : ExtWarn<
"uninitialized variable in a constexpr %select{function|constructor}0 "
"is a C++20 extension">, InGroup<CXX20>;
@@ -2712,6 +2896,8 @@ def warn_cxx11_compat_constexpr_body_multiple_return : Warning<
InGroup<CXXPre14Compat>, DefaultIgnore;
def note_constexpr_body_previous_return : Note<
"previous return statement is here">;
+def err_ms_constexpr_cannot_be_applied : Error<
+ "attribute 'msvc::constexpr' cannot be applied to the %select{constexpr|consteval|virtual}0 function %1">;
// C++20 function try blocks in constexpr
def ext_constexpr_function_try_block_cxx20 : ExtWarn<
@@ -2780,6 +2966,8 @@ def err_template_arg_list_constraints_not_satisfied : Error<
"template template parameter|template}0 %1%2">;
def note_substituted_constraint_expr_is_ill_formed : Note<
"because substituted constraint expression is ill-formed%0">;
+def note_constraint_references_error
+ : Note<"constraint depends on a previously diagnosed expression">;
def note_atomic_constraint_evaluated_to_false : Note<
"%select{and|because}0 '%1' evaluated to false">;
def note_concept_specialization_constraint_evaluated_to_false : Note<
@@ -2792,6 +2980,8 @@ def err_constrained_virtual_method : Error<
"virtual function cannot have a requires clause">;
def err_trailing_requires_clause_on_deduction_guide : Error<
"deduction guide cannot have a requires clause">;
+def err_constrained_non_templated_function
+ : Error<"non-templated function cannot have a requires clause">;
def err_reference_to_function_with_unsatisfied_constraints : Error<
"invalid reference to function %0: constraints not satisfied">;
def err_requires_expr_local_parameter_default_argument : Error<
@@ -2817,7 +3007,7 @@ def note_type_requirement_substitution_error : Note<
def note_type_requirement_unknown_substitution_error : Note<
"%select{and|because}0 '%1' would be invalid">;
def note_nested_requirement_substitution_error : Note<
- "%select{and|because}0 '%1' would be invalid: %2">;
+ "%select{and|because}0 '%1' would be invalid%2">;
def note_nested_requirement_unknown_substitution_error : Note<
"%select{and|because}0 '%1' would be invalid">;
def note_ambiguous_atomic_constraints : Note<
@@ -2872,11 +3062,20 @@ def warn_auto_var_is_id : Warning<
InGroup<DiagGroup<"auto-var-id">>;
// Attributes
-def warn_nomerge_attribute_ignored_in_stmt: Warning<
+def warn_attribute_ignored_no_calls_in_stmt: Warning<
"%0 attribute is ignored because there exists no call expression inside the "
"statement">,
InGroup<IgnoredAttributes>;
+def warn_attribute_ignored_non_function_pointer: Warning<
+ "%0 attribute is ignored because %1 is not a function pointer">,
+ InGroup<IgnoredAttributes>;
+
+def warn_function_attribute_ignored_in_stmt : Warning<
+ "attribute is ignored on this statement as it only applies to functions; "
+ "use '%0' on statements">,
+ InGroup<IgnoredAttributes>;
+
def err_musttail_needs_trivial_args : Error<
"tail call requires that the return value, all parameters, and any "
"temporaries created by the expression are trivially destructible">;
@@ -2922,22 +3121,38 @@ def err_musttail_scope : Error<
"cannot perform a tail call from this return statement">;
def err_musttail_no_variadic : Error<
"%0 attribute may not be used with variadic functions">;
+def err_musttail_no_return : Error<
+ "%0 attribute may not be used with no-return-attribute functions">;
def err_nsobject_attribute : Error<
"'NSObject' attribute is for pointer types only">;
def err_attributes_are_not_compatible : Error<
- "%0 and %1 attributes are not compatible">;
+ "%0 and %1%select{ attributes|}2 are not compatible">;
def err_attribute_invalid_argument : Error<
"%select{a reference type|an array type|a non-vector or "
"non-vectorizable scalar type}0 is an invalid argument to attribute %1">;
def err_attribute_wrong_number_arguments : Error<
"%0 attribute %plural{0:takes no arguments|1:takes one argument|"
":requires exactly %1 arguments}1">;
+def err_attribute_wrong_number_arguments_for : Error <
+ "%0 attribute references function %1, which %plural{0:takes no arguments|1:takes one argument|"
+ ":takes exactly %2 arguments}2">;
+def err_attribute_bounds_for_function : Error<
+ "%0 attribute references parameter %1, but the function %2 has only %3 parameters">;
+def err_attribute_no_member_function : Error<
+ "%0 attribute cannot be applied to non-static member functions">;
+def err_attribute_parameter_types : Error<
+ "%0 attribute parameter types do not match: parameter %1 of function %2 has type %3, "
+ "but parameter %4 of function %5 has type %6">;
+
def err_attribute_too_many_arguments : Error<
"%0 attribute takes no more than %1 argument%s1">;
def err_attribute_too_few_arguments : Error<
"%0 attribute takes at least %1 argument%s1">;
def err_attribute_invalid_vector_type : Error<"invalid vector element type %0">;
+def err_attribute_invalid_bitint_vector_type : Error<
+ "'_BitInt' vector element width must be %select{a power of 2|"
+ "at least as wide as 'CHAR_BIT'}0">;
def err_attribute_invalid_matrix_type : Error<"invalid matrix element type %0">;
def err_attribute_bad_neon_vector_size : Error<
"Neon vector size must be 64 or 128 bits">;
@@ -2949,21 +3164,48 @@ def err_attribute_bad_sve_vector_size : Error<
def err_attribute_arm_feature_sve_bits_unsupported : Error<
"%0 is only supported when '-msve-vector-bits=<bits>' is specified with a "
"value of 128, 256, 512, 1024 or 2048.">;
+def warn_attribute_arm_sm_incompat_builtin : Warning<
+ "builtin call has undefined behaviour when called from a %0 function">,
+ InGroup<DiagGroup<"undefined-arm-streaming">>;
+def warn_attribute_arm_za_builtin_no_za_state : Warning<
+ "builtin call is not valid when calling from a function without active ZA state">,
+ InGroup<DiagGroup<"undefined-arm-za">>;
+def warn_attribute_arm_zt0_builtin_no_zt0_state : Warning<
+ "builtin call is not valid when calling from a function without active ZT0 state">,
+ InGroup<DiagGroup<"undefined-arm-zt0">>;
+def err_sve_vector_in_non_sve_target : Error<
+ "SVE vector type %0 cannot be used in a target without sve">;
+def err_attribute_riscv_rvv_bits_unsupported : Error<
+ "%0 is only supported when '-mrvv-vector-bits=<bits>' is specified with a "
+ "value of \"zvl\" or a power 2 in the range [64,65536]">;
+def err_attribute_bad_rvv_vector_size : Error<
+ "invalid RVV vector size '%0', expected size is '%1' based on LMUL of type "
+ "and '-mrvv-vector-bits'">;
+def err_attribute_invalid_rvv_type : Error<
+ "%0 attribute applied to non-RVV type %1">;
def err_attribute_requires_positive_integer : Error<
"%0 attribute requires a %select{positive|non-negative}1 "
"integral compile time constant expression">;
def err_attribute_requires_opencl_version : Error<
- "%0 attribute requires OpenCL version %1%select{| or above}2">;
+ "attribute %0 is supported in the OpenCL version %1%select{| onwards}2">;
def err_invalid_branch_protection_spec : Error<
"invalid or misplaced branch protection specification '%0'">;
+def warn_unsupported_branch_protection_spec : Warning<
+ "unsupported branch protection specification '%0'">, InGroup<BranchProtection>;
+
def warn_unsupported_target_attribute
- : Warning<"%select{unsupported|duplicate|unknown}0%select{| architecture|"
- " tune CPU}1 '%2' in the 'target' attribute string; 'target' "
+ : Warning<"%select{unsupported|duplicate|unknown}0%select{| CPU|"
+ " tune CPU}1 '%2' in the '%select{target|target_clones|target_version}3' "
+ "attribute string; '%select{target|target_clones|target_version}3' "
"attribute ignored">,
InGroup<IgnoredAttributes>;
def err_attribute_unsupported
: Error<"%0 attribute is not supported on targets missing %1;"
" specify an appropriate -march= or -mcpu=">;
+def err_duplicate_target_attribute
+ : Error<"%select{unsupported|duplicate|unknown}0%select{| CPU|"
+ " tune CPU}1 '%2' in the '%select{target|target_clones|target_version}3' "
+ "attribute string; ">;
// The err_*_attribute_argument_not_int are separate because they're used by
// VerifyIntegerConstantExpression.
def err_aligned_attribute_argument_not_int : Error<
@@ -2971,8 +3213,9 @@ def err_aligned_attribute_argument_not_int : Error<
def err_align_value_attribute_argument_not_int : Error<
"'align_value' attribute requires integer constant">;
def err_alignas_attribute_wrong_decl_type : Error<
- "%0 attribute cannot be applied to a %select{function parameter|"
- "variable with 'register' storage class|'catch' variable|bit-field}1">;
+ "%0 attribute cannot be applied to %select{a function parameter|"
+ "a variable with 'register' storage class|a 'catch' variable|a bit-field|"
+ "an enumeration}1">;
def err_alignas_missing_on_definition : Error<
"%0 must be specified on definition if it is specified on any declaration">;
def note_alignas_on_declaration : Note<"declared with %0 attribute here">;
@@ -2980,11 +3223,13 @@ def err_alignas_mismatch : Error<
"redeclaration has different alignment requirement (%1 vs %0)">;
def err_alignas_underaligned : Error<
"requested alignment is less than minimum alignment of %1 for type %0">;
+def warn_aligned_attr_underaligned : Warning<err_alignas_underaligned.Summary>,
+ InGroup<IgnoredAttributes>;
def err_attribute_sizeless_type : Error<
"%0 attribute cannot be applied to sizeless type %1">;
def err_attribute_argument_n_type : Error<
"%0 attribute requires parameter %1 to be %select{int or bool|an integer "
- "constant|a string|an identifier|a constant expression}2">;
+ "constant|a string|an identifier|a constant expression|a builtin function}2">;
def err_attribute_argument_type : Error<
"%0 attribute requires %select{int or bool|an integer "
"constant|a string|an identifier}1">;
@@ -3002,7 +3247,7 @@ def note_previous_uuid : Note<"previous uuid specified here">;
def warn_attribute_pointers_only : Warning<
"%0 attribute only applies to%select{| constant}1 pointer arguments">,
InGroup<IgnoredAttributes>;
-def err_attribute_pointers_only : Error<warn_attribute_pointers_only.Text>;
+def err_attribute_pointers_only : Error<warn_attribute_pointers_only.Summary>;
def err_attribute_integers_only : Error<
"%0 attribute argument may only refer to a function parameter of integer "
"type">;
@@ -3027,9 +3272,7 @@ def note_ownership_returns_index_mismatch : Note<
"declared with index %0 here">;
def err_format_strftime_third_parameter : Error<
"strftime format attribute requires 3rd parameter to be 0">;
-def err_format_attribute_requires_variadic : Error<
- "format attribute requires variadic function">;
-def err_format_attribute_not : Error<"format argument not %0">;
+def err_format_attribute_not : Error<"format argument not a string type">;
def err_format_attribute_result_not : Error<"function does not return %0">;
def err_format_attribute_implicit_this_format_string : Error<
"format attribute cannot specify the implicit this argument as the format "
@@ -3054,10 +3297,11 @@ def err_attribute_invalid_size : Error<
"vector size not an integral multiple of component size">;
def err_attribute_zero_size : Error<"zero %0 size">;
def err_attribute_size_too_large : Error<"%0 size too large">;
-def err_typecheck_sve_ambiguous : Error<
- "cannot combine fixed-length and sizeless SVE vectors in expression, result is ambiguous (%0 and %1)">;
-def err_typecheck_sve_gnu_ambiguous : Error<
- "cannot combine GNU and SVE vectors in expression, result is ambiguous (%0 and %1)">;
+def err_typecheck_sve_rvv_ambiguous : Error<
+ "cannot combine fixed-length and sizeless %select{SVE|RVV}0 vectors "
+ "in expression, result is ambiguous (%1 and %2)">;
+def err_typecheck_sve_rvv_gnu_ambiguous : Error<
+ "cannot combine GNU and %select{SVE|RVV}0 vectors in expression, result is ambiguous (%1 and %2)">;
def err_typecheck_vector_not_convertable_implict_truncation : Error<
"cannot convert between %select{scalar|vector}0 type %1 and vector type"
" %2 as implicit conversion would cause truncation">;
@@ -3186,6 +3430,8 @@ def warn_objc_redundant_literal_use : Warning<
def err_attr_tlsmodel_arg : Error<"tls_model must be \"global-dynamic\", "
"\"local-dynamic\", \"initial-exec\" or \"local-exec\"">;
+def err_attr_codemodel_arg : Error<"code model '%0' is not supported on this target">;
+
def err_aix_attr_unsupported_tls_model : Error<"TLS model '%0' is not yet supported on AIX">;
def err_tls_var_aligned_over_maximum : Error<
@@ -3240,7 +3486,7 @@ def err_alignment_too_big : Error<
def err_alignment_not_power_of_two : Error<
"requested alignment is not a power of 2">;
def warn_alignment_not_power_of_two : Warning<
- err_alignment_not_power_of_two.Text>,
+ err_alignment_not_power_of_two.Summary>,
InGroup<DiagGroup<"non-power-of-two-alignment">>;
def err_alignment_dependent_typedef_name : Error<
"requested alignment is dependent but declaration is not dependent">;
@@ -3255,9 +3501,11 @@ def warn_assume_aligned_too_great
"alignment assumed">,
InGroup<DiagGroup<"builtin-assume-aligned-alignment">>;
def warn_not_xl_compatible
- : Warning<"requesting an alignment of 16 bytes or greater for struct"
- " members is not binary compatible with AIX XL 16.1 and older">,
+ : Warning<"alignment of 16 bytes for a struct member is not binary "
+ "compatible with IBM XL C/C++ for AIX 16.1.0 or older">,
InGroup<AIXCompat>;
+def note_misaligned_member_used_here : Note<
+ "passing byval argument %0 with potentially incompatible alignment here">;
def warn_redeclaration_without_attribute_prev_attribute_ignored : Warning<
"%q0 redeclared without %1 attribute: previous %1 ignored">,
InGroup<MicrosoftInconsistentDllImport>;
@@ -3267,8 +3515,6 @@ def warn_redeclaration_without_import_attribute : Warning<
def warn_dllimport_dropped_from_inline_function : Warning<
"%q0 redeclared inline; %1 attribute ignored">,
InGroup<IgnoredAttributes>;
-def warn_attribute_ignored : Warning<"%0 attribute ignored">,
- InGroup<IgnoredAttributes>;
def warn_nothrow_attribute_ignored : Warning<"'nothrow' attribute conflicts with"
" exception specification; attribute ignored">,
InGroup<IgnoredAttributes>;
@@ -3298,19 +3544,26 @@ def warn_attribute_has_no_effect_on_infinite_loop : Warning<
InGroup<IgnoredAttributes>;
def note_attribute_has_no_effect_on_infinite_loop_here : Note<
"annotating the infinite loop here">;
-def warn_attribute_has_no_effect_on_if_constexpr : Warning<
- "attribute %0 has no effect when annotating an 'if constexpr' statement">,
+def warn_attribute_has_no_effect_on_compile_time_if : Warning<
+ "attribute %0 has no effect when annotating an 'if %select{constexpr|consteval}1' statement">,
InGroup<IgnoredAttributes>;
-def note_attribute_has_no_effect_on_if_constexpr_here : Note<
- "annotating the 'if constexpr' statement here">;
+def note_attribute_has_no_effect_on_compile_time_if_here : Note<
+ "annotating the 'if %select{constexpr|consteval}0' statement here">;
def err_decl_attribute_invalid_on_stmt : Error<
- "%0 attribute cannot be applied to a statement">;
-def err_stmt_attribute_invalid_on_decl : Error<
- "%0 attribute cannot be applied to a declaration">;
+ "%0%select{ attribute|}1 cannot be applied to a statement">;
+def err_attribute_invalid_on_decl : Error<
+ "%0%select{ attribute|}1 cannot be applied to a declaration">;
+def warn_type_attribute_deprecated_on_decl : Warning<
+ "applying attribute %0 to a declaration is deprecated; apply it to the type instead">,
+ InGroup<DeprecatedAttributes>;
def warn_declspec_attribute_ignored : Warning<
"attribute %0 is ignored, place it after "
- "\"%select{class|struct|interface|union|enum}1\" to apply attribute to "
+ "\"%select{class|struct|interface|union|enum|enum class|enum struct}1\" to apply attribute to "
"type declaration">, InGroup<IgnoredAttributes>;
+def err_declspec_keyword_has_no_effect : Error<
+ "%0 cannot appear here, place it after "
+ "\"%select{class|struct|interface|union|enum}1\" to apply it to the "
+ "type declaration">;
def warn_attribute_precede_definition : Warning<
"attribute declaration must precede definition">,
InGroup<IgnoredAttributes>;
@@ -3371,6 +3624,8 @@ def warn_attribute_dll_redeclaration : Warning<
InGroup<DiagGroup<"dll-attribute-on-redeclaration">>;
def err_attribute_dllimport_function_definition : Error<
"dllimport cannot be applied to non-inline function definition">;
+def err_attribute_dllimport_function_specialization_definition : Error<
+ "cannot define non-inline dllimport template specialization">;
def err_attribute_dll_deleted : Error<
"attribute %q0 cannot be applied to a deleted function">;
def err_attribute_dllimport_data_definition : Error<
@@ -3382,7 +3637,7 @@ def warn_attribute_dllimport_static_field_definition : Warning<
InGroup<DiagGroup<"dllimport-static-field-def">>;
def warn_attribute_dllexport_explicit_instantiation_decl : Warning<
"explicit instantiation declaration should not be 'dllexport'">,
- InGroup<DiagGroup<"dllexport-explicit-instantiation-decl">>;
+ InGroup<DllexportExplicitInstantiationDecl>;
def warn_attribute_dllexport_explicit_instantiation_def : Warning<
"'dllexport' attribute ignored on explicit instantiation definition">,
InGroup<IgnoredAttributes>;
@@ -3407,11 +3662,11 @@ def err_attribute_weakref_without_alias : Error<
def err_alias_not_supported_on_darwin : Error <
"aliases are not supported on darwin">;
def warn_attribute_wrong_decl_type_str : Warning<
- "%0 attribute only applies to %1">, InGroup<IgnoredAttributes>;
+ "%0%select{ attribute|}1 only applies to %2">, InGroup<IgnoredAttributes>;
def err_attribute_wrong_decl_type_str : Error<
- warn_attribute_wrong_decl_type_str.Text>;
+ warn_attribute_wrong_decl_type_str.Summary>;
def warn_attribute_wrong_decl_type : Warning<
- "%0 attribute only applies to %select{"
+ "%0%select{ attribute|}1 only applies to %select{"
"functions"
"|unions"
"|variables and functions"
@@ -3424,13 +3679,15 @@ def warn_attribute_wrong_decl_type : Warning<
"|types and namespaces"
"|variables, functions and classes"
"|kernel functions"
- "|non-K&R-style functions}1">,
+ "|non-K&R-style functions}2">,
InGroup<IgnoredAttributes>;
-def err_attribute_wrong_decl_type : Error<warn_attribute_wrong_decl_type.Text>;
+def err_attribute_wrong_decl_type : Error<warn_attribute_wrong_decl_type.Summary>;
def warn_type_attribute_wrong_type : Warning<
"'%0' only applies to %select{function|pointer|"
"Objective-C object or block pointer}1 types; type here is %2">,
InGroup<IgnoredAttributes>;
+def err_type_attribute_wrong_type : Error<
+ warn_type_attribute_wrong_type.Summary>;
def warn_incomplete_encoded_type : Warning<
"encoding of %0 type is incomplete because %1 component has unknown encoding">,
InGroup<DiagGroup<"encode-type">>;
@@ -3446,6 +3703,32 @@ def err_attribute_vecreturn_only_vector_member : Error<
"the vecreturn attribute can only be used on a class or structure with one member, which must be a vector">;
def err_attribute_vecreturn_only_pod_record : Error<
"the vecreturn attribute can only be used on a POD (plain old data) class or structure (i.e. no virtual functions)">;
+def err_sme_attr_mismatch : Error<
+ "function declared %0 was previously declared %1, which has different SME function attributes">;
+def err_sme_call_in_non_sme_target : Error<
+ "call to a streaming function requires 'sme'">;
+def err_sme_za_call_no_za_state : Error<
+ "call to a shared ZA function requires the caller to have ZA state">;
+def err_sme_zt0_call_no_zt0_state : Error<
+ "call to a shared ZT0 function requires the caller to have ZT0 state">;
+def err_sme_unimplemented_za_save_restore : Error<
+ "call to a function that shares state other than 'za' from a "
+ "function that has live 'za' state requires a spill/fill of ZA, which is not yet "
+ "implemented">;
+def note_sme_use_preserves_za : Note<
+ "add '__arm_preserves(\"za\")' to the callee if it preserves ZA">;
+def err_sme_definition_using_sm_in_non_sme_target : Error<
+ "function executed in streaming-SVE mode requires 'sme'">;
+def err_sme_definition_using_za_in_non_sme_target : Error<
+ "function using ZA state requires 'sme'">;
+def err_sme_definition_using_zt0_in_non_sme2_target : Error<
+ "function using ZT0 state requires 'sme2'">;
+def err_conflicting_attributes_arm_state : Error<
+ "conflicting attributes for state '%0'">;
+def err_unknown_arm_state : Error<
+ "unknown state '%0'">;
+def err_missing_arm_state : Error<
+ "missing state for %0">;
def err_cconv_change : Error<
"function declared '%0' here was previously declared "
"%select{'%2'|without calling convention}1">;
@@ -3458,11 +3741,11 @@ def warn_cconv_unsupported : Warning<
"|on builtin function"
"}1">,
InGroup<IgnoredAttributes>;
-def error_cconv_unsupported : Error<warn_cconv_unsupported.Text>;
+def error_cconv_unsupported : Error<warn_cconv_unsupported.Summary>;
def err_cconv_knr : Error<
"function with no prototype cannot use the %0 calling convention">;
def warn_cconv_knr : Warning<
- err_cconv_knr.Text>,
+ err_cconv_knr.Summary>,
InGroup<DiagGroup<"missing-prototype-for-cc">>;
def err_cconv_varargs : Error<
"variadic function cannot use %0 calling convention">;
@@ -3481,9 +3764,7 @@ def err_invalid_pcs : Error<"invalid PCS type">;
def warn_attribute_not_on_decl : Warning<
"%0 attribute ignored when parsing type">, InGroup<IgnoredAttributes>;
def err_base_specifier_attribute : Error<
- "%0 attribute cannot be applied to a base specifier">;
-def err_invalid_attribute_on_virtual_function : Error<
- "%0 attribute cannot be applied to virtual functions">;
+ "%0%select{ attribute|}1 cannot be applied to a base specifier">;
def warn_declspec_allocator_nonpointer : Warning<
"ignoring __declspec(allocator) because the function return type %0 is not "
"a pointer or reference type">, InGroup<IgnoredAttributes>;
@@ -3532,12 +3813,15 @@ def warn_availability_swift_unavailable_deprecated_only : Warning<
InGroup<Availability>;
def note_protocol_method : Note<
"protocol method is here">;
+def warn_availability_fuchsia_unavailable_minor : Warning<
+ "Fuchsia API Level prohibits specifying a minor or sub-minor version">,
+ InGroup<Availability>;
def warn_unguarded_availability :
Warning<"%0 is only available on %1 %2 or newer">,
InGroup<UnguardedAvailability>, DefaultIgnore;
def warn_unguarded_availability_new :
- Warning<warn_unguarded_availability.Text>,
+ Warning<warn_unguarded_availability.Summary>,
InGroup<UnguardedAvailabilityNew>;
def note_decl_unguarded_availability_silence : Note<
"annotate %select{%1|anonymous %1}0 with an availability attribute to silence this warning">;
@@ -3641,7 +3925,7 @@ def warn_fun_requires_negative_cap : Warning<
"calling function %0 requires negative capability '%1'">,
InGroup<ThreadSafetyAnalysis>, DefaultIgnore;
-// Thread safety warnings on pass by reference
+// Thread safety warnings on pass/return by reference
def warn_guarded_pass_by_reference : Warning<
"passing variable %1 by reference requires holding %0 "
"%select{'%2'|'%2' exclusively}3">,
@@ -3650,6 +3934,14 @@ def warn_pt_guarded_pass_by_reference : Warning<
"passing the value that %1 points to by reference requires holding %0 "
"%select{'%2'|'%2' exclusively}3">,
InGroup<ThreadSafetyReference>, DefaultIgnore;
+def warn_guarded_return_by_reference : Warning<
+ "returning variable %1 by reference requires holding %0 "
+ "%select{'%2'|'%2' exclusively}3">,
+ InGroup<ThreadSafetyReferenceReturn>, DefaultIgnore;
+def warn_pt_guarded_return_by_reference : Warning<
+ "returning the value that %1 points to by reference requires holding %0 "
+ "%select{'%2'|'%2' exclusively}3">,
+ InGroup<ThreadSafetyReferenceReturn>, DefaultIgnore;
// Imprecise thread safety warnings
def warn_variable_requires_lock : Warning<
@@ -3666,13 +3958,13 @@ def warn_fun_requires_lock : Warning<
// Precise thread safety warnings
def warn_variable_requires_lock_precise :
- Warning<warn_variable_requires_lock.Text>,
+ Warning<warn_variable_requires_lock.Summary>,
InGroup<ThreadSafetyPrecise>, DefaultIgnore;
def warn_var_deref_requires_lock_precise :
- Warning<warn_var_deref_requires_lock.Text>,
+ Warning<warn_var_deref_requires_lock.Summary>,
InGroup<ThreadSafetyPrecise>, DefaultIgnore;
def warn_fun_requires_lock_precise :
- Warning<warn_fun_requires_lock.Text>,
+ Warning<warn_fun_requires_lock.Summary>,
InGroup<ThreadSafetyPrecise>, DefaultIgnore;
def note_found_mutex_near_match : Note<"found near match '%0'">;
@@ -3754,6 +4046,9 @@ def warn_impcast_integer_64_32 : Warning<
def warn_impcast_integer_precision_constant : Warning<
"implicit conversion from %2 to %3 changes value from %0 to %1">,
InGroup<ConstantConversion>;
+def warn_impcast_single_bit_bitield_precision_constant : Warning<
+ "implicit truncation from %2 to a one-bit wide bit-field changes value from "
+ "%0 to %1">, InGroup<SingleBitBitFieldConstantConversion>;
def warn_impcast_bitfield_precision_constant : Warning<
"implicit truncation from %2 to bit-field changes value from %0 to %1">,
InGroup<BitFieldConstantConversion>;
@@ -3897,7 +4192,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,
@@ -3914,13 +4210,13 @@ def warn_pointer_to_int_cast : Warning<
"cast to smaller integer type %1 from %0">,
InGroup<PointerToIntCast>;
def warn_pointer_to_enum_cast : Warning<
- warn_pointer_to_int_cast.Text>,
+ warn_pointer_to_int_cast.Summary>,
InGroup<PointerToEnumCast>;
def warn_void_pointer_to_int_cast : Warning<
"cast to smaller integer type %1 from %0">,
InGroup<VoidPointerToIntCast>;
def warn_void_pointer_to_enum_cast : Warning<
- warn_void_pointer_to_int_cast.Text>,
+ warn_void_pointer_to_int_cast.Summary>,
InGroup<VoidPointerToEnumCast>;
def warn_attribute_ignored_for_field_of_type : Warning<
@@ -3956,6 +4252,9 @@ def warn_transparent_union_attribute_zero_fields : Warning<
def warn_attribute_type_not_supported : Warning<
"%0 attribute argument not supported: %1">,
InGroup<IgnoredAttributes>;
+def warn_attribute_type_not_supported_global : Warning<
+ "%0 attribute argument '%1' not supported on a global variable">,
+ InGroup<IgnoredAttributes>;
def warn_attribute_unknown_visibility : Warning<"unknown visibility %0">,
InGroup<IgnoredAttributes>;
def warn_attribute_protected_visibility :
@@ -3981,6 +4280,9 @@ def warn_vector_mode_deprecated : Warning<
"specifying vector types with the 'mode' attribute is deprecated; "
"use the 'vector_size' attribute instead">,
InGroup<DeprecatedAttributes>;
+def warn_deprecated_noreturn_spelling : Warning<
+ "the '[[_Noreturn]]' attribute spelling is deprecated in C23; use "
+ "'[[noreturn]]' instead">, InGroup<DeprecatedAttributes>;
def err_complex_mode_vector_type : Error<
"type of machine mode does not support base vector types">;
def err_enum_mode_vector_type : Error<
@@ -3991,6 +4293,10 @@ def warn_attribute_nonnull_no_pointers : Warning<
def warn_attribute_nonnull_parm_no_args : Warning<
"'nonnull' attribute when used on parameters takes no arguments">,
InGroup<IgnoredAttributes>;
+def warn_function_stmt_attribute_precedence : Warning<
+ "statement attribute %0 has higher precedence than function attribute "
+ "'%select{always_inline|flatten|noinline}1'">,
+ InGroup<IgnoredAttributes>;
def note_declared_nonnull : Note<
"declared %select{'returns_nonnull'|'nonnull'}0 here">;
def warn_attribute_sentinel_named_arguments : Warning<
@@ -4028,6 +4334,9 @@ def err_attribute_not_supported_on_arch
def warn_gcc_ignores_type_attr : Warning<
"GCC does not allow the %0 attribute to be written on a type">,
InGroup<GccCompat>;
+def warn_gcc_requires_variadic_function : Warning<
+ "GCC requires a function with the %0 attribute to be variadic">,
+ InGroup<GccCompat>;
// Clang-Specific Attributes
def warn_attribute_iboutlet : Warning<
@@ -4084,7 +4393,7 @@ def err_attribute_preferred_name_arg_invalid : Error<
"argument %0 to 'preferred_name' attribute is not a typedef for "
"a specialization of %1">;
def err_attribute_builtin_alias : Error<
- "%0 attribute can only be applied to a ARM or RISC-V builtin">;
+ "%0 attribute can only be applied to a ARM, HLSL or RISC-V builtin">;
// called-once attribute diagnostics.
def err_called_once_attribute_wrong_type : Error<
@@ -4256,14 +4565,15 @@ def err_void_param_qualified : Error<
"'void' as parameter must not have type qualifiers">;
def err_ident_list_in_fn_declaration : Error<
"a parameter list without types is only allowed in a function definition">;
-def ext_param_not_declared : Extension<
- "parameter %0 was not declared, defaulting to type 'int'">;
+def ext_param_not_declared : ExtWarn<
+ "parameter %0 was not declared, defaults to 'int'; ISO C99 and later do not "
+ "support implicit int">, InGroup<ImplicitInt>;
def err_param_default_argument : Error<
"C does not support default arguments">;
def err_param_default_argument_redefinition : Error<
"redefinition of default argument">;
def ext_param_default_argument_redefinition : ExtWarn<
- err_param_default_argument_redefinition.Text>,
+ err_param_default_argument_redefinition.Summary>,
InGroup<MicrosoftDefaultArgRedefinition>;
def err_param_default_argument_missing : Error<
"missing default argument on parameter">;
@@ -4299,6 +4609,9 @@ def err_uninitialized_member_in_ctor : Error<
def err_default_arg_makes_ctor_special : Error<
"addition of default argument on redeclaration makes this constructor a "
"%select{default|copy|move}0 constructor">;
+def err_stmt_expr_in_default_arg : Error<
+ "default %select{argument|non-type template argument}0 may not use a GNU "
+ "statement expression">;
def err_use_of_default_argument_to_function_declared_later : Error<
"use of default argument to function %0 that is declared later in class %1">;
@@ -4443,12 +4756,14 @@ def note_ovl_candidate_non_deduced_mismatch_qualified : Note<
// Note that we don't treat templates differently for this diagnostic.
def note_ovl_candidate_arity : Note<"candidate "
"%sub{select_ovl_candidate_kind}0,1,2 not viable: "
- "requires%select{ at least| at most|}3 %4 argument%s4, but %5 "
+ "requires%select{ at least| at most|}3 %4 "
+ "%select{|non-object }6argument%s4, but %5 "
"%plural{1:was|:were}5 provided">;
def note_ovl_candidate_arity_one : Note<"candidate "
"%sub{select_ovl_candidate_kind}0,1,2 not viable: "
"%select{requires at least|allows at most single|requires single}3 "
+ "%select{|non-object }6"
"argument %4, but %plural{0:no|:%5}5 arguments were provided">;
def note_ovl_candidate_deleted : Note<
@@ -4472,7 +4787,8 @@ def note_ovl_candidate_bad_conv_incomplete : Note<
"; remove &}7">;
def note_ovl_candidate_bad_list_argument : Note<
"candidate %sub{select_ovl_candidate_kind}0,1,2 not viable: "
- "cannot convert initializer list argument to %4">;
+ "%select{cannot convert initializer list|too few initializers in list"
+ "|too many initializers in list}7 argument to %4">;
def note_ovl_candidate_bad_overload : Note<
"candidate %sub{select_ovl_candidate_kind}0,1,2 not viable: "
"no overload of %4 matching %3 for %ordinal5 argument">;
@@ -4523,9 +4839,6 @@ def note_ovl_candidate_bad_cvr : Note<
"%select{const|restrict|const and restrict|volatile|const and volatile|"
"volatile and restrict|const, volatile, and restrict}4 qualifier"
"%select{||s||s|s|s}4">;
-def note_ovl_candidate_bad_unaligned : Note<
- "candidate %sub{select_ovl_candidate_kind}0,1,2 not viable: "
- "%ordinal5 argument (%3) would lose __unaligned qualifier">;
def note_ovl_candidate_bad_base_to_derived_conv : Note<
"candidate %sub{select_ovl_candidate_kind}0,1,2 not viable: "
"cannot %select{convert from|convert from|bind}3 "
@@ -4540,6 +4853,8 @@ def note_ovl_candidate_bad_target : Note<
def note_ovl_candidate_constraints_not_satisfied : Note<
"candidate %sub{select_ovl_candidate_kind}0,1,2 not viable: constraints "
"not satisfied">;
+def note_ovl_surrogate_constraints_not_satisfied : Note<
+ "conversion candidate %0 not viable: constraints not satisfied">;
def note_implicit_member_target_infer_collision : Note<
"implicit %sub{select_special_member_kind}0 inferred target collision: call to both "
"%select{__device__|__global__|__host__|__host__ __device__}1 and "
@@ -4582,6 +4897,8 @@ def ext_ovl_ambiguous_oper_binary_reversed : ExtWarn<
def note_ovl_ambiguous_oper_binary_reversed_self : Note<
"ambiguity is between a regular call to this operator and a call with the "
"argument order reversed">;
+def note_ovl_ambiguous_eqeq_reversed_self_non_const : Note<
+ "mark 'operator==' as const or add a matching 'operator!=' to resolve the ambiguity">;
def note_ovl_ambiguous_oper_binary_selected_candidate : Note<
"candidate function with non-reversed arguments">;
def note_ovl_ambiguous_oper_binary_reversed_candidate : Note<
@@ -4614,16 +4931,22 @@ def err_bound_member_function : Error<
"reference to non-static member function must be called"
"%select{|; did you mean to call it with no arguments?}0">;
def note_possible_target_of_call : Note<"possible target for call">;
+def err_no_viable_destructor : Error<
+ "no viable destructor found for class %0">;
+def err_ambiguous_destructor : Error<
+ "destructor of class %0 is ambiguous">;
def err_ovl_no_viable_object_call : Error<
"no matching function for call to object of type %0">;
def err_ovl_ambiguous_object_call : Error<
"call to object of type %0 is ambiguous">;
+def err_ovl_ambiguous_subscript_call : Error<
+ "call to subscript operator of type %0 is ambiguous">;
def err_ovl_deleted_object_call : Error<
"call to deleted function call operator in type %0">;
def note_ovl_surrogate_cand : Note<"conversion candidate of type %0">;
def err_member_call_without_object : Error<
- "call to non-static member function without an object argument">;
+ "call to %select{non-static|explicit}0 member function without an object argument">;
// C++ Address of Overloaded Function
def err_addr_ovl_no_viable : Error<
@@ -4648,8 +4971,10 @@ def err_ovl_no_viable_literal_operator : Error<
def err_template_param_shadow : Error<
"declaration of %0 shadows template parameter">;
def ext_template_param_shadow : ExtWarn<
- err_template_param_shadow.Text>, InGroup<MicrosoftTemplateShadow>;
+ err_template_param_shadow.Summary>, InGroup<MicrosoftTemplateShadow>;
def note_template_param_here : Note<"template parameter is declared here">;
+def note_template_param_external : Note<
+ "template parameter from hidden source: %0">;
def warn_template_export_unsupported : Warning<
"exported templates are unsupported">;
def err_template_outside_namespace_or_class_scope : Error<
@@ -4719,8 +5044,12 @@ def warn_cxx14_compat_template_nontype_parm_auto_type : Warning<
DefaultIgnore, InGroup<CXXPre17Compat>;
def err_template_param_default_arg_redefinition : Error<
"template parameter redefines default argument">;
+def err_template_param_default_arg_inconsistent_redefinition : Error<
+ "template parameter default argument is inconsistent with previous definition">;
def note_template_param_prev_default_arg : Note<
"previous default template argument defined here">;
+def note_template_param_prev_default_arg_in_other_module : Note<
+ "previous default template argument defined in module %0">;
def err_template_param_default_arg_missing : Error<
"template parameter missing a default argument">;
def ext_template_parameter_default_in_function_template : ExtWarn<
@@ -4745,6 +5074,7 @@ def warn_cxx11_compat_variable_template : Warning<
def err_template_variable_noparams : Error<
"extraneous 'template<>' in declaration of variable %0">;
def err_template_member : Error<"member %0 declared as a template">;
+def err_member_with_template_arguments : Error<"member %0 cannot have template arguments">;
def err_template_member_noparams : Error<
"extraneous 'template<>' in declaration of member %0">;
def err_template_tag_noparams : Error<
@@ -4759,6 +5089,9 @@ def ext_adl_only_template_id : ExtWarn<
"use of function template name with no prior declaration in function call "
"with explicit template arguments is a C++20 extension">, InGroup<CXX20>;
+def warn_unqualified_call_to_std_cast_function : Warning<
+ "unqualified call to '%0'">, InGroup<DiagGroup<"unqualified-std-cast-call">>;
+
// C++ Template Argument Lists
def err_template_missing_args : Error<
"use of "
@@ -4770,6 +5103,8 @@ def err_template_arg_list_different_arity : Error<
"%select{class template|function template|variable template|alias template|"
"template template parameter|concept|template}1 %2">;
def note_template_decl_here : Note<"template is declared here">;
+def note_template_decl_external : Note<
+ "template declaration from hidden source: %0">;
def err_template_arg_must_be_type : Error<
"template argument for template type parameter must be a type">;
def err_template_arg_must_be_type_suggest : Error<
@@ -4832,8 +5167,6 @@ def err_non_type_template_arg_subobject : Error<
"non-type template argument refers to subobject '%0'">;
def err_non_type_template_arg_addr_label_diff : Error<
"template argument / label address difference / what did you expect?">;
-def err_non_type_template_arg_unsupported : Error<
- "sorry, non-type template argument of type %0 is not yet supported">;
def err_template_arg_not_convertible : Error<
"non-type template argument of type %0 cannot be converted to a value "
"of type %1">;
@@ -4885,9 +5218,8 @@ def err_template_arg_not_object_or_func : Error<
"non-type template argument does not refer to an object or function">;
def err_template_arg_not_pointer_to_member_form : Error<
"non-type template argument is not a pointer to member constant">;
-def err_template_arg_member_ptr_base_derived_not_supported : Error<
- "sorry, non-type template argument of pointer-to-member type %1 that refers "
- "to member %q0 of a different class is not supported yet">;
+def err_template_arg_invalid : Error<
+ "non-type template argument '%0' is invalid">;
def ext_template_arg_extra_parens : ExtWarn<
"address non-type template argument cannot be surrounded by parentheses">;
def warn_cxx98_compat_template_arg_extra_parens : Warning<
@@ -4924,8 +5256,6 @@ def err_template_spec_unknown_kind : Error<
"class template">;
def note_specialized_entity : Note<
"explicitly specialized declaration is here">;
-def note_explicit_specialization_declared_here : Note<
- "explicit specialization declared here">;
def err_template_spec_decl_function_scope : Error<
"explicit specialization of %0 in function scope">;
def err_template_spec_decl_friend : Error<
@@ -4970,11 +5300,11 @@ def err_explicit_specialization_inconsistent_storage_class : Error<
"'%select{none|extern|static|__private_extern__|auto|register}0'">;
def err_dependent_function_template_spec_no_match : Error<
"no candidate function template was found for dependent"
- " friend function template specialization">;
+ " %select{member|friend}0 function template specialization">;
def note_dependent_function_template_spec_discard_reason : Note<
- "candidate ignored: %select{not a function template"
- "|not a member of the enclosing namespace;"
- " did you mean to explicitly qualify the specialization?}0">;
+ "candidate ignored: %select{not a function template|"
+ "not a member of the enclosing %select{class template|"
+ "namespace; did you mean to explicitly qualify the specialization?}1}0">;
// C++ class template specializations and out-of-line definitions
def err_template_spec_needs_header : Error<
@@ -5034,8 +5364,6 @@ def err_partial_spec_ordering_ambiguous : Error<
def note_partial_spec_match : Note<"partial specialization matches %0">;
def err_partial_spec_redeclared : Error<
"class template partial specialization %0 cannot be redeclared">;
-def note_partial_specialization_declared_here : Note<
- "explicit specialization declared here">;
def note_prev_partial_spec_here : Note<
"previous declaration of class template partial specialization %0 is here">;
def err_partial_spec_fully_specialized : Error<
@@ -5068,6 +5396,8 @@ def err_function_template_partial_spec : Error<
def err_template_recursion_depth_exceeded : Error<
"recursive template instantiation exceeded maximum depth of %0">,
DefaultFatal, NoSFINAE;
+def err_constraint_depends_on_self : Error<
+ "satisfaction of constraint '%0' depends on itself">, NoSFINAE;
def note_template_recursion_depth : Note<
"use -ftemplate-depth=N to increase recursive template instantiation depth">;
@@ -5104,6 +5434,8 @@ def note_template_exception_spec_instantiation_here : Note<
"in instantiation of exception specification for %0 requested here">;
def note_template_requirement_instantiation_here : Note<
"in instantiation of requirement here">;
+def note_template_requirement_params_instantiation_here : Note<
+ "in instantiation of requirement parameters here">;
def warn_var_template_missing : Warning<"instantiation of variable %q0 "
"required here, but no definition is available">,
InGroup<UndefinedVarTemplate>;
@@ -5158,6 +5490,10 @@ def note_constraint_normalization_here : Note<
def note_parameter_mapping_substitution_here : Note<
"while substituting into concept arguments here; substitution failures not "
"allowed in concept arguments">;
+def note_building_deduction_guide_here : Note<
+ "while building implicit deduction guide first needed here">;
+def note_lambda_substitution_here : Note<
+ "while substituting into a lambda expression here">;
def note_instantiation_contexts_suppressed : Note<
"(skipping %0 context%s0 in backtrace; use -ftemplate-backtrace-limit=0 to "
"see all)">;
@@ -5263,7 +5599,7 @@ def err_mismatched_exception_spec_explicit_instantiation : Error<
"exception specification in explicit instantiation does not match "
"instantiated one">;
def ext_mismatched_exception_spec_explicit_instantiation : ExtWarn<
- err_mismatched_exception_spec_explicit_instantiation.Text>,
+ err_mismatched_exception_spec_explicit_instantiation.Summary>,
InGroup<MicrosoftExceptionSpec>;
def err_explicit_instantiation_dependent : Error<
"explicit instantiation has dependent template arguments">;
@@ -5301,6 +5637,12 @@ def err_typename_refers_to_using_value_decl : Error<
"%0 in %1">;
def note_using_value_decl_missing_typename : Note<
"add 'typename' to treat this using declaration as a type">;
+def warn_cxx17_compat_implicit_typename : Warning<"use of implicit 'typename' is "
+ "incompatible with C++ standards before C++20">, InGroup<CXX20Compat>,
+ DefaultIgnore;
+def ext_implicit_typename : ExtWarn<"missing 'typename' prior to dependent "
+ "type name %0%1; implicit 'typename' is a C++20 extension">,
+ InGroup<CXX20>;
def err_template_kw_refers_to_non_template : Error<
"%0%select{| following the 'template' keyword}1 "
@@ -5310,10 +5652,10 @@ def note_template_kw_refers_to_non_template : Note<
def err_template_kw_refers_to_dependent_non_template : Error<
"%0%select{| following the 'template' keyword}1 "
"cannot refer to a dependent template">;
-def err_template_kw_refers_to_class_template : Error<
- "'%0%1' instantiated to a class template, not a function template">;
-def note_referenced_class_template : Note<
- "class template declared here">;
+def err_template_kw_refers_to_type_template : Error<
+ "'%0%1' is expected to be a non-type template, but instantiated to a %select{class|type alias}2 template">;
+def note_referenced_type_template : Note<
+ "%select{class|type alias}0 template declared here">;
def err_template_kw_missing : Error<
"missing 'template' keyword prior to dependent template name '%0%1'">;
def ext_template_outside_of_template : ExtWarn<
@@ -5359,9 +5701,9 @@ def err_unexpanded_parameter_pack : Error<
"%select{expression|base type|declaration type|data member type|bit-field "
"size|static assertion|fixed underlying type|enumerator value|"
"using declaration|friend declaration|qualifier|initializer|default argument|"
- "non-type template parameter type|exception type|partial specialization|"
- "__if_exists name|__if_not_exists name|lambda|block|type constraint|"
- "requirement|requires clause}0 "
+ "non-type template parameter type|exception type|explicit specialization|"
+ "partial specialization|__if_exists name|__if_not_exists name|lambda|block|"
+ "type constraint|requirement|requires clause}0 "
"contains%plural{0: an|:}1 unexpanded parameter pack"
"%plural{0:|1: %2|2:s %2 and %3|:s %2, %3, ...}1">;
@@ -5417,6 +5759,9 @@ def err_found_later_in_class : Error<"member %0 used before its declaration">;
def ext_found_later_in_class : ExtWarn<
"use of member %0 before its declaration is a Microsoft extension">,
InGroup<MicrosoftTemplate>;
+def ext_unqualified_base_class : ExtWarn<
+ "unqualified base initializer of class templates is a Microsoft extension">,
+ InGroup<MicrosoftTemplate>;
def note_dependent_member_use : Note<
"must qualify identifier to find this declaration in dependent base class">;
def err_not_found_by_two_phase_lookup : Error<"call to function %0 that is neither "
@@ -5444,6 +5789,9 @@ def warn_deprecated_def : Warning<
def warn_unavailable_def : Warning<
"implementing unavailable method">,
InGroup<DeprecatedImplementations>, DefaultIgnore;
+def warn_deprecated_builtin : Warning<
+ "builtin %0 is deprecated; use %1 instead">,
+ InGroup<DeprecatedBuiltins>;
def err_unavailable : Error<"%0 is unavailable">;
def err_property_method_unavailable :
Error<"property access is using %0 method which is unavailable">;
@@ -5467,16 +5815,28 @@ def warn_missing_sentinel : Warning <
InGroup<Sentinel>;
def note_sentinel_here : Note<
"%select{function|method|block}0 has been explicitly marked sentinel here">;
+def warn_strict_uses_without_prototype : Warning<
+ "passing arguments to %select{a function|%1}0 without a prototype is "
+ "deprecated in all versions of C and is not supported in C23">,
+ InGroup<DeprecatedNonPrototype>;
def warn_missing_prototype : Warning<
"no previous prototype for function %0">,
InGroup<DiagGroup<"missing-prototypes">>, DefaultIgnore;
def note_declaration_not_a_prototype : Note<
"this declaration is not a prototype; add %select{'void'|parameter declarations}0 "
"to make it %select{a prototype for a zero-parameter function|one}0">;
-def warn_strict_prototypes : Warning<
- "this %select{function declaration is not|block declaration is not|"
- "old-style function definition is not preceded by}0 a prototype">,
- InGroup<DiagGroup<"strict-prototypes">>, DefaultIgnore;
+// This is not actually an extension, but we only want it to be enabled in
+// -pedantic mode and this is the most direct way of accomplishing that.
+def warn_strict_prototypes : Extension<
+ "a %select{function|block}0 declaration without a prototype is deprecated "
+ "%select{in all versions of C|}0">, InGroup<StrictPrototypes>;
+def warn_non_prototype_changes_behavior : Warning<
+ "a function %select{declaration|definition}0 without a prototype is "
+ "deprecated in all versions of C %select{and is not supported in C23|and is "
+ "treated as a zero-parameter prototype in C23, conflicting with a "
+ "%select{previous|subsequent}2 %select{declaration|definition}3}1">,
+ InGroup<DeprecatedNonPrototype>;
+def note_conflicting_prototype : Note<"conflicting prototype is here">;
def warn_missing_variable_declarations : Warning<
"no previous extern declaration for non-static variable %0">,
InGroup<DiagGroup<"missing-variable-declarations">>, DefaultIgnore;
@@ -5511,6 +5871,12 @@ def err_new_abi_tag_on_redeclaration : Error<
def note_use_ifdef_guards : Note<
"unguarded header; consider using #ifdef guards or #pragma once">;
+def warn_var_decl_not_read_only : Warning<
+ "object of type %0 cannot be placed in read-only memory">,
+ InGroup<ReadOnlyPlacementChecks>;
+def note_enforce_read_only_placement : Note<"type was declared read-only here">;
+
+
def note_deleted_dtor_no_operator_delete : Note<
"virtual destructor requires an unambiguous, accessible 'operator delete'">;
def note_deleted_special_member_class_subobject : Note<
@@ -5563,8 +5929,8 @@ def warn_undefined_inline : Warning<"inline function %q0 is not defined">,
def err_undefined_inline_var : Error<"inline variable %q0 is not defined">;
def note_used_here : Note<"used here">;
-def err_internal_linkage_redeclaration : Error<
- "'internal_linkage' attribute does not appear on the first declaration of %0">;
+def err_attribute_missing_on_first_decl : Error<
+ "%0 attribute does not appear on the first declaration">;
def warn_internal_linkage_local_storage : Warning<
"'internal_linkage' attribute on a non-static local variable is ignored">,
InGroup<IgnoredAttributes>;
@@ -5640,6 +6006,8 @@ def warn_forward_class_redefinition : Warning<
def err_redefinition_different_typedef : Error<
"%select{typedef|type alias|type alias template}0 "
"redefinition with different types%diff{ ($ vs $)|}1,2">;
+def err_redefinition_different_concept : Error<
+ "redefinition of concept %0 with different template parameters or requirements">;
def err_tag_reference_non_tag : Error<
"%select{non-struct type|non-class type|non-union type|non-enum "
"type|typedef|type alias|template|type alias template|template "
@@ -5727,7 +6095,7 @@ def warn_typecheck_function_qualifiers_unspecified : Warning<
"'%0' qualifier on function type %1 has unspecified behavior">;
def warn_typecheck_reference_qualifiers : Warning<
"'%0' qualifier on reference type %1 has no effect">,
- InGroup<IgnoredQualifiers>;
+ InGroup<IgnoredReferenceQualifiers>;
def err_typecheck_invalid_restrict_not_pointer : Error<
"restrict requires a pointer or reference (%0 is invalid)">;
def err_typecheck_invalid_restrict_not_pointer_noarg : Error<
@@ -5737,7 +6105,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">;
@@ -5757,7 +6125,7 @@ def err_loader_uninitialized_extern_decl
: Error<"variable %0 cannot be declared both 'extern' and with the "
"'loader_uninitialized' attribute">;
def err_block_extern_cant_init : Error<
- "'extern' variable cannot have an initializer">;
+ "declaration of block scope identifier with linkage cannot have an initializer">;
def warn_extern_init : Warning<"'extern' variable has an initializer">,
InGroup<DiagGroup<"extern-initializer">>;
def err_variable_object_no_init : Error<
@@ -5778,7 +6146,7 @@ def ext_excess_initializers_in_char_array_initializer : ExtWarn<
"excess elements in char array initializer">,
InGroup<ExcessInitializers>;
def err_initializer_string_for_char_array_too_long : Error<
- "initializer-string for char array is too long">;
+ "initializer-string for char array is too long, array size is %0 but initializer has size %1 (including the null terminating character)">;
def ext_initializer_string_for_char_array_too_long : ExtWarn<
"initializer-string for char array is too long">,
InGroup<ExcessInitializers>;
@@ -5818,12 +6186,20 @@ def err_illegal_initializer_type : Error<"illegal initializer type %0">;
def ext_init_list_type_narrowing : ExtWarn<
"type %0 cannot be narrowed to %1 in initializer list">,
InGroup<CXX11Narrowing>, DefaultError, SFINAEFailure;
+def ext_init_list_type_narrowing_const_reference : ExtWarn<
+ ext_init_list_type_narrowing.Summary>,
+ InGroup<CXX11NarrowingConstReference>, DefaultError, SFINAEFailure;
def ext_init_list_variable_narrowing : ExtWarn<
"non-constant-expression cannot be narrowed from type %0 to %1 in "
"initializer list">, InGroup<CXX11Narrowing>, DefaultError, SFINAEFailure;
+def ext_init_list_variable_narrowing_const_reference : ExtWarn<
+ ext_init_list_variable_narrowing.Summary>, InGroup<CXX11NarrowingConstReference>, DefaultError, SFINAEFailure;
def ext_init_list_constant_narrowing : ExtWarn<
"constant expression evaluates to %0 which cannot be narrowed to type %1">,
InGroup<CXX11Narrowing>, DefaultError, SFINAEFailure;
+def ext_init_list_constant_narrowing_const_reference : ExtWarn<
+ ext_init_list_constant_narrowing.Summary>,
+ InGroup<CXX11NarrowingConstReference>, DefaultError, SFINAEFailure;
def warn_init_list_type_narrowing : Warning<
"type %0 cannot be narrowed to %1 in initializer list in C++11">,
InGroup<CXX11Narrowing>, DefaultIgnore;
@@ -5926,6 +6302,8 @@ def note_protected_by_vla_type_alias : Note<
"jump bypasses initialization of VLA type alias">;
def note_protected_by_constexpr_if : Note<
"jump enters controlled statement of constexpr if">;
+def note_protected_by_consteval_if : Note<
+ "jump enters controlled statement of consteval if">;
def note_protected_by_if_available : Note<
"jump enters controlled statement of if available">;
def note_protected_by_vla : Note<
@@ -5971,6 +6349,8 @@ def note_enters_block_captures_non_trivial_c_struct : Note<
"to destroy">;
def note_enters_compound_literal_scope : Note<
"jump enters lifetime of a compound literal that is non-trivial to destruct">;
+def note_enters_statement_expression : Note<
+ "jump enters a statement expression">;
def note_exits_cleanup : Note<
"jump exits scope of variable with __attribute__((cleanup))">;
@@ -6085,6 +6465,19 @@ def warn_superclass_variable_sized_type_not_at_end : Warning<
"field %0 can overwrite instance variable %1 with variable sized type %2"
" in superclass %3">, InGroup<ObjCFlexibleArray>;
+def err_flexible_array_count_not_in_same_struct : Error<
+ "'counted_by' field %0 isn't within the same struct as the flexible array">;
+def err_counted_by_attr_not_on_flexible_array_member : Error<
+ "'counted_by' only applies to C99 flexible array members">;
+def err_counted_by_attr_refers_to_flexible_array : Error<
+ "'counted_by' cannot refer to the flexible array %0">;
+def err_counted_by_must_be_in_structure : Error<
+ "field %0 in 'counted_by' not inside structure">;
+def err_flexible_array_counted_by_attr_field_not_integer : Error<
+ "field %0 in 'counted_by' must be a non-boolean integer type">;
+def note_flexible_array_counted_by_attr_field : Note<
+ "field %0 declared here">;
+
let CategoryName = "ARC Semantic Issue" in {
// ARC-mode diagnostics.
@@ -6351,10 +6744,23 @@ def err_func_def_incomplete_result : Error<
def err_atomic_specifier_bad_type
: Error<"_Atomic cannot be applied to "
"%select{incomplete |array |function |reference |atomic |qualified "
- "|sizeless ||integer }0type "
- "%1 %select{|||||||which is not trivially copyable|}0">;
+ "|sizeless ||integer |}0type "
+ "%1 %select{|||||||which is not trivially copyable||in C23}0">;
+def warn_atomic_member_access : Warning<
+ "accessing a member of an atomic structure or union is undefined behavior">,
+ InGroup<DiagGroup<"atomic-access">>, DefaultError;
// Expressions.
+def err_using_placeholder_variable : Error<
+ "ambiguous reference to placeholder '_', which is defined multiple times">;
+def note_reference_placeholder : Note<
+ "placeholder declared here">;
+def ext_placeholder_var_definition : ExtWarn<
+ "placeholder variables are a C++2c extension">, InGroup<CXX26>;
+def warn_cxx23_placeholder_var_definition : Warning<
+ "placeholder variables are incompatible with C++ standards before C++2c">,
+ DefaultIgnore, InGroup<CXXPre26Compat>;
+
def ext_sizeof_alignof_function_type : Extension<
"invalid application of '%0' to a function type">, InGroup<PointerArith>;
def ext_sizeof_alignof_void_type : Extension<
@@ -6368,7 +6774,8 @@ def err_sizeof_alignof_function_type : Error<
def err_openmp_default_simd_align_expr : Error<
"invalid application of '__builtin_omp_required_simd_align' to an expression, only type is allowed">;
def err_sizeof_alignof_typeof_bitfield : Error<
- "invalid application of '%select{sizeof|alignof|typeof}0' to bit-field">;
+ "invalid application of '%select{sizeof|alignof|typeof|typeof_unqual}0' to "
+ "bit-field">;
def err_alignof_member_of_incomplete_type : Error<
"invalid application of 'alignof' to a field of a class still being defined">;
def err_vecstep_non_scalar_vector_type : Error<
@@ -6391,22 +6798,21 @@ def warn_sub_ptr_zero_size_types : Warning<
def warn_pointer_arith_null_ptr : Warning<
"performing pointer arithmetic on a null pointer has undefined behavior%select{| if the offset is nonzero}0">,
InGroup<NullPointerArithmetic>, DefaultIgnore;
-def warn_gnu_null_ptr_arith : Warning<
+def warn_gnu_null_ptr_arith : Extension<
"arithmetic on a null pointer treated as a cast from integer to pointer is a GNU extension">,
- InGroup<NullPointerArithmetic>, DefaultIgnore;
+ InGroup<GNUNullPointerArithmetic>;
def warn_pointer_sub_null_ptr : Warning<
"performing pointer subtraction with a null pointer %select{has|may have}0 undefined behavior">,
InGroup<NullPointerSubtraction>, DefaultIgnore;
-def err_kernel_invalidates_sycl_unique_stable_name
- : Error<"kernel instantiation changes the result of an evaluated "
- "'__builtin_sycl_unique_stable_name'">;
-def note_sycl_unique_stable_name_evaluated_here
- : Note<"'__builtin_sycl_unique_stable_name' evaluated here">;
def warn_floatingpoint_eq : Warning<
"comparing floating point with == or != is unsafe">,
InGroup<DiagGroup<"float-equal">>, DefaultIgnore;
+def err_setting_eval_method_used_in_unsafe_context : Error <
+ "%select{'#pragma clang fp eval_method'|option 'ffp-eval-method'}0 cannot be used with "
+ "%select{option 'fapprox-func'|option 'mreassociate'|option 'freciprocal'|option 'ffp-eval-method'|'#pragma clang fp reassociate'|'#pragma clang fp reciprocal'}1">;
+
def warn_remainder_division_by_zero : Warning<
"%select{remainder|division}0 by zero is undefined">,
InGroup<DivZero>;
@@ -6476,15 +6882,27 @@ def warn_addition_in_bitshift : Warning<
"'%1' will be evaluated first">, InGroup<ShiftOpParentheses>;
def warn_self_assignment_builtin : Warning<
- "explicitly assigning value of variable of type %0 to itself">,
+ "explicitly assigning value of variable of type %0 to itself%select{|; did "
+ "you mean to assign to member %2?}1">,
InGroup<SelfAssignment>, DefaultIgnore;
def warn_self_assignment_overloaded : Warning<
- "explicitly assigning value of variable of type %0 to itself">,
+ "explicitly assigning value of variable of type %0 to itself%select{|; did "
+ "you mean to assign to member %2?}1">,
InGroup<SelfAssignmentOverloaded>, DefaultIgnore;
def warn_self_move : Warning<
- "explicitly moving variable of type %0 to itself">,
+ "explicitly moving variable of type %0 to itself%select{|; did you mean to "
+ "move to member %2?}1">,
InGroup<SelfMove>, DefaultIgnore;
+def err_builtin_move_forward_unsupported : Error<
+ "unsupported signature for %q0">;
+def err_use_of_unaddressable_function : Error<
+ "taking address of non-addressable standard library function">;
+// FIXME: This should also be in -Wc++23-compat once we have it.
+def warn_cxx20_compat_use_of_unaddressable_function : Warning<
+ "taking address of non-addressable standard library function "
+ "is incompatible with C++20">, InGroup<CXX20Compat>;
+
def warn_redundant_move_on_return : Warning<
"redundant move in return statement">,
InGroup<RedundantMove>, DefaultIgnore;
@@ -6527,7 +6945,8 @@ def err_arithmetic_nonfragile_interface : Error<
"this architecture and platform">;
def warn_deprecated_comma_subscript : Warning<
- "top-level comma expression in array subscript is deprecated">,
+ "top-level comma expression in array subscript is deprecated "
+ "in C++20 and unsupported in C++23">,
InGroup<DeprecatedCommaSubscript>;
def ext_subscript_non_lvalue : Extension<
@@ -6540,10 +6959,13 @@ def err_subscript_function_type : Error<
"subscript of pointer to function type %0">;
def err_subscript_incomplete_or_sizeless_type : Error<
"subscript of pointer to %select{incomplete|sizeless}0 type %1">;
+def err_subscript_svbool_t : Error<
+ "subscript of svbool_t is not allowed">;
def err_dereference_incomplete_type : Error<
"dereference of pointer to incomplete type %0">;
def ext_gnu_subscript_void_type : Extension<
- "subscript of a pointer to void is a GNU extension">, InGroup<PointerArith>;
+ "subscript of a pointer to void is a GNU extension">,
+ InGroup<GNUPointerArith>;
def err_typecheck_member_reference_struct_union : Error<
"member reference base type %0 is not a structure or union">;
def err_typecheck_member_reference_ivar : Error<
@@ -6602,6 +7024,11 @@ def err_member_decl_does_not_match : Error<
"does not match any declaration in %1">;
def err_friend_decl_with_def_arg_must_be_def : Error<
"friend declaration specifying a default argument must be a definition">;
+def err_friend_decl_with_enclosing_temp_constraint_must_be_def : Error<
+ "friend declaration with a constraint that depends on an enclosing "
+ "template parameter must be a definition">;
+def err_non_temp_friend_decl_with_requires_clause_must_be_def : Error<
+ "non-template friend declaration with a requires clause must be a definition">;
def err_friend_decl_with_def_arg_redeclared : Error<
"friend declaration specifying a default argument must be the only declaration">;
def err_friend_decl_does_not_match : Error<
@@ -6624,7 +7051,7 @@ def ext_out_of_line_declaration : ExtWarn<
def err_member_extra_qualification : Error<
"extra qualification on member %0">;
def warn_member_extra_qualification : Warning<
- err_member_extra_qualification.Text>, InGroup<MicrosoftExtraQualification>;
+ err_member_extra_qualification.Summary>, InGroup<MicrosoftExtraQualification>;
def warn_namespace_member_extra_qualification : Warning<
"extra qualification on member %0">,
InGroup<DiagGroup<"extra-qualification">>;
@@ -6682,8 +7109,8 @@ def err_array_init_plain_string_into_char8_t : Error<
def note_array_init_plain_string_into_char8_t : Note<
"add 'u8' prefix to form a 'char8_t' string literal">;
def err_array_init_utf8_string_into_char : Error<
- "%select{|ISO C++20 does not permit }0initialization of char array with "
- "UTF-8 string literal%select{ is not permitted by '-fchar8_t'|}0">;
+ "initialization of %select{|signed }0char array with "
+ "UTF-8 string literal is not permitted by %select{'-fchar8_t'|C++20}1">;
def warn_cxx20_compat_utf8_string : Warning<
"type of UTF-8 string literal will change from array of const char to "
"array of const char8_t in C++20">, InGroup<CXX20Compat>, DefaultIgnore;
@@ -6718,7 +7145,7 @@ def warn_standalone_specifier : Warning<"'%0' ignored on this declaration">,
def ext_standalone_specifier : ExtWarn<"'%0' is not permitted on a declaration "
"of a type">, InGroup<MissingDeclarations>;
def err_standalone_class_nested_name_specifier : Error<
- "forward declaration of %select{class|struct|interface|union|enum}0 cannot "
+ "forward declaration of %select{class|struct|interface|union|enum|enum class|enum struct}0 cannot "
"have a nested name specifier">;
def err_typecheck_sclass_func : Error<"illegal storage class on function">;
def err_static_block_func : Error<
@@ -6752,8 +7179,10 @@ def err_typecheck_unary_expr : Error<
def err_typecheck_indirection_requires_pointer : Error<
"indirection requires pointer operand (%0 invalid)">;
def ext_typecheck_indirection_through_void_pointer : ExtWarn<
- "ISO C++ does not allow indirection on operand of type %0">,
- InGroup<DiagGroup<"void-ptr-dereference">>;
+ "ISO C does not allow indirection on operand of type %0">,
+ InGroup<VoidPointerDeref>;
+def err_typecheck_indirection_through_void_pointer_cpp
+ : Error<"indirection not permitted on operand of type %0">;
def warn_indirection_through_null : Warning<
"indirection of non-volatile null pointer will be deleted, not trap">,
InGroup<NullDereference>;
@@ -6770,7 +7199,7 @@ def warn_taking_address_of_packed_member : Warning<
"taking address of packed member %0 of class or structure %q1 may result in an unaligned pointer value">,
InGroup<DiagGroup<"address-of-packed-member">>;
def warn_param_mismatched_alignment : Warning<
- "passing %0-byte aligned argument to %1-byte aligned parameter %2 of %3 may result in an unaligned pointer access">,
+ "passing %0-byte aligned argument to %1-byte aligned parameter %2%select{| of %4}3 may result in an unaligned pointer access">,
InGroup<DiagGroup<"align-mismatch">>;
def err_objc_object_assignment : Error<
@@ -6848,6 +7277,11 @@ def warn_arith_conv_enum_float_cxx20 : Warning<
"%plural{2:with|4:from|:and}0 "
"%select{enumeration|floating-point}1 type %3 is deprecated">,
InGroup<DeprecatedEnumFloatConversion>;
+def err_arith_conv_enum_float_cxx26 : Error<
+ "invalid %sub{select_arith_conv_kind}0 "
+ "%select{floating-point|enumeration}1 type %2 "
+ "%plural{2:with|4:from|:and}0 "
+ "%select{enumeration|floating-point}1 type %3">;
def warn_arith_conv_mixed_enum_types : Warning<
"%sub{select_arith_conv_kind}0 "
"different enumeration types%diff{ ($ and $)|}1,2">,
@@ -6856,23 +7290,27 @@ def warn_arith_conv_mixed_enum_types_cxx20 : Warning<
"%sub{select_arith_conv_kind}0 "
"different enumeration types%diff{ ($ and $)|}1,2 is deprecated">,
InGroup<DeprecatedEnumEnumConversion>;
+def err_conv_mixed_enum_types_cxx26 : Error<
+ "invalid %sub{select_arith_conv_kind}0 "
+ "different enumeration types%diff{ ($ and $)|}1,2">;
+
def warn_arith_conv_mixed_anon_enum_types : Warning<
- warn_arith_conv_mixed_enum_types.Text>,
+ warn_arith_conv_mixed_enum_types.Summary>,
InGroup<AnonEnumEnumConversion>, DefaultIgnore;
def warn_arith_conv_mixed_anon_enum_types_cxx20 : Warning<
- warn_arith_conv_mixed_enum_types_cxx20.Text>,
+ warn_arith_conv_mixed_enum_types_cxx20.Summary>,
InGroup<DeprecatedAnonEnumEnumConversion>;
def warn_conditional_mixed_enum_types : Warning<
- warn_arith_conv_mixed_enum_types.Text>,
+ warn_arith_conv_mixed_enum_types.Summary>,
InGroup<EnumCompareConditional>, DefaultIgnore;
def warn_conditional_mixed_enum_types_cxx20 : Warning<
- warn_arith_conv_mixed_enum_types_cxx20.Text>,
+ warn_arith_conv_mixed_enum_types_cxx20.Summary>,
InGroup<DeprecatedEnumCompareConditional>;
def warn_comparison_mixed_enum_types : Warning<
- warn_arith_conv_mixed_enum_types.Text>,
+ warn_arith_conv_mixed_enum_types.Summary>,
InGroup<EnumCompare>;
def warn_comparison_mixed_enum_types_cxx20 : Warning<
- warn_arith_conv_mixed_enum_types_cxx20.Text>,
+ warn_arith_conv_mixed_enum_types_cxx20.Summary>,
InGroup<DeprecatedEnumCompare>;
def warn_comparison_of_mixed_enum_types_switch : Warning<
"comparison of different enumeration types in switch statement"
@@ -6932,7 +7370,7 @@ def warn_out_of_range_compare : Warning<
"result of comparison of %select{constant %0|true|false}1 with "
"%select{expression of type %2|boolean expression}3 is always %4">,
InGroup<TautologicalOutOfRangeCompare>;
-def warn_tautological_bool_compare : Warning<warn_out_of_range_compare.Text>,
+def warn_tautological_bool_compare : Warning<warn_out_of_range_compare.Summary>,
InGroup<TautologicalConstantCompare>;
def warn_integer_constants_in_conditional_always_true : Warning<
"converting the result of '?:' with integer constants to a boolean always "
@@ -6964,14 +7402,16 @@ def note_logical_not_silence_with_parens : Note<
"add parentheses around left hand side expression to silence this warning">;
def err_invalid_this_use : Error<
- "invalid use of 'this' outside of a non-static member function">;
+ "invalid use of 'this' %select{outside of a non-static member function"
+ "|in a function with an explicit object parameter}0">;
def err_this_static_member_func : Error<
"'this' cannot be%select{| implicitly}0 used in a static member function "
"declaration">;
-def err_invalid_member_use_in_static_method : Error<
- "invalid use of member %0 in static member function">;
+def err_invalid_member_use_in_method : Error<
+ "invalid use of member %0 in %select{static|explicit object}1 member function">;
+
def err_invalid_qualified_function_type : Error<
- "%select{non-member function|static member function|deduction guide}0 "
+ "%select{non-member function|static member function|explicit object member function|deduction guide}0 "
"%select{of type %2 |}1cannot have '%3' qualifier">;
def err_compound_qualified_function_type : Error<
"%select{block pointer|pointer|reference}0 to function type %select{%2 |}1"
@@ -6979,6 +7419,26 @@ def err_compound_qualified_function_type : Error<
def err_qualified_function_typeid : Error<
"type operand %0 of 'typeid' cannot have '%1' qualifier">;
+def err_cxx20_deducing_this : Error<
+ "explicit object parameters are incompatible with C++ standards before C++2b">;
+def err_explicit_object_default_arg: Error<
+ "the explicit object parameter cannot have a default argument">;
+def err_explicit_object_parameter_pack: Error<
+ "the explicit object parameter cannot be a function parameter pack">;
+def err_explicit_object_parameter_must_be_first: Error<
+ "an explicit object parameter can only appear as the first parameter "
+ "of the %select{function|lambda}0">;
+def err_explicit_object_parameter_nonmember: Error<
+ "an explicit object parameter cannot appear in a "
+ "%select{static|virtual|non-member}0 %select{function|lambda}1">;
+def err_explicit_object_parameter_constructor: Error<
+ "an explicit object parameter cannot appear in a %select{constructor|destructor}0">;
+def err_explicit_object_parameter_mutable: Error<
+ "a lambda with an explicit object parameter cannot be mutable">;
+def err_invalid_explicit_object_type_in_lambda: Error<
+ "invalid explicit object parameter type %0 in lambda with capture; "
+ "the type must be the same as, or derived from, the lambda">;
+
def err_ref_qualifier_overload : Error<
"cannot overload a member function %select{without a ref-qualifier|with "
"ref-qualifier '&'|with ref-qualifier '&&'}0 with a member function %select{"
@@ -7064,11 +7524,11 @@ def err_duplicate_property : Error<
"property has a previous declaration">;
def ext_gnu_void_ptr : Extension<
"arithmetic on%select{ a|}0 pointer%select{|s}0 to void is a GNU extension">,
- InGroup<PointerArith>;
+ InGroup<GNUPointerArith>;
def ext_gnu_ptr_func_arith : Extension<
"arithmetic on%select{ a|}0 pointer%select{|s}0 to%select{ the|}2 function "
"type%select{|s}2 %1%select{| and %3}2 is a GNU extension">,
- InGroup<PointerArith>;
+ InGroup<GNUPointerArith>;
def err_readonly_message_assignment : Error<
"assigning to 'readonly' return result of an Objective-C message not allowed">;
def ext_integer_increment_complex : Extension<
@@ -7174,6 +7634,8 @@ def err_attribute_arm_builtin_alias : Error<
"'__clang_arm_builtin_alias' attribute can only be applied to an ARM builtin">;
def err_attribute_arm_mve_polymorphism : Error<
"'__clang_arm_mve_strict_polymorphism' attribute can only be applied to an MVE/NEON vector type">;
+def err_attribute_webassembly_funcref : Error<
+ "'__funcref' attribute can only be applied to a function pointer type">;
def warn_setter_getter_impl_required : Warning<
"property %0 requires method %1 to be defined - "
@@ -7314,8 +7776,6 @@ def err_bad_dynamic_cast_not_polymorphic : Error<"%0 is not polymorphic">;
// Other C++ expressions
def err_need_header_before_typeid : Error<
"you need to include <typeinfo> before using the 'typeid' operator">;
-def err_need_header_before_ms_uuidof : Error<
- "you need to include <guiddef.h> before using the '__uuidof' operator">;
def err_need_header_before_placement_new : Error<
"no matching %0 function for non-allocating placement new expression; "
"include <new>">;
@@ -7413,17 +7873,20 @@ def note_member_declared_here : Note<
"member %0 declared here">;
def note_member_first_declared_here : Note<
"member %0 first declared here">;
+def warn_bitwise_instead_of_logical : Warning<
+ "use of bitwise '%0' with boolean operands">,
+ InGroup<BitwiseInsteadOfLogical>, DefaultIgnore;
def warn_bitwise_negation_bool : Warning<
"bitwise negation of a boolean expression%select{;| always evaluates to 'true';}0 "
"did you mean logical negation?">,
- InGroup<DiagGroup<"bool-operation">>;
+ InGroup<BoolOperation>, DefaultIgnore;
def err_decrement_bool : Error<"cannot decrement expression of type bool">;
def warn_increment_bool : Warning<
"incrementing expression of type bool is deprecated and "
"incompatible with C++17">, InGroup<DeprecatedIncrementBool>;
def ext_increment_bool : ExtWarn<
"ISO C++17 does not allow incrementing expression of type bool">,
- DefaultError, InGroup<IncrementBool>;
+ DefaultError, SFINAEFailure, InGroup<IncrementBool>;
def err_increment_decrement_enum : Error<
"cannot %select{decrement|increment}0 expression of enum type %1">;
@@ -7433,9 +7896,6 @@ def warn_deprecated_increment_decrement_volatile : Warning<
def warn_deprecated_simple_assign_volatile : Warning<
"use of result of assignment to object of volatile-qualified type %0 "
"is deprecated">, InGroup<DeprecatedVolatile>;
-def warn_deprecated_compound_assign_volatile : Warning<
- "compound assignment to object of volatile-qualified type %0 is deprecated">,
- InGroup<DeprecatedVolatile>;
def warn_deprecated_volatile_return : Warning<
"volatile-qualified return type %0 is deprecated">,
InGroup<DeprecatedVolatile>;
@@ -7452,6 +7912,12 @@ def warn_deprecated_altivec_src_compat : Warning<
"'-altivec-compat=xl' option">,
InGroup<DiagGroup<"deprecated-altivec-src-compat">>;
+def warn_deprecated_lax_vec_conv_all : Warning<
+ "Implicit conversion between vector types ('%0' and '%1') is deprecated. "
+ "In the future, the behavior implied by '-fno-lax-vector-conversions' "
+ "will be the default.">,
+ InGroup<DiagGroup<"deprecate-lax-vec-conv-all">>;
+
def err_catch_incomplete_ptr : Error<
"cannot catch pointer to incomplete type %0">;
def err_catch_incomplete_ref : Error<
@@ -7490,7 +7956,8 @@ def note_throw_in_function : Note<"function declared non-throwing here">;
def err_seh_try_outside_functions : Error<
"cannot use SEH '__try' in blocks, captured regions, or Obj-C method decls">;
def err_mixing_cxx_try_seh_try : Error<
- "cannot use C++ 'try' in the same function as SEH '__try'">;
+ "cannot use %select{C++ 'try'|Objective-C '@try'}0 "
+ "in the same function as SEH '__try'">;
def err_seh_try_unsupported : Error<
"SEH '__try' is not supported on this target">;
def note_conflicting_try_here : Note<
@@ -7528,6 +7995,8 @@ def warn_overaligned_type : Warning<
"type %0 requires %1 bytes of alignment and the default allocator only "
"guarantees %2 bytes">,
InGroup<OveralignedType>, DefaultIgnore;
+def err_array_element_alignment : Error<
+ "size of array element of type %0 (%1 bytes) isn't a multiple of its alignment (%2 bytes)">;
def err_aligned_allocation_unavailable : Error<
"aligned %select{allocation|deallocation}0 function of type '%1' is "
"%select{only|not}4 available on %2%select{ %3 or newer|}4">;
@@ -7578,6 +8047,8 @@ def err_return_in_constructor_handler : Error<
def warn_cdtor_function_try_handler_mem_expr : Warning<
"cannot refer to a non-static member from the handler of a "
"%select{constructor|destructor}0 function try block">, InGroup<Exceptions>;
+def err_throw_object_throwing_dtor : Error<
+ "cannot throw object of type %0 with a potentially-throwing destructor">;
let CategoryName = "Lambda Issue" in {
def err_capture_more_than_once : Error<
@@ -7688,7 +8159,7 @@ let CategoryName = "Lambda Issue" in {
"is a C++20 extension">, InGroup<CXX20>;
def warn_deprecated_this_capture : Warning<
"implicit capture of 'this' with a capture default of '=' is deprecated">,
- InGroup<DeprecatedThisCapture>, DefaultIgnore;
+ InGroup<DeprecatedThisCapture>;
def note_deprecated_this_capture : Note<
"add an explicit capture of 'this' to capture '*this' by reference">;
@@ -7755,6 +8226,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 "
+ "%select{is not exported|has internal linkage|has module linkage}1">;
def err_invalid_declarator_global_scope : Error<
"definition or redeclaration of %0 cannot name the global scope">;
def err_invalid_declarator_in_function : Error<
@@ -7870,24 +8346,6 @@ def err_incompatible_qualified_id : Error<
"sending type to parameter of incompatible type}0,1"
"|%diff{casting $ to incompatible type $|"
"casting type to incompatible type}0,1}2">;
-def ext_typecheck_convert_pointer_int : ExtWarn<
- "incompatible pointer to integer conversion "
- "%select{%diff{assigning to $ from $|assigning to different types}0,1"
- "|%diff{passing $ to parameter of type $|"
- "passing to parameter of different type}0,1"
- "|%diff{returning $ from a function with result type $|"
- "returning from function with different return type}0,1"
- "|%diff{converting $ to type $|converting between types}0,1"
- "|%diff{initializing $ with an expression of type $|"
- "initializing with expression of different type}0,1"
- "|%diff{sending $ to parameter of type $|"
- "sending to parameter of different type}0,1"
- "|%diff{casting $ to type $|casting between types}0,1}2"
- "%select{|; dereference with *|"
- "; take the address with &|"
- "; remove *|"
- "; remove &}3">,
- InGroup<IntConversion>;
def err_typecheck_convert_pointer_int : Error<
"incompatible pointer to integer conversion "
"%select{%diff{assigning to $ from $|assigning to different types}0,1"
@@ -7905,24 +8363,9 @@ def err_typecheck_convert_pointer_int : Error<
"; take the address with &|"
"; remove *|"
"; remove &}3">;
-def ext_typecheck_convert_int_pointer : ExtWarn<
- "incompatible integer to pointer conversion "
- "%select{%diff{assigning to $ from $|assigning to different types}0,1"
- "|%diff{passing $ to parameter of type $|"
- "passing to parameter of different type}0,1"
- "|%diff{returning $ from a function with result type $|"
- "returning from function with different return type}0,1"
- "|%diff{converting $ to type $|converting between types}0,1"
- "|%diff{initializing $ with an expression of type $|"
- "initializing with expression of different type}0,1"
- "|%diff{sending $ to parameter of type $|"
- "sending to parameter of different type}0,1"
- "|%diff{casting $ to type $|casting between types}0,1}2"
- "%select{|; dereference with *|"
- "; take the address with &|"
- "; remove *|"
- "; remove &}3">,
- InGroup<IntConversion>, SFINAEFailure;
+def ext_typecheck_convert_pointer_int : ExtWarn<
+ err_typecheck_convert_pointer_int.Summary>,
+ InGroup<IntConversion>, DefaultError;
def err_typecheck_convert_int_pointer : Error<
"incompatible integer to pointer conversion "
"%select{%diff{assigning to $ from $|assigning to different types}0,1"
@@ -7940,6 +8383,9 @@ def err_typecheck_convert_int_pointer : Error<
"; take the address with &|"
"; remove *|"
"; remove &}3">;
+def ext_typecheck_convert_int_pointer : ExtWarn<
+ err_typecheck_convert_int_pointer.Summary>,
+ InGroup<IntConversion>, DefaultError;
def ext_typecheck_convert_pointer_void_func : Extension<
"%select{%diff{assigning to $ from $|assigning to different types}0,1"
"|%diff{passing $ to parameter of type $|"
@@ -7982,7 +8428,7 @@ def ext_typecheck_convert_incompatible_pointer_sign : ExtWarn<
"where one is of the unique plain 'char' type and the other is not}3">,
InGroup<DiagGroup<"pointer-sign">>;
def err_typecheck_convert_incompatible_pointer_sign :
- Error<ext_typecheck_convert_incompatible_pointer_sign.Text>;
+ Error<ext_typecheck_convert_incompatible_pointer_sign.Summary>;
def ext_typecheck_convert_incompatible_pointer : ExtWarn<
"incompatible pointer types "
"%select{%diff{assigning to $ from $|assigning to different types}0,1"
@@ -8018,24 +8464,6 @@ def err_typecheck_convert_incompatible_pointer : Error<
"; take the address with &|"
"; remove *|"
"; remove &}3">;
-def ext_typecheck_convert_incompatible_function_pointer : ExtWarn<
- "incompatible function pointer types "
- "%select{%diff{assigning to $ from $|assigning to different types}0,1"
- "|%diff{passing $ to parameter of type $|"
- "passing to parameter of different type}0,1"
- "|%diff{returning $ from a function with result type $|"
- "returning from function with different return type}0,1"
- "|%diff{converting $ to type $|converting between types}0,1"
- "|%diff{initializing $ with an expression of type $|"
- "initializing with expression of different type}0,1"
- "|%diff{sending $ to parameter of type $|"
- "sending to parameter of different type}0,1"
- "|%diff{casting $ to type $|casting between types}0,1}2"
- "%select{|; dereference with *|"
- "; take the address with &|"
- "; remove *|"
- "; remove &}3">,
- InGroup<IncompatibleFunctionPointerTypes>;
def err_typecheck_convert_incompatible_function_pointer : Error<
"incompatible function pointer types "
"%select{%diff{assigning to $ from $|assigning to different types}0,1"
@@ -8053,6 +8481,12 @@ def err_typecheck_convert_incompatible_function_pointer : Error<
"; take the address with &|"
"; remove *|"
"; remove &}3">;
+def ext_typecheck_convert_incompatible_function_pointer : ExtWarn<
+ err_typecheck_convert_incompatible_function_pointer.Summary>,
+ InGroup<IncompatibleFunctionPointerTypes>, DefaultError;
+def warn_typecheck_convert_incompatible_function_pointer_strict : Warning<
+ err_typecheck_convert_incompatible_function_pointer.Summary>,
+ InGroup<DiagGroup<"incompatible-function-pointer-types-strict">>, DefaultIgnore;
def ext_typecheck_convert_discards_qualifiers : ExtWarn<
"%select{%diff{assigning to $ from $|assigning to different types}0,1"
"|%diff{passing $ to parameter of type $|"
@@ -8228,53 +8662,65 @@ def err_call_function_incomplete_return : Error<
def err_call_incomplete_argument : Error<
"argument type %0 is incomplete">;
def err_typecheck_call_too_few_args : Error<
- "too few %select{|||execution configuration }0arguments to "
+ "too few %select{|||execution configuration }0"
+ "%select{|non-object }3arguments to "
"%select{function|block|method|kernel function}0 call, "
"expected %1, have %2">;
def err_typecheck_call_too_few_args_one : Error<
- "too few %select{|||execution configuration }0arguments to "
+ "too few %select{|||execution configuration }0"
+ "%select{|non-object }2arguments to "
"%select{function|block|method|kernel function}0 call, "
"single argument %1 was not specified">;
def err_typecheck_call_too_few_args_at_least : Error<
- "too few %select{|||execution configuration }0arguments to "
+ "too few %select{|||execution configuration }0"
+ "%select{|non-object }3arguments to "
"%select{function|block|method|kernel function}0 call, "
"expected at least %1, have %2">;
def err_typecheck_call_too_few_args_at_least_one : Error<
- "too few %select{|||execution configuration }0arguments to "
+ "too few %select{|||execution configuration }0"
+ "%select{|non-object }2arguments to "
"%select{function|block|method|kernel function}0 call, "
"at least argument %1 must be specified">;
def err_typecheck_call_too_few_args_suggest : Error<
- "too few %select{|||execution configuration }0arguments to "
+ "too few %select{|||execution configuration }0"
+ "%select{|non-object }3arguments to "
"%select{function|block|method|kernel function}0 call, "
- "expected %1, have %2; did you mean %3?">;
+ "expected %1, have %2; did you mean %4?">;
def err_typecheck_call_too_few_args_at_least_suggest : Error<
- "too few %select{|||execution configuration }0arguments to "
+ "too few %select{|||execution configuration }0"
+ "%select{|non-object }3arguments to "
"%select{function|block|method|kernel function}0 call, "
- "expected at least %1, have %2; did you mean %3?">;
+ "expected at least %1, have %2; did you mean %4?">;
def err_typecheck_call_too_many_args : Error<
- "too many %select{|||execution configuration }0arguments to "
+ "too many %select{|||execution configuration }0"
+ "%select{|non-object }3arguments to "
"%select{function|block|method|kernel function}0 call, "
"expected %1, have %2">;
def err_typecheck_call_too_many_args_one : Error<
- "too many %select{|||execution configuration }0arguments to "
+ "too many %select{|||execution configuration }0"
+ "%select{|non-object }3arguments to "
"%select{function|block|method|kernel function}0 call, "
"expected single argument %1, have %2 arguments">;
def err_typecheck_call_too_many_args_at_most : Error<
- "too many %select{|||execution configuration }0arguments to "
+ "too many %select{|||execution configuration }0"
+ "%select{|non-object }3arguments to "
"%select{function|block|method|kernel function}0 call, "
"expected at most %1, have %2">;
def err_typecheck_call_too_many_args_at_most_one : Error<
"too many %select{|||execution configuration }0arguments to "
"%select{function|block|method|kernel function}0 call, "
- "expected at most single argument %1, have %2 arguments">;
+ "expected at most single %select{|non-object }3argument %1, "
+ "have %2%select{|non-object}3 arguments">;
def err_typecheck_call_too_many_args_suggest : Error<
- "too many %select{|||execution configuration }0arguments to "
+ "too many %select{|||execution configuration }0"
+ "%select{|non-object }3arguments to "
"%select{function|block|method|kernel function}0 call, "
- "expected %1, have %2; did you mean %3?">;
+ "expected %1, have %2; did you mean %4?">;
def err_typecheck_call_too_many_args_at_most_suggest : Error<
- "too many %select{|||execution configuration }0arguments to "
+ "too many %select{|||execution configuration }0"
+ "%select{|non-object }3arguments to "
"%select{function|block|method|kernel function}0 call, "
- "expected at most %1, have %2; did you mean %3?">;
+ "expected at most %1, have %2; did you mean %4?">;
def err_arc_typecheck_convert_incompatible_pointer : Error<
"incompatible pointer types passing retainable parameter of type %0"
@@ -8302,8 +8748,8 @@ def err_atomic_exclusive_builtin_pointer_size : Error<
" 1,2,4 or 8 byte type (%0 invalid)">;
def err_atomic_builtin_ext_int_size : Error<
"Atomic memory operand must have a power-of-two size">;
-def err_atomic_builtin_ext_int_prohibit : Error<
- "argument to atomic builtin of type '_ExtInt' is not supported">;
+def err_atomic_builtin_bit_int_prohibit : Error<
+ "argument to atomic builtin of type '_BitInt' is not supported">;
def err_atomic_op_needs_atomic : Error<
"address argument to atomic operation must be a pointer to _Atomic "
"type (%0 invalid)">;
@@ -8322,11 +8768,14 @@ def err_atomic_op_needs_atomic_int_ptr_or_fp : Error<
def err_atomic_op_needs_atomic_int_or_ptr : Error<
"address argument to atomic operation must be a pointer to %select{|atomic }0"
"integer or pointer (%1 invalid)">;
+def err_atomic_op_needs_atomic_int_or_fp : Error<
+ "address argument to atomic operation must be a pointer to %select{|atomic }0"
+ "integer or supported floating point type (%1 invalid)">;
def err_atomic_op_needs_atomic_int : Error<
"address argument to atomic operation must be a pointer to "
"%select{|atomic }0integer (%1 invalid)">;
def warn_atomic_op_has_invalid_memory_order : Warning<
- "memory order argument to atomic operation is invalid">,
+ "%select{|success |failure }0memory order argument to atomic operation is invalid">,
InGroup<DiagGroup<"atomic-memory-ordering">>;
def err_atomic_op_has_invalid_synch_scope : Error<
"synchronization scope argument to atomic operation is invalid">;
@@ -8335,13 +8784,22 @@ def warn_atomic_implicit_seq_cst : Warning<
InGroup<DiagGroup<"atomic-implicit-seq-cst">>, DefaultIgnore;
def err_overflow_builtin_must_be_int : Error<
- "operand argument to overflow builtin must be an integer (%0 invalid)">;
+ "operand argument to %select{overflow builtin|checked integer operation}0 "
+ "must be an integer type %select{|other than plain 'char', 'bool', bit-precise, "
+ "or an enumeration }0(%1 invalid)">;
def err_overflow_builtin_must_be_ptr_int : Error<
- "result argument to overflow builtin must be a pointer "
- "to a non-const integer (%0 invalid)">;
-def err_overflow_builtin_ext_int_max_size : Error<
- "__builtin_mul_overflow does not support signed _ExtInt operands of more "
+ "result argument to %select{overflow builtin|checked integer operation}0 "
+ "must be a pointer to a non-const integer type %select{|other than plain 'char', "
+ "'bool', bit-precise, or an enumeration }0(%1 invalid)">;
+def err_overflow_builtin_bit_int_max_size : Error<
+ "__builtin_mul_overflow does not support 'signed _BitInt' operands of more "
"than %0 bits">;
+def err_expected_struct_pointer_argument : Error<
+ "expected pointer to struct as %ordinal0 argument to %1, found %2">;
+def err_expected_callable_argument : Error<
+ "expected a callable expression as %ordinal0 argument to %1, found %2">;
+def note_building_builtin_dump_struct_call : Note<
+ "in call to printing function with arguments '(%0)' while dumping struct">;
def err_atomic_load_store_uses_lib : Error<
"atomic %select{load|store}0 requires runtime support that is not "
@@ -8380,8 +8838,10 @@ def err_ref_bad_target_global_initializer : Error<
"function %1 in global initializer">;
def err_capture_bad_target : Error<
"capture host variable %0 by reference in device or host device lambda function">;
-def err_capture_bad_target_this_ptr : Error<
- "capture host side class data member by this pointer in device or host device lambda function">;
+def warn_maybe_capture_bad_target_this_ptr : Warning<
+ "capture host side class data member by this pointer in device or host device lambda function "
+ "may result in invalid memory access if this pointer is not accessible on device side">,
+ InGroup<DiagGroup<"gpu-maybe-wrong-side">>;
def warn_kern_is_method : Extension<
"kernel function %0 is a member function; this may not be accepted by nvcc">,
InGroup<CudaCompat>;
@@ -8391,8 +8851,8 @@ def warn_kern_is_inline : Warning<
def err_variadic_device_fn : Error<
"CUDA device code does not support variadic functions">;
def err_va_arg_in_device : Error<
- "CUDA device code does not support va_arg">;
-def err_alias_not_supported_on_nvptx : Error<"CUDA does not support aliases">;
+"CUDA device code does not support va_arg">;
+def err_alias_not_supported_on_nvptx : Error<"CUDA older than 10.0 does not support .alias">;
def err_cuda_unattributed_constexpr_cannot_overload_device : Error<
"constexpr function %0 without __host__ or __device__ attributes cannot "
"overload __device__ function with same signature. Add a __host__ "
@@ -8441,6 +8901,10 @@ def note_cuda_device_builtin_surftex_should_be_template_class : Note<
def err_hip_invalid_args_builtin_mangled_name : Error<
"invalid argument: symbol must be a device-side function or global variable">;
+def warn_hip_omp_target_directives : Warning<
+ "HIP does not support OpenMP target directives; directive has been ignored">,
+ InGroup<HIPOpenMPOffloading>, DefaultError;
+
def warn_non_pod_vararg_with_format_string : Warning<
"cannot pass %select{non-POD|non-trivial}0 object of type %1 to variadic "
"%select{function|block|method|constructor}2; expected type from format "
@@ -8527,10 +8991,13 @@ def warn_bad_function_cast : Warning<
def warn_cast_function_type : Warning<
"cast %diff{from $ to $ |}0,1converts to incompatible function type">,
InGroup<CastFunctionType>, DefaultIgnore;
+def warn_cast_function_type_strict : Warning<warn_cast_function_type.Summary>,
+ InGroup<CastFunctionTypeStrict>, DefaultIgnore;
def err_cast_pointer_to_non_pointer_int : Error<
"pointer cannot be cast to type %0">;
-def err_cast_to_bfloat16 : Error<"cannot type-cast to __bf16">;
-def err_cast_from_bfloat16 : Error<"cannot type-cast from __bf16">;
+def err_nullptr_cast : Error<
+ "cannot cast an object of type %select{'nullptr_t' to %1|%1 to 'nullptr_t'}0"
+>;
def err_typecheck_expect_scalar_operand : Error<
"operand of type %0 where arithmetic or pointer type is required">;
def err_typecheck_cond_incompatible_operands : Error<
@@ -8540,6 +9007,10 @@ def err_typecheck_expect_flt_or_vector : Error<
"a vector of such types is required">;
def err_cast_selector_expr : Error<
"cannot type cast @selector expression">;
+def err_make_signed_integral_only : Error<
+ "'%select{make_unsigned|make_signed}0' is only compatible with "
+ "non-%select{bool|_BitInt(1)}1 integers and enum types, but was given "
+ "%2%select{| whose underlying type is %4}3">;
def ext_typecheck_cond_incompatible_pointers : ExtWarn<
"pointer type mismatch%diff{ ($ and $)|}0,1">,
InGroup<DiagGroup<"pointer-type-mismatch">>;
@@ -8551,6 +9022,9 @@ def err_typecheck_choose_expr_requires_constant : Error<
"'__builtin_choose_expr' requires a constant expression">;
def warn_unused_expr : Warning<"expression result unused">,
InGroup<UnusedValue>;
+def warn_unused_comma_left_operand : Warning<
+ "left operand of comma operator has no effect">,
+ InGroup<UnusedValue>;
def warn_unused_voidptr : Warning<
"expression result unused; should this cast be to 'void'?">,
InGroup<UnusedValue>;
@@ -8581,16 +9055,20 @@ def warn_unused_result : Warning<
def warn_unused_result_msg : Warning<
"ignoring return value of function declared with %0 attribute: %1">,
InGroup<UnusedResult>;
+def warn_unused_result_typedef_unsupported_spelling : Warning<
+ "'[[%select{nodiscard|gnu::warn_unused_result}0]]' attribute ignored when "
+ "applied to a typedef; consider using '__attribute__((warn_unused_result))' "
+ "or '[[clang::warn_unused_result]]' instead">, InGroup<IgnoredAttributes>;
def warn_unused_volatile : Warning<
"expression result unused; assign into a variable to force a volatile load">,
InGroup<DiagGroup<"unused-volatile-lvalue">>;
def ext_cxx14_attr : Extension<
- "use of the %0 attribute is a C++14 extension">, InGroup<CXX14>;
+ "use of the %0 attribute is a C++14 extension">, InGroup<CXX14Attrs>;
def ext_cxx17_attr : Extension<
- "use of the %0 attribute is a C++17 extension">, InGroup<CXX17>;
+ "use of the %0 attribute is a C++17 extension">, InGroup<CXX17Attrs>;
def ext_cxx20_attr : Extension<
- "use of the %0 attribute is a C++20 extension">, InGroup<CXX20>;
+ "use of the %0 attribute is a C++20 extension">, InGroup<CXX20Attrs>;
def warn_unused_comparison : Warning<
"%select{equality|inequality|relational|three-way}0 comparison result unused">,
@@ -8654,6 +9132,9 @@ def warn_redefine_extname_not_applied : Warning<
// inline asm.
let CategoryName = "Inline Assembly Issue" in {
+ def err_asm_pmf_through_constraint_not_permitted
+ : Error<"cannot pass a pointer-to-member through register-constrained "
+ "inline assembly parameter">;
def err_asm_invalid_lvalue_in_output : Error<"invalid lvalue in asm output">;
def err_asm_invalid_output_constraint : Error<
"invalid output constraint '%0' in asm">;
@@ -8688,6 +9169,8 @@ let CategoryName = "Inline Assembly Issue" in {
" in asm %select{input|output}1 with a memory constraint '%2'">;
def err_asm_input_duplicate_match : Error<
"more than one input constraint matches the same output '%0'">;
+ def err_store_value_to_reg : Error<
+ "impossible constraint in asm: can't store value into a register">;
def warn_asm_label_on_auto_decl : Warning<
"ignored asm label '%0' on automatic variable">;
@@ -8857,6 +9340,14 @@ def ext_ms_anonymous_record : ExtWarn<
def err_reference_to_local_in_enclosing_context : Error<
"reference to local %select{variable|binding}1 %0 declared in enclosing "
"%select{%3|block literal|lambda expression|context}2">;
+def err_capture_binding_openmp : Error<
+ "capturing a structured binding is not yet supported in OpenMP">;
+def ext_capture_binding : ExtWarn<
+ "captured structured bindings are a C++20 extension">, InGroup<CXX20>;
+def warn_cxx17_compat_capture_binding : Warning<
+ "captured structured bindings are incompatible with "
+ "C++ standards before C++20">,
+ InGroup<CXXPre20Compat>, DefaultIgnore;
def err_static_data_member_not_allowed_in_local_class : Error<
"static data member %0 not allowed in local %sub{select_tag_type_kind}2 %1">;
@@ -8910,10 +9401,22 @@ def err_operator_overload_needs_class_or_enum : Error<
"or enumeration type">;
def err_operator_overload_variadic : Error<"overloaded %0 cannot be variadic">;
+def warn_cxx20_compat_operator_overload_static : Warning<
+ "declaring overloaded %0 as 'static' is incompatible with C++ standards "
+ "before C++23">, InGroup<CXXPre23Compat>, DefaultIgnore;
+def ext_operator_overload_static : ExtWarn<
+ "declaring overloaded %0 as 'static' is a C++23 extension">, InGroup<CXX23>;
def err_operator_overload_static : Error<
"overloaded %0 cannot be a static member function">;
def err_operator_overload_default_arg : Error<
"parameter of overloaded %0 cannot have a default argument">;
+
+def ext_subscript_overload : Warning<
+ "overloaded %0 with %select{no|a defaulted|more than one}1 parameter is a "
+ "C++23 extension">, InGroup<CXXPre23Compat>, DefaultIgnore;
+def error_subscript_overload : Error<
+ "overloaded %0 cannot have %select{no|a defaulted|more than one}1 parameter before C++23">;
+
def err_operator_overload_must_be : Error<
"overloaded %0 must be a %select{unary|binary|unary or binary}2 operator "
"(has %1 parameter%s1)">;
@@ -8989,8 +9492,8 @@ def ext_string_literal_operator_template : ExtWarn<
"string literal operator templates are a GNU extension">,
InGroup<GNUStringLiteralOperatorTemplate>;
def warn_user_literal_reserved : Warning<
- "user-defined literal suffixes not starting with '_' are reserved"
- "%select{; no literal will invoke this operator|}0">,
+ "user-defined literal suffixes %select{<ERROR>|not starting with '_'|containing '__'}0 are reserved"
+ "%select{; no literal will invoke this operator|}1">,
InGroup<UserDefinedLiterals>;
// C++ conversion functions
@@ -9038,10 +9541,10 @@ def warn_cxx98_compat_explicit_conversion_functions : Warning<
// C++11 defaulted functions
def err_defaulted_special_member_params : Error<
- "an explicitly-defaulted %select{|copy |move }0constructor cannot "
+ "an explicitly-defaulted %sub{select_special_member_kind}0 cannot "
"have default arguments">;
def err_defaulted_special_member_variadic : Error<
- "an explicitly-defaulted %select{|copy |move }0constructor cannot "
+ "an explicitly-defaulted %sub{select_special_member_kind}0 cannot "
"be variadic">;
def err_defaulted_special_member_return_type : Error<
"explicitly-defaulted %select{copy|move}0 assignment operator must "
@@ -9049,6 +9552,9 @@ def err_defaulted_special_member_return_type : Error<
def err_defaulted_special_member_quals : Error<
"an explicitly-defaulted %select{copy|move}0 assignment operator may not "
"have 'const'%select{, 'constexpr'|}1 or 'volatile' qualifiers">;
+def err_defaulted_special_member_explicit_object_mismatch : Error<
+ "the type of the explicit object parameter of an explicitly-defaulted "
+ "%select{copy|move}0 assignment operator should match the type of the class %1">;
def err_defaulted_special_member_volatile_param : Error<
"the parameter for an explicitly-defaulted %sub{select_special_member_kind}0 "
"may not be volatile">;
@@ -9065,12 +9571,16 @@ def err_defaulted_copy_assign_not_ref : Error<
def err_incorrect_defaulted_constexpr : Error<
"defaulted definition of %sub{select_special_member_kind}0 "
"is not constexpr">;
+def err_incorrect_defaulted_constexpr_with_vb: Error<
+ "%sub{select_special_member_kind}0 cannot be 'constexpr' in a class with virtual base class">;
def err_incorrect_defaulted_consteval : Error<
"defaulted declaration of %sub{select_special_member_kind}0 "
"cannot be consteval because implicit definition is not constexpr">;
def warn_defaulted_method_deleted : Warning<
"explicitly defaulted %sub{select_special_member_kind}0 is implicitly "
"deleted">, InGroup<DefaultedFunctionDeleted>;
+def note_replace_equals_default_to_delete : Note<
+ "replace 'default' with 'delete'">;
def err_out_of_line_default_deletes : Error<
"defaulting this %sub{select_special_member_kind}0 "
"would delete it after its first declaration">;
@@ -9100,15 +9610,22 @@ def warn_cxx17_compat_defaulted_comparison : Warning<
"before C++20">, InGroup<CXXPre20Compat>, DefaultIgnore;
def err_defaulted_comparison_template : Error<
"comparison operator template cannot be defaulted">;
-def err_defaulted_comparison_out_of_class : Error<
- "%sub{select_defaulted_comparison_kind}0 can only be defaulted in a class "
- "definition">;
+def err_defaulted_comparison_num_args : Error<
+ "%select{non-member|member}0 %sub{select_defaulted_comparison_kind}1"
+ " must have %select{2|1}0 parameters">;
def err_defaulted_comparison_param : Error<
"invalid parameter type for defaulted %sub{select_defaulted_comparison_kind}0"
"; found %1, expected %2%select{| or %4}3">;
+def err_defaulted_comparison_param_unknown : Error<
+ "invalid parameter type for non-member defaulted"
+ " %sub{select_defaulted_comparison_kind}0"
+ "; found %1, expected class or reference to a constant class">;
def err_defaulted_comparison_param_mismatch : Error<
"parameters for defaulted %sub{select_defaulted_comparison_kind}0 "
"must have the same type%diff{ (found $ vs $)|}1,2">;
+def err_defaulted_comparison_not_friend : Error<
+ "%sub{select_defaulted_comparison_kind}0 is not a friend of"
+ " %select{|incomplete class }1%2">;
def err_defaulted_comparison_non_const : Error<
"defaulted member %sub{select_defaulted_comparison_kind}0 must be "
"const-qualified">;
@@ -9125,6 +9642,9 @@ def err_non_first_default_compare_deletes : Error<
"defaulting %select{this %sub{select_defaulted_comparison_kind}1|"
"the corresponding implicit 'operator==' for this defaulted 'operator<=>'}0 "
"would delete it after its first declaration">;
+def err_non_first_default_compare_in_class : Error<
+ "defaulting this %sub{select_defaulted_comparison_kind}0 "
+ "is not allowed because it was already declared outside the class">;
def note_defaulted_comparison_union : Note<
"defaulted %0 is implicitly deleted because "
"%2 is a %select{union-like class|union}1 with variant members">;
@@ -9142,14 +9662,18 @@ def note_defaulted_comparison_calls_deleted : Note<
"defaulted %0 is implicitly deleted because it would invoke a deleted "
"comparison function%select{| for member %2| for base class %2}1">;
def note_defaulted_comparison_no_viable_function : Note<
- "defaulted %0 is implicitly deleted because there is no viable three-way "
- "comparison function for%select{| member| base class}1 %2">;
+ "defaulted %0 is implicitly deleted because there is no viable "
+ "%select{three-way comparison function|'operator=='}1 for "
+ "%select{|member |base class }2%3">;
def note_defaulted_comparison_no_viable_function_synthesized : Note<
"three-way comparison cannot be synthesized because there is no viable "
"function for %select{'=='|'<'}0 comparison">;
def note_defaulted_comparison_not_rewritten_callee : Note<
"defaulted %0 is implicitly deleted because this non-rewritten comparison "
"function would be the best match for the comparison">;
+def note_defaulted_comparison_not_rewritten_conversion : Note<
+ "defaulted %0 is implicitly deleted because a builtin comparison function "
+ "using this conversion would be the best match for the comparison">;
def note_defaulted_comparison_cannot_deduce : Note<
"return type of defaulted 'operator<=>' cannot be deduced because "
"return type %2 of three-way comparison for %select{|member|base class}0 %1 "
@@ -9162,12 +9686,21 @@ def note_defaulted_comparison_cannot_deduce_undeduced_auto : Note<
"%select{|member|base class}0 %1 declared here">;
def note_defaulted_comparison_cannot_deduce_callee : Note<
"selected 'operator<=>' for %select{|member|base class}0 %1 declared here">;
-def err_incorrect_defaulted_comparison_constexpr : Error<
+def ext_defaulted_comparison_constexpr_mismatch : Extension<
"defaulted definition of %select{%sub{select_defaulted_comparison_kind}1|"
- "three-way comparison operator}0 "
- "cannot be declared %select{constexpr|consteval}2 because "
- "%select{it|the corresponding implicit 'operator=='}0 "
- "invokes a non-constexpr comparison function">;
+ "three-way comparison operator}0 that is "
+ "declared %select{constexpr|consteval}2 but"
+ "%select{|for which the corresponding implicit 'operator==' }0 "
+ "invokes a non-constexpr comparison function is a C++23 extension">,
+ InGroup<DiagGroup<"c++23-default-comp-relaxed-constexpr">>;
+def warn_cxx23_compat_defaulted_comparison_constexpr_mismatch : Warning<
+ "defaulted definition of %select{%sub{select_defaulted_comparison_kind}1|"
+ "three-way comparison operator}0 that is "
+ "declared %select{constexpr|consteval}2 but"
+ "%select{|for which the corresponding implicit 'operator==' }0 "
+ "invokes a non-constexpr comparison function is incompatible with C++ "
+ "standards before C++23">,
+ InGroup<CXXPre23Compat>, DefaultIgnore;
def note_defaulted_comparison_not_constexpr : Note<
"non-constexpr comparison function would be used to compare "
"%select{|member %1|base class %1}0">;
@@ -9176,6 +9709,10 @@ def note_defaulted_comparison_not_constexpr_here : Note<
def note_in_declaration_of_implicit_equality_comparison : Note<
"while declaring the corresponding implicit 'operator==' "
"for this defaulted 'operator<=>'">;
+def err_volatile_comparison_operator : Error<
+ "defaulted comparison function must not be volatile">;
+def err_ref_qualifier_comparison_operator : Error<
+ "ref-qualifier '&&' is not allowed on a defaulted comparison operator">;
def ext_implicit_exception_spec_mismatch : ExtWarn<
"function previously declared with an %select{explicit|implicit}0 exception "
@@ -9186,15 +9723,14 @@ def warn_ptr_arith_precedes_bounds : Warning<
"the pointer decremented by %0 refers before the beginning of the array">,
InGroup<ArrayBoundsPointerArithmetic>, DefaultIgnore;
def warn_ptr_arith_exceeds_bounds : Warning<
- "the pointer incremented by %0 refers past the end of the array (that "
- "contains %1 element%s2)">,
+ "the pointer incremented by %0 refers past the end of the array (that has type %1)">,
InGroup<ArrayBoundsPointerArithmetic>, DefaultIgnore;
def warn_array_index_precedes_bounds : Warning<
"array index %0 is before the beginning of the array">,
InGroup<ArrayBounds>;
def warn_array_index_exceeds_bounds : Warning<
- "array index %0 is past the end of the array (which contains %1 "
- "element%s2)">, InGroup<ArrayBounds>;
+ "array index %0 is past the end of the array (that has type %1%select{|, cast to %3}2)">,
+ InGroup<ArrayBounds>;
def warn_ptr_arith_exceeds_max_addressable_bounds : Warning<
"the pointer incremented by %0 refers past the last possible element for an array in %1-bit "
"address space containing %2-bit (%3-byte) elements (max possible %4 element%s5)">,
@@ -9206,6 +9742,12 @@ def warn_array_index_exceeds_max_addressable_bounds : Warning<
def note_array_declared_here : Note<
"array %0 declared here">;
+def warn_inconsistent_array_form : Warning<
+ "argument %0 of type %1 with mismatched bound">,
+ InGroup<ArrayParameter>, DefaultIgnore;
+def note_previous_declaration_as : Note<
+ "previously declared as %0 here">;
+
def warn_printf_insufficient_data_args : Warning<
"more '%%' conversions than data arguments">, InGroup<FormatInsufficientArgs>;
def warn_printf_data_arg_not_used : Warning<
@@ -9224,17 +9766,17 @@ def warn_format_conversion_argument_type_mismatch : Warning<
"%select{type|underlying type}2 %1">,
InGroup<Format>;
def warn_format_conversion_argument_type_mismatch_pedantic : Extension<
- warn_format_conversion_argument_type_mismatch.Text>,
+ warn_format_conversion_argument_type_mismatch.Summary>,
InGroup<FormatPedantic>;
def warn_format_conversion_argument_type_mismatch_confusion : Warning<
- warn_format_conversion_argument_type_mismatch.Text>,
+ warn_format_conversion_argument_type_mismatch.Summary>,
InGroup<FormatTypeConfusion>, DefaultIgnore;
def warn_format_argument_needs_cast : Warning<
"%select{values of type|enum values with underlying type}2 '%0' should not "
"be used as format arguments; add an explicit cast to %1 instead">,
InGroup<Format>;
def warn_format_argument_needs_cast_pedantic : Warning<
- warn_format_argument_needs_cast.Text>,
+ warn_format_argument_needs_cast.Summary>,
InGroup<FormatPedantic>, DefaultIgnore;
def warn_printf_positional_arg_exceeds_data_args : Warning <
"data argument position '%0' exceeds the number of data arguments (%1)">,
@@ -9305,6 +9847,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>;
@@ -9351,7 +9896,7 @@ def note_lambda_capture_initializer : Note<
"%select{implicitly |}2captured%select{| by reference}3"
"%select{%select{ due to use|}2 here|"
" via initialization of lambda capture %0}1">;
-def note_init_with_default_member_initalizer : Note<
+def note_init_with_default_member_initializer : Note<
"initializing field %0 with default member initializer">;
// Check for initializing a member variable with the address or a reference to
@@ -9410,10 +9955,10 @@ def warn_new_dangling_initializer_list : Warning<
"will be destroyed at the end of the full-expression">,
InGroup<DanglingInitializerList>;
def warn_unsupported_lifetime_extension : Warning<
- "sorry, lifetime extension of "
+ "lifetime extension of "
"%select{temporary|backing array of initializer list}0 created "
- "by aggregate initialization using default member initializer "
- "is not supported; lifetime of %select{temporary|backing array}0 "
+ "by aggregate initialization using a default member initializer "
+ "is not yet supported; lifetime of %select{temporary|backing array}0 "
"will end at the end of the full-expression">, InGroup<Dangling>;
// For non-floating point, expressions of the form x == x or x != x
@@ -9429,6 +9974,12 @@ def warn_comparison_bitwise_always : Warning<
def warn_comparison_bitwise_or : Warning<
"bitwise or with non-zero value always evaluates to true">,
InGroup<TautologicalBitwiseCompare>, DefaultIgnore;
+def warn_tautological_negation_and_compare: Warning<
+ "'&&' of a value and its negation always evaluates to false">,
+ InGroup<TautologicalNegationCompare>, DefaultIgnore;
+def warn_tautological_negation_or_compare: Warning<
+ "'||' of a value and its negation always evaluates to true">,
+ InGroup<TautologicalNegationCompare>, DefaultIgnore;
def warn_tautological_overlap_comparison : Warning<
"overlapping comparisons always evaluate to %select{false|true}0">,
InGroup<TautologicalOverlapCompare>, DefaultIgnore;
@@ -9484,7 +10035,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">;
@@ -9521,6 +10073,11 @@ def err_break_not_in_loop_or_switch : Error<
def warn_loop_ctrl_binds_to_inner : Warning<
"'%0' is bound to current loop, GCC binds it to the enclosing loop">,
InGroup<GccCompat>;
+def err_omp_bind_required_on_loop : Error<
+ "expected 'bind' clause for 'loop' construct without an enclosing OpenMP "
+ "construct">;
+def err_omp_loop_reduction_clause : Error<
+ "'reduction' clause not allowed with '#pragma omp loop bind(teams)'">;
def warn_break_binds_to_switch : Warning<
"'break' is bound to loop, GCC binds it to switch">,
InGroup<GccCompat>;
@@ -9538,6 +10095,11 @@ def err_duplicate_case_differing_expr : Error<
def warn_case_empty_range : Warning<"empty case range specified">;
def warn_missing_case_for_condition :
Warning<"no case matching constant switch condition '%0'">;
+def err_loop_attr_conflict : Error<
+ "conflicting loop attribute %0">;
+def err_attribute_power_of_two_in_range : Error<
+ "%0 attribute requires an integer argument which is a constant power of two "
+ "between %1 and %2 inclusive; provided argument was %3">;
def warn_def_missing_case : Warning<"%plural{"
"1:enumeration value %1 not explicitly handled in switch|"
@@ -9552,6 +10114,8 @@ def warn_missing_case : Warning<"%plural{"
"3:enumeration values %1, %2, and %3 not handled in switch|"
":%0 enumeration values not handled in switch: %1, %2, %3...}0">,
InGroup<Switch>;
+def warn_switch_default : Warning<"'switch' missing 'default' label">,
+ InGroup<SwitchDefault>, DefaultIgnore;
def warn_unannotated_fallthrough : Warning<
"unannotated fall-through between switch labels">,
@@ -9570,9 +10134,6 @@ def err_fallthrough_attr_outside_switch : Error<
"fallthrough annotation is outside switch statement">;
def err_fallthrough_attr_invalid_placement : Error<
"fallthrough annotation does not directly precede switch label">;
-def warn_fallthrough_attr_unreachable : Warning<
- "fallthrough annotation in unreachable code">,
- InGroup<ImplicitFallthrough>, DefaultIgnore;
def warn_unreachable_default : Warning<
"default label in switch which covers all enumeration values">,
@@ -9623,6 +10184,9 @@ def err_ms_va_start_used_in_sysv_function : Error<
def warn_second_arg_of_va_start_not_last_named_param : Warning<
"second argument to 'va_start' is not the last named parameter">,
InGroup<Varargs>;
+def warn_c17_compat_ellipsis_only_parameter : Warning<
+ "'...' as the only parameter of a function is incompatible with C standards "
+ "before C23">, DefaultIgnore, InGroup<CPre23Compat>;
def warn_va_start_type_is_undefined : Warning<
"passing %select{an object that undergoes default argument promotion|"
"an object of reference type|a parameter declared with the 'register' "
@@ -9668,10 +10232,6 @@ def warn_falloff_noreturn_function : Warning<
InGroup<InvalidNoreturn>;
def err_noreturn_block_has_return_expr : Error<
"block declared 'noreturn' should not return">;
-def err_noreturn_missing_on_first_decl : Error<
- "function declared '[[noreturn]]' after its first declaration">;
-def note_noreturn_missing_first_decl : Note<
- "declaration missing '[[noreturn]]' attribute is here">;
def err_carries_dependency_missing_on_first_decl : Error<
"%select{function|parameter}0 declared '[[carries_dependency]]' "
"after its first declaration">;
@@ -9702,8 +10262,8 @@ def err_shufflevector_argument_too_large : Error<
def err_convertvector_non_vector : Error<
"first argument to __builtin_convertvector must be a vector">;
-def err_convertvector_non_vector_type : Error<
- "second argument to __builtin_convertvector must be a vector type">;
+def err_builtin_non_vector_type : Error<
+ "%0 argument to %1 must be of vector type">;
def err_convertvector_incompatible_vector : Error<
"first two arguments to __builtin_convertvector must have the same number of elements">;
@@ -9729,6 +10289,9 @@ def err_argument_invalid_range : Error<
def warn_argument_invalid_range : Warning<
"argument value %0 is outside the valid range [%1, %2]">, DefaultError,
InGroup<DiagGroup<"argument-outside-range">>;
+def warn_argument_undefined_behaviour : Warning<
+ "argument value %0 will result in undefined behaviour">,
+ InGroup<DiagGroup<"argument-undefined-behaviour">>;
def err_argument_not_multiple : Error<
"argument should be a multiple of %0">;
def err_argument_not_power_of_2 : Error<
@@ -9739,10 +10302,10 @@ def err_argument_not_shifted_byte_or_xxff : Error<
"argument should be an 8-bit value shifted by a multiple of 8 bits, or in the form 0x??FF">;
def err_argument_not_contiguous_bit_field : Error<
"argument %0 value should represent a contiguous bit field">;
-def err_rotation_argument_to_cadd
- : Error<"argument should be the value 90 or 270">;
-def err_rotation_argument_to_cmla
- : Error<"argument should be the value 0, 90, 180 or 270">;
+def err_rotation_argument_to_cadd : Error<
+ "argument should be the value 90 or 270">;
+def err_rotation_argument_to_cmla : Error<
+ "argument should be the value 0, 90, 180 or 270">;
def warn_neon_vector_initializer_non_portable : Warning<
"vector initializers are not compatible with NEON intrinsics in big endian "
"mode">, InGroup<DiagGroup<"nonportable-vector-initialization">>;
@@ -9767,10 +10330,12 @@ def err_mips_builtin_requires_dspr2 : Error<
"this builtin requires 'dsp r2' ASE, please use -mdspr2">;
def err_mips_builtin_requires_msa : Error<
"this builtin requires 'msa' ASE, please use -mmsa">;
-def err_ppc_builtin_only_on_arch : Error<
- "this builtin is only valid on POWER%0 or later CPUs">;
+def err_ppc_builtin_requires_abi : Error<
+ "this builtin requires ABI -mabi=%0">;
def err_ppc_invalid_use_mma_type : Error<
"invalid use of PPC MMA type">;
+def err_ppc_invalid_test_data_class_type : Error<
+ "expected a 'float', 'double' or '__float128' for the first argument">;
def err_x86_builtin_invalid_rounding : Error<
"invalid rounding argument">;
def err_x86_builtin_invalid_scale : Error<
@@ -9793,8 +10358,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">;
@@ -9822,6 +10390,8 @@ def warn_duplicate_attribute_exact : Warning<
def warn_duplicate_attribute : Warning<
"attribute %0 is already applied with different arguments">,
InGroup<IgnoredAttributes>;
+def err_disallowed_duplicate_attribute : Error<
+ "attribute %0 cannot appear more than once on a declaration">;
def warn_sync_fetch_and_nand_semantics_change : Warning<
"the semantics of this intrinsic changed with GCC "
@@ -9835,15 +10405,13 @@ def warn_receiver_forward_class : Warning<
"receiver %0 is a forward class and corresponding @interface may not exist">,
InGroup<ForwardClassReceiver>;
def note_method_sent_forward_class : Note<"method %0 is used for the forward class">;
-def ext_missing_declspec : ExtWarn<
- "declaration specifier missing, defaulting to 'int'">;
def ext_missing_type_specifier : ExtWarn<
- "type specifier missing, defaults to 'int'">,
- InGroup<ImplicitInt>;
+ "type specifier missing, defaults to 'int'; ISO C99 and later do not support "
+ "implicit int">, InGroup<ImplicitInt>;
+def err_missing_type_specifier : Error<
+ "a type specifier is required for all declarations">;
def err_decimal_unsupported : Error<
"GNU decimal type extension not supported">;
-def err_missing_type_specifier : Error<
- "C++ requires a type specifier for all declarations">;
def err_objc_array_of_interfaces : Error<
"array of interface %0 is invalid (probably should be an array of pointers)">;
def ext_c99_array_usage : Extension<
@@ -9866,9 +10434,9 @@ def err_nserrordomain_wrong_type : Error<
"domain argument %0 does not point to an NSString or CFString constant">;
def warn_nsconsumed_attribute_mismatch : Warning<
- err_nsconsumed_attribute_mismatch.Text>, InGroup<NSConsumedMismatch>;
+ err_nsconsumed_attribute_mismatch.Summary>, InGroup<NSConsumedMismatch>;
def warn_nsreturns_retained_attribute_mismatch : Warning<
- err_nsreturns_retained_attribute_mismatch.Text>, InGroup<NSReturnsMismatch>;
+ err_nsreturns_retained_attribute_mismatch.Summary>, InGroup<NSReturnsMismatch>;
def note_getter_unavailable : Note<
"or because setter is declared here, but no getter method %0 is found">;
@@ -10036,8 +10604,6 @@ def err_opencl_scalar_type_rank_greater_than_vector_type : Error<
"element. (%0 and %1)">;
def err_bad_kernel_param_type : Error<
"%0 cannot be used as the type of a kernel parameter">;
-def err_opencl_implicit_function_decl : Error<
- "implicit declaration of function %0 is invalid in OpenCL">;
def err_record_with_pointers_kernel_param : Error<
"%select{struct|union}0 kernel parameters may not contain pointers">;
def note_within_field_of_type : Note<
@@ -10071,8 +10637,8 @@ def err_reference_pipe_type : Error <
def err_opencl_no_main : Error<"%select{function|kernel}0 cannot be called 'main'">;
def err_opencl_kernel_attr :
Error<"attribute %0 can only be applied to an OpenCL kernel function">;
-def err_opencl_return_value_with_address_space : Error<
- "return value cannot be qualified with address space">;
+def err_return_value_with_address_space : Error<
+ "return type cannot be qualified with address space">;
def err_opencl_constant_no_init : Error<
"variable in constant address space must be initialized">;
def err_opencl_atomic_init: Error<
@@ -10091,8 +10657,7 @@ def err_opencl_type_can_only_be_used_as_function_parameter : Error <
def err_opencl_type_not_found : Error<
"%0 type %1 not found; include the base header with -finclude-default-header">;
def warn_opencl_attr_deprecated_ignored : Warning <
- "%0 attribute is deprecated and ignored in OpenCL version %1">,
- InGroup<IgnoredAttributes>;
+ "%0 attribute is deprecated and ignored in %1">, InGroup<IgnoredAttributes>;
def err_opencl_variadic_function : Error<
"invalid prototype, variadic arguments are not allowed in OpenCL">;
def err_opencl_requires_extension : Error<
@@ -10157,7 +10722,7 @@ def err_opencl_builtin_expected_type : Error<
// OpenCL v3.0 s6.3.7 - Vector Components
def ext_opencl_ext_vector_type_rgba_selector: ExtWarn<
- "vector component name '%0' is an OpenCL C version 3.0 feature">,
+ "vector component name '%0' is a feature from OpenCL version 3.0 onwards">,
InGroup<OpenCLUnsupportedRGBA>;
def err_openclcxx_placement_new : Error<
@@ -10167,6 +10732,11 @@ def err_openclcxx_placement_new : Error<
def warn_mig_server_routine_does_not_return_kern_return_t : Warning<
"'mig_server_routine' attribute only applies to routines that return a kern_return_t">,
InGroup<IgnoredAttributes>;
+
+def warn_imp_cast_drops_unaligned : Warning<
+ "implicit cast from type %0 to type %1 drops __unaligned qualifier">,
+ InGroup<DiagGroup<"unaligned-qualifier-implicit-cast">>;
+
} // end of sema category
let CategoryName = "OpenMP Issue" in {
@@ -10196,10 +10766,20 @@ def err_omp_lastprivate_incomplete_type : Error<
"a lastprivate variable with incomplete type %0">;
def err_omp_reduction_incomplete_type : Error<
"a reduction list item with incomplete type %0">;
+def warn_omp_minus_in_reduction_deprecated : Warning<
+ "minus(-) operator for reductions is deprecated; use + or user defined reduction instead">,
+ InGroup<Deprecated>;
def err_omp_unexpected_clause_value : Error<
"expected %0 in OpenMP clause '%1'">;
+def err_omp_unexpected_call_to_omp_runtime_api
+ : Error<"calls to OpenMP runtime API are not allowed within a region that "
+ "corresponds to a construct with an order clause that specifies "
+ "concurrent">;
def err_omp_expected_var_name_member_expr : Error<
"expected variable name%select{| or data member of current class}0">;
+def err_omp_expected_var_name_member_expr_with_type : Error<
+ "expected variable%select{| or static data member|, static data member, "
+ "or non-static data member of current class}0 of type '%1'">;
def err_omp_expected_var_name_member_expr_or_array_item : Error<
"expected variable name%select{|, data member of current class}0, array element or array section">;
def err_omp_expected_addressable_lvalue_or_array_item : Error<
@@ -10353,9 +10933,12 @@ def err_omp_simd_region_cannot_use_stmt : Error<
def warn_omp_loop_64_bit_var : Warning<
"OpenMP loop iteration variable cannot have more than 64 bits size and will be narrowed">,
InGroup<OpenMPLoopForm>;
-def err_omp_unknown_reduction_identifier : Error<
+def err_omp_unknown_reduction_identifier_prior_omp_6_0 : Error<
"incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', "
"'&&', '||', 'min' or 'max' or declare reduction for type %0">;
+def err_omp_unknown_reduction_identifier_since_omp_6_0 : Error<
+ "incorrect reduction identifier, expected one of '+', '*', '&', '|', '^', "
+ "'&&', '||', 'min' or 'max' or declare reduction for type %0">;
def err_omp_not_resolved_reduction_identifier : Error<
"unable to resolve declare reduction construct for type %0">;
def err_omp_reduction_ref_type_arg : Error<
@@ -10389,6 +10972,9 @@ def err_omp_prohibited_region_simd : Error<
"OpenMP constructs may not be nested inside a simd region%select{| except for ordered simd, simd, scan, or atomic directive}0">;
def err_omp_prohibited_region_atomic : Error<
"OpenMP constructs may not be nested inside an atomic region">;
+def err_omp_prohibited_region_order
+ : Error<"construct '%0' not allowed in a region associated with a "
+ "directive with 'order' clause">;
def err_omp_prohibited_region_critical_same_name : Error<
"cannot nest 'critical' regions having the same name %0">;
def note_omp_previous_critical_region : Note<
@@ -10438,8 +11024,25 @@ def err_omp_atomic_capture_not_compound_statement : Error<
" where x is an lvalue expression with scalar type">;
def note_omp_atomic_capture: Note<
"%select{expected assignment expression|expected compound statement|expected exactly two expression statements|expected in right hand side of the first expression}0">;
+def err_omp_atomic_compare : Error<
+ "the statement for 'atomic compare' must be a compound statement of form '{x = expr ordop x ? expr : x;}', '{x = x ordop expr? expr : x;}',"
+ " '{x = x == e ? d : x;}', '{x = e == x ? d : x;}', or 'if(expr ordop x) {x = expr;}', 'if(x ordop expr) {x = expr;}', 'if(x == e) {x = d;}',"
+ " 'if(e == x) {x = d;}' where 'x' is an lvalue expression with scalar type, 'expr', 'e', and 'd' are expressions with scalar type,"
+ " and 'ordop' is one of '<' or '>'.">;
+def err_omp_atomic_compare_capture : Error<
+ "the statement for 'atomic compare capture' must be a compound statement of form '{v = x; cond-up-stmt}', ''{cond-up-stmt v = x;}', '{if(x == e) {x = d;} else {v = x;}}',"
+ " '{r = x == e; if(r) {x = d;}}', or '{r = x == e; if(r) {x = d;} else {v = x;}}', where 'cond-update-stmt' can have one of the following forms: 'if(expr ordop x) {x = expr;}',"
+ " 'if(x ordop expr) {x = expr;}', 'if(x == e) {x = d;}', or 'if(e == x) {x = d;}' where 'x', 'r', and 'v' are lvalue expressions with scalar type, 'expr', 'e', and 'd' are expressions with scalar type,"
+ " and 'ordop' is one of '<' or '>'.">;
+def note_omp_atomic_compare: Note<
+ "%select{expected compound statement|expected exactly one expression statement|expected assignment statement|expected conditional operator|expect result value to be at false expression|"
+ "expect binary operator in conditional expression|expect '<', '>' or '==' as order operator|expect comparison in a form of 'x == e', 'e == x', 'x ordop expr', or 'expr ordop x'|"
+ "expect lvalue for result value|expect scalar value|expect integer value|unexpected 'else' statement|expect '==' operator|expect an assignment statement 'v = x'|"
+ "expect a 'if' statement|expect no more than two statements|expect a compound statement|expect 'else' statement|expect a form 'r = x == e; if (r) ...'}0">;
+def err_omp_atomic_fail_wrong_or_no_clauses : Error<"expected a memory order clause">;
+def err_omp_atomic_fail_no_compare : Error<"expected 'compare' clause with the 'fail' modifier">;
def err_omp_atomic_several_clauses : Error<
- "directive '#pragma omp atomic' cannot contain more than one 'read', 'write', 'update' or 'capture' clause">;
+ "directive '#pragma omp atomic' cannot contain more than one 'read', 'write', 'update', 'capture', or 'compare' clause">;
def err_omp_several_mem_order_clauses : Error<
"directive '#pragma omp %0' cannot contain more than one %select{'seq_cst', 'relaxed', |}1'acq_rel', 'acquire' or 'release' clause">;
def err_omp_atomic_incompatible_mem_order_clause : Error<
@@ -10454,6 +11057,8 @@ def note_omp_nested_statement_here : Note<
"%select{statement|directive}0 outside teams construct here">;
def err_omp_single_copyprivate_with_nowait : Error<
"the 'copyprivate' clause must not be used with the 'nowait' clause">;
+def err_omp_nowait_clause_without_depend: Error<
+ "directive '#pragma omp taskwait' cannot use 'nowait' clause without 'depend' clause">;
def note_omp_nowait_clause_here : Note<
"'nowait' clause is here">;
def err_omp_single_decl_in_declare_simd_variant : Error<
@@ -10506,6 +11111,8 @@ def err_omp_wrong_linear_modifier : Error<
"expected %select{'val' modifier|one of 'ref', val' or 'uval' modifiers}0">;
def err_omp_wrong_linear_modifier_non_reference : Error<
"variable of non-reference type %0 can be used only with 'val' modifier, but used with '%1'">;
+def err_omp_step_simple_modifier_exclusive : Error<
+ "step simple modifier is exclusive and can't be use with 'val', 'uval' or 'ref' modifier">;
def err_omp_wrong_simdlen_safelen_values : Error<
"the value of 'simdlen' parameter must be less than or equal to the value of the 'safelen' parameter">;
def err_omp_wrong_if_directive_name_modifier : Error<
@@ -10519,7 +11126,7 @@ def note_omp_previous_named_if_clause : Note<
def err_omp_ordered_directive_with_param : Error<
"'ordered' directive %select{without any clauses|with 'threads' clause}0 cannot be closely nested inside ordered region with specified parameter">;
def err_omp_ordered_directive_without_param : Error<
- "'ordered' directive with 'depend' clause cannot be closely nested inside ordered region without specified parameter">;
+ "'ordered' directive with '%0' clause cannot be closely nested inside ordered region without specified parameter">;
def note_omp_ordered_param : Note<
"'ordered' clause%select{| with specified parameter}0">;
def err_omp_expected_base_var_name : Error<
@@ -10528,6 +11135,8 @@ def err_omp_map_shared_storage : Error<
"variable already marked as mapped in current construct">;
def err_omp_invalid_map_type_for_directive : Error<
"%select{map type '%1' is not allowed|map type must be specified}0 for '#pragma omp %2'">;
+def err_omp_invalid_map_type_modifier_for_directive : Error<
+ "map type modifier '%0' is not allowed for '#pragma omp %1'">;
def err_omp_no_clause_for_directive : Error<
"expected at least one %0 clause for '#pragma omp %1'">;
def err_omp_threadprivate_in_clause : Error<
@@ -10549,21 +11158,25 @@ def note_omp_critical_hint_here : Note<
def note_omp_critical_no_hint : Note<
"%select{|previous }0directive with no 'hint' clause specified">;
def err_omp_depend_clause_thread_simd : Error<
- "'depend' clauses cannot be mixed with '%0' clause">;
+ "'%0' clauses cannot be mixed with '%1' clause">;
def err_omp_depend_sink_expected_loop_iteration : Error<
"expected%select{| %1}0 loop iteration variable">;
def err_omp_depend_sink_unexpected_expr : Error<
"unexpected expression: number of expressions is larger than the number of associated loops">;
def err_omp_depend_sink_expected_plus_minus : Error<
"expected '+' or '-' operation">;
-def err_omp_depend_sink_source_not_allowed : Error<
- "'depend(%select{source|sink:vec}0)' clause%select{|s}0 cannot be mixed with 'depend(%select{sink:vec|source}0)' clause%select{s|}0">;
+def err_omp_taskwait_depend_mutexinoutset_not_allowed : Error<
+ "'mutexinoutset' modifier not allowed in 'depend' clause on 'taskwait' directive">;
+def err_omp_sink_and_source_not_allowed : Error<
+ "'%0(%select{source|sink:vec}1)' clause%select{|s}1 cannot be mixed with '%0(%select{sink:vec|source}1)' clause%select{s|}1">;
def err_omp_depend_zero_length_array_section_not_allowed : Error<
"zero-length array section is not allowed in 'depend' clause">;
def err_omp_depend_sink_source_with_modifier : Error<
"depend modifier cannot be used with 'sink' or 'source' depend type">;
def err_omp_depend_modifier_not_iterator : Error<
"expected iterator specification as depend modifier">;
+def err_omp_map_modifier_not_iterator : Error<
+ "expected iterator specification as map modifier">;
def err_omp_linear_ordered : Error<
"'linear' clause cannot be specified along with 'ordered' clause with a parameter">;
def err_omp_unexpected_schedule_modifier : Error<
@@ -10584,6 +11197,8 @@ def err_omp_expected_int_param : Error<
"expected a reference to an integer-typed parameter">;
def err_omp_at_least_one_motion_clause_required : Error<
"expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'">;
+def err_omp_cannot_update_with_internal_linkage : Error<
+ "the host cannot update a declare target variable that is not externally visible.">;
def err_omp_usedeviceptr_not_a_pointer : Error<
"expected pointer or reference to pointer in 'use_device_ptr' clause">;
def err_omp_argument_type_isdeviceptr : Error <
@@ -10614,6 +11229,8 @@ def err_omp_directive_before_requires : Error <
"'%0' region encountered before requires directive with '%1' clause">;
def note_omp_requires_encountered_directive : Note <
"'%0' previously encountered here">;
+def err_omp_device_ancestor_without_requires_reverse_offload : Error <
+ "Device clause with ancestor device-modifier used without specifying 'requires reverse_offload'">;
def err_omp_invalid_scope : Error <
"'#pragma omp %0' directive must appear only in file scope">;
def note_omp_invalid_length_on_this_ptr_mapping : Note <
@@ -10677,9 +11294,9 @@ def err_omp_invariant_or_linear_dependency : Error<
"expected loop invariant expression or '<invariant1> * %0 + <invariant2>' kind of expression">;
def err_omp_wrong_dependency_iterator_type : Error<
"expected an integer or a pointer type of the outer loop counter '%0' for non-rectangular nests">;
-def err_device_unsupported_type
- : Error<"%0 requires %select{|%2 bit size}1 %3 type support, but device "
- "'%4' does not support it">;
+def err_target_unsupported_type
+ : Error<"%0 requires %select{|%2 bit size}1 %3 %select{|return }4type support,"
+ " but target '%5' does not support it">;
def err_omp_lambda_capture_in_declare_target_not_to : Error<
"variable captured in declare target region must appear in a to clause">;
def err_omp_device_type_mismatch : Error<
@@ -10714,9 +11331,16 @@ def err_omp_declare_variant_diff : Error<
"function with '#pragma omp declare variant' has a different %select{calling convention"
"|return type|constexpr specification|inline specification|storage class|"
"linkage}0">;
+def err_omp_declare_variant_prototype_required : Error<
+ "function with '#pragma omp declare variant' must have a prototype when "
+ "'append_args' is used">;
+def err_omp_interop_type_not_found : Error<
+ "'omp_interop_t' must be defined when 'append_args' clause is used; include <omp.h>">;
def err_omp_declare_variant_incompat_types : Error<
- "variant in '#pragma omp declare variant' with type %0 is incompatible with type %1"
- >;
+ "variant in '#pragma omp declare variant' with type %0 is incompatible with"
+ " type %1%select{| with appended arguments}2">;
+def err_omp_declare_variant_same_base_function : Error<
+ "variant in '#pragma omp declare variant' is the same as the base function">;
def warn_omp_declare_variant_marked_as_declare_variant : Warning<
"variant function in '#pragma omp declare variant' is itself marked as '#pragma omp declare variant'"
>, InGroup<SourceUsesOpenMP>;
@@ -10734,11 +11358,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">;
@@ -10762,6 +11381,9 @@ def note_omp_protected_structured_block
: Note<"jump bypasses OpenMP structured block">;
def note_omp_exits_structured_block
: Note<"jump exits scope of OpenMP structured block">;
+def err_omp_lastprivate_loop_var_non_loop_iteration : Error<
+ "only loop iteration variables are allowed in 'lastprivate' clause in "
+ "'omp %0' directives">;
def err_omp_interop_variable_expected : Error<
"expected%select{| non-const}0 variable of type 'omp_interop_t'">;
def err_omp_interop_variable_wrong_type : Error<
@@ -10779,6 +11401,21 @@ def err_omp_dispatch_statement_call
def err_omp_unroll_full_variable_trip_count : Error<
"loop to be fully unrolled must have a constant trip count">;
def note_omp_directive_here : Note<"'%0' directive found here">;
+def err_omp_instantiation_not_supported
+ : Error<"instantiation of '%0' not supported yet">;
+def err_omp_adjust_arg_multiple_clauses : Error<
+ "'adjust_arg' argument %0 used in multiple clauses">;
+def err_omp_clause_requires_dispatch_construct : Error<
+ "'%0' clause requires 'dispatch' context selector">;
+def err_omp_append_args_with_varargs : Error<
+ "'append_args' is not allowed with varargs functions">;
+def err_openmp_vla_in_task_untied : Error<
+ "variable length arrays are not supported in OpenMP tasking regions with 'untied' clause">;
+def warn_omp_unterminated_declare_target : Warning<
+ "expected '#pragma omp end declare target' at end of file to match '#pragma omp %0'">,
+ InGroup<SourceUsesOpenMP>;
+def err_ompx_bare_no_grid : Error<
+ "'ompx_bare' clauses requires explicit grid size via 'num_teams' and 'thread_limit' clauses">;
} // end of OpenMP category
let CategoryName = "Related Result Type Issue" in {
@@ -10811,7 +11448,7 @@ def err_invalid_type_for_program_scope_var : Error<
let CategoryName = "Modules Issue" in {
def err_module_decl_in_module_map_module : Error<
"'module' declaration found while building module from module map">;
-def err_module_decl_in_header_module : Error<
+def err_module_decl_in_header_unit : Error<
"'module' declaration found while building header unit">;
def err_module_interface_implementation_mismatch : Error<
"missing 'export' specifier in module declaration while "
@@ -10872,10 +11509,14 @@ def ext_module_import_not_at_top_level_noop : ExtWarn<
def note_module_import_not_at_top_level : Note<"%0 begins here">;
def err_module_self_import : Error<
"import of module '%0' appears within same top-level module '%1'">;
+def err_module_self_import_cxx20 : Error<
+ "import of module '%0' appears within its own %select{interface|implementation}1">;
def err_module_import_in_implementation : Error<
"@import of module '%0' in implementation of '%1'; use #import">;
// C++ Modules
+def err_module_import_non_interface_nor_parition : Error<
+ "import of module '%0' imported non C++20 importable modules">;
def err_module_decl_not_at_start : Error<
"module declaration must occur at the start of the translation unit">;
def note_global_module_introducer_missing : Note<
@@ -10884,27 +11525,22 @@ def note_global_module_introducer_missing : Note<
def err_export_within_anonymous_namespace : Error<
"export declaration appears within anonymous namespace">;
def note_anonymous_namespace : Note<"anonymous namespace begins here">;
-def ext_export_no_name_block : ExtWarn<
- "ISO C++20 does not permit %select{an empty|a static_assert}0 declaration "
- "to appear in an export block">, InGroup<ExportUnnamed>;
-def ext_export_no_names : ExtWarn<
- "ISO C++20 does not permit a declaration that does not introduce any names "
- "to be exported">, InGroup<ExportUnnamed>;
def note_export : Note<"export block begins here">;
-def err_export_no_name : Error<
- "%select{empty|static_assert|asm}0 declaration cannot be exported">;
-def ext_export_using_directive : ExtWarn<
- "ISO C++20 does not permit using directive to be exported">,
- InGroup<DiagGroup<"export-using-directive">>;
def err_export_within_export : Error<
"export declaration appears within another export declaration">;
+def err_export_anon_ns_internal : Error<
+ "anonymous namespaces cannot be exported">;
def err_export_internal : Error<
"declaration of %0 with internal linkage cannot be exported">;
def err_export_using_internal : Error<
- "using declaration referring to %0 with internal linkage cannot be exported">;
+ "using declaration referring to %1 with %select{internal|module|unknown}0 "
+ "linkage cannot be exported">;
def err_export_not_in_module_interface : Error<
- "export declaration can only be used within a module interface unit"
- "%select{ after the module declaration|}0">;
+ "export declaration can only be used within a module purview">;
+def err_export_inline_not_defined : Error<
+ "inline function not defined%select{| before the private module fragment}0">;
+def err_export_partition_impl : Error<
+ "module partition implementations cannot be exported">;
def err_export_in_private_module_fragment : Error<
"export declaration cannot be used in a private module fragment">;
def note_private_module_fragment : Note<
@@ -10917,6 +11553,13 @@ def err_private_module_fragment_not_module_interface : Error<
"private module fragment in module implementation unit">;
def note_not_module_interface_add_export : Note<
"add 'export' here if this is intended to be a module interface unit">;
+def err_invalid_module_name : Error<"%0 is an invalid name for a module">;
+def err_extern_def_in_header_unit : Error<
+ "non-inline external definitions are not permitted in C++ header units">;
+
+def warn_experimental_header_unit : Warning<
+ "the implementation of header units is in an experimental phase">,
+ InGroup<DiagGroup<"experimental-header-units">>;
def ext_equivalent_internal_linkage_decl_in_modules : ExtWarn<
"ambiguous use of internal linkage declaration %0 defined in multiple modules">,
@@ -10949,7 +11592,7 @@ def err_coroutine_invalid_func_context : Error<
"|a function with a deduced return type|a varargs function"
"|a consteval function}0">;
def err_implied_coroutine_type_not_found : Error<
- "%0 type was not found; include <experimental/coroutine> before defining "
+ "%0 type was not found; include <coroutine> before defining "
"a coroutine">;
def err_implicit_coroutine_std_nothrow_type_not_found : Error<
"std::nothrow was not found; include <new> before defining a coroutine which "
@@ -10957,11 +11600,11 @@ def err_implicit_coroutine_std_nothrow_type_not_found : Error<
def err_malformed_std_nothrow : Error<
"std::nothrow must be a valid variable declaration">;
def err_malformed_std_coroutine_handle : Error<
- "std::experimental::coroutine_handle must be a class template">;
+ "std::coroutine_handle isn't a class template">;
def err_coroutine_handle_missing_member : Error<
- "std::experimental::coroutine_handle missing a member named '%0'">;
+ "std::coroutine_handle must have a member named '%0'">;
def err_malformed_std_coroutine_traits : Error<
- "'std::experimental::coroutine_traits' must be a class template">;
+ "std::coroutine_traits isn't a class template">;
def err_implied_std_coroutine_traits_promise_type_not_found : Error<
"this function cannot be a coroutine: %q0 has no member named 'promise_type'">;
def err_implied_std_coroutine_traits_promise_type_not_class : Error<
@@ -10973,8 +11616,6 @@ def err_coroutine_type_missing_specialization : Error<
"specialization %0">;
def err_coroutine_promise_incompatible_return_functions : Error<
"the coroutine promise type %0 declares both 'return_value' and 'return_void'">;
-def err_coroutine_promise_requires_return_function : Error<
- "the coroutine promise type %0 must declare either 'return_value' or 'return_void'">;
def note_coroutine_promise_implicit_await_transform_required_here : Note<
"call to 'await_transform' implicitly required by 'co_await' here">;
def note_coroutine_promise_suspend_implicitly_required : Note<
@@ -11009,11 +11650,39 @@ def err_coroutine_promise_final_suspend_requires_nothrow : Error<
def note_coroutine_function_declare_noexcept : Note<
"must be declared with 'noexcept'"
>;
+def warn_always_inline_coroutine : Warning<
+ "this coroutine may be split into pieces; not every piece is guaranteed to be inlined"
+ >,
+ InGroup<AlwaysInlineCoroutine>;
+def err_coroutine_unusable_new : Error<
+ "'operator new' provided by %0 is not usable with the function signature of %1"
+>;
+def err_coroutine_unfound_nothrow_new : Error <
+ "unable to find %select{'::operator new(size_t, nothrow_t)'|"
+ "'::operator new(size_t, align_val_t, nothrow_t)'}1 for %0"
+>;
+def warn_non_aligned_allocation_function : Warning <
+ "under -fcoro-aligned-allocation, the non-aligned allocation function "
+ "for the promise type %0 has higher precedence than the global aligned "
+ "allocation function">,
+ InGroup<CoroNonAlignedAllocationFunction>;
+def err_conflicting_aligned_options : Error <
+ "conflicting option '-fcoro-aligned-allocation' and '-fno-aligned-allocation'"
+>;
+def err_coro_invalid_addr_of_label : Error<
+ "the GNU address of label extension is not allowed in coroutines."
+>;
+def err_coroutine_return_type : Error<
+ "function returns a type %0 marked with [[clang::coro_return_type]] but is neither a coroutine nor a coroutine wrapper; "
+ "non-coroutines should be marked with [[clang::coro_wrapper]] to allow returning coroutine return type"
+>;
} // end of coroutines issue category
let CategoryName = "Documentation Issue" in {
def warn_not_a_doxygen_trailing_member_comment : Warning<
"not a Doxygen trailing comment">, InGroup<Documentation>, DefaultIgnore;
+def warn_splice_in_doxygen_comment : Warning<
+ "line splicing in Doxygen comments are not supported">, InGroup<Documentation>, DefaultIgnore;
} // end of documentation issue category
let CategoryName = "Nullability Issue" in {
@@ -11145,6 +11814,10 @@ def err_objc_type_args_wrong_arity : Error<
"too %select{many|few}0 type arguments for class %1 (have %2, expected %3)">;
}
+def err_type_available_only_in_default_eval_method : Error<
+ "cannot use type '%0' within '#pragma clang fp eval_method'; type is set "
+ "according to the default eval method for the translation unit">;
+
def err_objc_type_arg_not_id_compatible : Error<
"type argument %0 is neither an Objective-C object nor a block type">;
@@ -11170,7 +11843,7 @@ def note_shadow_field : Note<"declared here">;
def err_multiversion_required_in_redecl : Error<
"function declaration is missing %select{'target'|'cpu_specific' or "
- "'cpu_dispatch'}0 attribute in a multiversioned function">;
+ "'cpu_dispatch'|'target_version'}0 attribute in a multiversioned function">;
def note_multiversioning_caused_here : Note<
"function multiversioning caused by this declaration">;
def err_multiversion_after_used : Error<
@@ -11183,21 +11856,23 @@ def err_multiversion_duplicate : Error<
"multiversioned function redeclarations require identical target attributes">;
def err_multiversion_noproto : Error<
"multiversioned function must have a prototype">;
-def err_multiversion_disallowed_other_attr : Error<
- "attribute '%select{target|cpu_specific|cpu_dispatch}0' multiversioning cannot be combined"
- " with attribute %1">;
-def err_multiversion_mismatched_attrs
- : Error<"attributes on multiversioned functions must all match, attribute "
- "%0 %select{is missing|has different arguments}1">;
+def err_multiversion_disallowed_other_attr
+ : Error<"attribute "
+ "'%select{|target|cpu_specific|cpu_dispatch|target_clones|target_version}0' "
+ "multiversioning cannot be combined"
+ " with attribute %1">;
def err_multiversion_diff : Error<
"multiversioned function declaration has a different %select{calling convention"
- "|return type|constexpr specification|inline specification|storage class|"
- "linkage}0">;
-def err_multiversion_doesnt_support : Error<
- "attribute '%select{target|cpu_specific|cpu_dispatch}0' multiversioned functions do not "
- "yet support %select{function templates|virtual functions|"
- "deduced return types|constructors|destructors|deleted functions|"
- "defaulted functions|constexpr functions|consteval function}1">;
+ "|return type|constexpr specification|inline specification|linkage|"
+ "language linkage}0">;
+def err_multiversion_doesnt_support
+ : Error<"attribute "
+ "'%select{|target|cpu_specific|cpu_dispatch|target_clones|target_version}0' "
+ "multiversioned functions do not "
+ "yet support %select{function templates|virtual functions|"
+ "deduced return types|constructors|destructors|deleted functions|"
+ "defaulted functions|constexpr functions|consteval "
+ "function|lambdas}1">;
def err_multiversion_not_allowed_on_main : Error<
"'main' cannot be a multiversioned function">;
def err_multiversion_not_supported : Error<
@@ -11214,6 +11889,22 @@ def warn_multiversion_duplicate_entries : Warning<
def warn_dispatch_body_ignored : Warning<
"body of cpu_dispatch function will be ignored">,
InGroup<FunctionMultiVersioning>;
+def err_target_clone_must_have_default
+ : Error<"'target_clones' multiversioning requires a default target">;
+def err_target_clone_doesnt_match
+ : Error<"'target_clones' attribute does not match previous declaration">;
+def warn_target_clone_mixed_values
+ : ExtWarn<
+ "mixing 'target_clones' specifier mechanisms is permitted for GCC "
+ "compatibility; use a comma separated sequence of string literals, "
+ "or a string literal containing a comma-separated list of versions">,
+ InGroup<TargetClonesMixedSpecifiers>;
+def warn_target_clone_duplicate_options
+ : Warning<"version list contains duplicate entries">,
+ InGroup<FunctionMultiVersioning>;
+def warn_target_clone_no_impact_options
+ : Warning<"version list contains entries that don't impact code generation">,
+ InGroup<FunctionMultiVersioning>;
// three-way comparison operator diagnostics
def err_implied_comparison_category_type_not_found : Error<
@@ -11257,6 +11948,14 @@ def err_builtin_launder_invalid_arg : Error<
"%select{non-pointer|function pointer|void pointer}0 argument to "
"'__builtin_launder' is not allowed">;
+def err_builtin_invalid_arg_type: Error <
+ "%ordinal0 argument must be a "
+ "%select{vector, integer or floating point type|matrix|"
+ "pointer to a valid matrix element type|"
+ "signed integer or floating point type|vector type|"
+ "floating point type|"
+ "vector of integers}1 (was %2)">;
+
def err_builtin_matrix_disabled: Error<
"matrix types extension is disabled. Pass -fenable-matrix to enable it">;
def err_matrix_index_not_integer: Error<
@@ -11269,11 +11968,8 @@ def err_matrix_separate_incomplete_index: Error<
"matrix row and column subscripts cannot be separated by any expression">;
def err_matrix_subscript_comma: Error<
"comma expressions are not allowed as indices in matrix subscript expressions">;
-def err_builtin_matrix_arg: Error<"1st argument must be a matrix">;
def err_builtin_matrix_scalar_unsigned_arg: Error<
"%0 argument must be a constant unsigned integer expression">;
-def err_builtin_matrix_pointer_arg: Error<
- "%ordinal0 argument must be a pointer to a valid matrix element type">;
def err_builtin_matrix_pointer_arg_mismatch: Error<
"the pointee of the 2nd argument must match the element type of the 1st argument (%0 != %1)">;
def err_builtin_matrix_store_to_const: Error<
@@ -11324,10 +12020,17 @@ 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 warn_cuda_maxclusterrank_sm_90 : Warning<
+ "maxclusterrank requires sm_90 or higher, CUDA arch provided: %0, ignoring "
+ "%1 attribute">, InGroup<IgnoredAttributes>;
-def err_ext_int_bad_size : Error<"%select{signed|unsigned}0 _ExtInt must "
+def err_bit_int_bad_size : Error<"%select{signed|unsigned}0 _BitInt must "
"have a bit size of at least %select{2|1}0">;
-def err_ext_int_max_size : Error<"%select{signed|unsigned}0 _ExtInt of bit "
+def err_bit_int_max_size : Error<"%select{signed|unsigned}0 _BitInt of bit "
"sizes greater than %1 not supported">;
// errors of expect.with.probability
@@ -11347,7 +12050,118 @@ 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%select{| at least one of the following extensions}0: %1">;
def err_riscv_builtin_invalid_lmul : Error<
"LMUL argument must be in the range [0,3] or [5,7]">;
+def err_riscv_type_requires_extension : Error<
+ "RISC-V type %0 requires the '%1' extension"
+>;
+
+def err_std_source_location_impl_not_found : Error<
+ "'std::source_location::__impl' was not found; it must be defined before '__builtin_source_location' is called">;
+def err_std_source_location_impl_malformed : Error<
+ "'std::source_location::__impl' must be standard-layout and have only two 'const char *' fields '_M_file_name' and '_M_function_name', and two integral fields '_M_line' and '_M_column'">;
+
+// HLSL Diagnostics
+def err_hlsl_attr_unsupported_in_stage : Error<"attribute %0 is unsupported in '%1' shaders, requires %select{|one of the following: }2%3">;
+def err_hlsl_attr_invalid_type : Error<
+ "attribute %0 only applies to a field or parameter of type '%1'">;
+def err_hlsl_attr_invalid_ast_node : Error<
+ "attribute %0 only applies to %1">;
+def err_hlsl_entry_shader_attr_mismatch : Error<
+ "%0 attribute on entry function does not match the target profile">;
+def err_hlsl_numthreads_argument_oor : Error<"argument '%select{X|Y|Z}0' to numthreads attribute cannot exceed %1">;
+def err_hlsl_numthreads_invalid : Error<"total number of threads cannot exceed %0">;
+def err_hlsl_missing_numthreads : Error<"missing numthreads attribute for %0 shader entry">;
+def err_hlsl_attribute_param_mismatch : Error<"%0 attribute parameters do not match the previous declaration">;
+def err_hlsl_duplicate_parameter_modifier : Error<"duplicate parameter modifier %0">;
+def err_hlsl_missing_semantic_annotation : Error<
+ "semantic annotations must be present for all parameters of an entry "
+ "function or patch constant function">;
+def err_hlsl_init_priority_unsupported : Error<
+ "initializer priorities are not supported in HLSL">;
+
+def err_hlsl_unsupported_register_type : Error<"invalid resource class specifier '%0' used; expected 'b', 's', 't', or 'u'">;
+def err_hlsl_unsupported_register_number : Error<"register number should be an integer">;
+def err_hlsl_expected_space : Error<"invalid space specifier '%0' used; expected 'space' followed by an integer, like space1">;
+def err_hlsl_pointers_unsupported : Error<
+ "%select{pointers|references}0 are unsupported in HLSL">;
+
+def err_hlsl_operator_unsupported : Error<
+ "the '%select{&|*|->}0' operator is unsupported in HLSL">;
+
+def err_hlsl_param_qualifier_mismatch :
+ Error<"conflicting parameter qualifier %0 on parameter %1">;
+
+// Layout randomization diagnostics.
+def err_non_designated_init_used : Error<
+ "a randomized struct can only be initialized with a designated initializer">;
+def err_cast_from_randomized_struct : Error<
+ "casting from randomized structure pointer type %0 to %1">;
+
+// Unsafe buffer usage diagnostics.
+def warn_unsafe_buffer_variable : Warning<
+ "%0 is an %select{unsafe pointer used for buffer access|unsafe buffer that "
+ "does not perform bounds checks}1">,
+ InGroup<UnsafeBufferUsage>, DefaultIgnore;
+def warn_unsafe_buffer_operation : Warning<
+ "%select{unsafe pointer operation|unsafe pointer arithmetic|"
+ "unsafe buffer access|function introduces unsafe buffer manipulation|unsafe invocation of span::data}0">,
+ InGroup<UnsafeBufferUsage>, DefaultIgnore;
+def note_unsafe_buffer_operation : Note<
+ "used%select{| in pointer arithmetic| in buffer access}0 here">;
+def note_unsafe_buffer_variable_fixit_group : Note<
+ "change type of %0 to '%select{std::span|std::array|std::span::iterator}1' to preserve bounds information%select{|, and change %2 to '%select{std::span|std::array|std::span::iterator}1' to propagate bounds information between them}3">;
+def note_unsafe_buffer_variable_fixit_together : Note<
+ "change type of %0 to '%select{std::span|std::array|std::span::iterator}1' to preserve bounds information"
+ "%select{|, and change %2 to safe types to make function %4 bounds-safe}3">;
+def note_safe_buffer_usage_suggestions_disabled : Note<
+ "pass -fsafe-buffer-usage-suggestions to receive code hardening suggestions">;
+#ifndef NDEBUG
+// Not a user-facing diagnostic. Useful for debugging false negatives in
+// -fsafe-buffer-usage-suggestions (i.e. lack of -Wunsafe-buffer-usage fixits).
+def note_safe_buffer_debug_mode : Note<"safe buffers debug: %0">;
+#endif
+
+def err_builtin_pass_in_regs_non_class : Error<
+ "argument %0 is not an unqualified class type">;
+
+
+// WebAssembly reference type and table diagnostics.
+def err_wasm_reference_pr : Error<
+ "%select{pointer|reference}0 to WebAssembly reference type is not allowed">;
+def err_wasm_ca_reference : Error<
+ "cannot %select{capture|take address of}0 WebAssembly reference">;
+def err_wasm_funcref_not_wasm : Error<
+ "invalid use of '__funcref' keyword outside the WebAssembly triple">;
+def err_wasm_table_pr : Error<
+ "cannot form a %select{pointer|reference}0 to a WebAssembly table">;
+def err_typecheck_wasm_table_must_have_zero_length : Error<
+ "only zero-length WebAssembly tables are currently supported">;
+def err_wasm_table_in_function : Error<
+ "WebAssembly table cannot be declared within a function">;
+def err_wasm_table_as_function_parameter : Error<
+ "cannot use WebAssembly table as a function parameter">;
+def err_wasm_table_invalid_uett_operand : Error<
+ "invalid application of '%0' to WebAssembly table">;
+def err_wasm_cast_table : Error<
+ "cannot cast %select{to|from}0 a WebAssembly table">;
+def err_wasm_table_conditional_expression : Error<
+ "cannot use a WebAssembly table within a branch of a conditional expression">;
+def err_wasm_table_art : Error<
+ "cannot %select{assign|return|throw|subscript}0 a WebAssembly table">;
+def err_wasm_reftype_tc : Error<
+ "cannot %select{throw|catch}0 a WebAssembly reference type">;
+def err_wasm_reftype_exception_spec : Error<
+ "WebAssembly reference type not allowed in exception specification">;
+def err_wasm_table_must_be_static : Error<
+ "WebAssembly table must be static">;
+def err_wasm_reftype_multidimensional_array : Error<
+ "multi-dimensional arrays of WebAssembly references are not allowed">;
+def err_wasm_builtin_arg_must_be_table_type : Error <
+ "%ordinal0 argument must be a WebAssembly table">;
+def err_wasm_builtin_arg_must_match_table_element_type : Error <
+ "%ordinal0 argument must match the element type of the WebAssembly table in the %ordinal1 argument">;
+def err_wasm_builtin_arg_must_be_integer_type : Error <
+ "%ordinal0 argument must be an integer">;
} // 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/DiagnosticSerializationKinds.td b/contrib/llvm-project/clang/include/clang/Basic/DiagnosticSerializationKinds.td
index bf3221be004d..11c706ebf84b 100644
--- a/contrib/llvm-project/clang/include/clang/Basic/DiagnosticSerializationKinds.td
+++ b/contrib/llvm-project/clang/include/clang/Basic/DiagnosticSerializationKinds.td
@@ -20,7 +20,7 @@ def err_fe_pch_malformed_block : Error<
def err_fe_ast_file_modified : Error<
"file '%0' has been modified since the "
"%select{precompiled header|module file|AST file}1 '%2' was built"
- ": %select{size|mtime|content}3 changed">,
+ ": %select{size|mtime|content}3 changed%select{| (was %5, now %6)}4">,
DefaultFatal;
def err_fe_pch_file_overridden : Error<
"file '%0' from the precompiled header has been overridden">;
@@ -62,7 +62,7 @@ def err_ast_file_out_of_date : Error<
"%select{PCH|module|AST}0 file '%1' is out of date and "
"needs to be rebuilt%select{|: %3}2">, DefaultFatal;
def err_ast_file_invalid : Error<
- "file '%1' is not a valid precompiled %select{PCH|module|AST}0 file">, DefaultFatal;
+ "file '%1' is not a valid precompiled %select{PCH|module|AST}0 file: %2">, DefaultFatal;
def note_module_file_imported_by : Note<
"imported by %select{|module '%2' in }1'%0'">;
def err_module_file_not_module : Error<
@@ -75,6 +75,7 @@ def note_module_file_conflict : Note<
def remark_module_import : Remark<
"importing module '%0'%select{| into '%3'}2 from '%1'">,
+ ShowInSystemHeader,
InGroup<ModuleImport>;
def err_imported_module_not_found : Error<
@@ -115,274 +116,10 @@ def note_module_odr_violation_no_possible_decls : Note<
"definition has no member %0">;
def note_module_odr_violation_possible_decl : Note<
"declaration of %0 does not match">;
-def err_module_odr_violation_different_definitions : Error<
- "%q0 has different definitions in different modules; "
- "%select{definition in module '%2' is here|defined here}1">;
-def note_first_module_difference : Note<
- "in first definition, possible difference is here">;
-def note_module_odr_violation_different_definitions : Note<
- "definition in module '%0' is here">;
-def note_second_module_difference : Note<
- "in second definition, possible difference is here">;
def err_module_odr_violation_different_instantiations : Error<
"instantiation of %q0 is different in different modules">;
-def err_module_odr_violation_definition_data : Error <
- "%q0 has different definitions in different modules; first difference is "
- "%select{definition in module '%2'|defined here}1 found "
- "%select{"
- "%4 base %plural{1:class|:classes}4|"
- "%4 virtual base %plural{1:class|:classes}4|"
- "%ordinal4 base class with type %5|"
- "%ordinal4 %select{non-virtual|virtual}5 base class %6|"
- "%ordinal4 base class %5 with "
- "%select{public|protected|private|no}6 access specifier}3">;
-
-def note_module_odr_violation_definition_data : Note <
- "but in '%0' found "
- "%select{"
- "%2 base %plural{1:class|:classes}2|"
- "%2 virtual base %plural{1:class|:classes}2|"
- "%ordinal2 base class with different type %3|"
- "%ordinal2 %select{non-virtual|virtual}3 base class %4|"
- "%ordinal2 base class %3 with "
- "%select{public|protected|private|no}4 access specifier}1">;
-
-def err_module_odr_violation_template_parameter : Error <
- "%q0 has different definitions in different modules; first difference is "
- "%select{definition in module '%2'|defined here}1 found "
- "%select{"
- "unnamed template parameter|"
- "template parameter %4|"
- "template parameter with %select{no |}4default argument|"
- "template parameter with default argument}3">;
-
-
-def note_module_odr_violation_template_parameter : Note <
- "but in '%0' found "
- "%select{"
- "unnamed template parameter %2|"
- "template parameter %2|"
- "template parameter with %select{no |}2default argument|"
- "template parameter with different default argument}1">;
-
-def err_module_odr_violation_mismatch_decl : Error<
- "%q0 has different definitions in different modules; first difference is "
- "%select{definition in module '%2'|defined here}1 found "
- "%select{end of class|public access specifier|private access specifier|"
- "protected access specifier|static assert|field|method|type alias|typedef|"
- "data member|friend declaration|function template}3">;
-def note_module_odr_violation_mismatch_decl : Note<"but in '%0' found "
- "%select{end of class|public access specifier|private access specifier|"
- "protected access specifier|static assert|field|method|type alias|typedef|"
- "data member|friend declaration|function template}1">;
-
-def err_module_odr_violation_mismatch_decl_diff : Error<
- "%q0 has different definitions in different modules; first difference is "
- "%select{definition in module '%2'|defined here}1 found "
- "%select{"
- "static assert with condition|"
- "static assert with message|"
- "static assert with %select{|no }4message|"
- "field %4|"
- "field %4 with type %5|"
- "%select{non-|}5bitfield %4|"
- "bitfield %4 with one width expression|"
- "%select{non-|}5mutable field %4|"
- "field %4 with %select{no|an}5 initalizer|"
- "field %4 with an initializer|"
- "%select{method %5|constructor|destructor}4|"
- "%select{method %5|constructor|destructor}4 "
- "is %select{not deleted|deleted}6|"
- "%select{method %5|constructor|destructor}4 "
- "is %select{not defaulted|defaulted}6|"
- "%select{method %5|constructor|destructor}4 "
- "is %select{|pure }6%select{not virtual|virtual}7|"
- "%select{method %5|constructor|destructor}4 "
- "is %select{not static|static}6|"
- "%select{method %5|constructor|destructor}4 "
- "is %select{not volatile|volatile}6|"
- "%select{method %5|constructor|destructor}4 "
- "is %select{not const|const}6|"
- "%select{method %5|constructor|destructor}4 "
- "is %select{not inline|inline}6|"
- "%select{method %5|constructor|destructor}4 "
- "that has %6 parameter%s6|"
- "%select{method %5|constructor|destructor}4 "
- "with %ordinal6 parameter of type %7%select{| decayed from %9}8|"
- "%select{method %5|constructor|destructor}4 "
- "with %ordinal6 parameter named %7|"
- "%select{method %5|constructor|destructor}4 "
- "with %ordinal6 parameter with%select{out|}7 a default argument|"
- "%select{method %5|constructor|destructor}4 "
- "with %ordinal6 parameter with a default argument|"
- "%select{method %5|constructor|destructor}4 "
- "with %select{no |}6template arguments|"
- "%select{method %5|constructor|destructor}4 "
- "with %6 template argument%s6|"
- "%select{method %5|constructor|destructor}4 "
- "with %6 for %ordinal7 template argument|"
- "%select{method %5|constructor|destructor}4 "
- "with %select{no body|body}6|"
- "%select{method %5|constructor|destructor}4 "
- "with body|"
- "%select{typedef|type alias}4 name %5|"
- "%select{typedef|type alias}4 %5 with underlying type %6|"
- "data member with name %4|"
- "data member %4 with type %5|"
- "data member %4 with%select{out|}5 an initializer|"
- "data member %4 with an initializer|"
- "data member %4 %select{is constexpr|is not constexpr}5|"
- "friend %select{class|function}4|"
- "friend %4|"
- "friend function %4|"
- "function template %4 with %5 template parameter%s5|"
- "function template %4 with %ordinal5 template parameter being a "
- "%select{type|non-type|template}6 template parameter|"
- "function template %4 with %ordinal5 template parameter "
- "%select{with no name|named %7}6|"
- "function template %4 with %ordinal5 template parameter with "
- "%select{no |}6default argument|"
- "function template %4 with %ordinal5 template parameter with "
- "default argument %6|"
- "function template %4 with %ordinal5 template parameter with one type|"
- "function template %4 with %ordinal5 template parameter %select{not |}6"
- "being a template parameter pack|"
- "}3">;
-
-def note_module_odr_violation_mismatch_decl_diff : Note<"but in '%0' found "
- "%select{"
- "static assert with different condition|"
- "static assert with different message|"
- "static assert with %select{|no }2message|"
- "field %2|"
- "field %2 with type %3|"
- "%select{non-|}3bitfield %2|"
- "bitfield %2 with different width expression|"
- "%select{non-|}3mutable field %2|"
- "field %2 with %select{no|an}3 initializer|"
- "field %2 with a different initializer|"
- "%select{method %3|constructor|destructor}2|"
- "%select{method %3|constructor|destructor}2 "
- "is %select{not deleted|deleted}4|"
- "%select{method %3|constructor|destructor}2 "
- "is %select{not defaulted|defaulted}4|"
- "%select{method %3|constructor|destructor}2 "
- "is %select{|pure }4%select{not virtual|virtual}5|"
- "%select{method %3|constructor|destructor}2 "
- "is %select{not static|static}4|"
- "%select{method %3|constructor|destructor}2 "
- "is %select{not volatile|volatile}4|"
- "%select{method %3|constructor|destructor}2 "
- "is %select{not const|const}4|"
- "%select{method %3|constructor|destructor}2 "
- "is %select{not inline|inline}4|"
- "%select{method %3|constructor|destructor}2 "
- "that has %4 parameter%s4|"
- "%select{method %3|constructor|destructor}2 "
- "with %ordinal4 parameter of type %5%select{| decayed from %7}6|"
- "%select{method %3|constructor|destructor}2 "
- "with %ordinal4 parameter named %5|"
- "%select{method %3|constructor|destructor}2 "
- "with %ordinal4 parameter with%select{out|}5 a default argument|"
- "%select{method %3|constructor|destructor}2 "
- "with %ordinal4 parameter with a different default argument|"
- "%select{method %3|constructor|destructor}2 "
- "with %select{no |}4template arguments|"
- "%select{method %3|constructor|destructor}2 "
- "with %4 template argument%s4|"
- "%select{method %3|constructor|destructor}2 "
- "with %4 for %ordinal5 template argument|"
- "%select{method %3|constructor|destructor}2 "
- "with %select{no body|body}4|"
- "%select{method %3|constructor|destructor}2 "
- "with different body|"
- "%select{typedef|type alias}2 name %3|"
- "%select{typedef|type alias}2 %3 with different underlying type %4|"
- "data member with name %2|"
- "data member %2 with different type %3|"
- "data member %2 with%select{out|}3 an initializer|"
- "data member %2 with a different initializer|"
- "data member %2 %select{is constexpr|is not constexpr}3|"
- "friend %select{class|function}2|"
- "friend %2|"
- "friend function %2|"
- "function template %2 with %3 template parameter%s3|"
- "function template %2 with %ordinal3 template paramter being a "
- "%select{type|non-type|template}4 template parameter|"
- "function template %2 with %ordinal3 template parameter "
- "%select{with no name|named %5}4|"
- "function template %2 with %ordinal3 template parameter with "
- "%select{no |}4default argument|"
- "function template %2 with %ordinal3 template parameter with "
- "default argument %4|"
- "function template %2 with %ordinal3 template parameter with different type|"
- "function template %2 with %ordinal3 template parameter %select{not |}4"
- "being a template parameter pack|"
- "}1">;
-
-def err_module_odr_violation_function : Error<
- "%q0 has different definitions in different modules; "
- "%select{definition in module '%2'|defined here}1 "
- "first difference is "
- "%select{"
- "return type is %4|"
- "%ordinal4 parameter with name %5|"
- "%ordinal4 parameter with type %5%select{| decayed from %7}6|"
- "%ordinal4 parameter with%select{out|}5 a default argument|"
- "%ordinal4 parameter with a default argument|"
- "function body"
- "}3">;
-
-def note_module_odr_violation_function : Note<"but in '%0' found "
- "%select{"
- "different return type %2|"
- "%ordinal2 parameter with name %3|"
- "%ordinal2 parameter with type %3%select{| decayed from %5}4|"
- "%ordinal2 parameter with%select{out|}3 a default argument|"
- "%ordinal2 parameter with a different default argument|"
- "a different body"
- "}1">;
-
-def err_module_odr_violation_enum : Error<
- "%q0 has different definitions in different modules; "
- "%select{definition in module '%2'|defined here}1 "
- "first difference is "
- "%select{"
- "enum that is %select{not scoped|scoped}4|"
- "enum scoped with keyword %select{struct|class}4|"
- "enum %select{without|with}4 specified type|"
- "enum with specified type %4|"
- "enum with %4 element%s4|"
- "%ordinal4 element has name %5|"
- "%ordinal4 element %5 %select{has|does not have}6 an initilizer|"
- "%ordinal4 element %5 has an initializer|"
- "}3">;
-
-def note_module_odr_violation_enum : Note<"but in '%0' found "
- "%select{"
- "enum that is %select{not scoped|scoped}2|"
- "enum scoped with keyword %select{struct|class}2|"
- "enum %select{without|with}2 specified type|"
- "enum with specified type %2|"
- "enum with %2 element%s2|"
- "%ordinal2 element has name %3|"
- "%ordinal2 element %3 %select{has|does not have}4 an initializer|"
- "%ordinal2 element %3 has different initializer|"
- "}1">;
-
-def err_module_odr_violation_mismatch_decl_unknown : Error<
- "%q0 %select{with definition in module '%2'|defined here}1 has different "
- "definitions in different modules; first difference is this "
- "%select{||||static assert|field|method|type alias|typedef|data member|"
- "friend declaration|unexpected decl}3">;
-def note_module_odr_violation_mismatch_decl_unknown : Note<
- "but in '%0' found "
- "%select{||||different static assert|different field|different method|"
- "different type alias|different typedef|different data member|"
- "different friend declaration|another unexpected decl}1">;
-
def warn_duplicate_module_file_extension : Warning<
"duplicate module file extension block name '%0'">,
InGroup<ModuleFileExtension>;
@@ -391,6 +128,9 @@ def warn_module_system_bit_conflict : Warning<
"module file '%0' was validated as a system module and is now being imported "
"as a non-system module; any difference in diagnostic options will be ignored">,
InGroup<ModuleConflict>;
+
+def err_failed_to_find_module_file : Error<
+ "failed to find module file for module '%0'">;
} // let CategoryName
let CategoryName = "AST Serialization Issue" in {
diff --git a/contrib/llvm-project/clang/include/clang/Basic/DirectoryEntry.h b/contrib/llvm-project/clang/include/clang/Basic/DirectoryEntry.h
index edb8031a20b8..906c2e9af23b 100644
--- a/contrib/llvm-project/clang/include/clang/Basic/DirectoryEntry.h
+++ b/contrib/llvm-project/clang/include/clang/Basic/DirectoryEntry.h
@@ -14,13 +14,18 @@
#ifndef LLVM_CLANG_BASIC_DIRECTORYENTRY_H
#define LLVM_CLANG_BASIC_DIRECTORYENTRY_H
+#include "clang/Basic/CustomizableOptional.h"
#include "clang/Basic/LLVM.h"
#include "llvm/ADT/DenseMapInfo.h"
#include "llvm/ADT/Hashing.h"
+#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/ErrorOr.h"
+#include <optional>
+#include <utility>
+
namespace clang {
namespace FileMgr {
@@ -31,12 +36,17 @@ template <class RefTy> class MapEntryOptionalStorage;
/// Cached information about one directory (either on disk or in
/// the virtual file system).
class DirectoryEntry {
+ DirectoryEntry() = default;
+ DirectoryEntry(const DirectoryEntry &) = delete;
+ DirectoryEntry &operator=(const DirectoryEntry &) = delete;
friend class FileManager;
+ friend class FileEntryTestHelper;
// FIXME: We should not be storing a directory entry name here.
StringRef Name; // Name of the directory.
public:
+ LLVM_DEPRECATED("Use DirectoryEntryRef::getName() instead.", "")
StringRef getName() const { return Name; }
};
@@ -62,7 +72,7 @@ public:
bool isSameRef(DirectoryEntryRef RHS) const { return ME == RHS.ME; }
DirectoryEntryRef() = delete;
- DirectoryEntryRef(const MapEntry &ME) : ME(&ME) {}
+ explicit DirectoryEntryRef(const MapEntry &ME) : ME(&ME) {}
/// Allow DirectoryEntryRef to degrade into 'const DirectoryEntry*' to
/// facilitate incremental adoption.
@@ -108,6 +118,8 @@ private:
const MapEntry *ME;
};
+using OptionalDirectoryEntryRef = CustomizableOptional<DirectoryEntryRef>;
+
namespace FileMgr {
/// Customized storage for refs derived from map entires in FileManager, using
@@ -120,27 +132,25 @@ public:
MapEntryOptionalStorage() : MaybeRef(optional_none_tag()) {}
template <class... ArgTypes>
- explicit MapEntryOptionalStorage(llvm::in_place_t, ArgTypes &&...Args)
+ explicit MapEntryOptionalStorage(std::in_place_t, ArgTypes &&...Args)
: MaybeRef(std::forward<ArgTypes>(Args)...) {}
void reset() { MaybeRef = optional_none_tag(); }
- bool hasValue() const { return MaybeRef.hasOptionalValue(); }
+ bool has_value() const { return MaybeRef.hasOptionalValue(); }
- RefTy &getValue() LLVM_LVALUE_FUNCTION {
- assert(hasValue());
+ RefTy &value() & {
+ assert(has_value());
return MaybeRef;
}
- RefTy const &getValue() const LLVM_LVALUE_FUNCTION {
- assert(hasValue());
+ RefTy const &value() const & {
+ assert(has_value());
return MaybeRef;
}
-#if LLVM_HAS_RVALUE_REFERENCE_THIS
- RefTy &&getValue() && {
- assert(hasValue());
+ RefTy &&value() && {
+ assert(has_value());
return std::move(MaybeRef);
}
-#endif
template <class... Args> void emplace(Args &&...args) {
MaybeRef = RefTy(std::forward<Args>(args)...);
@@ -153,9 +163,7 @@ public:
};
} // end namespace FileMgr
-} // end namespace clang
-namespace llvm {
namespace optional_detail {
/// Customize OptionalStorage<DirectoryEntryRef> to use DirectoryEntryRef and
@@ -170,8 +178,8 @@ public:
OptionalStorage() = default;
template <class... ArgTypes>
- explicit OptionalStorage(in_place_t, ArgTypes &&...Args)
- : StorageImpl(in_place_t{}, std::forward<ArgTypes>(Args)...) {}
+ explicit OptionalStorage(std::in_place_t, ArgTypes &&...Args)
+ : StorageImpl(std::in_place_t{}, std::forward<ArgTypes>(Args)...) {}
OptionalStorage &operator=(clang::DirectoryEntryRef Ref) {
StorageImpl::operator=(Ref);
@@ -179,15 +187,30 @@ public:
}
};
-static_assert(sizeof(Optional<clang::DirectoryEntryRef>) ==
- sizeof(clang::DirectoryEntryRef),
- "Optional<DirectoryEntryRef> must avoid size overhead");
+static_assert(sizeof(OptionalDirectoryEntryRef) == sizeof(DirectoryEntryRef),
+ "OptionalDirectoryEntryRef must avoid size overhead");
-static_assert(
- std::is_trivially_copyable<Optional<clang::DirectoryEntryRef>>::value,
- "Optional<DirectoryEntryRef> should be trivially copyable");
+static_assert(std::is_trivially_copyable<OptionalDirectoryEntryRef>::value,
+ "OptionalDirectoryEntryRef should be trivially copyable");
} // end namespace optional_detail
+} // namespace clang
+
+namespace llvm {
+
+template <> struct PointerLikeTypeTraits<clang::DirectoryEntryRef> {
+ static inline void *getAsVoidPointer(clang::DirectoryEntryRef Dir) {
+ return const_cast<clang::DirectoryEntryRef::MapEntry *>(&Dir.getMapEntry());
+ }
+
+ static inline clang::DirectoryEntryRef getFromVoidPointer(void *Ptr) {
+ return clang::DirectoryEntryRef(
+ *reinterpret_cast<const clang::DirectoryEntryRef::MapEntry *>(Ptr));
+ }
+
+ static constexpr int NumLowBitsAvailable = PointerLikeTypeTraits<
+ const clang::DirectoryEntryRef::MapEntry *>::NumLowBitsAvailable;
+};
/// Specialisation of DenseMapInfo for DirectoryEntryRef.
template <> struct DenseMapInfo<clang::DirectoryEntryRef> {
@@ -222,76 +245,4 @@ template <> struct DenseMapInfo<clang::DirectoryEntryRef> {
} // end namespace llvm
-namespace clang {
-
-/// Wrapper around Optional<DirectoryEntryRef> that degrades to 'const
-/// DirectoryEntry*', facilitating incremental patches to propagate
-/// DirectoryEntryRef.
-///
-/// This class can be used as return value or field where it's convenient for
-/// an Optional<DirectoryEntryRef> to degrade to a 'const DirectoryEntry*'. The
-/// purpose is to avoid code churn due to dances like the following:
-/// \code
-/// // Old code.
-/// lvalue = rvalue;
-///
-/// // Temporary code from an incremental patch.
-/// Optional<DirectoryEntryRef> MaybeF = rvalue;
-/// lvalue = MaybeF ? &MaybeF.getDirectoryEntry() : nullptr;
-///
-/// // Final code.
-/// lvalue = rvalue;
-/// \endcode
-///
-/// FIXME: Once DirectoryEntryRef is "everywhere" and DirectoryEntry::LastRef
-/// and DirectoryEntry::getName have been deleted, delete this class and
-/// replace instances with Optional<DirectoryEntryRef>.
-class OptionalDirectoryEntryRefDegradesToDirectoryEntryPtr
- : public Optional<DirectoryEntryRef> {
-public:
- OptionalDirectoryEntryRefDegradesToDirectoryEntryPtr() = default;
- OptionalDirectoryEntryRefDegradesToDirectoryEntryPtr(
- OptionalDirectoryEntryRefDegradesToDirectoryEntryPtr &&) = default;
- OptionalDirectoryEntryRefDegradesToDirectoryEntryPtr(
- const OptionalDirectoryEntryRefDegradesToDirectoryEntryPtr &) = default;
- OptionalDirectoryEntryRefDegradesToDirectoryEntryPtr &
- operator=(OptionalDirectoryEntryRefDegradesToDirectoryEntryPtr &&) = default;
- OptionalDirectoryEntryRefDegradesToDirectoryEntryPtr &
- operator=(const OptionalDirectoryEntryRefDegradesToDirectoryEntryPtr &) = default;
-
- OptionalDirectoryEntryRefDegradesToDirectoryEntryPtr(llvm::NoneType) {}
- OptionalDirectoryEntryRefDegradesToDirectoryEntryPtr(DirectoryEntryRef Ref)
- : Optional<DirectoryEntryRef>(Ref) {}
- OptionalDirectoryEntryRefDegradesToDirectoryEntryPtr(Optional<DirectoryEntryRef> MaybeRef)
- : Optional<DirectoryEntryRef>(MaybeRef) {}
-
- OptionalDirectoryEntryRefDegradesToDirectoryEntryPtr &operator=(llvm::NoneType) {
- Optional<DirectoryEntryRef>::operator=(None);
- return *this;
- }
- OptionalDirectoryEntryRefDegradesToDirectoryEntryPtr &operator=(DirectoryEntryRef Ref) {
- Optional<DirectoryEntryRef>::operator=(Ref);
- return *this;
- }
- OptionalDirectoryEntryRefDegradesToDirectoryEntryPtr &
- operator=(Optional<DirectoryEntryRef> MaybeRef) {
- Optional<DirectoryEntryRef>::operator=(MaybeRef);
- return *this;
- }
-
- /// Degrade to 'const DirectoryEntry *' to allow DirectoryEntry::LastRef and
- /// DirectoryEntry::getName have been deleted, delete this class and replace
- /// instances with Optional<DirectoryEntryRef>
- operator const DirectoryEntry *() const {
- return hasValue() ? &getValue().getDirEntry() : nullptr;
- }
-};
-
-static_assert(std::is_trivially_copyable<
- OptionalDirectoryEntryRefDegradesToDirectoryEntryPtr>::value,
- "OptionalDirectoryEntryRefDegradesToDirectoryEntryPtr should be "
- "trivially copyable");
-
-} // end namespace clang
-
#endif // LLVM_CLANG_BASIC_DIRECTORYENTRY_H
diff --git a/contrib/llvm-project/clang/include/clang/Basic/ExceptionSpecificationType.h b/contrib/llvm-project/clang/include/clang/Basic/ExceptionSpecificationType.h
index 5616860555c8..d3c9e9cd063b 100644
--- a/contrib/llvm-project/clang/include/clang/Basic/ExceptionSpecificationType.h
+++ b/contrib/llvm-project/clang/include/clang/Basic/ExceptionSpecificationType.h
@@ -50,6 +50,11 @@ inline bool isUnresolvedExceptionSpec(ExceptionSpecificationType ESpecType) {
return ESpecType == EST_Unevaluated || ESpecType == EST_Uninstantiated;
}
+inline bool isExplicitThrowExceptionSpec(ExceptionSpecificationType ESpecType) {
+ return ESpecType == EST_Dynamic || ESpecType == EST_MSAny ||
+ ESpecType == EST_NoexceptFalse;
+}
+
/// Possible results from evaluation of a noexcept expression.
enum CanThrowResult {
CT_Cannot,
diff --git a/contrib/llvm-project/clang/include/clang/Basic/FPOptions.def b/contrib/llvm-project/clang/include/clang/Basic/FPOptions.def
index a93fa475cd5f..79f04c89c9fe 100644
--- a/contrib/llvm-project/clang/include/clang/Basic/FPOptions.def
+++ b/contrib/llvm-project/clang/include/clang/Basic/FPOptions.def
@@ -14,13 +14,19 @@
// OPTION(name, type, width, previousName)
OPTION(FPContractMode, LangOptions::FPModeKind, 2, First)
-OPTION(RoundingMode, LangOptions::RoundingMode, 3, FPContractMode)
-OPTION(FPExceptionMode, LangOptions::FPExceptionModeKind, 2, RoundingMode)
-OPTION(AllowFEnvAccess, bool, 1, FPExceptionMode)
+OPTION(RoundingMath, bool, 1, FPContractMode)
+OPTION(ConstRoundingMode, LangOptions::RoundingMode, 3, RoundingMath)
+OPTION(SpecifiedExceptionMode, LangOptions::FPExceptionModeKind, 2, ConstRoundingMode)
+OPTION(AllowFEnvAccess, bool, 1, SpecifiedExceptionMode)
OPTION(AllowFPReassociate, bool, 1, AllowFEnvAccess)
OPTION(NoHonorNaNs, bool, 1, AllowFPReassociate)
OPTION(NoHonorInfs, bool, 1, NoHonorNaNs)
OPTION(NoSignedZero, bool, 1, NoHonorInfs)
OPTION(AllowReciprocal, bool, 1, NoSignedZero)
OPTION(AllowApproxFunc, bool, 1, AllowReciprocal)
+OPTION(FPEvalMethod, LangOptions::FPEvalMethodKind, 2, AllowApproxFunc)
+OPTION(Float16ExcessPrecision, LangOptions::ExcessPrecisionKind, 2, FPEvalMethod)
+OPTION(BFloat16ExcessPrecision, LangOptions::ExcessPrecisionKind, 2, Float16ExcessPrecision)
+OPTION(MathErrno, bool, 1, BFloat16ExcessPrecision)
+OPTION(ComplexRange, LangOptions::ComplexRangeKind, 2, MathErrno)
#undef OPTION
diff --git a/contrib/llvm-project/clang/include/clang/Basic/Features.def b/contrib/llvm-project/clang/include/clang/Basic/Features.def
index 6ca0e646b865..5fad5fc3623c 100644
--- a/contrib/llvm-project/clang/include/clang/Basic/Features.def
+++ b/contrib/llvm-project/clang/include/clang/Basic/Features.def
@@ -45,7 +45,12 @@ FEATURE(leak_sanitizer,
FEATURE(hwaddress_sanitizer,
LangOpts.Sanitize.hasOneOf(SanitizerKind::HWAddress |
SanitizerKind::KernelHWAddress))
-FEATURE(memtag_sanitizer, LangOpts.Sanitize.has(SanitizerKind::MemTag))
+FEATURE(memtag_stack,
+ LangOpts.Sanitize.has(SanitizerKind::MemtagStack))
+FEATURE(memtag_heap,
+ LangOpts.Sanitize.has(SanitizerKind::MemtagHeap))
+FEATURE(memtag_globals,
+ LangOpts.Sanitize.has(SanitizerKind::MemtagGlobals))
FEATURE(xray_instrument, LangOpts.XRayInstrument)
FEATURE(undefined_behavior_sanitizer,
LangOpts.Sanitize.hasOneOf(SanitizerKind::Undefined))
@@ -58,6 +63,7 @@ FEATURE(attribute_availability_app_extension, true)
FEATURE(attribute_availability_with_version_underscores, true)
FEATURE(attribute_availability_tvos, true)
FEATURE(attribute_availability_watchos, true)
+FEATURE(attribute_availability_driverkit, true)
FEATURE(attribute_availability_with_strict, true)
FEATURE(attribute_availability_with_replacement, true)
FEATURE(attribute_availability_in_templates, true)
@@ -83,6 +89,8 @@ FEATURE(blocks, LangOpts.Blocks)
FEATURE(c_thread_safety_attributes, true)
FEATURE(cxx_exceptions, LangOpts.CXXExceptions)
FEATURE(cxx_rtti, LangOpts.RTTI &&LangOpts.RTTIData)
+EXTENSION(define_target_os_macros,
+ PP.getPreprocessorOpts().DefineTargetOSMacros)
FEATURE(enumerator_attributes, true)
FEATURE(nullability, true)
FEATURE(nullability_on_arrays, true)
@@ -96,6 +104,7 @@ FEATURE(scudo, LangOpts.Sanitize.hasOneOf(SanitizerKind::Scudo))
FEATURE(swiftasynccc,
PP.getTargetInfo().checkCallingConvention(CC_SwiftAsync) ==
clang::TargetInfo::CCCR_OK)
+FEATURE(pragma_stdc_cx_limited_range, true)
// Objective-C features
FEATURE(objc_arr, LangOpts.ObjCAutoRefCount) // FIXME: REMOVE?
FEATURE(objc_arc, LangOpts.ObjCAutoRefCount)
@@ -222,22 +231,29 @@ FEATURE(is_trivially_assignable, LangOpts.CPlusPlus)
FEATURE(is_trivially_constructible, LangOpts.CPlusPlus)
FEATURE(is_trivially_copyable, LangOpts.CPlusPlus)
FEATURE(is_union, LangOpts.CPlusPlus)
+FEATURE(kcfi, LangOpts.Sanitize.has(SanitizerKind::KCFI))
FEATURE(modules, LangOpts.Modules)
FEATURE(safe_stack, LangOpts.Sanitize.has(SanitizerKind::SafeStack))
FEATURE(shadow_call_stack,
LangOpts.Sanitize.has(SanitizerKind::ShadowCallStack))
FEATURE(tls, PP.getTargetInfo().isTLSSupported())
FEATURE(underlying_type, LangOpts.CPlusPlus)
+FEATURE(experimental_library, LangOpts.ExperimentalLibrary)
// C11 features supported by other languages as extensions.
EXTENSION(c_alignas, true)
EXTENSION(c_alignof, true)
EXTENSION(c_atomic, true)
EXTENSION(c_generic_selections, true)
+EXTENSION(c_generic_selection_with_controlling_type, true)
EXTENSION(c_static_assert, true)
EXTENSION(c_thread_local, PP.getTargetInfo().isTLSSupported())
+// C23 features supported by other languages as extensions
+EXTENSION(c_attributes, true)
// C++11 features supported by other languages as extensions.
EXTENSION(cxx_atomic, LangOpts.CPlusPlus)
+EXTENSION(cxx_default_function_template_args, LangOpts.CPlusPlus)
+EXTENSION(cxx_defaulted_functions, LangOpts.CPlusPlus)
EXTENSION(cxx_deleted_functions, LangOpts.CPlusPlus)
EXTENSION(cxx_explicit_conversions, LangOpts.CPlusPlus)
EXTENSION(cxx_inline_namespaces, LangOpts.CPlusPlus)
@@ -253,6 +269,10 @@ EXTENSION(cxx_fixed_enum, true)
EXTENSION(cxx_binary_literals, true)
EXTENSION(cxx_init_captures, LangOpts.CPlusPlus11)
EXTENSION(cxx_variable_templates, LangOpts.CPlusPlus)
+//C++20
+EXTENSION(cxx_generalized_nttp, LangOpts.CPlusPlus20)
+//C++23
+EXTENSION(cxx_explicit_this_parameter, LangOpts.CPlusPlus23)
// Miscellaneous language extensions
EXTENSION(overloadable_unmarked, true)
EXTENSION(pragma_clang_attribute_namespaces, true)
@@ -260,11 +280,17 @@ EXTENSION(pragma_clang_attribute_external_declaration, true)
EXTENSION(statement_attributes_with_gnu_syntax, true)
EXTENSION(gnu_asm, LangOpts.GNUAsm)
EXTENSION(gnu_asm_goto_with_outputs, LangOpts.GNUAsm)
+EXTENSION(gnu_asm_goto_with_outputs_full, LangOpts.GNUAsm)
EXTENSION(matrix_types, LangOpts.MatrixTypes)
EXTENSION(matrix_types_scalar_division, true)
EXTENSION(cxx_attributes_on_using_declarations, LangOpts.CPlusPlus11)
+EXTENSION(datasizeof, LangOpts.CPlusPlus)
FEATURE(cxx_abi_relative_vtable, LangOpts.CPlusPlus && LangOpts.RelativeCXXABIVTables)
+// CUDA/HIP Features
+FEATURE(cuda_noinline_keyword, LangOpts.CUDA)
+EXTENSION(cuda_implicit_host_device_templates, LangOpts.CUDA && LangOpts.OffloadImplicitHostDeviceTemplates)
+
#undef EXTENSION
#undef FEATURE
diff --git a/contrib/llvm-project/clang/include/clang/Basic/FileEntry.h b/contrib/llvm-project/clang/include/clang/Basic/FileEntry.h
index 6e91b42e18b7..35efa147950f 100644
--- a/contrib/llvm-project/clang/include/clang/Basic/FileEntry.h
+++ b/contrib/llvm-project/clang/include/clang/Basic/FileEntry.h
@@ -14,6 +14,7 @@
#ifndef LLVM_CLANG_BASIC_FILEENTRY_H
#define LLVM_CLANG_BASIC_FILEENTRY_H
+#include "clang/Basic/CustomizableOptional.h"
#include "clang/Basic/DirectoryEntry.h"
#include "clang/Basic/LLVM.h"
#include "llvm/ADT/DenseMapInfo.h"
@@ -24,6 +25,9 @@
#include "llvm/Support/ErrorOr.h"
#include "llvm/Support/FileSystem/UniqueID.h"
+#include <optional>
+#include <utility>
+
namespace llvm {
class MemoryBuffer;
@@ -39,19 +43,12 @@ namespace clang {
class FileEntryRef;
-} // namespace clang
-
-namespace llvm {
namespace optional_detail {
/// Forward declare a template specialization for OptionalStorage.
-template <>
-class OptionalStorage<clang::FileEntryRef, /*is_trivially_copyable*/ true>;
+template <> class OptionalStorage<clang::FileEntryRef>;
} // namespace optional_detail
-} // namespace llvm
-
-namespace clang {
class FileEntry;
@@ -59,13 +56,22 @@ class FileEntry;
/// accessed by the FileManager's client.
class FileEntryRef {
public:
- StringRef getName() const { return ME->first(); }
+ /// The name of this FileEntry. If a VFS uses 'use-external-name', this is
+ /// the redirected name. See getRequestedName().
+ StringRef getName() const { return getBaseMapEntry().first(); }
+
+ /// The name of this FileEntry, as originally requested without applying any
+ /// remappings for VFS 'use-external-name'.
+ ///
+ /// FIXME: this should be the semantics of getName(). See comment in
+ /// FileManager::getFileRef().
+ StringRef getNameAsRequested() const { return ME->first(); }
+
const FileEntry &getFileEntry() const {
- return *ME->second->V.get<FileEntry *>();
+ return *getBaseMapEntry().second->V.get<FileEntry *>();
}
- DirectoryEntryRef getDir() const { return *ME->second->Dir; }
+ DirectoryEntryRef getDir() const { return ME->second->Dir; }
- inline bool isValid() const;
inline off_t getSize() const;
inline unsigned getUID() const;
inline const llvm::sys::fs::UniqueID &getUniqueID() const;
@@ -112,17 +118,14 @@ public:
/// VFSs that use external names. In that case, the \c FileEntryRef
/// returned by the \c FileManager will have the external name, and not the
/// name that was used to lookup the file.
- ///
- /// The second type is really a `const MapEntry *`, but that confuses
- /// gcc5.3. Once that's no longer supported, change this back.
- llvm::PointerUnion<FileEntry *, const void *> V;
+ llvm::PointerUnion<FileEntry *, const MapEntry *> V;
- /// Directory the file was found in. Set if and only if V is a FileEntry.
- Optional<DirectoryEntryRef> Dir;
+ /// Directory the file was found in.
+ DirectoryEntryRef Dir;
MapValue() = delete;
MapValue(FileEntry &FE, DirectoryEntryRef Dir) : V(&FE), Dir(Dir) {}
- MapValue(MapEntry &ME) : V(&ME) {}
+ MapValue(MapEntry &ME, DirectoryEntryRef Dir) : V(&ME), Dir(Dir) {}
};
/// Check if RHS referenced the file in exactly the same way.
@@ -151,13 +154,20 @@ public:
explicit FileEntryRef(const MapEntry &ME) : ME(&ME) {
assert(ME.second && "Expected payload");
assert(ME.second->V && "Expected non-null");
- assert(ME.second->V.is<FileEntry *>() && "Expected FileEntry");
}
/// Expose the underlying MapEntry to simplify packing in a PointerIntPair or
/// PointerUnion and allow construction in Optional.
const clang::FileEntryRef::MapEntry &getMapEntry() const { return *ME; }
+ /// Retrieve the base MapEntry after redirects.
+ const MapEntry &getBaseMapEntry() const {
+ const MapEntry *Base = ME;
+ while (const auto *Next = Base->second->V.dyn_cast<const MapEntry *>())
+ Base = Next;
+ return *Base;
+ }
+
private:
friend class FileMgr::MapEntryOptionalStorage<FileEntryRef>;
struct optional_none_tag {};
@@ -189,9 +199,8 @@ static_assert(sizeof(FileEntryRef) == sizeof(const FileEntry *),
static_assert(std::is_trivially_copyable<FileEntryRef>::value,
"FileEntryRef must be trivially copyable");
-} // end namespace clang
+using OptionalFileEntryRef = CustomizableOptional<FileEntryRef>;
-namespace llvm {
namespace optional_detail {
/// Customize OptionalStorage<FileEntryRef> to use FileEntryRef and its
@@ -206,8 +215,8 @@ public:
OptionalStorage() = default;
template <class... ArgTypes>
- explicit OptionalStorage(in_place_t, ArgTypes &&...Args)
- : StorageImpl(in_place_t{}, std::forward<ArgTypes>(Args)...) {}
+ explicit OptionalStorage(std::in_place_t, ArgTypes &&...Args)
+ : StorageImpl(std::in_place_t{}, std::forward<ArgTypes>(Args)...) {}
OptionalStorage &operator=(clang::FileEntryRef Ref) {
StorageImpl::operator=(Ref);
@@ -215,14 +224,16 @@ public:
}
};
-static_assert(sizeof(Optional<clang::FileEntryRef>) ==
- sizeof(clang::FileEntryRef),
- "Optional<FileEntryRef> must avoid size overhead");
+static_assert(sizeof(OptionalFileEntryRef) == sizeof(FileEntryRef),
+ "OptionalFileEntryRef must avoid size overhead");
-static_assert(std::is_trivially_copyable<Optional<clang::FileEntryRef>>::value,
- "Optional<FileEntryRef> should be trivially copyable");
+static_assert(std::is_trivially_copyable<OptionalFileEntryRef>::value,
+ "OptionalFileEntryRef should be trivially copyable");
} // end namespace optional_detail
+} // namespace clang
+
+namespace llvm {
/// Specialisation of DenseMapInfo for FileEntryRef.
template <> struct DenseMapInfo<clang::FileEntryRef> {
@@ -250,78 +261,36 @@ template <> struct DenseMapInfo<clang::FileEntryRef> {
// It's safe to use operator==.
return LHS == RHS;
}
+
+ /// Support for finding `const FileEntry *` in a `DenseMap<FileEntryRef, T>`.
+ /// @{
+ static unsigned getHashValue(const clang::FileEntry *Val) {
+ return llvm::hash_value(Val);
+ }
+ static bool isEqual(const clang::FileEntry *LHS, clang::FileEntryRef RHS) {
+ if (RHS.isSpecialDenseMapKey())
+ return false;
+ return LHS == RHS;
+ }
+ /// @}
};
} // end namespace llvm
namespace clang {
-/// Wrapper around Optional<FileEntryRef> that degrades to 'const FileEntry*',
-/// facilitating incremental patches to propagate FileEntryRef.
-///
-/// This class can be used as return value or field where it's convenient for
-/// an Optional<FileEntryRef> to degrade to a 'const FileEntry*'. The purpose
-/// is to avoid code churn due to dances like the following:
-/// \code
-/// // Old code.
-/// lvalue = rvalue;
-///
-/// // Temporary code from an incremental patch.
-/// Optional<FileEntryRef> MaybeF = rvalue;
-/// lvalue = MaybeF ? &MaybeF.getFileEntry() : nullptr;
-///
-/// // Final code.
-/// lvalue = rvalue;
-/// \endcode
-///
-/// FIXME: Once FileEntryRef is "everywhere" and FileEntry::LastRef and
-/// FileEntry::getName have been deleted, delete this class and replace
-/// instances with Optional<FileEntryRef>.
-class OptionalFileEntryRefDegradesToFileEntryPtr
- : public Optional<FileEntryRef> {
-public:
- OptionalFileEntryRefDegradesToFileEntryPtr() = default;
- OptionalFileEntryRefDegradesToFileEntryPtr(
- OptionalFileEntryRefDegradesToFileEntryPtr &&) = default;
- OptionalFileEntryRefDegradesToFileEntryPtr(
- const OptionalFileEntryRefDegradesToFileEntryPtr &) = default;
- OptionalFileEntryRefDegradesToFileEntryPtr &
- operator=(OptionalFileEntryRefDegradesToFileEntryPtr &&) = default;
- OptionalFileEntryRefDegradesToFileEntryPtr &
- operator=(const OptionalFileEntryRefDegradesToFileEntryPtr &) = default;
-
- OptionalFileEntryRefDegradesToFileEntryPtr(llvm::NoneType) {}
- OptionalFileEntryRefDegradesToFileEntryPtr(FileEntryRef Ref)
- : Optional<FileEntryRef>(Ref) {}
- OptionalFileEntryRefDegradesToFileEntryPtr(Optional<FileEntryRef> MaybeRef)
- : Optional<FileEntryRef>(MaybeRef) {}
-
- OptionalFileEntryRefDegradesToFileEntryPtr &operator=(llvm::NoneType) {
- Optional<FileEntryRef>::operator=(None);
- return *this;
- }
- OptionalFileEntryRefDegradesToFileEntryPtr &operator=(FileEntryRef Ref) {
- Optional<FileEntryRef>::operator=(Ref);
- return *this;
- }
- OptionalFileEntryRefDegradesToFileEntryPtr &
- operator=(Optional<FileEntryRef> MaybeRef) {
- Optional<FileEntryRef>::operator=(MaybeRef);
- return *this;
- }
-
- /// Degrade to 'const FileEntry *' to allow FileEntry::LastRef and
- /// FileEntry::getName have been deleted, delete this class and replace
- /// instances with Optional<FileEntryRef>
- operator const FileEntry *() const {
- return hasValue() ? &getValue().getFileEntry() : nullptr;
- }
-};
-
-static_assert(
- std::is_trivially_copyable<
- OptionalFileEntryRefDegradesToFileEntryPtr>::value,
- "OptionalFileEntryRefDegradesToFileEntryPtr should be trivially copyable");
+inline bool operator==(const FileEntry *LHS, const OptionalFileEntryRef &RHS) {
+ return LHS == (RHS ? &RHS->getFileEntry() : nullptr);
+}
+inline bool operator==(const OptionalFileEntryRef &LHS, const FileEntry *RHS) {
+ return (LHS ? &LHS->getFileEntry() : nullptr) == RHS;
+}
+inline bool operator!=(const FileEntry *LHS, const OptionalFileEntryRef &RHS) {
+ return !(LHS == RHS);
+}
+inline bool operator!=(const OptionalFileEntryRef &LHS, const FileEntry *RHS) {
+ return !(LHS == RHS);
+}
/// Cached information about one file (either on disk
/// or in the virtual file system).
@@ -330,6 +299,10 @@ static_assert(
/// descriptor for the file.
class FileEntry {
friend class FileManager;
+ friend class FileEntryTestHelper;
+ FileEntry();
+ FileEntry(const FileEntry &) = delete;
+ FileEntry &operator=(const FileEntry &) = delete;
std::string RealPathName; // Real path to the file; could be empty.
off_t Size = 0; // File size in bytes.
@@ -338,7 +311,6 @@ class FileEntry {
llvm::sys::fs::UniqueID UniqueID;
unsigned UID = 0; // A unique (small) ID for the file.
bool IsNamedPipe = false;
- bool IsValid = false; // Is this \c FileEntry initialized and valid?
/// The open file, if it is owned by the \p FileEntry.
mutable std::unique_ptr<llvm::vfs::File> File;
@@ -352,20 +324,14 @@ class FileEntry {
// default constructor). It should always have a value in practice.
//
// TODO: remove this once everyone that needs a name uses FileEntryRef.
- Optional<FileEntryRef> LastRef;
+ OptionalFileEntryRef LastRef;
public:
- FileEntry();
~FileEntry();
-
- FileEntry(const FileEntry &) = delete;
- FileEntry &operator=(const FileEntry &) = delete;
-
+ LLVM_DEPRECATED("Use FileEntryRef::getName() instead.", "")
StringRef getName() const { return LastRef->getName(); }
- FileEntryRef getLastRef() const { return *LastRef; }
StringRef tryGetRealPathName() const { return RealPathName; }
- bool isValid() const { return IsValid; }
off_t getSize() const { return Size; }
unsigned getUID() const { return UID; }
const llvm::sys::fs::UniqueID &getUniqueID() const { return UniqueID; }
@@ -374,8 +340,6 @@ public:
/// Return the directory the file lives in.
const DirectoryEntry *getDir() const { return Dir; }
- bool operator<(const FileEntry &RHS) const { return UniqueID < RHS.UniqueID; }
-
/// Check whether the file is a named pipe (and thus can't be opened by
/// the native FileManager methods).
bool isNamedPipe() const { return IsNamedPipe; }
@@ -383,8 +347,6 @@ public:
void closeFile() const;
};
-bool FileEntryRef::isValid() const { return getFileEntry().isValid(); }
-
off_t FileEntryRef::getSize() const { return getFileEntry().getSize(); }
unsigned FileEntryRef::getUID() const { return getFileEntry().getUID(); }
diff --git a/contrib/llvm-project/clang/include/clang/Basic/FileManager.h b/contrib/llvm-project/clang/include/clang/Basic/FileManager.h
index 974771a8f8f3..56cb093dd8c3 100644
--- a/contrib/llvm-project/clang/include/clang/Basic/FileManager.h
+++ b/contrib/llvm-project/clang/include/clang/Basic/FileManager.h
@@ -53,24 +53,26 @@ class FileSystemStatCache;
class FileManager : public RefCountedBase<FileManager> {
IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS;
FileSystemOptions FileSystemOpts;
+ llvm::SpecificBumpPtrAllocator<FileEntry> FilesAlloc;
+ llvm::SpecificBumpPtrAllocator<DirectoryEntry> DirsAlloc;
/// Cache for existing real directories.
- std::map<llvm::sys::fs::UniqueID, DirectoryEntry> UniqueRealDirs;
+ llvm::DenseMap<llvm::sys::fs::UniqueID, DirectoryEntry *> UniqueRealDirs;
/// Cache for existing real files.
- std::map<llvm::sys::fs::UniqueID, FileEntry> UniqueRealFiles;
+ llvm::DenseMap<llvm::sys::fs::UniqueID, FileEntry *> UniqueRealFiles;
/// The virtual directories that we have allocated.
///
/// For each virtual file (e.g. foo/bar/baz.cpp), we add all of its parent
/// directories (foo/ and foo/bar/) here.
- SmallVector<std::unique_ptr<DirectoryEntry>, 4> VirtualDirectoryEntries;
+ SmallVector<DirectoryEntry *, 4> VirtualDirectoryEntries;
/// The virtual files that we have allocated.
- SmallVector<std::unique_ptr<FileEntry>, 4> VirtualFileEntries;
+ SmallVector<FileEntry *, 4> VirtualFileEntries;
/// A set of files that bypass the maps and uniquing. They can have
/// conflicting filenames.
- SmallVector<std::unique_ptr<FileEntry>, 0> BypassFileEntries;
+ SmallVector<FileEntry *, 0> BypassFileEntries;
/// A cache that maps paths to directory entries (either real or
/// virtual) we have looked up, or an error that occurred when we looked up
@@ -100,7 +102,7 @@ class FileManager : public RefCountedBase<FileManager> {
SeenBypassFileEntries;
/// The file entry for stdin, if it has been accessed through the FileManager.
- Optional<FileEntryRef> STDIN;
+ OptionalFileEntryRef STDIN;
/// The canonical names of files and directories .
llvm::DenseMap<const void *, llvm::StringRef> CanonicalNames;
@@ -164,8 +166,8 @@ public:
bool CacheFailure = true);
/// Get a \c DirectoryEntryRef if it exists, without doing anything on error.
- llvm::Optional<DirectoryEntryRef>
- getOptionalDirectoryRef(StringRef DirName, bool CacheFailure = true) {
+ OptionalDirectoryEntryRef getOptionalDirectoryRef(StringRef DirName,
+ bool CacheFailure = true) {
return llvm::expectedToOptional(getDirectoryRef(DirName, CacheFailure));
}
@@ -229,9 +231,9 @@ public:
llvm::Expected<FileEntryRef> getSTDIN();
/// Get a FileEntryRef if it exists, without doing anything on error.
- llvm::Optional<FileEntryRef> getOptionalFileRef(StringRef Filename,
- bool OpenFile = false,
- bool CacheFailure = true) {
+ OptionalFileEntryRef getOptionalFileRef(StringRef Filename,
+ bool OpenFile = false,
+ bool CacheFailure = true) {
return llvm::expectedToOptional(
getFileRef(Filename, OpenFile, CacheFailure));
}
@@ -241,6 +243,10 @@ public:
const FileSystemOptions &getFileSystemOpts() const { return FileSystemOpts; }
llvm::vfs::FileSystem &getVirtualFileSystem() const { return *FS; }
+ llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem>
+ getVirtualFileSystemPtr() const {
+ return FS;
+ }
void setVirtualFileSystem(IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS) {
this->FS = std::move(FS);
@@ -264,12 +270,12 @@ public:
/// bypasses all mapping and uniquing, blindly creating a new FileEntry.
/// There is no attempt to deduplicate these; if you bypass the same file
/// twice, you get two new file entries.
- llvm::Optional<FileEntryRef> getBypassFile(FileEntryRef VFE);
+ OptionalFileEntryRef getBypassFile(FileEntryRef VFE);
/// Open the specified file as a MemoryBuffer, returning a new
/// MemoryBuffer if successful, otherwise returning null.
llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
- getBufferForFile(const FileEntry *Entry, bool isVolatile = false,
+ getBufferForFile(FileEntryRef Entry, bool isVolatile = false,
bool RequiresNullTerminator = true);
llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
getBufferForFile(StringRef Filename, bool isVolatile = false,
@@ -305,24 +311,31 @@ public:
bool makeAbsolutePath(SmallVectorImpl<char> &Path) const;
/// Produce an array mapping from the unique IDs assigned to each
- /// file to the corresponding FileEntry pointer.
- void GetUniqueIDMapping(
- SmallVectorImpl<const FileEntry *> &UIDToFiles) const;
+ /// file to the corresponding FileEntryRef.
+ void
+ GetUniqueIDMapping(SmallVectorImpl<OptionalFileEntryRef> &UIDToFiles) const;
/// Retrieve the canonical name for a given directory.
///
/// This is a very expensive operation, despite its results being cached,
/// and should only be used when the physical layout of the file system is
/// required, which is (almost) never.
- StringRef getCanonicalName(const DirectoryEntry *Dir);
+ StringRef getCanonicalName(DirectoryEntryRef Dir);
/// Retrieve the canonical name for a given file.
///
/// This is a very expensive operation, despite its results being cached,
/// and should only be used when the physical layout of the file system is
/// required, which is (almost) never.
- StringRef getCanonicalName(const FileEntry *File);
+ StringRef getCanonicalName(FileEntryRef File);
+
+private:
+ /// Retrieve the canonical name for a given file or directory.
+ ///
+ /// The first param is a key in the CanonicalNames array.
+ StringRef getCanonicalName(const void *Entry, StringRef Name);
+public:
void PrintStats() const;
};
diff --git a/contrib/llvm-project/clang/include/clang/Basic/FileSystemStatCache.h b/contrib/llvm-project/clang/include/clang/Basic/FileSystemStatCache.h
index d37f2d507f83..5a003a748178 100644
--- a/contrib/llvm-project/clang/include/clang/Basic/FileSystemStatCache.h
+++ b/contrib/llvm-project/clang/include/clang/Basic/FileSystemStatCache.h
@@ -23,6 +23,7 @@
#include <cstdint>
#include <ctime>
#include <memory>
+#include <optional>
#include <string>
#include <utility>
@@ -54,7 +55,7 @@ public:
protected:
// FIXME: The pointer here is a non-owning/optional reference to the
- // unique_ptr. Optional<unique_ptr<vfs::File>&> might be nicer, but
+ // unique_ptr. std::optional<unique_ptr<vfs::File>&> might be nicer, but
// Optional needs some work to support references so this isn't possible yet.
virtual std::error_code getStat(StringRef Path, llvm::vfs::Status &Status,
bool isFile,
diff --git a/contrib/llvm-project/clang/include/clang/Basic/HLSLRuntime.h b/contrib/llvm-project/clang/include/clang/Basic/HLSLRuntime.h
new file mode 100644
index 000000000000..03166805daa6
--- /dev/null
+++ b/contrib/llvm-project/clang/include/clang/Basic/HLSLRuntime.h
@@ -0,0 +1,66 @@
+//===- HLSLRuntime.h - HLSL Runtime -----------------------------*- 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
+/// Defines helper utilities for supporting the HLSL runtime environment.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef CLANG_BASIC_HLSLRUNTIME_H
+#define CLANG_BASIC_HLSLRUNTIME_H
+
+#include "clang/Basic/LangOptions.h"
+#include <cstdint>
+
+namespace clang {
+namespace hlsl {
+
+constexpr ShaderStage
+getStageFromEnvironment(const llvm::Triple::EnvironmentType &E) {
+ uint32_t Pipeline =
+ static_cast<uint32_t>(E) - static_cast<uint32_t>(llvm::Triple::Pixel);
+
+ if (Pipeline > (uint32_t)ShaderStage::Invalid)
+ return ShaderStage::Invalid;
+ return static_cast<ShaderStage>(Pipeline);
+}
+
+#define ENUM_COMPARE_ASSERT(Value) \
+ static_assert( \
+ getStageFromEnvironment(llvm::Triple::Value) == ShaderStage::Value, \
+ "Mismatch between llvm::Triple and clang::ShaderStage for " #Value);
+
+ENUM_COMPARE_ASSERT(Pixel)
+ENUM_COMPARE_ASSERT(Vertex)
+ENUM_COMPARE_ASSERT(Geometry)
+ENUM_COMPARE_ASSERT(Hull)
+ENUM_COMPARE_ASSERT(Domain)
+ENUM_COMPARE_ASSERT(Compute)
+ENUM_COMPARE_ASSERT(Library)
+ENUM_COMPARE_ASSERT(RayGeneration)
+ENUM_COMPARE_ASSERT(Intersection)
+ENUM_COMPARE_ASSERT(AnyHit)
+ENUM_COMPARE_ASSERT(ClosestHit)
+ENUM_COMPARE_ASSERT(Miss)
+ENUM_COMPARE_ASSERT(Callable)
+ENUM_COMPARE_ASSERT(Mesh)
+ENUM_COMPARE_ASSERT(Amplification)
+
+static_assert(getStageFromEnvironment(llvm::Triple::UnknownEnvironment) ==
+ ShaderStage::Invalid,
+ "Mismatch between llvm::Triple and "
+ "clang::ShaderStage for Invalid");
+static_assert(getStageFromEnvironment(llvm::Triple::MSVC) ==
+ ShaderStage::Invalid,
+ "Mismatch between llvm::Triple and "
+ "clang::ShaderStage for Invalid");
+
+} // namespace hlsl
+} // namespace clang
+
+#endif // CLANG_BASIC_HLSLRUNTIME_H
diff --git a/contrib/llvm-project/clang/include/clang/Basic/HeaderInclude.h b/contrib/llvm-project/clang/include/clang/Basic/HeaderInclude.h
new file mode 100644
index 000000000000..83c26543bbd3
--- /dev/null
+++ b/contrib/llvm-project/clang/include/clang/Basic/HeaderInclude.h
@@ -0,0 +1,73 @@
+//===--- HeaderInclude.h - Header Include -----------------------*- 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
+/// Defines enums used when emitting included header information.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_BASIC_HEADERINCLUDEFORMATKIND_H
+#define LLVM_CLANG_BASIC_HEADERINCLUDEFORMATKIND_H
+#include "llvm/ADT/StringSwitch.h"
+#include "llvm/Support/ErrorHandling.h"
+#include <utility>
+
+namespace clang {
+/// The format in which header information is emitted.
+enum HeaderIncludeFormatKind { HIFMT_None, HIFMT_Textual, HIFMT_JSON };
+
+/// Whether header information is filtered or not. If HIFIL_Only_Direct_System
+/// is used, only information on system headers directly included from
+/// non-system headers is emitted.
+enum HeaderIncludeFilteringKind { HIFIL_None, HIFIL_Only_Direct_System };
+
+inline HeaderIncludeFormatKind
+stringToHeaderIncludeFormatKind(const char *Str) {
+ return llvm::StringSwitch<HeaderIncludeFormatKind>(Str)
+ .Case("textual", HIFMT_Textual)
+ .Case("json", HIFMT_JSON)
+ .Default(HIFMT_None);
+}
+
+inline bool stringToHeaderIncludeFiltering(const char *Str,
+ HeaderIncludeFilteringKind &Kind) {
+ std::pair<bool, HeaderIncludeFilteringKind> P =
+ llvm::StringSwitch<std::pair<bool, HeaderIncludeFilteringKind>>(Str)
+ .Case("none", {true, HIFIL_None})
+ .Case("only-direct-system", {true, HIFIL_Only_Direct_System})
+ .Default({false, HIFIL_None});
+ Kind = P.second;
+ return P.first;
+}
+
+inline const char *headerIncludeFormatKindToString(HeaderIncludeFormatKind K) {
+ switch (K) {
+ case HIFMT_None:
+ llvm_unreachable("unexpected format kind");
+ case HIFMT_Textual:
+ return "textual";
+ case HIFMT_JSON:
+ return "json";
+ }
+ llvm_unreachable("Unknown HeaderIncludeFormatKind enum");
+}
+
+inline const char *
+headerIncludeFilteringKindToString(HeaderIncludeFilteringKind K) {
+ switch (K) {
+ case HIFIL_None:
+ return "none";
+ case HIFIL_Only_Direct_System:
+ return "only-direct-system";
+ }
+ llvm_unreachable("Unknown HeaderIncludeFilteringKind enum");
+}
+
+} // end namespace clang
+
+#endif // LLVM_CLANG_BASIC_HEADERINCLUDEFORMATKIND_H
diff --git a/contrib/llvm-project/clang/include/clang/Basic/IdentifierTable.h b/contrib/llvm-project/clang/include/clang/Basic/IdentifierTable.h
index f2379c7ddfbd..1ac182d4fce2 100644
--- a/contrib/llvm-project/clang/include/clang/Basic/IdentifierTable.h
+++ b/contrib/llvm-project/clang/include/clang/Basic/IdentifierTable.h
@@ -15,9 +15,13 @@
#ifndef LLVM_CLANG_BASIC_IDENTIFIERTABLE_H
#define LLVM_CLANG_BASIC_IDENTIFIERTABLE_H
+#include "clang/Basic/DiagnosticIDs.h"
#include "clang/Basic/LLVM.h"
#include "clang/Basic/TokenKinds.h"
#include "llvm/ADT/DenseMapInfo.h"
+#include "llvm/ADT/FoldingSet.h"
+#include "llvm/ADT/PointerIntPair.h"
+#include "llvm/ADT/PointerUnion.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
@@ -43,11 +47,34 @@ class SourceLocation;
enum class ReservedIdentifierStatus {
NotReserved = 0,
StartsWithUnderscoreAtGlobalScope,
+ StartsWithUnderscoreAndIsExternC,
StartsWithDoubleUnderscore,
StartsWithUnderscoreFollowedByCapitalLetter,
ContainsDoubleUnderscore,
};
+enum class ReservedLiteralSuffixIdStatus {
+ NotReserved = 0,
+ NotStartsWithUnderscore,
+ ContainsDoubleUnderscore,
+};
+
+/// Determine whether an identifier is reserved for use as a name at global
+/// scope. Such identifiers might be implementation-specific global functions
+/// or variables.
+inline bool isReservedAtGlobalScope(ReservedIdentifierStatus Status) {
+ return Status != ReservedIdentifierStatus::NotReserved;
+}
+
+/// Determine whether an identifier is reserved in all contexts. Such
+/// identifiers might be implementation-specific keywords or macros, for
+/// example.
+inline bool isReservedInAllContexts(ReservedIdentifierStatus Status) {
+ return Status != ReservedIdentifierStatus::NotReserved &&
+ Status != ReservedIdentifierStatus::StartsWithUnderscoreAtGlobalScope &&
+ Status != ReservedIdentifierStatus::StartsWithUnderscoreAndIsExternC;
+}
+
/// A simple pair of identifier info and location.
using IdentifierLocPair = std::pair<IdentifierInfo *, SourceLocation>;
@@ -58,6 +85,21 @@ enum { IdentifierInfoAlignment = 8 };
static constexpr int ObjCOrBuiltinIDBits = 16;
+/// The "layout" of ObjCOrBuiltinID is:
+/// - The first value (0) represents "not a special identifier".
+/// - The next (NUM_OBJC_KEYWORDS - 1) values represent ObjCKeywordKinds (not
+/// including objc_not_keyword).
+/// - The next (NUM_INTERESTING_IDENTIFIERS - 1) values represent
+/// InterestingIdentifierKinds (not including not_interesting).
+/// - The rest of the values represent builtin IDs (not including NotBuiltin).
+static constexpr int FirstObjCKeywordID = 1;
+static constexpr int LastObjCKeywordID =
+ FirstObjCKeywordID + tok::NUM_OBJC_KEYWORDS - 2;
+static constexpr int FirstInterestingIdentifierID = LastObjCKeywordID + 1;
+static constexpr int LastInterestingIdentifierID =
+ FirstInterestingIdentifierID + tok::NUM_INTERESTING_IDENTIFIERS - 2;
+static constexpr int FirstBuiltinID = LastInterestingIdentifierID + 1;
+
/// One of these records is kept for each identifier that
/// is lexed. This contains information about whether the token was \#define'd,
/// is a language keyword, or if it is a front-end token of some sort (e.g. a
@@ -68,6 +110,7 @@ class alignas(IdentifierInfoAlignment) IdentifierInfo {
friend class IdentifierTable;
// Front-end token ID or tok::identifier.
+ LLVM_PREFERRED_TYPE(tok::TokenKind)
unsigned TokenID : 9;
// ObjC keyword ('protocol' in '@protocol') or builtin (__builtin_inf).
@@ -76,52 +119,78 @@ class alignas(IdentifierInfoAlignment) IdentifierInfo {
unsigned ObjCOrBuiltinID : ObjCOrBuiltinIDBits;
// True if there is a #define for this.
+ LLVM_PREFERRED_TYPE(bool)
unsigned HasMacro : 1;
// True if there was a #define for this.
+ LLVM_PREFERRED_TYPE(bool)
unsigned HadMacro : 1;
// True if the identifier is a language extension.
+ LLVM_PREFERRED_TYPE(bool)
unsigned IsExtension : 1;
// True if the identifier is a keyword in a newer or proposed Standard.
+ LLVM_PREFERRED_TYPE(bool)
unsigned IsFutureCompatKeyword : 1;
// True if the identifier is poisoned.
+ LLVM_PREFERRED_TYPE(bool)
unsigned IsPoisoned : 1;
// True if the identifier is a C++ operator keyword.
+ LLVM_PREFERRED_TYPE(bool)
unsigned IsCPPOperatorKeyword : 1;
// Internal bit set by the member function RecomputeNeedsHandleIdentifier.
// See comment about RecomputeNeedsHandleIdentifier for more info.
+ LLVM_PREFERRED_TYPE(bool)
unsigned NeedsHandleIdentifier : 1;
// True if the identifier was loaded (at least partially) from an AST file.
+ LLVM_PREFERRED_TYPE(bool)
unsigned IsFromAST : 1;
// True if the identifier has changed from the definition
// loaded from an AST file.
+ LLVM_PREFERRED_TYPE(bool)
unsigned ChangedAfterLoad : 1;
// True if the identifier's frontend information has changed from the
// definition loaded from an AST file.
+ LLVM_PREFERRED_TYPE(bool)
unsigned FEChangedAfterLoad : 1;
// True if revertTokenIDToIdentifier was called.
+ LLVM_PREFERRED_TYPE(bool)
unsigned RevertedTokenID : 1;
// True if there may be additional information about
// this identifier stored externally.
+ LLVM_PREFERRED_TYPE(bool)
unsigned OutOfDate : 1;
// True if this is the 'import' contextual keyword.
+ LLVM_PREFERRED_TYPE(bool)
unsigned IsModulesImport : 1;
// True if this is a mangled OpenMP variant name.
+ LLVM_PREFERRED_TYPE(bool)
unsigned IsMangledOpenMPVariantName : 1;
- // 28 bits left in a 64-bit word.
+ // True if this is a deprecated macro.
+ LLVM_PREFERRED_TYPE(bool)
+ unsigned IsDeprecatedMacro : 1;
+
+ // True if this macro is unsafe in headers.
+ LLVM_PREFERRED_TYPE(bool)
+ unsigned IsRestrictExpansion : 1;
+
+ // True if this macro is final.
+ LLVM_PREFERRED_TYPE(bool)
+ unsigned IsFinal : 1;
+
+ // 22 bits left in a 64-bit word.
// Managed by the language front-end.
void *FETokenInfo = nullptr;
@@ -134,7 +203,8 @@ class alignas(IdentifierInfoAlignment) IdentifierInfo {
IsPoisoned(false), IsCPPOperatorKeyword(false),
NeedsHandleIdentifier(false), IsFromAST(false), ChangedAfterLoad(false),
FEChangedAfterLoad(false), RevertedTokenID(false), OutOfDate(false),
- IsModulesImport(false), IsMangledOpenMPVariantName(false) {}
+ IsModulesImport(false), IsMangledOpenMPVariantName(false),
+ IsDeprecatedMacro(false), IsRestrictExpansion(false), IsFinal(false) {}
public:
IdentifierInfo(const IdentifierInfo &) = delete;
@@ -182,6 +252,14 @@ public:
NeedsHandleIdentifier = true;
HadMacro = true;
} else {
+ // If this is a final macro, make the deprecation and header unsafe bits
+ // stick around after the undefinition so they apply to any redefinitions.
+ if (!IsFinal) {
+ // Because calling the setters of these calls recomputes, just set them
+ // manually to avoid recomputing a bunch of times.
+ IsDeprecatedMacro = false;
+ IsRestrictExpansion = false;
+ }
RecomputeNeedsHandleIdentifier();
}
}
@@ -192,6 +270,34 @@ public:
return HadMacro;
}
+ bool isDeprecatedMacro() const { return IsDeprecatedMacro; }
+
+ void setIsDeprecatedMacro(bool Val) {
+ if (IsDeprecatedMacro == Val)
+ return;
+ IsDeprecatedMacro = Val;
+ if (Val)
+ NeedsHandleIdentifier = true;
+ else
+ RecomputeNeedsHandleIdentifier();
+ }
+
+ bool isRestrictExpansion() const { return IsRestrictExpansion; }
+
+ void setIsRestrictExpansion(bool Val) {
+ if (IsRestrictExpansion == Val)
+ return;
+ IsRestrictExpansion = Val;
+ if (Val)
+ NeedsHandleIdentifier = true;
+ else
+ RecomputeNeedsHandleIdentifier();
+ }
+
+ bool isFinal() const { return IsFinal; }
+
+ void setIsFinal(bool Val) { IsFinal = Val; }
+
/// If this is a source-language token (e.g. 'for'), this API
/// can be used to cause the lexer to map identifiers to source-language
/// tokens.
@@ -226,7 +332,9 @@ public:
///
/// For example, 'class' will return tok::objc_class if ObjC is enabled.
tok::ObjCKeywordKind getObjCKeywordID() const {
- if (ObjCOrBuiltinID < tok::NUM_OBJC_KEYWORDS)
+ static_assert(FirstObjCKeywordID == 1,
+ "hard-coding this assumption to simplify code");
+ if (ObjCOrBuiltinID <= LastObjCKeywordID)
return tok::ObjCKeywordKind(ObjCOrBuiltinID);
else
return tok::objc_not_keyword;
@@ -237,15 +345,30 @@ public:
///
/// 0 is not-built-in. 1+ are specific builtin functions.
unsigned getBuiltinID() const {
- if (ObjCOrBuiltinID >= tok::NUM_OBJC_KEYWORDS)
- return ObjCOrBuiltinID - tok::NUM_OBJC_KEYWORDS;
+ if (ObjCOrBuiltinID >= FirstBuiltinID)
+ return 1 + (ObjCOrBuiltinID - FirstBuiltinID);
else
return 0;
}
void setBuiltinID(unsigned ID) {
- ObjCOrBuiltinID = ID + tok::NUM_OBJC_KEYWORDS;
- assert(ObjCOrBuiltinID - unsigned(tok::NUM_OBJC_KEYWORDS) == ID
- && "ID too large for field!");
+ assert(ID != 0);
+ ObjCOrBuiltinID = FirstBuiltinID + (ID - 1);
+ assert(getBuiltinID() == ID && "ID too large for field!");
+ }
+ void clearBuiltinID() { ObjCOrBuiltinID = 0; }
+
+ tok::InterestingIdentifierKind getInterestingIdentifierID() const {
+ if (ObjCOrBuiltinID >= FirstInterestingIdentifierID &&
+ ObjCOrBuiltinID <= LastInterestingIdentifierID)
+ return tok::InterestingIdentifierKind(
+ 1 + (ObjCOrBuiltinID - FirstInterestingIdentifierID));
+ else
+ return tok::not_interesting;
+ }
+ void setInterestingIdentifierID(unsigned ID) {
+ assert(ID != tok::not_interesting);
+ ObjCOrBuiltinID = FirstInterestingIdentifierID + (ID - 1);
+ assert(getInterestingIdentifierID() == ID && "ID too large for field!");
}
unsigned getObjCOrBuiltinID() const { return ObjCOrBuiltinID; }
@@ -388,13 +511,24 @@ public:
/// function(<#int x#>);
/// \endcode
bool isEditorPlaceholder() const {
- return getName().startswith("<#") && getName().endswith("#>");
+ return getName().starts_with("<#") && getName().ends_with("#>");
}
/// Determine whether \p this is a name reserved for the implementation (C99
/// 7.1.3, C++ [lib.global.names]).
ReservedIdentifierStatus isReserved(const LangOptions &LangOpts) const;
+ /// Determine whether \p this is a name reserved for future standardization or
+ /// the implementation (C++ [usrlit.suffix]).
+ ReservedLiteralSuffixIdStatus isReservedLiteralSuffixId() 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;
+ bool isPlaceholder() const {
+ return getLength() == 1 && getNameStart()[0] == '_';
+ }
+
/// Provide less than operator for lexicographical sorting.
bool operator<(const IdentifierInfo &RHS) const {
return getName() < RHS.getName();
@@ -527,7 +661,7 @@ public:
/// Return the identifier token info for the specified named
/// identifier.
IdentifierInfo &get(StringRef Name) {
- auto &Entry = *HashTable.insert(std::make_pair(Name, nullptr)).first;
+ auto &Entry = *HashTable.try_emplace(Name, nullptr).first;
IdentifierInfo *&II = Entry.second;
if (II) return *II;
@@ -601,6 +735,12 @@ public:
/// Populate the identifier table with info about the language keywords
/// for the language specified by \p LangOpts.
void AddKeywords(const LangOptions &LangOpts);
+
+ /// Returns the correct diagnostic to issue for a future-compat diagnostic
+ /// warning. Note, this function assumes the identifier passed has already
+ /// been determined to be a future compatible keyword.
+ diag::kind getFutureCompatDiagKind(const IdentifierInfo &II,
+ const LangOptions &LangOpts);
};
/// A family of Objective-C methods.
@@ -675,6 +815,121 @@ enum ObjCStringFormatFamily {
SFF_CFString
};
+namespace detail {
+
+/// DeclarationNameExtra is used as a base of various uncommon special names.
+/// This class is needed since DeclarationName has not enough space to store
+/// the kind of every possible names. Therefore the kind of common names is
+/// stored directly in DeclarationName, and the kind of uncommon names is
+/// stored in DeclarationNameExtra. It is aligned to 8 bytes because
+/// DeclarationName needs the lower 3 bits to store the kind of common names.
+/// DeclarationNameExtra is tightly coupled to DeclarationName and any change
+/// here is very likely to require changes in DeclarationName(Table).
+class alignas(IdentifierInfoAlignment) DeclarationNameExtra {
+ friend class clang::DeclarationName;
+ friend class clang::DeclarationNameTable;
+
+protected:
+ /// The kind of "extra" information stored in the DeclarationName. See
+ /// @c ExtraKindOrNumArgs for an explanation of how these enumerator values
+ /// are used. Note that DeclarationName depends on the numerical values
+ /// of the enumerators in this enum. See DeclarationName::StoredNameKind
+ /// for more info.
+ enum ExtraKind {
+ CXXDeductionGuideName,
+ CXXLiteralOperatorName,
+ CXXUsingDirective,
+ ObjCMultiArgSelector
+ };
+
+ /// ExtraKindOrNumArgs has one of the following meaning:
+ /// * The kind of an uncommon C++ special name. This DeclarationNameExtra
+ /// is in this case in fact either a CXXDeductionGuideNameExtra or
+ /// a CXXLiteralOperatorIdName.
+ ///
+ /// * It may be also name common to C++ using-directives (CXXUsingDirective),
+ ///
+ /// * Otherwise it is ObjCMultiArgSelector+NumArgs, where NumArgs is
+ /// the number of arguments in the Objective-C selector, in which
+ /// case the DeclarationNameExtra is also a MultiKeywordSelector.
+ unsigned ExtraKindOrNumArgs;
+
+ DeclarationNameExtra(ExtraKind Kind) : ExtraKindOrNumArgs(Kind) {}
+ DeclarationNameExtra(unsigned NumArgs)
+ : ExtraKindOrNumArgs(ObjCMultiArgSelector + NumArgs) {}
+
+ /// Return the corresponding ExtraKind.
+ ExtraKind getKind() const {
+ return static_cast<ExtraKind>(ExtraKindOrNumArgs >
+ (unsigned)ObjCMultiArgSelector
+ ? (unsigned)ObjCMultiArgSelector
+ : ExtraKindOrNumArgs);
+ }
+
+ /// Return the number of arguments in an ObjC selector. Only valid when this
+ /// is indeed an ObjCMultiArgSelector.
+ unsigned getNumArgs() const {
+ assert(ExtraKindOrNumArgs >= (unsigned)ObjCMultiArgSelector &&
+ "getNumArgs called but this is not an ObjC selector!");
+ return ExtraKindOrNumArgs - (unsigned)ObjCMultiArgSelector;
+ }
+};
+
+} // namespace detail
+
+/// One of these variable length records is kept for each
+/// selector containing more than one keyword. We use a folding set
+/// to unique aggregate names (keyword selectors in ObjC parlance). Access to
+/// this class is provided strictly through Selector.
+class alignas(IdentifierInfoAlignment) MultiKeywordSelector
+ : public detail::DeclarationNameExtra,
+ public llvm::FoldingSetNode {
+ MultiKeywordSelector(unsigned nKeys) : DeclarationNameExtra(nKeys) {}
+
+public:
+ // Constructor for keyword selectors.
+ MultiKeywordSelector(unsigned nKeys, IdentifierInfo **IIV)
+ : DeclarationNameExtra(nKeys) {
+ assert((nKeys > 1) && "not a multi-keyword selector");
+
+ // Fill in the trailing keyword array.
+ IdentifierInfo **KeyInfo = reinterpret_cast<IdentifierInfo **>(this + 1);
+ for (unsigned i = 0; i != nKeys; ++i)
+ KeyInfo[i] = IIV[i];
+ }
+
+ // getName - Derive the full selector name and return it.
+ std::string getName() const;
+
+ using DeclarationNameExtra::getNumArgs;
+
+ using keyword_iterator = IdentifierInfo *const *;
+
+ keyword_iterator keyword_begin() const {
+ return reinterpret_cast<keyword_iterator>(this + 1);
+ }
+
+ keyword_iterator keyword_end() const {
+ return keyword_begin() + getNumArgs();
+ }
+
+ IdentifierInfo *getIdentifierInfoForSlot(unsigned i) const {
+ assert(i < getNumArgs() && "getIdentifierInfoForSlot(): illegal index");
+ return keyword_begin()[i];
+ }
+
+ static void Profile(llvm::FoldingSetNodeID &ID, keyword_iterator ArgTys,
+ unsigned NumArgs) {
+ ID.AddInteger(NumArgs);
+ for (unsigned i = 0; i != NumArgs; ++i)
+ ID.AddPointer(ArgTys[i]);
+ }
+
+ void Profile(llvm::FoldingSetNodeID &ID) {
+ Profile(ID, keyword_begin(), getNumArgs());
+ }
+};
+
/// Smart pointer class that efficiently represents Objective-C method
/// names.
///
@@ -690,43 +945,58 @@ class Selector {
enum IdentifierInfoFlag {
// Empty selector = 0. Note that these enumeration values must
// correspond to the enumeration values of DeclarationName::StoredNameKind
- ZeroArg = 0x01,
- OneArg = 0x02,
+ ZeroArg = 0x01,
+ OneArg = 0x02,
+ // IMPORTANT NOTE: see comments in InfoPtr (below) about this enumerator
+ // value.
MultiArg = 0x07,
- ArgFlags = 0x07
};
- /// A pointer to the MultiKeywordSelector or IdentifierInfo. We use the low
- /// three bits of InfoPtr to store an IdentifierInfoFlag. Note that in any
- /// case IdentifierInfo and MultiKeywordSelector are already aligned to
- /// 8 bytes even on 32 bits archs because of DeclarationName.
- uintptr_t InfoPtr = 0;
+ /// IMPORTANT NOTE: the order of the types in this PointerUnion are
+ /// important! The DeclarationName class has bidirectional conversion
+ /// to/from Selector through an opaque pointer (void *) which corresponds
+ /// to this PointerIntPair. The discriminator bit from the PointerUnion
+ /// corresponds to the high bit in the MultiArg enumerator. So while this
+ /// PointerIntPair only has two bits for the integer (and we mask off the
+ /// high bit in `MultiArg` when it is used), that discrimator bit is
+ /// still necessary for the opaque conversion. The discriminator bit
+ /// from the PointerUnion and the two integer bits from the
+ /// PointerIntPair are also exposed via the DeclarationName::StoredNameKind
+ /// enumeration; see the comments in DeclarationName.h for more details.
+ /// Do not reorder or add any arguments to this template
+ /// without thoroughly understanding how tightly coupled these classes are.
+ llvm::PointerIntPair<
+ llvm::PointerUnion<IdentifierInfo *, MultiKeywordSelector *>, 2>
+ InfoPtr;
Selector(IdentifierInfo *II, unsigned nArgs) {
- InfoPtr = reinterpret_cast<uintptr_t>(II);
- assert((InfoPtr & ArgFlags) == 0 &&"Insufficiently aligned IdentifierInfo");
assert(nArgs < 2 && "nArgs not equal to 0/1");
- InfoPtr |= nArgs+1;
+ InfoPtr.setPointerAndInt(II, nArgs + 1);
}
Selector(MultiKeywordSelector *SI) {
- InfoPtr = reinterpret_cast<uintptr_t>(SI);
- assert((InfoPtr & ArgFlags) == 0 &&"Insufficiently aligned IdentifierInfo");
- InfoPtr |= MultiArg;
+ // IMPORTANT NOTE: we mask off the upper bit of this value because we only
+ // reserve two bits for the integer in the PointerIntPair. See the comments
+ // in `InfoPtr` for more details.
+ InfoPtr.setPointerAndInt(SI, MultiArg & 0b11);
}
IdentifierInfo *getAsIdentifierInfo() const {
- if (getIdentifierInfoFlag() < MultiArg)
- return reinterpret_cast<IdentifierInfo *>(InfoPtr & ~ArgFlags);
- return nullptr;
+ return InfoPtr.getPointer().dyn_cast<IdentifierInfo *>();
}
MultiKeywordSelector *getMultiKeywordSelector() const {
- return reinterpret_cast<MultiKeywordSelector *>(InfoPtr & ~ArgFlags);
+ return InfoPtr.getPointer().get<MultiKeywordSelector *>();
}
unsigned getIdentifierInfoFlag() const {
- return InfoPtr & ArgFlags;
+ unsigned new_flags = InfoPtr.getInt();
+ // IMPORTANT NOTE: We have to reconstitute this data rather than use the
+ // value directly from the PointerIntPair. See the comments in `InfoPtr`
+ // for more details.
+ if (InfoPtr.getPointer().is<MultiKeywordSelector *>())
+ new_flags |= MultiArg;
+ return new_flags;
}
static ObjCMethodFamily getMethodFamilyImpl(Selector sel);
@@ -737,31 +1007,27 @@ public:
/// The default ctor should only be used when creating data structures that
/// will contain selectors.
Selector() = default;
- explicit Selector(uintptr_t V) : InfoPtr(V) {}
+ explicit Selector(uintptr_t V) {
+ InfoPtr.setFromOpaqueValue(reinterpret_cast<void *>(V));
+ }
/// operator==/!= - Indicate whether the specified selectors are identical.
bool operator==(Selector RHS) const {
- return InfoPtr == RHS.InfoPtr;
+ return InfoPtr.getOpaqueValue() == RHS.InfoPtr.getOpaqueValue();
}
bool operator!=(Selector RHS) const {
- return InfoPtr != RHS.InfoPtr;
+ return InfoPtr.getOpaqueValue() != RHS.InfoPtr.getOpaqueValue();
}
- void *getAsOpaquePtr() const {
- return reinterpret_cast<void*>(InfoPtr);
- }
+ void *getAsOpaquePtr() const { return InfoPtr.getOpaqueValue(); }
/// Determine whether this is the empty selector.
- bool isNull() const { return InfoPtr == 0; }
+ bool isNull() const { return InfoPtr.getOpaqueValue() == nullptr; }
// Predicates to identify the selector type.
- bool isKeywordSelector() const {
- return getIdentifierInfoFlag() != ZeroArg;
- }
+ bool isKeywordSelector() const { return InfoPtr.getInt() != ZeroArg; }
- bool isUnarySelector() const {
- return getIdentifierInfoFlag() == ZeroArg;
- }
+ bool isUnarySelector() const { return InfoPtr.getInt() == ZeroArg; }
/// If this selector is the specific keyword selector described by Names.
bool isKeywordSelector(ArrayRef<StringRef> Names) const;
@@ -872,68 +1138,6 @@ public:
static std::string getPropertyNameFromSetterSelector(Selector Sel);
};
-namespace detail {
-
-/// DeclarationNameExtra is used as a base of various uncommon special names.
-/// This class is needed since DeclarationName has not enough space to store
-/// the kind of every possible names. Therefore the kind of common names is
-/// stored directly in DeclarationName, and the kind of uncommon names is
-/// stored in DeclarationNameExtra. It is aligned to 8 bytes because
-/// DeclarationName needs the lower 3 bits to store the kind of common names.
-/// DeclarationNameExtra is tightly coupled to DeclarationName and any change
-/// here is very likely to require changes in DeclarationName(Table).
-class alignas(IdentifierInfoAlignment) DeclarationNameExtra {
- friend class clang::DeclarationName;
- friend class clang::DeclarationNameTable;
-
-protected:
- /// The kind of "extra" information stored in the DeclarationName. See
- /// @c ExtraKindOrNumArgs for an explanation of how these enumerator values
- /// are used. Note that DeclarationName depends on the numerical values
- /// of the enumerators in this enum. See DeclarationName::StoredNameKind
- /// for more info.
- enum ExtraKind {
- CXXDeductionGuideName,
- CXXLiteralOperatorName,
- CXXUsingDirective,
- ObjCMultiArgSelector
- };
-
- /// ExtraKindOrNumArgs has one of the following meaning:
- /// * The kind of an uncommon C++ special name. This DeclarationNameExtra
- /// is in this case in fact either a CXXDeductionGuideNameExtra or
- /// a CXXLiteralOperatorIdName.
- ///
- /// * It may be also name common to C++ using-directives (CXXUsingDirective),
- ///
- /// * Otherwise it is ObjCMultiArgSelector+NumArgs, where NumArgs is
- /// the number of arguments in the Objective-C selector, in which
- /// case the DeclarationNameExtra is also a MultiKeywordSelector.
- unsigned ExtraKindOrNumArgs;
-
- DeclarationNameExtra(ExtraKind Kind) : ExtraKindOrNumArgs(Kind) {}
- DeclarationNameExtra(unsigned NumArgs)
- : ExtraKindOrNumArgs(ObjCMultiArgSelector + NumArgs) {}
-
- /// Return the corresponding ExtraKind.
- ExtraKind getKind() const {
- return static_cast<ExtraKind>(ExtraKindOrNumArgs >
- (unsigned)ObjCMultiArgSelector
- ? (unsigned)ObjCMultiArgSelector
- : ExtraKindOrNumArgs);
- }
-
- /// Return the number of arguments in an ObjC selector. Only valid when this
- /// is indeed an ObjCMultiArgSelector.
- unsigned getNumArgs() const {
- assert(ExtraKindOrNumArgs >= (unsigned)ObjCMultiArgSelector &&
- "getNumArgs called but this is not an ObjC selector!");
- return ExtraKindOrNumArgs - (unsigned)ObjCMultiArgSelector;
- }
-};
-
-} // namespace detail
-
} // namespace clang
namespace llvm {
@@ -970,34 +1174,6 @@ struct PointerLikeTypeTraits<clang::Selector> {
static constexpr int NumLowBitsAvailable = 0;
};
-// Provide PointerLikeTypeTraits for IdentifierInfo pointers, which
-// are not guaranteed to be 8-byte aligned.
-template<>
-struct PointerLikeTypeTraits<clang::IdentifierInfo*> {
- static void *getAsVoidPointer(clang::IdentifierInfo* P) {
- return P;
- }
-
- static clang::IdentifierInfo *getFromVoidPointer(void *P) {
- return static_cast<clang::IdentifierInfo*>(P);
- }
-
- static constexpr int NumLowBitsAvailable = 1;
-};
-
-template<>
-struct PointerLikeTypeTraits<const clang::IdentifierInfo*> {
- static const void *getAsVoidPointer(const clang::IdentifierInfo* P) {
- return P;
- }
-
- static const clang::IdentifierInfo *getFromVoidPointer(const void *P) {
- return static_cast<const clang::IdentifierInfo*>(P);
- }
-
- static constexpr int NumLowBitsAvailable = 1;
-};
-
} // namespace llvm
#endif // LLVM_CLANG_BASIC_IDENTIFIERTABLE_H
diff --git a/contrib/llvm-project/clang/include/clang/Basic/JsonSupport.h b/contrib/llvm-project/clang/include/clang/Basic/JsonSupport.h
index 8b02e440df44..bcaa3d364444 100644
--- a/contrib/llvm-project/clang/include/clang/Basic/JsonSupport.h
+++ b/contrib/llvm-project/clang/include/clang/Basic/JsonSupport.h
@@ -12,6 +12,7 @@
#include "clang/Basic/LLVM.h"
#include "clang/Basic/SourceManager.h"
#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Path.h"
#include "llvm/Support/raw_ostream.h"
#include <iterator>
@@ -70,7 +71,7 @@ inline std::string JsonFormat(StringRef RawSR, bool AddQuotes) {
}
// Remove new-lines.
- Str.erase(std::remove(Str.begin(), Str.end(), '\n'), Str.end());
+ llvm::erase(Str, '\n');
if (!AddQuotes)
return Str;
@@ -98,18 +99,15 @@ inline void printSourceLocationAsJson(raw_ostream &Out, SourceLocation Loc,
if (AddBraces)
Out << "{ ";
std::string filename(PLoc.getFilename());
-#ifdef _WIN32
- // Remove forbidden Windows path characters
- auto RemoveIt =
- std::remove_if(filename.begin(), filename.end(), [](auto Char) {
- static const char ForbiddenChars[] = "<>*?\"|";
- return std::find(std::begin(ForbiddenChars), std::end(ForbiddenChars),
- Char) != std::end(ForbiddenChars);
- });
- filename.erase(RemoveIt, filename.end());
- // Handle windows-specific path delimiters.
- std::replace(filename.begin(), filename.end(), '\\', '/');
-#endif
+ if (is_style_windows(llvm::sys::path::Style::native)) {
+ // Remove forbidden Windows path characters
+ llvm::erase_if(filename, [](auto Char) {
+ static const char ForbiddenChars[] = "<>*?\"|";
+ return llvm::is_contained(ForbiddenChars, Char);
+ });
+ // Handle windows-specific path delimiters.
+ std::replace(filename.begin(), filename.end(), '\\', '/');
+ }
Out << "\"line\": " << PLoc.getLine()
<< ", \"column\": " << PLoc.getColumn()
<< ", \"file\": \"" << filename << "\"";
diff --git a/contrib/llvm-project/clang/include/clang/Basic/LLVM.h b/contrib/llvm-project/clang/include/clang/Basic/LLVM.h
index 4ac2d744af3c..f4956cd16cbc 100644
--- a/contrib/llvm-project/clang/include/clang/Basic/LLVM.h
+++ b/contrib/llvm-project/clang/include/clang/Basic/LLVM.h
@@ -19,9 +19,6 @@
// dependencies.
// Casting.h has complex templates that cannot be easily forward declared.
#include "llvm/Support/Casting.h"
-// None.h includes an enumerator that is desired & cannot be forward declared
-// without a definition of NoneType.
-#include "llvm/ADT/None.h"
// Add this header as a workaround to prevent `too few template arguments for
// class template 'SmallVector'` building error with build compilers like XL.
#include "llvm/ADT/SmallVector.h"
@@ -37,7 +34,6 @@ namespace llvm {
template<unsigned InternalLen> class SmallString;
template<typename T, unsigned N> class SmallVector;
template<typename T> class SmallVectorImpl;
- template<typename T> class Optional;
template <class T> class Expected;
template<typename T>
@@ -58,16 +54,17 @@ namespace clang {
// Casting operators.
using llvm::isa;
using llvm::isa_and_nonnull;
+ using llvm::isa_and_present;
using llvm::cast;
using llvm::dyn_cast;
using llvm::dyn_cast_or_null;
+ using llvm::dyn_cast_if_present;
using llvm::cast_or_null;
+ using llvm::cast_if_present;
// ADT's.
using llvm::ArrayRef;
using llvm::MutableArrayRef;
- using llvm::None;
- using llvm::Optional;
using llvm::OwningArrayRef;
using llvm::SaveAndRestore;
using llvm::SmallString;
diff --git a/contrib/llvm-project/clang/include/clang/Basic/Lambda.h b/contrib/llvm-project/clang/include/clang/Basic/Lambda.h
index 853821a33c2a..de01d6f33c01 100644
--- a/contrib/llvm-project/clang/include/clang/Basic/Lambda.h
+++ b/contrib/llvm-project/clang/include/clang/Basic/Lambda.h
@@ -32,7 +32,7 @@ enum LambdaCaptureDefault {
/// is an expression.
enum LambdaCaptureKind {
LCK_This, ///< Capturing the \c *this object by reference
- LCK_StarThis, /// < Capturing the \c *this object by copy
+ LCK_StarThis, ///< Capturing the \c *this object by copy
LCK_ByCopy, ///< Capturing by copy (a.k.a., by value)
LCK_ByRef, ///< Capturing by reference
LCK_VLAType ///< Capturing variable-length array type
diff --git a/contrib/llvm-project/clang/include/clang/Basic/LangOptions.def b/contrib/llvm-project/clang/include/clang/Basic/LangOptions.def
index 74deba6ef7fb..4942dcaa086e 100644
--- a/contrib/llvm-project/clang/include/clang/Basic/LangOptions.def
+++ b/contrib/llvm-project/clang/include/clang/Basic/LangOptions.def
@@ -7,7 +7,11 @@
//===----------------------------------------------------------------------===//
//
// This file defines the language options. Users of this file must
-// define the LANGOPT macro to make use of this information.
+// define the LANGOPT macro to make use of this information. The arguments to
+// the macro are:
+// LANGOPT(Name, Bits, DefaultValue, Description)
+// Note that the DefaultValue must be a constant value (literal or enumeration);
+// it cannot depend on the value of another language option.
//
// Optionally, the user may also define:
//
@@ -82,8 +86,9 @@
LANGOPT(C99 , 1, 0, "C99")
LANGOPT(C11 , 1, 0, "C11")
LANGOPT(C17 , 1, 0, "C17")
-LANGOPT(C2x , 1, 0, "C2x")
+LANGOPT(C23 , 1, 0, "C23")
LANGOPT(MSVCCompat , 1, 0, "Microsoft Visual C++ full compatibility mode")
+LANGOPT(Kernel , 1, 0, "Kernel mode")
LANGOPT(MicrosoftExt , 1, 0, "Microsoft C++ extensions")
LANGOPT(AsmBlocks , 1, 0, "Microsoft inline asm blocks")
LANGOPT(Borland , 1, 0, "Borland extensions")
@@ -92,7 +97,8 @@ LANGOPT(CPlusPlus11 , 1, 0, "C++11")
LANGOPT(CPlusPlus14 , 1, 0, "C++14")
LANGOPT(CPlusPlus17 , 1, 0, "C++17")
LANGOPT(CPlusPlus20 , 1, 0, "C++20")
-LANGOPT(CPlusPlus2b , 1, 0, "C++2b")
+LANGOPT(CPlusPlus23 , 1, 0, "C++23")
+LANGOPT(CPlusPlus26 , 1, 0, "C++26")
LANGOPT(ObjC , 1, 0, "Objective-C")
BENIGN_LANGOPT(ObjCDefaultSynthProperties , 1, 0,
"Objective-C auto-synthesized properties")
@@ -107,7 +113,7 @@ LANGOPT(Trigraphs , 1, 0,"trigraphs")
LANGOPT(LineComment , 1, 0, "'//' comments")
LANGOPT(Bool , 1, 0, "bool, true, and false keywords")
LANGOPT(Half , 1, 0, "half keyword")
-LANGOPT(WChar , 1, CPlusPlus, "wchar_t keyword")
+LANGOPT(WChar , 1, 0, "wchar_t keyword")
LANGOPT(Char8 , 1, 0, "char8_t keyword")
LANGOPT(IEEE128 , 1, 0, "__ieee128 keyword")
LANGOPT(DeclSpecKeyword , 1, 0, "__declspec keyword")
@@ -116,9 +122,9 @@ BENIGN_LANGOPT(AsmPreprocessor, 1, 0, "preprocessor in asm mode")
LANGOPT(GNUMode , 1, 1, "GNU extensions")
LANGOPT(GNUKeywords , 1, 1, "GNU keywords")
VALUE_LANGOPT(GNUCVersion , 32, 0, "GNU C compatibility version")
-BENIGN_LANGOPT(ImplicitInt, 1, !C99 && !CPlusPlus, "C89 implicit 'int'")
+LANGOPT(DisableKNRFunctions, 1, 0, "require function types to have a prototype")
LANGOPT(Digraphs , 1, 0, "digraphs")
-BENIGN_LANGOPT(HexFloats , 1, C99, "C99 hexadecimal float constants")
+BENIGN_LANGOPT(HexFloats , 1, 0, "C99 hexadecimal float constants")
LANGOPT(CXXOperatorNames , 1, 0, "C++ operator name keywords")
LANGOPT(AppleKext , 1, 0, "Apple kext support")
BENIGN_LANGOPT(PascalStrings, 1, 0, "Pascal string support")
@@ -139,17 +145,21 @@ ENUM_LANGOPT(ExceptionHandling, ExceptionHandlingKind, 3,
ExceptionHandlingKind::None, "exception handling")
LANGOPT(IgnoreExceptions , 1, 0, "ignore exceptions")
LANGOPT(ExternCNoUnwind , 1, 0, "Assume extern C functions don't unwind")
+LANGOPT(AssumeNothrowExceptionDtor , 1, 0, "Assume exception object's destructor is nothrow")
LANGOPT(TraditionalCPP , 1, 0, "traditional CPP emulation")
LANGOPT(RTTI , 1, 1, "run-time type information")
LANGOPT(RTTIData , 1, 1, "emit run-time type information data")
LANGOPT(MSBitfields , 1, 0, "Microsoft-compatible structure layout")
+LANGOPT(MSVolatile , 1, 0, "Microsoft-compatible volatile loads and stores")
LANGOPT(Freestanding, 1, 0, "freestanding implementation")
LANGOPT(NoBuiltin , 1, 0, "disable builtin functions")
LANGOPT(NoMathBuiltin , 1, 0, "disable math builtin functions")
LANGOPT(GNUAsm , 1, 1, "GNU-style inline assembly")
LANGOPT(Coroutines , 1, 0, "C++20 coroutines")
+LANGOPT(CoroAlignedAllocation, 1, 0, "prefer Aligned Allocation according to P2014 Option 2")
LANGOPT(DllExportInlines , 1, 1, "dllexported classes dllexport inline methods")
LANGOPT(RelaxedTemplateTemplateArgs, 1, 0, "C++17 relaxed matching of template template arguments")
+LANGOPT(ExperimentalLibrary, 1, 0, "enable unstable and experimental library features")
LANGOPT(DoubleSquareBracketAttributes, 1, 0, "'[[]]' attributes extension for all language standard modes")
@@ -163,9 +173,10 @@ BENIGN_LANGOPT(EmitAllDecls , 1, 0, "emitting all declarations")
LANGOPT(MathErrno , 1, 1, "errno in math functions")
BENIGN_LANGOPT(HeinousExtensions , 1, 0, "extensions that we really don't like and may be ripped out at any time")
LANGOPT(Modules , 1, 0, "modules semantics")
-COMPATIBLE_LANGOPT(ModulesTS , 1, 0, "C++ Modules TS syntax")
COMPATIBLE_LANGOPT(CPlusPlusModules, 1, 0, "C++ modules syntax")
-BENIGN_ENUM_LANGOPT(CompilingModule, CompilingModuleKind, 2, CMK_None,
+LANGOPT(SkipODRCheckInGMF, 1, 0, "Skip ODR checks for decls in the global module fragment")
+LANGOPT(BuiltinHeadersInSystemModules, 1, 0, "builtin headers belong to system modules, and _Builtin_ modules are ignored for cstdlib headers")
+BENIGN_ENUM_LANGOPT(CompilingModule, CompilingModuleKind, 3, CMK_None,
"compiling a module interface")
BENIGN_LANGOPT(CompilingPCH, 1, 0, "building a pch")
BENIGN_LANGOPT(BuildingPCHWithObjectFile, 1, 0, "building a pch which has a corresponding object file")
@@ -174,6 +185,7 @@ BENIGN_LANGOPT(PCHInstantiateTemplates, 1, 0, "instantiate templates while build
COMPATIBLE_LANGOPT(ModulesDeclUse , 1, 0, "require declaration of module uses")
BENIGN_LANGOPT(ModulesSearchAll , 1, 1, "searching even non-imported modules to find unresolved references")
COMPATIBLE_LANGOPT(ModulesStrictDeclUse, 1, 0, "requiring declaration of module uses and all headers to be in modules")
+COMPATIBLE_LANGOPT(ModulesValidateTextualHeaderIncludes, 1, 1, "validation of textual header includes")
BENIGN_LANGOPT(ModulesErrorRecovery, 1, 1, "automatically importing modules as needed when performing error recovery")
BENIGN_LANGOPT(ImplicitModules, 1, 1, "building modules that are not specified via -fmodule-file")
COMPATIBLE_LANGOPT(ModulesLocalVisibility, 1, 0, "local submodule visibility")
@@ -189,6 +201,7 @@ VALUE_LANGOPT(DoubleSize , 32, 0, "width of double")
VALUE_LANGOPT(LongDoubleSize , 32, 0, "width of long double")
LANGOPT(PPCIEEELongDouble , 1, 0, "use IEEE 754 quadruple-precision for long double")
LANGOPT(EnableAIXExtendedAltivecABI , 1, 0, "__EXTABI__ predefined macro")
+LANGOPT(EnableAIXQuadwordAtomicsABI , 1, 0, "Use 16-byte atomic lock free semantics")
COMPATIBLE_VALUE_LANGOPT(PICLevel , 2, 0, "__PIC__ level")
COMPATIBLE_VALUE_LANGOPT(PIE , 1, 0, "is pie")
LANGOPT(ROPI , 1, 0, "Read-only position independence")
@@ -208,6 +221,8 @@ BENIGN_LANGOPT(NoSignedZero , 1, 0, "Permit Floating Point optimization wit
BENIGN_LANGOPT(AllowRecip , 1, 0, "Permit Floating Point reciprocal")
BENIGN_LANGOPT(ApproxFunc , 1, 0, "Permit Floating Point approximation")
+ENUM_LANGOPT(ComplexRange, ComplexRangeKind, 2, CX_None, "Enable use of range reduction for complex arithmetics.")
+
BENIGN_LANGOPT(ObjCGCBitmapPrint , 1, 0, "printing of GC's bitmap layout for __weak/__strong ivars")
BENIGN_LANGOPT(AccessControl , 1, 1, "C++ access control")
@@ -227,44 +242,59 @@ LANGOPT(OpenCLGenericAddressSpace, 1, 0, "OpenCL generic keyword")
LANGOPT(OpenCLPipes , 1, 0, "OpenCL pipes language constructs and built-ins")
LANGOPT(NativeHalfType , 1, 0, "Native half type support")
LANGOPT(NativeHalfArgsAndReturns, 1, 0, "Native half args and returns")
-LANGOPT(HalfArgsAndReturns, 1, 0, "half args and returns")
LANGOPT(CUDA , 1, 0, "CUDA")
LANGOPT(HIP , 1, 0, "HIP")
LANGOPT(OpenMP , 32, 0, "OpenMP support and version of OpenMP (31, 40 or 45)")
+LANGOPT(OpenMPExtensions , 1, 1, "Enable all Clang extensions for OpenMP directives and clauses")
LANGOPT(OpenMPSimd , 1, 0, "Use SIMD only OpenMP support.")
LANGOPT(OpenMPUseTLS , 1, 0, "Use TLS for threadprivates or runtime calls")
-LANGOPT(OpenMPIsDevice , 1, 0, "Generate code only for OpenMP target device")
+LANGOPT(OpenMPIsTargetDevice , 1, 0, "Generate code only for OpenMP target device")
LANGOPT(OpenMPCUDAMode , 1, 0, "Generate code for OpenMP pragmas in SIMT/SPMD mode")
LANGOPT(OpenMPIRBuilder , 1, 0, "Use the experimental OpenMP-IR-Builder codegen path.")
-LANGOPT(OpenMPCUDAForceFullRuntime , 1, 0, "Force to use full runtime in all constructs when offloading to CUDA devices")
LANGOPT(OpenMPCUDANumSMs , 32, 0, "Number of SMs for CUDA devices.")
LANGOPT(OpenMPCUDABlocksPerSM , 32, 0, "Number of blocks per SM for CUDA devices.")
LANGOPT(OpenMPCUDAReductionBufNum , 32, 1024, "Number of the reduction records in the intermediate reduction buffer used for the teams reductions.")
-LANGOPT(OpenMPTargetNewRuntime , 1, 0, "Use the new bitcode library for OpenMP offloading")
+LANGOPT(OpenMPTargetDebug , 32, 0, "Enable debugging in the OpenMP offloading device RTL")
LANGOPT(OpenMPOptimisticCollapse , 1, 0, "Use at most 32 bits to represent the collapsed loop nest counter.")
+LANGOPT(OpenMPThreadSubscription , 1, 0, "Assume work-shared loops do not have more iterations than participating threads.")
+LANGOPT(OpenMPTeamSubscription , 1, 0, "Assume distributed loops do not have more iterations than participating teams.")
+LANGOPT(OpenMPNoThreadState , 1, 0, "Assume that no thread in a parallel region will modify an ICV.")
+LANGOPT(OpenMPNoNestedParallelism , 1, 0, "Assume that no thread in a parallel region will encounter a parallel region")
+LANGOPT(OpenMPOffloadMandatory , 1, 0, "Assert that offloading is mandatory and do not create a host fallback.")
+LANGOPT(OpenMPForceUSM , 1, 0, "Enable OpenMP unified shared memory mode via compiler.")
+LANGOPT(NoGPULib , 1, 0, "Indicate a build without the standard GPU libraries.")
LANGOPT(RenderScript , 1, 0, "RenderScript")
+LANGOPT(HLSL, 1, 0, "HLSL")
+ENUM_LANGOPT(HLSLVersion, HLSLLangStd, 16, HLSL_Unset, "HLSL Version")
+
LANGOPT(CUDAIsDevice , 1, 0, "compiling for CUDA device")
LANGOPT(CUDAAllowVariadicFunctions, 1, 0, "allowing variadic functions in CUDA device code")
LANGOPT(CUDAHostDeviceConstexpr, 1, 1, "treating unattributed constexpr functions as __host__ __device__")
-LANGOPT(CUDADeviceApproxTranscendentals, 1, 0, "using approximate transcendental functions")
+LANGOPT(GPUDeviceApproxTranscendentals, 1, 0, "using approximate transcendental functions")
LANGOPT(GPURelocatableDeviceCode, 1, 0, "generate relocatable device code")
+LANGOPT(OffloadImplicitHostDeviceTemplates, 1, 0, "assume template functions to be implicitly host device by default for CUDA/HIP")
LANGOPT(GPUAllowDeviceInit, 1, 0, "allowing device side global init functions for HIP")
LANGOPT(GPUMaxThreadsPerBlock, 32, 1024, "default max threads per block for kernel launch bounds for HIP")
LANGOPT(GPUDeferDiag, 1, 0, "defer host/device related diagnostic messages for CUDA/HIP")
LANGOPT(GPUExcludeWrongSideOverloads, 1, 0, "always exclude wrong side overloads in overloading resolution for CUDA/HIP")
+LANGOPT(OffloadingNewDriver, 1, 0, "use the new driver for generating offloading code.")
LANGOPT(SYCLIsDevice , 1, 0, "Generate code for SYCL device")
LANGOPT(SYCLIsHost , 1, 0, "SYCL host compilation")
ENUM_LANGOPT(SYCLVersion , SYCLMajorVersion, 2, SYCL_None, "Version of the SYCL standard used")
LANGOPT(HIPUseNewLaunchAPI, 1, 0, "Use new kernel launching API for HIP")
+LANGOPT(OffloadUniformBlock, 1, 0, "Assume that kernels are launched with uniform block sizes (default true for CUDA/HIP and false otherwise)")
+LANGOPT(HIPStdPar, 1, 0, "Enable Standard Parallel Algorithm Acceleration for HIP (experimental)")
+LANGOPT(HIPStdParInterposeAlloc, 1, 0, "Replace allocations / deallocations with HIP RT calls when Standard Parallel Algorithm Acceleration for HIP is enabled (Experimental)")
+
+LANGOPT(OpenACC , 1, 0, "OpenACC Enabled")
LANGOPT(SizedDeallocation , 1, 0, "sized deallocation")
LANGOPT(AlignedAllocation , 1, 0, "aligned allocation")
LANGOPT(AlignedAllocationUnavailable, 1, 0, "aligned allocation functions are unavailable")
LANGOPT(NewAlignOverride , 32, 0, "maximum alignment guaranteed by '::operator new(size_t)'")
-LANGOPT(ConceptSatisfactionCaching , 1, 1, "enable satisfaction caching for C++20 Concepts")
BENIGN_LANGOPT(ModulesCodegen , 1, 0, "Modules code generation")
BENIGN_LANGOPT(ModulesDebugInfo , 1, 0, "Modules debug info")
BENIGN_LANGOPT(ElideConstructors , 1, 1, "C++ copy constructor elision")
@@ -275,11 +305,14 @@ BENIGN_LANGOPT(DumpRecordLayoutsComplete , 1, 0, "dumping the AST layout of all
BENIGN_LANGOPT(DumpVTableLayouts , 1, 0, "dumping the layouts of emitted vtables")
LANGOPT(NoConstantCFStrings , 1, 0, "no constant CoreFoundation strings")
BENIGN_LANGOPT(InlineVisibilityHidden , 1, 0, "hidden visibility for inline C++ methods")
+BENIGN_ENUM_LANGOPT(DefaultVisibilityExportMapping, DefaultVisiblityExportMapping, 2, DefaultVisiblityExportMapping::None, "controls mapping of default visibility to dllexport")
BENIGN_LANGOPT(IgnoreXCOFFVisibility, 1, 0, "All the visibility attributes that are specified in the source code are ignored in aix XCOFF.")
BENIGN_LANGOPT(VisibilityInlinesHiddenStaticLocalVar, 1, 0,
"hidden visibility for static local variables in inline C++ "
"methods when -fvisibility-inlines hidden is enabled")
-LANGOPT(GlobalAllocationFunctionVisibilityHidden , 1, 0, "hidden visibility for global operator new and delete declaration")
+ENUM_LANGOPT(GlobalAllocationFunctionVisibility, VisibilityForcedKinds, 3, VisibilityForcedKinds::ForceDefault,
+ "How to apply visibility to global operator new and delete declarations")
+LANGOPT(NewInfallible , 1, 0, "Treats throwing global C++ operator new as always returning valid memory (annotates with __attribute__((returns_nonnull)) and throw()). This is detectable in source.")
BENIGN_LANGOPT(ParseUnknownAnytype, 1, 0, "__unknown_anytype")
BENIGN_LANGOPT(DebuggerSupport , 1, 0, "debugger support")
BENIGN_LANGOPT(DebuggerCastResultToId, 1, 0, "for 'po' in the debugger, cast the result to id if it is of unknown type")
@@ -294,8 +327,11 @@ COMPATIBLE_LANGOPT(CLFiniteMathOnly , 1, 0, "__FINITE_MATH_ONLY__ predefined mac
/// FP_CONTRACT mode (on/off/fast).
BENIGN_ENUM_LANGOPT(DefaultFPContractMode, FPModeKind, 2, FPM_Off, "FP contraction type")
COMPATIBLE_LANGOPT(ExpStrictFP, 1, false, "Enable experimental strict floating point")
-BENIGN_ENUM_LANGOPT(FPRoundingMode, RoundingMode, 3, RoundingMode::NearestTiesToEven, "FP Rounding Mode type")
-BENIGN_ENUM_LANGOPT(FPExceptionMode, FPExceptionModeKind, 2, FPE_Ignore, "FP Exception Behavior Mode type")
+BENIGN_LANGOPT(RoundingMath, 1, false, "Do not assume default floating-point rounding behavior")
+BENIGN_ENUM_LANGOPT(FPExceptionMode, FPExceptionModeKind, 2, FPE_Default, "FP Exception Behavior Mode type")
+BENIGN_ENUM_LANGOPT(FPEvalMethod, FPEvalMethodKind, 2, FEM_UnsetOnCommandLine, "FP type used for floating point arithmetic")
+ENUM_LANGOPT(Float16ExcessPrecision, ExcessPrecisionKind, 2, FPP_Standard, "Intermediate truncation behavior for Float16 arithmetic")
+ENUM_LANGOPT(BFloat16ExcessPrecision, ExcessPrecisionKind, 2, FPP_Standard, "Intermediate truncation behavior for BFloat16 arithmetic")
LANGOPT(NoBitFieldTypeAlign , 1, 0, "bit-field type alignment")
LANGOPT(HexagonQdsp6Compat , 1, 0, "hexagon-qdsp6 backward compatibility")
LANGOPT(ObjCAutoRefCount , 1, 0, "Objective-C automated reference counting")
@@ -320,22 +356,22 @@ LANGOPT(
"type's inheritance model would be determined under the Microsoft ABI")
ENUM_LANGOPT(GC, GCMode, 2, NonGC, "Objective-C Garbage Collection mode")
-ENUM_LANGOPT(ValueVisibilityMode, Visibility, 3, DefaultVisibility,
+BENIGN_ENUM_LANGOPT(ValueVisibilityMode, Visibility, 3, DefaultVisibility,
"default visibility for functions and variables [-fvisibility]")
-ENUM_LANGOPT(TypeVisibilityMode, Visibility, 3, DefaultVisibility,
+BENIGN_ENUM_LANGOPT(TypeVisibilityMode, Visibility, 3, DefaultVisibility,
"default visibility for types [-ftype-visibility]")
LANGOPT(SetVisibilityForExternDecls, 1, 0,
"apply global symbol visibility to external declarations without an explicit visibility")
-LANGOPT(VisibilityFromDLLStorageClass, 1, 0,
- "set the visiblity of globals from their DLL storage class [-fvisibility-from-dllstorageclass]")
-ENUM_LANGOPT(DLLExportVisibility, Visibility, 3, DefaultVisibility,
- "visibility for functions and variables with dllexport annotations [-fvisibility-from-dllstorageclass]")
-ENUM_LANGOPT(NoDLLStorageClassVisibility, Visibility, 3, HiddenVisibility,
- "visibility for functions and variables without an explicit DLL storage class [-fvisibility-from-dllstorageclass]")
-ENUM_LANGOPT(ExternDeclDLLImportVisibility, Visibility, 3, DefaultVisibility,
- "visibility for external declarations with dllimport annotations [-fvisibility-from-dllstorageclass]")
-ENUM_LANGOPT(ExternDeclNoDLLStorageClassVisibility, Visibility, 3, HiddenVisibility,
- "visibility for external declarations without an explicit DLL storage class [-fvisibility-from-dllstorageclass]")
+BENIGN_LANGOPT(VisibilityFromDLLStorageClass, 1, 0,
+ "override the visibility of globals based on their final DLL storage class [-fvisibility-from-dllstorageclass]")
+BENIGN_ENUM_LANGOPT(DLLExportVisibility, VisibilityFromDLLStorageClassKinds, 3, VisibilityFromDLLStorageClassKinds::Default,
+ "how to adjust the visibility for functions and variables with dllexport annotations [-fvisibility-dllexport]")
+BENIGN_ENUM_LANGOPT(NoDLLStorageClassVisibility, VisibilityFromDLLStorageClassKinds, 3, VisibilityFromDLLStorageClassKinds::Hidden,
+ "how to adjust the visibility for functions and variables without an explicit DLL storage class [-fvisibility-nodllstorageclass]")
+BENIGN_ENUM_LANGOPT(ExternDeclDLLImportVisibility, VisibilityFromDLLStorageClassKinds, 3, VisibilityFromDLLStorageClassKinds::Default,
+ "how to adjust the visibility for external declarations with dllimport annotations [-fvisibility-externs-dllimport]")
+BENIGN_ENUM_LANGOPT(ExternDeclNoDLLStorageClassVisibility, VisibilityFromDLLStorageClassKinds, 3, VisibilityFromDLLStorageClassKinds::Hidden,
+ "how to adjust the visibility for external declarations without an explicit DLL storage class [-fvisibility-externs-nodllstorageclass]")
BENIGN_LANGOPT(SemanticInterposition , 1, 0, "semantic interposition")
BENIGN_LANGOPT(HalfNoSemanticInterposition, 1, 0,
"Like -fno-semantic-interposition but don't use local aliases")
@@ -345,6 +381,8 @@ ENUM_LANGOPT(TrivialAutoVarInit, TrivialAutoVarInitKind, 2, TrivialAutoVarInitKi
"trivial automatic variable initialization")
VALUE_LANGOPT(TrivialAutoVarInitStopAfter, 32, 0,
"stop trivial automatic variable initialization after the specified number of instances. Must be greater than 0.")
+VALUE_LANGOPT(TrivialAutoVarInitMaxSize, 32, 0,
+ "stop trivial automatic variable initialization if var size exceeds the specified size (in bytes). Must be greater than 0.")
ENUM_LANGOPT(SignedOverflowBehavior, SignedOverflowBehaviorTy, 2, SOB_Undefined,
"signed integer overflow handling")
ENUM_LANGOPT(ThreadModel , ThreadModelKind, 2, ThreadModelKind::POSIX, "Thread Model")
@@ -373,6 +411,9 @@ LANGOPT(XLPragmaPack, 1, 0, "IBM XL #pragma pack handling")
LANGOPT(RetainCommentsFromSystemHeaders, 1, 0, "retain documentation comments from system headers in the AST")
+LANGOPT(APINotes, 1, 0, "use external API notes")
+LANGOPT(APINotesModules, 1, 0, "use module-based external API notes")
+
LANGOPT(SanitizeAddressFieldPadding, 2, 0, "controls how aggressive is ASan "
"field padding (0: none, 1:least "
"aggressive, 2: more aggressive)")
@@ -397,6 +438,7 @@ ENUM_LANGOPT(ClangABICompat, ClangABI, 4, ClangABI::Latest,
"with")
COMPATIBLE_VALUE_LANGOPT(FunctionAlignment, 5, 0, "Default alignment for functions")
+COMPATIBLE_VALUE_LANGOPT(LoopAlignment, 32, 0, "Default alignment for loops")
LANGOPT(FixedPoint, 1, 0, "fixed point types")
LANGOPT(PaddingOnUnsignedFixedPoint, 1, 0,
@@ -404,8 +446,14 @@ LANGOPT(PaddingOnUnsignedFixedPoint, 1, 0,
LANGOPT(RegisterStaticDestructors, 1, 1, "Register C++ static destructors")
+LANGOPT(RegCall4, 1, 0, "Set __regcall4 as a default calling convention to respect __regcall ABI v.4")
+
LANGOPT(MatrixTypes, 1, 0, "Enable or disable the builtin matrix type")
+ENUM_LANGOPT(StrictFlexArraysLevel, StrictFlexArraysLevelKind, 2,
+ StrictFlexArraysLevelKind::Default,
+ "Rely on strict definition of flexible arrays")
+
COMPATIBLE_VALUE_LANGOPT(MaxTokens, 32, 0, "Max number of tokens per TU or 0")
ENUM_LANGOPT(SignReturnAddressScope, SignReturnAddressScopeKind, 2, SignReturnAddressScopeKind::None,
@@ -413,18 +461,38 @@ ENUM_LANGOPT(SignReturnAddressScope, SignReturnAddressScopeKind, 2, SignReturnAd
ENUM_LANGOPT(SignReturnAddressKey, SignReturnAddressKeyKind, 1, SignReturnAddressKeyKind::AKey,
"Key used for return address signing")
LANGOPT(BranchTargetEnforcement, 1, 0, "Branch-target enforcement enabled")
+LANGOPT(BranchProtectionPAuthLR, 1, 0, "Use PC as a diversifier using PAuthLR NOP instructions.")
+LANGOPT(GuardedControlStack, 1, 0, "Guarded control stack enabled")
LANGOPT(SpeculativeLoadHardening, 1, 0, "Speculative load hardening enabled")
LANGOPT(RelativeCXXABIVTables, 1, 0,
"Use an ABI-incompatible v-table layout that uses relative references")
-LANGOPT(ArmSveVectorBits, 32, 0, "SVE vector size in bits")
+LANGOPT(OmitVTableRTTI, 1, 0,
+ "Use an ABI-incompatible v-table layout that omits the RTTI component")
-ENUM_LANGOPT(ExtendIntArgs, ExtendArgsKind, 1, ExtendArgsKind::ExtendTo32,
+LANGOPT(VScaleMin, 32, 0, "Minimum vscale value")
+LANGOPT(VScaleMax, 32, 0, "Maximum vscale value")
+
+ENUM_LANGOPT(ExtendIntArgs, ExtendArgsKind, 1, ExtendArgsKind::ExtendTo32,
"Controls how scalar integer arguments are extended in calls "
"to unprototyped and varargs functions")
+VALUE_LANGOPT(FuchsiaAPILevel, 32, 0, "Fuchsia API level")
+
+// This option will be removed in the future once the backend
+// supports all operations (like division or float-to-integer conversion)
+// on large _BitInts.
+BENIGN_VALUE_LANGOPT(MaxBitIntWidth, 32, 128, "Maximum width of a _BitInt")
+
+LANGOPT(IncrementalExtensions, 1, 0, " True if we want to process statements"
+ "on the global scope, ignore EOF token and continue later on (thus "
+ "avoid tearing the Lexer and etc. down). Controlled by "
+ "-fincremental-extensions.")
+
+BENIGN_LANGOPT(CheckNew, 1, 0, "Do not assume C++ operator new may not return NULL")
+
#undef LANGOPT
#undef COMPATIBLE_LANGOPT
#undef BENIGN_LANGOPT
diff --git a/contrib/llvm-project/clang/include/clang/Basic/LangOptions.h b/contrib/llvm-project/clang/include/clang/Basic/LangOptions.h
index b60b94a1ba08..c1cc5548ef10 100644
--- a/contrib/llvm-project/clang/include/clang/Basic/LangOptions.h
+++ b/contrib/llvm-project/clang/include/clang/Basic/LangOptions.h
@@ -23,7 +23,8 @@
#include "clang/Basic/Visibility.h"
#include "llvm/ADT/FloatingPointMode.h"
#include "llvm/ADT/StringRef.h"
-#include "llvm/ADT/Triple.h"
+#include "llvm/TargetParser/Triple.h"
+#include <optional>
#include <string>
#include <vector>
@@ -33,6 +34,7 @@ namespace clang {
/// this large collection of bitfields is a trivial class type.
class LangOptionsBase {
friend class CompilerInvocation;
+ friend class CompilerInvocationBase;
public:
// Define simple language options (with no accessors).
@@ -53,6 +55,29 @@ protected:
/// members used to implement virtual inheritance.
enum class MSVtorDispMode { Never, ForVBaseOverride, ForVFTable };
+/// Shader programs run in specific pipeline stages.
+/// The order of these values matters, and must be kept in sync with the
+/// Triple Environment enum in llvm::Triple. The ordering is enforced in
+/// static_asserts in Triple.cpp and in clang/Basic/HLSLRuntime.h.
+enum class ShaderStage {
+ Pixel = 0,
+ Vertex,
+ Geometry,
+ Hull,
+ Domain,
+ Compute,
+ Library,
+ RayGeneration,
+ Intersection,
+ AnyHit,
+ ClosestHit,
+ Miss,
+ Callable,
+ Mesh,
+ Amplification,
+ Invalid,
+};
+
/// Keeps track of the various options that can be
/// enabled, which controls the dialect of C or C++ that is accepted.
class LangOptions : public LangOptionsBase {
@@ -87,10 +112,10 @@ public:
/// Compiling a module from a module map.
CMK_ModuleMap,
- /// Compiling a module from a list of header files.
- CMK_HeaderModule,
+ /// Compiling a module header unit.
+ CMK_HeaderUnit,
- /// Compiling a C++ modules TS module interface unit.
+ /// Compiling a C++ modules interface unit.
CMK_ModuleInterface,
};
@@ -109,7 +134,8 @@ public:
DCC_FastCall,
DCC_StdCall,
DCC_VectorCall,
- DCC_RegCall
+ DCC_RegCall,
+ DCC_RtdCall
};
enum AddrSpaceMapMangling { ASMM_Target, ASMM_On, ASMM_Off };
@@ -124,7 +150,9 @@ public:
MSVC2017_5 = 1912,
MSVC2017_7 = 1914,
MSVC2019 = 1920,
+ MSVC2019_5 = 1925,
MSVC2019_8 = 1928,
+ MSVC2022_3 = 1933,
};
enum SYCLMajorVersion {
@@ -136,6 +164,16 @@ public:
SYCL_Default = SYCL_2020
};
+ enum HLSLLangStd {
+ HLSL_Unset = 0,
+ HLSL_2015 = 2015,
+ HLSL_2016 = 2016,
+ HLSL_2017 = 2017,
+ HLSL_2018 = 2018,
+ HLSL_2021 = 2021,
+ HLSL_202x = 2029,
+ };
+
/// Clang versions with different platform ABI conformance.
enum class ClangABI {
/// Attempt to be ABI-compatible with code generated by Clang 3.8.x
@@ -180,6 +218,30 @@ public:
/// global-scope inline variables incorrectly.
Ver12,
+ /// Attempt to be ABI-compatible with code generated by Clang 14.0.x.
+ /// This causes clang to:
+ /// - mangle dependent nested names incorrectly.
+ /// - make trivial only those defaulted copy constructors with a
+ /// parameter-type-list equivalent to the parameter-type-list of an
+ /// implicit declaration.
+ Ver14,
+
+ /// Attempt to be ABI-compatible with code generated by Clang 15.0.x.
+ /// This causes clang to:
+ /// - Reverse the implementation for DR692, DR1395 and DR1432.
+ /// - pack non-POD members of packed structs.
+ /// - consider classes with defaulted special member functions non-pod.
+ Ver15,
+
+ /// Attempt to be ABI-compatible with code generated by Clang 17.0.x.
+ /// This causes clang to revert some fixes to its implementation of the
+ /// Itanium name mangling scheme, with the consequence that overloaded
+ /// function templates are mangled the same if they differ only by:
+ /// - constraints
+ /// - whether a non-type template parameter has a deduced type
+ /// - the parameter list of a template template parameter
+ Ver17,
+
/// Conform to the underlying platform's C and C++ ABIs as closely
/// as we can.
Latest
@@ -216,10 +278,6 @@ public:
FPM_FastHonorPragmas
};
- /// Alias for RoundingMode::NearestTiesToEven.
- static constexpr unsigned FPR_ToNearest =
- static_cast<unsigned>(llvm::RoundingMode::NearestTiesToEven);
-
/// Possible floating point exception behavior.
enum FPExceptionModeKind {
/// Assume that floating-point exceptions are masked.
@@ -227,9 +285,31 @@ public:
/// Transformations do not cause new exceptions but may hide some.
FPE_MayTrap,
/// Strictly preserve the floating-point exception semantics.
- FPE_Strict
+ FPE_Strict,
+ /// Used internally to represent initial unspecified value.
+ FPE_Default
+ };
+
+ /// Possible float expression evaluation method choices.
+ enum FPEvalMethodKind {
+ /// The evaluation method cannot be determined or is inconsistent for this
+ /// target.
+ FEM_Indeterminable = -1,
+ /// Use the declared type for fp arithmetic.
+ FEM_Source = 0,
+ /// Use the type double for fp arithmetic.
+ FEM_Double = 1,
+ /// Use extended type for fp arithmetic.
+ FEM_Extended = 2,
+ /// Used only for FE option processing; this is only used to indicate that
+ /// the user did not specify an explicit evaluation method on the command
+ /// line and so the target should be queried for its default evaluation
+ /// method instead.
+ FEM_UnsetOnCommandLine = 3
};
+ enum ExcessPrecisionKind { FPP_Standard, FPP_Fast, FPP_None };
+
/// Possible exception handling behavior.
enum class ExceptionHandlingKind { None, SjLj, WinEH, DwarfCFI, Wasm };
@@ -286,6 +366,56 @@ public:
ExtendTo64
};
+ enum class GPUDefaultStreamKind {
+ /// Legacy default stream
+ Legacy,
+ /// Per-thread default stream
+ PerThread,
+ };
+
+ enum class DefaultVisiblityExportMapping {
+ None,
+ /// map only explicit default visibilities to exported
+ Explicit,
+ /// map all default visibilities to exported
+ All,
+ };
+
+ enum class VisibilityForcedKinds {
+ /// Force hidden visibility
+ ForceHidden,
+ /// Force protected visibility
+ ForceProtected,
+ /// Force default visibility
+ ForceDefault,
+ /// Don't alter the visibility
+ Source,
+ };
+
+ enum class VisibilityFromDLLStorageClassKinds {
+ /// Keep the IR-gen assigned visibility.
+ Keep,
+ /// Override the IR-gen assigned visibility with default visibility.
+ Default,
+ /// Override the IR-gen assigned visibility with hidden visibility.
+ Hidden,
+ /// Override the IR-gen assigned visibility with protected visibility.
+ Protected,
+ };
+
+ enum class StrictFlexArraysLevelKind {
+ /// Any trailing array member is a FAM.
+ Default = 0,
+ /// Any trailing array member of undefined, 0, or 1 size is a FAM.
+ OneZeroOrIncomplete = 1,
+ /// Any trailing array member of undefined or 0 size is a FAM.
+ ZeroOrIncomplete = 2,
+ /// Any trailing array member of undefined size is a FAM.
+ IncompleteOnly = 3,
+ };
+
+ enum ComplexRangeKind { CX_Full, CX_Limited, CX_Fortran, CX_None };
+
public:
/// The used language standard.
LangStandard::Kind LangStd;
@@ -373,14 +503,51 @@ public:
/// C++ ABI to compile with, if specified by the frontend through -fc++-abi=.
/// This overrides the default ABI used by the target.
- llvm::Optional<TargetCXXABI::Kind> CXXABI;
+ std::optional<TargetCXXABI::Kind> CXXABI;
/// Indicates whether the front-end is explicitly told that the
/// input is a header file (i.e. -x c-header).
bool IsHeaderFile = false;
+ /// The default stream kind used for HIP kernel launching.
+ GPUDefaultStreamKind GPUDefaultStream;
+
+ /// The seed used by the randomize structure layout feature.
+ std::string RandstructSeed;
+
+ /// Indicates whether to use target's platform-specific file separator when
+ /// __FILE__ macro is used and when concatenating filename with directory or
+ /// to use build environment environment's platform-specific file separator.
+ ///
+ /// The plaform-specific path separator is the backslash(\) for Windows and
+ /// forward slash (/) elsewhere.
+ bool UseTargetPathSeparator = false;
+
+ // Indicates whether we should keep all nullptr checks for pointers
+ // received as a result of a standard operator new (-fcheck-new)
+ bool CheckNew = false;
+
+ // In OpenACC mode, contains a user provided override for the _OPENACC macro.
+ // This exists so that we can override the macro value and test our incomplete
+ // implementation on real-world examples.
+ std::string OpenACCMacroOverride;
+
LangOptions();
+ /// Set language defaults for the given input language and
+ /// language standard in the given LangOptions object.
+ ///
+ /// \param Opts - The LangOptions object to set up.
+ /// \param Lang - The input language.
+ /// \param T - The target triple.
+ /// \param Includes - If the language requires extra headers to be implicitly
+ /// included, they will be appended to this list.
+ /// \param LangStd - The input language standard.
+ static void
+ setLangDefaults(LangOptions &Opts, Language Lang, const llvm::Triple &T,
+ std::vector<std::string> &Includes,
+ LangStandard::Kind LangStd = LangStandard::lang_unspecified);
+
// Define accessors/mutators for language options of enumeration type.
#define LANGOPT(Name, Bits, Default, Description)
#define ENUM_LANGOPT(Name, Type, Bits, Default, Description) \
@@ -388,11 +555,21 @@ public:
void set##Name(Type Value) { Name = static_cast<unsigned>(Value); }
#include "clang/Basic/LangOptions.def"
- /// Are we compiling a module interface (.cppm or module map)?
+ /// Are we compiling a module?
bool isCompilingModule() const {
return getCompilingModule() != CMK_None;
}
+ /// Are we compiling a standard c++ module interface?
+ bool isCompilingModuleInterface() const {
+ return getCompilingModule() == CMK_ModuleInterface;
+ }
+
+ /// Are we compiling a module implementation?
+ bool isCompilingModuleImplementation() const {
+ return !isCompilingModule() && !ModuleName.empty();
+ }
+
/// Do we need to track the owning module for a local declaration?
bool trackLocalOwningModule() const {
return isCompilingModule() || ModulesLocalVisibility;
@@ -431,6 +608,34 @@ public:
/// Return the OpenCL C or C++ version as a VersionTuple.
VersionTuple getOpenCLVersionTuple() const;
+ /// Return the OpenCL version that kernel language is compatible with
+ unsigned getOpenCLCompatibleVersion() const;
+
+ /// Return the OpenCL C or C++ for OpenCL language name and version
+ /// as a string.
+ std::string getOpenCLVersionString() const;
+
+ /// Returns true if functions without prototypes or functions with an
+ /// identifier list (aka K&R C functions) are not allowed.
+ bool requiresStrictPrototypes() const {
+ return CPlusPlus || C23 || DisableKNRFunctions;
+ }
+
+ /// Returns true if implicit function declarations are allowed in the current
+ /// language mode.
+ bool implicitFunctionsAllowed() const {
+ return !requiresStrictPrototypes() && !OpenCL;
+ }
+
+ /// Returns true if the language supports calling the 'atexit' function.
+ bool hasAtExit() const { return !(OpenMP && OpenMPIsTargetDevice); }
+
+ /// Returns true if implicit int is part of the language requirements.
+ bool isImplicitIntRequired() const { return !CPlusPlus && !C99; }
+
+ /// Returns true if implicit int is supported at all.
+ bool isImplicitIntAllowed() const { return !CPlusPlus && !C23; }
+
/// Check if return address signing is enabled.
bool hasSignReturnAddress() const {
return getSignReturnAddressScope() != SignReturnAddressScopeKind::None;
@@ -464,8 +669,55 @@ public:
bool isSYCL() const { return SYCLIsDevice || SYCLIsHost; }
+ bool hasDefaultVisibilityExportMapping() const {
+ return getDefaultVisibilityExportMapping() !=
+ DefaultVisiblityExportMapping::None;
+ }
+
+ bool isExplicitDefaultVisibilityExportMapping() const {
+ return getDefaultVisibilityExportMapping() ==
+ DefaultVisiblityExportMapping::Explicit;
+ }
+
+ bool isAllDefaultVisibilityExportMapping() const {
+ return getDefaultVisibilityExportMapping() ==
+ DefaultVisiblityExportMapping::All;
+ }
+
+ bool hasGlobalAllocationFunctionVisibility() const {
+ return getGlobalAllocationFunctionVisibility() !=
+ VisibilityForcedKinds::Source;
+ }
+
+ bool hasDefaultGlobalAllocationFunctionVisibility() const {
+ return getGlobalAllocationFunctionVisibility() ==
+ VisibilityForcedKinds::ForceDefault;
+ }
+
+ bool hasProtectedGlobalAllocationFunctionVisibility() const {
+ return getGlobalAllocationFunctionVisibility() ==
+ VisibilityForcedKinds::ForceProtected;
+ }
+
+ bool hasHiddenGlobalAllocationFunctionVisibility() const {
+ return getGlobalAllocationFunctionVisibility() ==
+ VisibilityForcedKinds::ForceHidden;
+ }
+
/// Remap path prefix according to -fmacro-prefix-path option.
- void remapPathPrefix(SmallString<256> &Path) const;
+ void remapPathPrefix(SmallVectorImpl<char> &Path) const;
+
+ RoundingMode getDefaultRoundingMode() const {
+ return RoundingMath ? RoundingMode::Dynamic
+ : RoundingMode::NearestTiesToEven;
+ }
+
+ FPExceptionModeKind getDefaultExceptionMode() const {
+ FPExceptionModeKind EM = getFPExceptionMode();
+ if (EM == FPExceptionModeKind::FPE_Default)
+ return FPExceptionModeKind::FPE_Ignore;
+ return EM;
+ }
};
/// Floating point control options
@@ -473,7 +725,7 @@ class FPOptionsOverride;
class FPOptions {
public:
// We start by defining the layout.
- using storage_type = uint16_t;
+ using storage_type = uint32_t;
using RoundingMode = llvm::RoundingMode;
@@ -499,11 +751,13 @@ public:
private:
storage_type Value;
+ FPOptionsOverride getChangesSlow(const FPOptions &Base) const;
+
public:
FPOptions() : Value(0) {
setFPContractMode(LangOptions::FPM_Off);
- setRoundingMode(static_cast<RoundingMode>(LangOptions::FPR_ToNearest));
- setFPExceptionMode(LangOptions::FPE_Ignore);
+ setConstRoundingMode(RoundingMode::Dynamic);
+ setSpecifiedExceptionMode(LangOptions::FPE_Default);
}
explicit FPOptions(const LangOptions &LO) {
Value = 0;
@@ -514,8 +768,9 @@ public:
if (LangOptContractMode == LangOptions::FPM_FastHonorPragmas)
LangOptContractMode = LangOptions::FPM_Fast;
setFPContractMode(LangOptContractMode);
- setRoundingMode(LO.getFPRoundingMode());
- setFPExceptionMode(LO.getFPExceptionMode());
+ setRoundingMath(LO.RoundingMath);
+ setConstRoundingMode(LangOptions::RoundingMode::Dynamic);
+ setSpecifiedExceptionMode(LO.getFPExceptionMode());
setAllowFPReassociate(LO.AllowFPReassoc);
setNoHonorNaNs(LO.NoHonorNaNs);
setNoHonorInfs(LO.NoHonorInfs);
@@ -524,12 +779,13 @@ public:
setAllowApproxFunc(LO.ApproxFunc);
if (getFPContractMode() == LangOptions::FPM_On &&
getRoundingMode() == llvm::RoundingMode::Dynamic &&
- getFPExceptionMode() == LangOptions::FPE_Strict)
+ getExceptionMode() == LangOptions::FPE_Strict)
// If the FP settings are set to the "strict" model, then
// FENV access is set to true. (ffp-model=strict)
setAllowFEnvAccess(true);
else
setAllowFEnvAccess(LangOptions::FPM_Off);
+ setComplexRange(LO.getComplexRange());
}
bool allowFPContractWithinStatement() const {
@@ -548,10 +804,33 @@ public:
bool isFPConstrained() const {
return getRoundingMode() != llvm::RoundingMode::NearestTiesToEven ||
- getFPExceptionMode() != LangOptions::FPE_Ignore ||
+ getExceptionMode() != LangOptions::FPE_Ignore ||
getAllowFEnvAccess();
}
+ RoundingMode getRoundingMode() const {
+ RoundingMode RM = getConstRoundingMode();
+ if (RM == RoundingMode::Dynamic) {
+ // C23: 7.6.2p3 If the FE_DYNAMIC mode is specified and FENV_ACCESS is
+ // "off", the translator may assume that the default rounding mode is in
+ // effect.
+ if (!getAllowFEnvAccess() && !getRoundingMath())
+ RM = RoundingMode::NearestTiesToEven;
+ }
+ return RM;
+ }
+
+ LangOptions::FPExceptionModeKind getExceptionMode() const {
+ LangOptions::FPExceptionModeKind EM = getSpecifiedExceptionMode();
+ if (EM == LangOptions::FPExceptionModeKind::FPE_Default) {
+ if (getAllowFEnvAccess())
+ return LangOptions::FPExceptionModeKind::FPE_Strict;
+ else
+ return LangOptions::FPExceptionModeKind::FPE_Ignore;
+ }
+ return EM;
+ }
+
bool operator==(FPOptions other) const { return Value == other.Value; }
/// Return the default value of FPOptions that's used when trailing
@@ -565,6 +844,9 @@ public:
return Opts;
}
+ /// Return difference with the given option set.
+ FPOptionsOverride getChangesFrom(const FPOptions &Base) const;
+
// We can define most of the accessors automatically:
#define OPTION(NAME, TYPE, WIDTH, PREVIOUS) \
TYPE get##NAME() const { \
@@ -599,7 +881,7 @@ public:
/// The type suitable for storing values of FPOptionsOverride. Must be twice
/// as wide as bit size of FPOption.
- using storage_type = uint32_t;
+ using storage_type = uint64_t;
static_assert(sizeof(storage_type) >= 2 * sizeof(FPOptions::storage_type),
"Too short type for FPOptionsOverride");
@@ -613,6 +895,8 @@ public:
: Options(LO), OverrideMask(OverrideMaskBits) {}
FPOptionsOverride(FPOptions FPO)
: Options(FPO), OverrideMask(OverrideMaskBits) {}
+ FPOptionsOverride(FPOptions FPO, FPOptions::storage_type Mask)
+ : Options(FPO), OverrideMask(Mask) {}
bool requiresTrailingStorage() const { return OverrideMask != 0; }
@@ -635,6 +919,7 @@ public:
setNoSignedZeroOverride(!Value);
setAllowReciprocalOverride(!Value);
setAllowApproxFuncOverride(!Value);
+ setMathErrnoOverride(Value);
if (Value)
/* Precise mode implies fp_contract=on and disables ffast-math */
setAllowFPContractWithinStatement();
@@ -693,6 +978,12 @@ public:
LLVM_DUMP_METHOD void dump();
};
+inline FPOptionsOverride FPOptions::getChangesFrom(const FPOptions &Base) const {
+ if (Value == Base.Value)
+ return FPOptionsOverride();
+ return getChangesSlow(Base);
+}
+
/// Describes the kind of translation unit being processed.
enum TranslationUnitKind {
/// The translation unit is a complete translation unit.
diff --git a/contrib/llvm-project/clang/include/clang/Basic/LangStandard.h b/contrib/llvm-project/clang/include/clang/Basic/LangStandard.h
index b0785409628c..bc49669a82ad 100644
--- a/contrib/llvm-project/clang/include/clang/Basic/LangStandard.h
+++ b/contrib/llvm-project/clang/include/clang/Basic/LangStandard.h
@@ -12,6 +12,10 @@
#include "clang/Basic/LLVM.h"
#include "llvm/ADT/StringRef.h"
+namespace llvm {
+class Triple;
+}
+
namespace clang {
/// The language for the input, used to select and validate the language
@@ -36,26 +40,29 @@ enum class Language : uint8_t {
CUDA,
RenderScript,
HIP,
+ HLSL,
///@}
};
+StringRef languageToString(Language L);
enum LangFeatures {
LineComment = (1 << 0),
C99 = (1 << 1),
C11 = (1 << 2),
C17 = (1 << 3),
- C2x = (1 << 4),
+ C23 = (1 << 4),
CPlusPlus = (1 << 5),
CPlusPlus11 = (1 << 6),
CPlusPlus14 = (1 << 7),
CPlusPlus17 = (1 << 8),
CPlusPlus20 = (1 << 9),
- CPlusPlus2b = (1 << 10),
- Digraphs = (1 << 11),
- GNUMode = (1 << 12),
- HexFloat = (1 << 13),
- ImplicitInt = (1 << 14),
- OpenCL = (1 << 15)
+ CPlusPlus23 = (1 << 10),
+ CPlusPlus26 = (1 << 11),
+ Digraphs = (1 << 12),
+ GNUMode = (1 << 13),
+ HexFloat = (1 << 14),
+ OpenCL = (1 << 15),
+ HLSL = (1 << 16)
};
/// LangStandard - Information about the properties of a particular language
@@ -95,8 +102,8 @@ public:
/// isC17 - Language is a superset of C17.
bool isC17() const { return Flags & C17; }
- /// isC2x - Language is a superset of C2x.
- bool isC2x() const { return Flags & C2x; }
+ /// isC23 - Language is a superset of C23.
+ bool isC23() const { return Flags & C23; }
/// isCPlusPlus - Language is a C++ variant.
bool isCPlusPlus() const { return Flags & CPlusPlus; }
@@ -113,8 +120,11 @@ public:
/// isCPlusPlus20 - Language is a C++20 variant (or later).
bool isCPlusPlus20() const { return Flags & CPlusPlus20; }
- /// isCPlusPlus2b - Language is a post-C++20 variant (or later).
- bool isCPlusPlus2b() const { return Flags & CPlusPlus2b; }
+ /// isCPlusPlus23 - Language is a post-C++23 variant (or later).
+ bool isCPlusPlus23() const { return Flags & CPlusPlus23; }
+
+ /// isCPlusPlus26 - Language is a post-C++26 variant (or later).
+ bool isCPlusPlus26() const { return Flags & CPlusPlus26; }
/// hasDigraphs - Language supports digraphs.
bool hasDigraphs() const { return Flags & Digraphs; }
@@ -125,9 +135,6 @@ public:
/// hasHexFloats - Language supports hexadecimal float constants.
bool hasHexFloats() const { return Flags & HexFloat; }
- /// hasImplicitInt - Language allows variables to be typed as int implicitly.
- bool hasImplicitInt() const { return Flags & ImplicitInt; }
-
/// isOpenCL - Language is a OpenCL variant.
bool isOpenCL() const { return Flags & OpenCL; }
@@ -136,6 +143,9 @@ public:
static const LangStandard *getLangStandardForName(StringRef Name);
};
+LangStandard::Kind getDefaultLanguageStandard(clang::Language Lang,
+ const llvm::Triple &T);
+
} // end namespace clang
#endif
diff --git a/contrib/llvm-project/clang/include/clang/Basic/LangStandards.def b/contrib/llvm-project/clang/include/clang/Basic/LangStandards.def
index 2cfeb68e56d6..b6192e48efc1 100644
--- a/contrib/llvm-project/clang/include/clang/Basic/LangStandards.def
+++ b/contrib/llvm-project/clang/include/clang/Basic/LangStandards.def
@@ -17,7 +17,7 @@
/// \param LANG - The Language for which this is a standard.
/// \param DESC - A short description of the standard.
/// \param FEATURES - The standard features as flags, these are enums from the
-/// clang::frontend namespace, which is assumed to be be available.
+/// clang::frontend namespace, which is assumed to be available.
/// LANGSTANDARD_ALIAS(IDENT, ALIAS)
/// \param IDENT - The name of the standard as a C++ identifier.
@@ -36,18 +36,17 @@
// C89-ish modes.
LANGSTANDARD(c89, "c89",
- C, "ISO C 1990",
- ImplicitInt)
+ C, "ISO C 1990", 0)
LANGSTANDARD_ALIAS(c89, "c90")
LANGSTANDARD_ALIAS(c89, "iso9899:1990")
LANGSTANDARD(c94, "iso9899:199409",
C, "ISO C 1990 with amendment 1",
- Digraphs | ImplicitInt)
+ Digraphs)
LANGSTANDARD(gnu89, "gnu89",
C, "ISO C 1990 with GNU extensions",
- LineComment | Digraphs | GNUMode | ImplicitInt)
+ LineComment | Digraphs | GNUMode)
LANGSTANDARD_ALIAS(gnu89, "gnu90")
// C99-ish modes
@@ -88,13 +87,17 @@ LANGSTANDARD(gnu17, "gnu17",
LineComment | C99 | C11 | C17 | Digraphs | GNUMode | HexFloat)
LANGSTANDARD_ALIAS(gnu17, "gnu18")
-// C2x modes
-LANGSTANDARD(c2x, "c2x",
- C, "Working Draft for ISO C2x",
- LineComment | C99 | C11 | C17 | C2x | Digraphs | HexFloat)
-LANGSTANDARD(gnu2x, "gnu2x",
- C, "Working Draft for ISO C2x with GNU extensions",
- LineComment | C99 | C11 | C17 | C2x | Digraphs | GNUMode | HexFloat)
+// C23 modes
+LANGSTANDARD(c23, "c23",
+ C, "Working Draft for ISO C23",
+ LineComment | C99 | C11 | C17 | C23 | Digraphs | HexFloat)
+LANGSTANDARD_ALIAS_DEPR(c23, "c2x")
+LANGSTANDARD(gnu23, "gnu23",
+ C, "Working Draft for ISO C23 with GNU extensions",
+ LineComment | C99 | C11 | C17 | C23 | Digraphs | GNUMode | HexFloat)
+LANGSTANDARD_ALIAS_DEPR(gnu23, "gnu2x")
+// FIXME: Add the alias for iso9899:202* once we know the year ISO publishes
+// the document (expected to be 2024).
// C++ modes
LANGSTANDARD(cxx98, "c++98",
@@ -152,15 +155,29 @@ LANGSTANDARD(gnucxx20, "gnu++20",
CPlusPlus20 | Digraphs | HexFloat | GNUMode)
LANGSTANDARD_ALIAS_DEPR(gnucxx20, "gnu++2a")
-LANGSTANDARD(cxx2b, "c++2b",
- CXX, "Working draft for ISO C++ 2023 DIS",
+LANGSTANDARD(cxx23, "c++23",
+ CXX, "ISO C++ 2023 DIS",
LineComment | CPlusPlus | CPlusPlus11 | CPlusPlus14 | CPlusPlus17 |
- CPlusPlus20 | CPlusPlus2b | Digraphs | HexFloat)
+ CPlusPlus20 | CPlusPlus23 | Digraphs | HexFloat)
+LANGSTANDARD_ALIAS_DEPR(cxx23, "c++2b")
-LANGSTANDARD(gnucxx2b, "gnu++2b",
- CXX, "Working draft for ISO C++ 2023 DIS with GNU extensions",
+LANGSTANDARD(gnucxx23, "gnu++23",
+ CXX, "ISO C++ 2023 DIS with GNU extensions",
LineComment | CPlusPlus | CPlusPlus11 | CPlusPlus14 | CPlusPlus17 |
- CPlusPlus20 | CPlusPlus2b | Digraphs | HexFloat | GNUMode)
+ CPlusPlus20 | CPlusPlus23 | Digraphs | HexFloat | GNUMode)
+LANGSTANDARD_ALIAS_DEPR(gnucxx23, "gnu++2b")
+
+LANGSTANDARD(cxx26, "c++2c",
+ CXX, "Working draft for C++2c",
+ LineComment | CPlusPlus | CPlusPlus11 | CPlusPlus14 | CPlusPlus17 |
+ CPlusPlus20 | CPlusPlus23 | CPlusPlus26 | Digraphs | HexFloat)
+LANGSTANDARD_ALIAS(cxx26, "c++26")
+
+LANGSTANDARD(gnucxx26, "gnu++2c",
+ CXX, "Working draft for C++2c with GNU extensions",
+ LineComment | CPlusPlus | CPlusPlus11 | CPlusPlus14 | CPlusPlus17 |
+ CPlusPlus20 | CPlusPlus23 | CPlusPlus26 | Digraphs | HexFloat | GNUMode)
+LANGSTANDARD_ALIAS(gnucxx26, "gnu++26")
// OpenCL
LANGSTANDARD(opencl10, "cl1.0",
@@ -180,8 +197,15 @@ LANGSTANDARD(opencl20, "cl2.0",
LANGSTANDARD(opencl30, "cl3.0",
OpenCL, "OpenCL 3.0",
LineComment | C99 | Digraphs | HexFloat | OpenCL)
-LANGSTANDARD(openclcpp, "clc++",
- OpenCL, "C++ for OpenCL",
+
+LANGSTANDARD(openclcpp10, "clc++1.0",
+ OpenCL, "C++ for OpenCL 1.0",
+ LineComment | CPlusPlus | CPlusPlus11 | CPlusPlus14 | CPlusPlus17 |
+ Digraphs | HexFloat | OpenCL)
+LANGSTANDARD_ALIAS(openclcpp10, "clc++")
+
+LANGSTANDARD(openclcpp2021, "clc++2021",
+ OpenCL, "C++ for OpenCL 2021",
LineComment | CPlusPlus | CPlusPlus11 | CPlusPlus14 | CPlusPlus17 |
Digraphs | HexFloat | OpenCL)
@@ -190,15 +214,39 @@ LANGSTANDARD_ALIAS_DEPR(opencl11, "CL1.1")
LANGSTANDARD_ALIAS_DEPR(opencl12, "CL1.2")
LANGSTANDARD_ALIAS_DEPR(opencl20, "CL2.0")
LANGSTANDARD_ALIAS_DEPR(opencl30, "CL3.0")
-LANGSTANDARD_ALIAS_DEPR(openclcpp, "CLC++")
+LANGSTANDARD_ALIAS_DEPR(openclcpp10, "CLC++")
+LANGSTANDARD_ALIAS_DEPR(openclcpp10, "CLC++1.0")
+LANGSTANDARD_ALIAS_DEPR(openclcpp2021, "CLC++2021")
-// CUDA
-LANGSTANDARD(cuda, "cuda", CUDA, "NVIDIA CUDA(tm)",
- LineComment | CPlusPlus | CPlusPlus11 | CPlusPlus14 | Digraphs)
+// HLSL
+LANGSTANDARD(hlsl, "hlsl",
+ HLSL, "High Level Shader Language",
+ LineComment | HLSL | CPlusPlus )
+
+LANGSTANDARD(hlsl2015, "hlsl2015",
+ HLSL, "High Level Shader Language 2015",
+ LineComment | HLSL | CPlusPlus )
+
+LANGSTANDARD(hlsl2016, "hlsl2016",
+ HLSL, "High Level Shader Language 2016",
+ LineComment | HLSL | CPlusPlus )
+
+LANGSTANDARD(hlsl2017, "hlsl2017",
+ HLSL, "High Level Shader Language 2017",
+ LineComment | HLSL | CPlusPlus )
+
+LANGSTANDARD(hlsl2018, "hlsl2018",
+ HLSL, "High Level Shader Language 2018",
+ LineComment | HLSL | CPlusPlus )
+
+LANGSTANDARD(hlsl2021, "hlsl2021",
+ HLSL, "High Level Shader Language 2021",
+ LineComment | HLSL | CPlusPlus )
+
+LANGSTANDARD(hlsl202x, "hlsl202x",
+ HLSL, "High Level Shader Language 202x",
+ LineComment | HLSL | CPlusPlus | CPlusPlus11)
-// HIP
-LANGSTANDARD(hip, "hip", HIP, "HIP",
- LineComment | CPlusPlus | CPlusPlus11 | CPlusPlus14 | Digraphs)
#undef LANGSTANDARD
#undef LANGSTANDARD_ALIAS
diff --git a/contrib/llvm-project/clang/include/clang/Basic/Linkage.h b/contrib/llvm-project/clang/include/clang/Basic/Linkage.h
index f4d442c084cf..fcf56b93b978 100644
--- a/contrib/llvm-project/clang/include/clang/Basic/Linkage.h
+++ b/contrib/llvm-project/clang/include/clang/Basic/Linkage.h
@@ -14,21 +14,25 @@
#ifndef LLVM_CLANG_BASIC_LINKAGE_H
#define LLVM_CLANG_BASIC_LINKAGE_H
+#include "llvm/Support/ErrorHandling.h"
#include <utility>
namespace clang {
/// Describes the different kinds of linkage
/// (C++ [basic.link], C99 6.2.2) that an entity may have.
-enum Linkage : unsigned char {
+enum class Linkage : unsigned char {
+ // Linkage hasn't been computed.
+ Invalid = 0,
+
/// No linkage, which means that the entity is unique and
/// can only be referred to from within its scope.
- NoLinkage = 0,
+ None,
/// Internal linkage, which indicates that the entity can
/// be referred to from within the translation unit (but not other
/// translation units).
- InternalLinkage,
+ Internal,
/// External linkage within a unique namespace.
///
@@ -37,26 +41,21 @@ enum Linkage : unsigned char {
/// their names are unique to this translation unit, which is
/// equivalent to having internal linkage from the code-generation
/// point of view.
- UniqueExternalLinkage,
+ UniqueExternal,
/// No linkage according to the standard, but is visible from other
/// translation units because of types defined in a inline function.
- VisibleNoLinkage,
-
- /// Internal linkage according to the Modules TS, but can be referred
- /// to from other translation units indirectly through inline functions and
- /// templates in the module interface.
- ModuleInternalLinkage,
+ VisibleNone,
/// Module linkage, which indicates that the entity can be referred
/// to from other translation units within the same module, and indirectly
/// from arbitrary other translation units through inline functions and
/// templates in the module interface.
- ModuleLinkage,
+ Module,
/// External linkage, which indicates that the entity can
/// be referred to from other translation units.
- ExternalLinkage
+ External
};
/// Describes the different kinds of language linkage
@@ -89,24 +88,34 @@ inline bool isUniqueGVALinkage(GVALinkage L) {
}
inline bool isExternallyVisible(Linkage L) {
- return L >= VisibleNoLinkage;
+ switch (L) {
+ case Linkage::Invalid:
+ llvm_unreachable("Linkage hasn't been computed!");
+ case Linkage::None:
+ case Linkage::Internal:
+ case Linkage::UniqueExternal:
+ return false;
+ case Linkage::VisibleNone:
+ case Linkage::Module:
+ case Linkage::External:
+ return true;
+ }
+ llvm_unreachable("Unhandled Linkage enum");
}
inline Linkage getFormalLinkage(Linkage L) {
switch (L) {
- case UniqueExternalLinkage:
- return ExternalLinkage;
- case VisibleNoLinkage:
- return NoLinkage;
- case ModuleInternalLinkage:
- return InternalLinkage;
+ case Linkage::UniqueExternal:
+ return Linkage::External;
+ case Linkage::VisibleNone:
+ return Linkage::None;
default:
return L;
}
}
inline bool isExternalFormalLinkage(Linkage L) {
- return getFormalLinkage(L) == ExternalLinkage;
+ return getFormalLinkage(L) == Linkage::External;
}
/// Compute the minimum linkage given two linkages.
@@ -118,13 +127,13 @@ inline bool isExternalFormalLinkage(Linkage L) {
/// special cases for when VisibleNoLinkage would lose the visible bit and
/// become NoLinkage.
inline Linkage minLinkage(Linkage L1, Linkage L2) {
- if (L2 == VisibleNoLinkage)
+ if (L2 == Linkage::VisibleNone)
std::swap(L1, L2);
- if (L1 == VisibleNoLinkage) {
- if (L2 == InternalLinkage)
- return NoLinkage;
- if (L2 == UniqueExternalLinkage)
- return NoLinkage;
+ if (L1 == Linkage::VisibleNone) {
+ if (L2 == Linkage::Internal)
+ return Linkage::None;
+ if (L2 == Linkage::UniqueExternal)
+ return Linkage::None;
}
return L1 < L2 ? L1 : L2;
}
diff --git a/contrib/llvm-project/clang/include/clang/Basic/MSP430Target.def b/contrib/llvm-project/clang/include/clang/Basic/MSP430Target.def
index a1e192c19261..7a10be1d54c8 100644
--- a/contrib/llvm-project/clang/include/clang/Basic/MSP430Target.def
+++ b/contrib/llvm-project/clang/include/clang/Basic/MSP430Target.def
@@ -238,8 +238,7 @@ MSP430_MCU_FEAT("msp430f4793", "32bit")
MSP430_MCU_FEAT("msp430f4784", "32bit")
MSP430_MCU_FEAT("msp430f4794", "32bit")
-// Generic MSUs
-MSP430_MCU("msp430")
+// Generic MCUs
MSP430_MCU("msp430i2xxgeneric")
#undef MSP430_MCU
diff --git a/contrib/llvm-project/clang/include/clang/Basic/MakeSupport.h b/contrib/llvm-project/clang/include/clang/Basic/MakeSupport.h
new file mode 100644
index 000000000000..c663014ba7bc
--- /dev/null
+++ b/contrib/llvm-project/clang/include/clang/Basic/MakeSupport.h
@@ -0,0 +1,23 @@
+//===- MakeSupport.h - Make Utilities ---------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_BASIC_MAKESUPPORT_H
+#define LLVM_CLANG_BASIC_MAKESUPPORT_H
+
+#include "clang/Basic/LLVM.h"
+#include "llvm/ADT/StringRef.h"
+
+namespace clang {
+
+/// Quote target names for inclusion in GNU Make dependency files.
+/// Only the characters '$', '#', ' ', '\t' are quoted.
+void quoteMakeTarget(StringRef Target, SmallVectorImpl<char> &Res);
+
+} // namespace clang
+
+#endif // LLVM_CLANG_BASIC_MAKESUPPORT_H
diff --git a/contrib/llvm-project/clang/include/clang/Basic/Module.h b/contrib/llvm-project/clang/include/clang/Basic/Module.h
index 3476b05d2e92..62786e3ac865 100644
--- a/contrib/llvm-project/clang/include/clang/Basic/Module.h
+++ b/contrib/llvm-project/clang/include/clang/Basic/Module.h
@@ -20,7 +20,6 @@
#include "clang/Basic/SourceLocation.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseSet.h"
-#include "llvm/ADT/Optional.h"
#include "llvm/ADT/PointerIntPair.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SetVector.h"
@@ -33,8 +32,10 @@
#include <cstdint>
#include <ctime>
#include <iterator>
+#include <optional>
#include <string>
#include <utility>
+#include <variant>
#include <vector>
namespace llvm {
@@ -71,8 +72,8 @@ struct ASTFileSignature : std::array<uint8_t, 20> {
return Value;
}
- static ASTFileSignature create(StringRef Bytes) {
- return create(Bytes.bytes_begin(), Bytes.bytes_end());
+ static ASTFileSignature create(std::array<uint8_t, 20> Bytes) {
+ return ASTFileSignature(std::move(Bytes));
}
static ASTFileSignature createDISentinel() {
@@ -81,6 +82,12 @@ struct ASTFileSignature : std::array<uint8_t, 20> {
return Sentinel;
}
+ static ASTFileSignature createDummy() {
+ ASTFileSignature Dummy;
+ Dummy.fill(0x00);
+ return Dummy;
+ }
+
template <typename InputIt>
static ASTFileSignature create(InputIt First, InputIt Last) {
assert(std::distance(First, Last) == size &&
@@ -93,7 +100,9 @@ struct ASTFileSignature : std::array<uint8_t, 20> {
};
/// Describes a module or submodule.
-class Module {
+///
+/// Aligned to 8 bytes to allow for llvm::PointerIntPair<Module *, 3>.
+class alignas(8) Module {
public:
/// The name of this module.
std::string Name;
@@ -101,19 +110,40 @@ public:
/// The location of the module definition.
SourceLocation DefinitionLoc;
+ // FIXME: Consider if reducing the size of this enum (having Partition and
+ // Named modules only) then representing interface/implementation separately
+ // is more efficient.
enum ModuleKind {
/// This is a module that was defined by a module map and built out
/// of header files.
ModuleMapModule,
- /// This is a C++ Modules TS module interface unit.
+ /// This is a C++ 20 header unit.
+ ModuleHeaderUnit,
+
+ /// This is a C++20 module interface unit.
ModuleInterfaceUnit,
- /// This is a fragment of the global module within some C++ module.
- GlobalModuleFragment,
+ /// This is a C++20 module implementation unit.
+ ModuleImplementationUnit,
+
+ /// This is a C++ 20 module partition interface.
+ ModulePartitionInterface,
+
+ /// This is a C++ 20 module partition implementation.
+ ModulePartitionImplementation,
+
+ /// This is the explicit Global Module Fragment of a modular TU.
+ /// As per C++ [module.global.frag].
+ ExplicitGlobalModuleFragment,
/// This is the private module fragment within some C++ module.
PrivateModuleFragment,
+
+ /// This is an implicit fragment of the global module which contains
+ /// only language linkage declarations (made in the purview of the
+ /// named module).
+ ImplicitGlobalModuleFragment,
};
/// The kind of this module.
@@ -126,14 +156,14 @@ public:
/// The build directory of this module. This is the directory in
/// which the module is notionally built, and relative to which its headers
/// are found.
- const DirectoryEntry *Directory = nullptr;
+ OptionalDirectoryEntryRef Directory;
/// The presumed file name for the module map defining this module.
/// Only non-empty when building from preprocessed source.
std::string PresumedModuleMapFile;
/// The umbrella header or directory.
- llvm::PointerUnion<const FileEntry *, const DirectoryEntry *> Umbrella;
+ std::variant<std::monostate, FileEntryRef, DirectoryEntryRef> Umbrella;
/// The module signature.
ASTFileSignature Signature;
@@ -148,10 +178,38 @@ public:
/// eventually be exposed, for use in "private" modules.
std::string ExportAsModule;
- /// Does this Module scope describe part of the purview of a named C++ module?
- bool isModulePurview() const {
- return Kind == ModuleInterfaceUnit || Kind == PrivateModuleFragment;
+ /// For the debug info, the path to this module's .apinotes file, if any.
+ std::string APINotesFile;
+
+ /// Does this Module is a named module of a standard named module?
+ bool isNamedModule() const {
+ switch (Kind) {
+ case ModuleInterfaceUnit:
+ case ModuleImplementationUnit:
+ case ModulePartitionInterface:
+ case ModulePartitionImplementation:
+ case PrivateModuleFragment:
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ /// Does this Module scope describe a fragment of the global module within
+ /// some C++ module.
+ bool isGlobalModule() const {
+ return isExplicitGlobalModule() || isImplicitGlobalModule();
}
+ bool isExplicitGlobalModule() const {
+ return Kind == ExplicitGlobalModuleFragment;
+ }
+ bool isImplicitGlobalModule() const {
+ return Kind == ImplicitGlobalModuleFragment;
+ }
+
+ bool isPrivateModule() const { return Kind == PrivateModuleFragment; }
+
+ bool isModuleMapModule() const { return Kind == ModuleMapModule; }
private:
/// The submodules of this module, indexed by name.
@@ -163,10 +221,10 @@ private:
/// The AST file if this is a top-level module which has a
/// corresponding serialized AST file, or null otherwise.
- Optional<FileEntryRef> ASTFile;
+ OptionalFileEntryRef ASTFile;
/// The top-level headers associated with this module.
- llvm::SmallSetVector<const FileEntry *, 2> TopHeaders;
+ llvm::SmallSetVector<FileEntryRef, 2> TopHeaders;
/// top-level header filenames that aren't resolved to FileEntries yet.
std::vector<std::string> TopHeaderNames;
@@ -192,9 +250,7 @@ public:
struct Header {
std::string NameAsWritten;
std::string PathRelativeToRootModuleDirectory;
- const FileEntry *Entry;
-
- explicit operator bool() { return Entry; }
+ FileEntryRef Entry;
};
/// Information about a directory name as found in the module map
@@ -202,9 +258,7 @@ public:
struct DirectoryName {
std::string NameAsWritten;
std::string PathRelativeToRootModuleDirectory;
- const DirectoryEntry *Entry;
-
- explicit operator bool() { return Entry; }
+ DirectoryEntryRef Entry;
};
/// The headers that are part of this module.
@@ -218,8 +272,8 @@ public:
std::string FileName;
bool IsUmbrella = false;
bool HasBuiltinHeader = false;
- Optional<off_t> Size;
- Optional<time_t> ModTime;
+ std::optional<off_t> Size;
+ std::optional<time_t> ModTime;
};
/// Headers that are mentioned in the module map file but that we have not
@@ -246,50 +300,62 @@ public:
/// Whether this module has declared itself unimportable, either because
/// it's missing a requirement from \p Requirements or because it's been
/// shadowed by another module.
+ LLVM_PREFERRED_TYPE(bool)
unsigned IsUnimportable : 1;
/// Whether we tried and failed to load a module file for this module.
+ LLVM_PREFERRED_TYPE(bool)
unsigned HasIncompatibleModuleFile : 1;
/// Whether this module is available in the current translation unit.
///
/// If the module is missing headers or does not meet all requirements then
/// this bit will be 0.
+ LLVM_PREFERRED_TYPE(bool)
unsigned IsAvailable : 1;
/// Whether this module was loaded from a module file.
+ LLVM_PREFERRED_TYPE(bool)
unsigned IsFromModuleFile : 1;
/// Whether this is a framework module.
+ LLVM_PREFERRED_TYPE(bool)
unsigned IsFramework : 1;
/// Whether this is an explicit submodule.
+ LLVM_PREFERRED_TYPE(bool)
unsigned IsExplicit : 1;
/// Whether this is a "system" module (which assumes that all
/// headers in it are system headers).
+ LLVM_PREFERRED_TYPE(bool)
unsigned IsSystem : 1;
/// Whether this is an 'extern "C"' module (which implicitly puts all
/// headers in it within an 'extern "C"' block, and allows the module to be
/// imported within such a block).
+ LLVM_PREFERRED_TYPE(bool)
unsigned IsExternC : 1;
/// Whether this is an inferred submodule (module * { ... }).
+ LLVM_PREFERRED_TYPE(bool)
unsigned IsInferred : 1;
/// Whether we should infer submodules for this module based on
/// the headers.
///
/// Submodules can only be inferred for modules with an umbrella header.
+ LLVM_PREFERRED_TYPE(bool)
unsigned InferSubmodules : 1;
/// Whether, when inferring submodules, the inferred submodules
/// should be explicit.
+ LLVM_PREFERRED_TYPE(bool)
unsigned InferExplicitSubmodules : 1;
/// Whether, when inferring submodules, the inferr submodules should
/// export all modules they import (e.g., the equivalent of "export *").
+ LLVM_PREFERRED_TYPE(bool)
unsigned InferExportWildcard : 1;
/// Whether the set of configuration macros is exhaustive.
@@ -297,16 +363,24 @@ public:
/// When the set of configuration macros is exhaustive, meaning
/// that no identifier not in this list should affect how the module is
/// built.
+ LLVM_PREFERRED_TYPE(bool)
unsigned ConfigMacrosExhaustive : 1;
/// Whether files in this module can only include non-modular headers
/// and headers from used modules.
+ LLVM_PREFERRED_TYPE(bool)
unsigned NoUndeclaredIncludes : 1;
/// Whether this module came from a "private" module map, found next
/// to a regular (public) module map.
+ LLVM_PREFERRED_TYPE(bool)
unsigned ModuleMapIsPrivate : 1;
+ /// Whether this C++20 named modules doesn't need an initializer.
+ /// This is only meaningful for C++20 modules.
+ LLVM_PREFERRED_TYPE(bool)
+ unsigned NamedModuleHasInit : 1;
+
/// Describes the visibility of the various names within a
/// particular module.
enum NameVisibilityKind {
@@ -326,6 +400,10 @@ public:
/// module depends.
llvm::SmallSetVector<Module *, 2> Imports;
+ /// The set of top-level modules that affected the compilation of this module,
+ /// but were not imported.
+ llvm::SmallSetVector<Module *, 2> AffectingClangModules;
+
/// Describes an exported module.
///
/// The pointer is the module being re-exported, while the bit will be true
@@ -359,6 +437,10 @@ public:
/// The set of use declarations that have yet to be resolved.
SmallVector<ModuleId, 2> UnresolvedDirectUses;
+ /// When \c NoUndeclaredIncludes is true, the set of modules this module tried
+ /// to import but didn't because they are not direct uses.
+ llvm::SmallSetVector<const Module *, 2> UndeclaredUses;
+
/// A library or framework to link against when an entity from this
/// module is used.
struct LinkLibrary {
@@ -438,6 +520,9 @@ public:
bool isUnimportable(const LangOptions &LangOpts, const TargetInfo &Target,
Requirement &Req, Module *&ShadowingModule) const;
+ /// Determine whether this module can be built in this compilation.
+ bool isForBuilding(const LangOptions &LangOpts) const;
+
/// Determine whether this module is available for use within the
/// current translation unit.
bool isAvailable() const { return IsAvailable; }
@@ -502,6 +587,62 @@ public:
Parent->SubModules.push_back(this);
}
+ /// Is this module have similar semantics as headers.
+ bool isHeaderLikeModule() const {
+ return isModuleMapModule() || isHeaderUnit();
+ }
+
+ /// Is this a module partition.
+ bool isModulePartition() const {
+ return Kind == ModulePartitionInterface ||
+ Kind == ModulePartitionImplementation;
+ }
+
+ /// Is this a module implementation.
+ bool isModuleImplementation() const {
+ return Kind == ModuleImplementationUnit;
+ }
+
+ /// Is this module a header unit.
+ bool isHeaderUnit() const { return Kind == ModuleHeaderUnit; }
+ // Is this a C++20 module interface or a partition.
+ bool isInterfaceOrPartition() const {
+ return Kind == ModuleInterfaceUnit || isModulePartition();
+ }
+
+ /// Is this a C++20 named module unit.
+ bool isNamedModuleUnit() const {
+ return isInterfaceOrPartition() || isModuleImplementation();
+ }
+
+ bool isModuleInterfaceUnit() const {
+ return Kind == ModuleInterfaceUnit || Kind == ModulePartitionInterface;
+ }
+
+ bool isNamedModuleInterfaceHasInit() const { return NamedModuleHasInit; }
+
+ /// Get the primary module interface name from a partition.
+ StringRef getPrimaryModuleInterfaceName() const {
+ // Technically, global module fragment belongs to global module. And global
+ // module has no name: [module.unit]p6:
+ // The global module has no name, no module interface unit, and is not
+ // introduced by any module-declaration.
+ //
+ // <global> is the default name showed in module map.
+ if (isGlobalModule())
+ return "<global>";
+
+ if (isModulePartition()) {
+ auto pos = Name.find(':');
+ return StringRef(Name.data(), pos);
+ }
+
+ if (isPrivateModule())
+ return getTopLevelModuleName();
+
+ return Name;
+ }
+
/// Retrieve the full name of this module, including the path from
/// its top-level module.
/// \param AllowStringLiterals If \c true, components that might not be
@@ -531,38 +672,39 @@ public:
}
/// The serialized AST file for this module, if one was created.
- OptionalFileEntryRefDegradesToFileEntryPtr getASTFile() const {
+ OptionalFileEntryRef getASTFile() const {
return getTopLevelModule()->ASTFile;
}
/// Set the serialized AST file for the top-level module of this module.
- void setASTFile(Optional<FileEntryRef> File) {
- assert((!File || !getASTFile() || getASTFile() == File) &&
- "file path changed");
+ void setASTFile(OptionalFileEntryRef File) {
+ assert((!getASTFile() || getASTFile() == File) && "file path changed");
getTopLevelModule()->ASTFile = File;
}
- /// Retrieve the directory for which this module serves as the
- /// umbrella.
- DirectoryName getUmbrellaDir() const;
+ /// Retrieve the umbrella directory as written.
+ std::optional<DirectoryName> getUmbrellaDirAsWritten() const {
+ if (const auto *Dir = std::get_if<DirectoryEntryRef>(&Umbrella))
+ return DirectoryName{UmbrellaAsWritten,
+ UmbrellaRelativeToRootModuleDirectory, *Dir};
+ return std::nullopt;
+ }
- /// Retrieve the header that serves as the umbrella header for this
- /// module.
- Header getUmbrellaHeader() const {
- if (auto *FE = Umbrella.dyn_cast<const FileEntry *>())
+ /// Retrieve the umbrella header as written.
+ std::optional<Header> getUmbrellaHeaderAsWritten() const {
+ if (const auto *Hdr = std::get_if<FileEntryRef>(&Umbrella))
return Header{UmbrellaAsWritten, UmbrellaRelativeToRootModuleDirectory,
- FE};
- return Header{};
+ *Hdr};
+ return std::nullopt;
}
- /// Determine whether this module has an umbrella directory that is
- /// not based on an umbrella header.
- bool hasUmbrellaDir() const {
- return Umbrella && Umbrella.is<const DirectoryEntry *>();
- }
+ /// Get the effective umbrella directory for this module: either the one
+ /// explicitly written in the module map file, or the parent of the umbrella
+ /// header.
+ OptionalDirectoryEntryRef getEffectiveUmbrellaDir() const;
/// Add a top-level header associated with this module.
- void addTopHeader(const FileEntry *File);
+ void addTopHeader(FileEntryRef File);
/// Add a top-level header filename associated with this module.
void addTopHeaderFilename(StringRef Filename) {
@@ -570,11 +712,11 @@ public:
}
/// The top-level headers associated with this module.
- ArrayRef<const FileEntry *> getTopHeaders(FileManager &FileMgr);
+ ArrayRef<FileEntryRef> getTopHeaders(FileManager &FileMgr);
/// Determine whether this module has declared its intention to
/// directly use another module.
- bool directlyUses(const Module *Requested) const;
+ bool directlyUses(const Module *Requested);
/// Add the given feature requirement to the list of features
/// required by this module.
@@ -603,6 +745,18 @@ public:
Module *findSubmodule(StringRef Name) const;
Module *findOrInferSubmodule(StringRef Name);
+ /// Get the Global Module Fragment (sub-module) for this module, it there is
+ /// one.
+ ///
+ /// \returns The GMF sub-module if found, or NULL otherwise.
+ Module *getGlobalModuleFragment() const;
+
+ /// Get the Private Module Fragment (sub-module) for this module, it there is
+ /// one.
+ ///
+ /// \returns The PMF sub-module if found, or NULL otherwise.
+ Module *getPrivateModuleFragment() const;
+
/// Determine whether the specified module would be visible to
/// a lookup at the end of this module.
///
@@ -620,16 +774,11 @@ public:
using submodule_iterator = std::vector<Module *>::iterator;
using submodule_const_iterator = std::vector<Module *>::const_iterator;
- submodule_iterator submodule_begin() { return SubModules.begin(); }
- submodule_const_iterator submodule_begin() const {return SubModules.begin();}
- submodule_iterator submodule_end() { return SubModules.end(); }
- submodule_const_iterator submodule_end() const { return SubModules.end(); }
-
llvm::iterator_range<submodule_iterator> submodules() {
- return llvm::make_range(submodule_begin(), submodule_end());
+ return llvm::make_range(SubModules.begin(), SubModules.end());
}
llvm::iterator_range<submodule_const_iterator> submodules() const {
- return llvm::make_range(submodule_begin(), submodule_end());
+ return llvm::make_range(SubModules.begin(), SubModules.end());
}
/// Appends this module's list of exported modules to \p Exported.
@@ -705,6 +854,11 @@ public:
ConflictCallback Cb = [](ArrayRef<Module *>, Module *,
StringRef) {});
+ /// Make transitive imports visible for [module.import]/7.
+ void makeTransitiveImportsVisible(
+ Module *M, SourceLocation Loc, VisibleCallback Vis = [](Module *) {},
+ ConflictCallback Cb = [](ArrayRef<Module *>, Module *, StringRef) {});
+
private:
/// Import locations for each visible module. Indexed by the module's
/// VisibilityID.
diff --git a/contrib/llvm-project/clang/include/clang/Basic/NoSanitizeList.h b/contrib/llvm-project/clang/include/clang/Basic/NoSanitizeList.h
index 3f80e0fdedda..43415859fcd5 100644
--- a/contrib/llvm-project/clang/include/clang/Basic/NoSanitizeList.h
+++ b/contrib/llvm-project/clang/include/clang/Basic/NoSanitizeList.h
@@ -41,6 +41,8 @@ public:
bool containsFunction(SanitizerMask Mask, StringRef FunctionName) const;
bool containsFile(SanitizerMask Mask, StringRef FileName,
StringRef Category = StringRef()) const;
+ bool containsMainFile(SanitizerMask Mask, StringRef FileName,
+ StringRef Category = StringRef()) const;
bool containsLocation(SanitizerMask Mask, SourceLocation Loc,
StringRef Category = StringRef()) const;
};
diff --git a/contrib/llvm-project/clang/include/clang/Basic/ObjCRuntime.h b/contrib/llvm-project/clang/include/clang/Basic/ObjCRuntime.h
index 26403bfa98c9..1ccf60f0b7be 100644
--- a/contrib/llvm-project/clang/include/clang/Basic/ObjCRuntime.h
+++ b/contrib/llvm-project/clang/include/clang/Basic/ObjCRuntime.h
@@ -16,9 +16,10 @@
#include "clang/Basic/LLVM.h"
#include "llvm/ADT/StringRef.h"
-#include "llvm/ADT/Triple.h"
#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/HashBuilder.h"
#include "llvm/Support/VersionTuple.h"
+#include "llvm/TargetParser/Triple.h"
#include <string>
namespace clang {
@@ -99,16 +100,24 @@ public:
bool isLegacyDispatchDefaultForArch(llvm::Triple::ArchType Arch) {
// The GNUstep runtime uses a newer dispatch method by default from
// version 1.6 onwards
- if (getKind() == GNUstep && getVersion() >= VersionTuple(1, 6)) {
- if (Arch == llvm::Triple::arm ||
- Arch == llvm::Triple::x86 ||
- Arch == llvm::Triple::x86_64)
- return false;
- }
- else if ((getKind() == MacOSX) && isNonFragile() &&
- (getVersion() >= VersionTuple(10, 0)) &&
- (getVersion() < VersionTuple(10, 6)))
- return Arch != llvm::Triple::x86_64;
+ if (getKind() == GNUstep) {
+ switch (Arch) {
+ case llvm::Triple::arm:
+ case llvm::Triple::x86:
+ case llvm::Triple::x86_64:
+ return !(getVersion() >= VersionTuple(1, 6));
+ case llvm::Triple::aarch64:
+ case llvm::Triple::mips64:
+ return !(getVersion() >= VersionTuple(1, 9));
+ case llvm::Triple::riscv64:
+ return !(getVersion() >= VersionTuple(2, 2));
+ default:
+ return true;
+ }
+ } else if ((getKind() == MacOSX) && isNonFragile() &&
+ (getVersion() >= VersionTuple(10, 0)) &&
+ (getVersion() < VersionTuple(10, 6)))
+ return Arch != llvm::Triple::x86_64;
// Except for deployment target of 10.5 or less,
// Mac runtimes use legacy dispatch everywhere now.
return true;
@@ -202,7 +211,13 @@ public:
case GCC:
return false;
case GNUstep:
- return false;
+ // This could be enabled for all versions, except for the fact that the
+ // implementation of `objc_retain` and friends prior to 2.2 call [object
+ // retain] in their fall-back paths, which leads to infinite recursion if
+ // the runtime is built with this enabled. Since distributions typically
+ // build all Objective-C things with the same compiler version and flags,
+ // it's better to be conservative here.
+ return (getVersion() >= VersionTuple(2, 2));
case ObjFW:
return false;
}
@@ -239,7 +254,7 @@ public:
case GCC:
return false;
case GNUstep:
- return false;
+ return getVersion() >= VersionTuple(2, 2);
case ObjFW:
return false;
}
@@ -257,6 +272,8 @@ public:
return getVersion() >= VersionTuple(12, 2);
case WatchOS:
return getVersion() >= VersionTuple(5, 2);
+ case GNUstep:
+ return getVersion() >= VersionTuple(2, 2);
default:
return false;
}
@@ -454,7 +471,8 @@ public:
case iOS: return true;
case WatchOS: return true;
case GCC: return false;
- case GNUstep: return false;
+ case GNUstep:
+ return (getVersion() >= VersionTuple(2, 2));
case ObjFW: return false;
}
llvm_unreachable("bad kind");
@@ -480,6 +498,12 @@ public:
friend llvm::hash_code hash_value(const ObjCRuntime &OCR) {
return llvm::hash_combine(OCR.getKind(), OCR.getVersion());
}
+
+ template <typename HasherT, llvm::endianness Endianness>
+ friend void addHash(llvm::HashBuilder<HasherT, Endianness> &HBuilder,
+ const ObjCRuntime &OCR) {
+ HBuilder.add(OCR.getKind(), OCR.getVersion());
+ }
};
raw_ostream &operator<<(raw_ostream &out, const ObjCRuntime &value);
diff --git a/contrib/llvm-project/clang/include/clang/Basic/OpenACCKinds.h b/contrib/llvm-project/clang/include/clang/Basic/OpenACCKinds.h
new file mode 100644
index 000000000000..6487a95910ed
--- /dev/null
+++ b/contrib/llvm-project/clang/include/clang/Basic/OpenACCKinds.h
@@ -0,0 +1,401 @@
+//===--- OpenACCKinds.h - OpenACC Enums -------------------------*- 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
+/// Defines some OpenACC-specific enums and functions.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_BASIC_OPENACCKINDS_H
+#define LLVM_CLANG_BASIC_OPENACCKINDS_H
+
+#include "clang/Basic/Diagnostic.h"
+#include "llvm/Support/ErrorHandling.h"
+
+namespace clang {
+// Represents the Construct/Directive kind of a pragma directive. Note the
+// OpenACC standard is inconsistent between calling these Construct vs
+// Directive, but we're calling it a Directive to be consistent with OpenMP.
+enum class OpenACCDirectiveKind {
+ // Compute Constructs.
+ Parallel,
+ Serial,
+ Kernels,
+
+ // Data Environment. "enter data" and "exit data" are also referred to in the
+ // Executable Directives section, but just as a back reference to the Data
+ // Environment.
+ Data,
+ EnterData,
+ ExitData,
+ HostData,
+
+ // Misc.
+ Loop,
+ Cache,
+
+ // Combined Constructs.
+ ParallelLoop,
+ SerialLoop,
+ KernelsLoop,
+
+ // Atomic Construct.
+ Atomic,
+
+ // Declare Directive.
+ Declare,
+
+ // Executable Directives. "wait" is first referred to here, but ends up being
+ // in its own section after "routine".
+ Init,
+ Shutdown,
+ Set,
+ Update,
+ Wait,
+
+ // Procedure Calls in Compute Regions.
+ Routine,
+
+ // Invalid.
+ Invalid,
+};
+
+inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &Out,
+ OpenACCDirectiveKind K) {
+ switch (K) {
+ case OpenACCDirectiveKind::Parallel:
+ return Out << "parallel";
+
+ case OpenACCDirectiveKind::Serial:
+ return Out << "serial";
+
+ case OpenACCDirectiveKind::Kernels:
+ return Out << "kernels";
+
+ case OpenACCDirectiveKind::Data:
+ return Out << "data";
+
+ case OpenACCDirectiveKind::EnterData:
+ return Out << "enter data";
+
+ case OpenACCDirectiveKind::ExitData:
+ return Out << "exit data";
+
+ case OpenACCDirectiveKind::HostData:
+ return Out << "host_data";
+
+ case OpenACCDirectiveKind::Loop:
+ return Out << "loop";
+
+ case OpenACCDirectiveKind::Cache:
+ return Out << "cache";
+
+ case OpenACCDirectiveKind::ParallelLoop:
+ return Out << "parallel loop";
+
+ case OpenACCDirectiveKind::SerialLoop:
+ return Out << "serial loop";
+
+ case OpenACCDirectiveKind::KernelsLoop:
+ return Out << "kernels loop";
+
+ case OpenACCDirectiveKind::Atomic:
+ return Out << "atomic";
+
+ case OpenACCDirectiveKind::Declare:
+ return Out << "declare";
+
+ case OpenACCDirectiveKind::Init:
+ return Out << "init";
+
+ case OpenACCDirectiveKind::Shutdown:
+ return Out << "shutdown";
+
+ case OpenACCDirectiveKind::Set:
+ return Out << "set";
+
+ case OpenACCDirectiveKind::Update:
+ return Out << "update";
+
+ case OpenACCDirectiveKind::Wait:
+ return Out << "wait";
+
+ case OpenACCDirectiveKind::Routine:
+ return Out << "routine";
+
+ case OpenACCDirectiveKind::Invalid:
+ return Out << "<invalid>";
+ }
+ llvm_unreachable("Uncovered directive kind");
+}
+
+enum class OpenACCAtomicKind {
+ Read,
+ Write,
+ Update,
+ Capture,
+ Invalid,
+};
+
+/// Represents the kind of an OpenACC clause.
+enum class OpenACCClauseKind {
+ /// 'finalize' clause, allowed on 'exit data' directive.
+ Finalize,
+ /// 'if_present' clause, allowed on 'host_data' and 'update' directives.
+ IfPresent,
+ /// 'seq' clause, allowed on 'loop' and 'routine' directives.
+ Seq,
+ /// 'independent' clause, allowed on 'loop' directives.
+ Independent,
+ /// 'auto' clause, allowed on 'loop' directives.
+ Auto,
+ /// 'worker' clause, allowed on 'loop', Combined, and 'routine' directives.
+ Worker,
+ /// 'vector' clause, allowed on 'loop', Combined, and 'routine' directives.
+ Vector,
+ /// 'nohost' clause, allowed on 'routine' directives.
+ NoHost,
+ /// 'default' clause, allowed on parallel, serial, kernel (and compound)
+ /// constructs.
+ Default,
+ /// 'if' clause, allowed on all the Compute Constructs, Data Constructs,
+ /// Executable Constructs, and Combined Constructs.
+ If,
+ /// 'self' clause, allowed on Compute and Combined Constructs, plus 'update'.
+ Self,
+ /// 'copy' clause, allowed on Compute and Combined Constructs, plus 'data' and
+ /// 'declare'.
+ Copy,
+ /// 'use_device' clause, allowed on 'host_data' construct.
+ UseDevice,
+ /// 'attach' clause, allowed on Compute and Combined constructs, plus 'data'
+ /// and 'enter data'.
+ Attach,
+ /// 'delete' clause, allowed on the 'exit data' construct.
+ Delete,
+ /// 'detach' clause, allowed on the 'exit data' construct.
+ Detach,
+ /// 'device' clause, allowed on the 'update' construct.
+ Device,
+ /// 'deviceptr' clause, allowed on Compute and Combined Constructs, plus
+ /// 'data' and 'declare'.
+ DevicePtr,
+ /// 'device_resident' clause, allowed on the 'declare' construct.
+ DeviceResident,
+ /// 'firstprivate' clause, allowed on 'parallel', 'serial', 'parallel loop',
+ /// and 'serial loop' constructs.
+ FirstPrivate,
+ /// 'host' clause, allowed on 'update' construct.
+ Host,
+ /// 'link' clause, allowed on 'declare' construct.
+ Link,
+ /// 'no_create' clause, allowed on allowed on Compute and Combined constructs,
+ /// plus 'data'.
+ NoCreate,
+ /// 'present' clause, allowed on Compute and Combined constructs, plus 'data'
+ /// and 'declare'.
+ Present,
+ /// 'private' clause, allowed on 'parallel', 'serial', 'loop', 'parallel
+ /// loop', and 'serial loop' constructs.
+ Private,
+ /// 'copyout' clause, allowed on Compute and Combined constructs, plus 'data',
+ /// 'exit data', and 'declare'.
+ CopyOut,
+ /// 'copyin' clause, allowed on Compute and Combined constructs, plus 'data',
+ /// 'enter data', and 'declare'.
+ CopyIn,
+ /// 'copyin' clause, allowed on Compute and Combined constructs, plus 'data',
+ /// 'enter data', and 'declare'.
+ Create,
+ /// 'reduction' clause, allowed on Parallel, Serial, Loop, and the combined
+ /// constructs.
+ Reduction,
+ /// 'collapse' clause, allowed on 'loop' and Combined constructs.
+ Collapse,
+ /// 'bind' clause, allowed on routine constructs.
+ Bind,
+ /// 'vector_length' clause, allowed on 'parallel', 'kernels', 'parallel loop',
+ /// and 'kernels loop' constructs.
+ VectorLength,
+ /// 'num_gangs' clause, allowed on 'parallel', 'kernels', parallel loop', and
+ /// 'kernels loop' constructs.
+ NumGangs,
+ /// 'num_workers' clause, allowed on 'parallel', 'kernels', parallel loop',
+ /// and 'kernels loop' constructs.
+ NumWorkers,
+ /// 'device_num' clause, allowed on 'init', 'shutdown', and 'set' constructs.
+ DeviceNum,
+ /// 'default_async' clause, allowed on 'set' construct.
+ DefaultAsync,
+ /// 'device_type' clause, allowed on Constructs, 'data', 'init', 'shutdown',
+ /// 'set', update', 'loop', 'routine', and Combined constructs.
+ DeviceType,
+ /// 'dtype' clause, an alias for 'device_type', stored separately for
+ /// diagnostic purposes.
+ DType,
+
+ /// Represents an invalid clause, for the purposes of parsing.
+ Invalid,
+};
+
+inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &Out,
+ OpenACCClauseKind K) {
+ switch (K) {
+ case OpenACCClauseKind::Finalize:
+ return Out << "finalize";
+
+ case OpenACCClauseKind::IfPresent:
+ return Out << "if_present";
+
+ case OpenACCClauseKind::Seq:
+ return Out << "seq";
+
+ case OpenACCClauseKind::Independent:
+ return Out << "independent";
+
+ case OpenACCClauseKind::Auto:
+ return Out << "auto";
+
+ case OpenACCClauseKind::Worker:
+ return Out << "worker";
+
+ case OpenACCClauseKind::Vector:
+ return Out << "vector";
+
+ case OpenACCClauseKind::NoHost:
+ return Out << "nohost";
+
+ case OpenACCClauseKind::Default:
+ return Out << "default";
+
+ case OpenACCClauseKind::If:
+ return Out << "if";
+
+ case OpenACCClauseKind::Self:
+ return Out << "self";
+
+ case OpenACCClauseKind::Copy:
+ return Out << "copy";
+
+ case OpenACCClauseKind::UseDevice:
+ return Out << "use_device";
+
+ case OpenACCClauseKind::Attach:
+ return Out << "attach";
+
+ case OpenACCClauseKind::Delete:
+ return Out << "delete";
+
+ case OpenACCClauseKind::Detach:
+ return Out << "detach";
+
+ case OpenACCClauseKind::Device:
+ return Out << "device";
+
+ case OpenACCClauseKind::DevicePtr:
+ return Out << "deviceptr";
+
+ case OpenACCClauseKind::DeviceResident:
+ return Out << "device_resident";
+
+ case OpenACCClauseKind::FirstPrivate:
+ return Out << "firstprivate";
+
+ case OpenACCClauseKind::Host:
+ return Out << "host";
+
+ case OpenACCClauseKind::Link:
+ return Out << "link";
+
+ case OpenACCClauseKind::NoCreate:
+ return Out << "no_create";
+
+ case OpenACCClauseKind::Present:
+ return Out << "present";
+
+ case OpenACCClauseKind::Private:
+ return Out << "private";
+
+ case OpenACCClauseKind::CopyOut:
+ return Out << "copyout";
+
+ case OpenACCClauseKind::CopyIn:
+ return Out << "copyin";
+
+ case OpenACCClauseKind::Create:
+ return Out << "create";
+
+ case OpenACCClauseKind::Reduction:
+ return Out << "reduction";
+
+ case OpenACCClauseKind::Collapse:
+ return Out << "collapse";
+
+ case OpenACCClauseKind::Bind:
+ return Out << "bind";
+
+ case OpenACCClauseKind::VectorLength:
+ return Out << "vector_length";
+
+ case OpenACCClauseKind::NumGangs:
+ return Out << "num_gangs";
+
+ case OpenACCClauseKind::NumWorkers:
+ return Out << "num_workers";
+
+ case OpenACCClauseKind::DeviceNum:
+ return Out << "device_num";
+
+ case OpenACCClauseKind::DefaultAsync:
+ return Out << "default_async";
+
+ case OpenACCClauseKind::DeviceType:
+ return Out << "device_type";
+
+ case OpenACCClauseKind::DType:
+ return Out << "dtype";
+
+ case OpenACCClauseKind::Invalid:
+ return Out << "<invalid>";
+ }
+ llvm_unreachable("Uncovered clause kind");
+}
+enum class OpenACCDefaultClauseKind {
+ /// 'none' option.
+ None,
+ /// 'present' option.
+ Present,
+ /// Not a valid option.
+ Invalid,
+};
+
+enum class OpenACCReductionOperator {
+ /// '+'.
+ Addition,
+ /// '*'.
+ Multiplication,
+ /// 'max'.
+ Max,
+ /// 'min'.
+ Min,
+ /// '&'.
+ BitwiseAnd,
+ /// '|'.
+ BitwiseOr,
+ /// '^'.
+ BitwiseXOr,
+ /// '&&'.
+ And,
+ /// '||'.
+ Or,
+ /// Invalid Reduction Clause Kind.
+ Invalid,
+};
+} // namespace clang
+
+#endif // LLVM_CLANG_BASIC_OPENACCKINDS_H
diff --git a/contrib/llvm-project/clang/include/clang/Basic/OpenCLExtensionTypes.def b/contrib/llvm-project/clang/include/clang/Basic/OpenCLExtensionTypes.def
index 84ffbe936b77..17c72d69a020 100644
--- a/contrib/llvm-project/clang/include/clang/Basic/OpenCLExtensionTypes.def
+++ b/contrib/llvm-project/clang/include/clang/Basic/OpenCLExtensionTypes.def
@@ -28,10 +28,10 @@ INTEL_SUBGROUP_AVC_TYPE(mce_result_t, MceResult)
INTEL_SUBGROUP_AVC_TYPE(ime_result_t, ImeResult)
INTEL_SUBGROUP_AVC_TYPE(ref_result_t, RefResult)
INTEL_SUBGROUP_AVC_TYPE(sic_result_t, SicResult)
-INTEL_SUBGROUP_AVC_TYPE(ime_result_single_reference_streamout_t, ImeResultSingleRefStreamout)
-INTEL_SUBGROUP_AVC_TYPE(ime_result_dual_reference_streamout_t, ImeResultDualRefStreamout)
-INTEL_SUBGROUP_AVC_TYPE(ime_single_reference_streamin_t, ImeSingleRefStreamin)
-INTEL_SUBGROUP_AVC_TYPE(ime_dual_reference_streamin_t, ImeDualRefStreamin)
+INTEL_SUBGROUP_AVC_TYPE(ime_result_single_reference_streamout_t, ImeResultSingleReferenceStreamout)
+INTEL_SUBGROUP_AVC_TYPE(ime_result_dual_reference_streamout_t, ImeResultDualReferenceStreamout)
+INTEL_SUBGROUP_AVC_TYPE(ime_single_reference_streamin_t, ImeSingleReferenceStreamin)
+INTEL_SUBGROUP_AVC_TYPE(ime_dual_reference_streamin_t, ImeDualReferenceStreamin)
#undef INTEL_SUBGROUP_AVC_TYPE
#endif // INTEL_SUBGROUP_AVC_TYPE
diff --git a/contrib/llvm-project/clang/include/clang/Basic/OpenCLExtensions.def b/contrib/llvm-project/clang/include/clang/Basic/OpenCLExtensions.def
index a053a0e9adb5..6f73b2613750 100644
--- a/contrib/llvm-project/clang/include/clang/Basic/OpenCLExtensions.def
+++ b/contrib/llvm-project/clang/include/clang/Basic/OpenCLExtensions.def
@@ -31,7 +31,7 @@
// If extensions are to be enumerated without any information,
// define OPENCLEXTNAME(ext) where ext is the name of the extension.
//
-// Difference between optional core feature and core feature is that the
+// Difference between optional core feature and core feature is that the
// later is unconditionally supported in specific OpenCL version.
//
// As per The OpenCL Extension Specification, Section 1.2, in this file, an
@@ -94,12 +94,6 @@ OPENCL_EXTENSION(__cl_clang_bitfields, true, 100)
OPENCL_EXTENSION(cl_amd_media_ops, true, 100)
OPENCL_EXTENSION(cl_amd_media_ops2, true, 100)
-// ARM OpenCL extensions
-OPENCL_EXTENSION(cl_arm_integer_dot_product_int8, true, 120)
-OPENCL_EXTENSION(cl_arm_integer_dot_product_accumulate_int8, true, 120)
-OPENCL_EXTENSION(cl_arm_integer_dot_product_accumulate_int16, true, 120)
-OPENCL_EXTENSION(cl_arm_integer_dot_product_accumulate_saturate_int8, true, 120)
-
// Intel OpenCL extensions
OPENCL_EXTENSION(cl_intel_subgroups, true, 120)
OPENCL_EXTENSION(cl_intel_subgroups_short, true, 120)
diff --git a/contrib/llvm-project/clang/include/clang/Basic/OpenCLOptions.h b/contrib/llvm-project/clang/include/clang/Basic/OpenCLOptions.h
index 1a035626fade..d6cb1a210519 100644
--- a/contrib/llvm-project/clang/include/clang/Basic/OpenCLOptions.h
+++ b/contrib/llvm-project/clang/include/clang/Basic/OpenCLOptions.h
@@ -58,7 +58,7 @@ static inline OpenCLVersionID encodeOpenCLVersion(unsigned OpenCLVersion) {
// mask.
static inline bool isOpenCLVersionContainedInMask(const LangOptions &LO,
unsigned Mask) {
- auto CLVer = LO.OpenCLCPlusPlus ? 200 : LO.OpenCLVersion;
+ auto CLVer = LO.getOpenCLCompatibleVersion();
OpenCLVersionID Code = encodeOpenCLVersion(CLVer);
return Mask & Code;
}
@@ -79,8 +79,8 @@ public:
// the __opencl_c_program_scope_global_variables feature is supported
// C++ for OpenCL inherits rule from OpenCL C v2.0.
bool areProgramScopeVariablesSupported(const LangOptions &Opts) const {
- return Opts.OpenCLCPlusPlus || Opts.OpenCLVersion == 200 ||
- (Opts.OpenCLVersion == 300 &&
+ return Opts.getOpenCLCompatibleVersion() == 200 ||
+ (Opts.getOpenCLCompatibleVersion() == 300 &&
isSupported("__opencl_c_program_scope_global_variables", Opts));
}
@@ -115,8 +115,7 @@ public:
// Is option available in OpenCL version \p LO.
bool isAvailableIn(const LangOptions &LO) const {
// In C++ mode all extensions should work at least as in v2.0.
- auto CLVer = LO.OpenCLCPlusPlus ? 200 : LO.OpenCLVersion;
- return CLVer >= Avail;
+ return LO.getOpenCLCompatibleVersion() >= Avail;
}
// Is core option in OpenCL version \p LO.
diff --git a/contrib/llvm-project/clang/include/clang/Basic/OpenMPKinds.def b/contrib/llvm-project/clang/include/clang/Basic/OpenMPKinds.def
index 9f9c32da4aa0..f46a92d5ecfd 100644
--- a/contrib/llvm-project/clang/include/clang/Basic/OpenMPKinds.def
+++ b/contrib/llvm-project/clang/include/clang/Basic/OpenMPKinds.def
@@ -41,6 +41,15 @@
#ifndef OPENMP_ATOMIC_DEFAULT_MEM_ORDER_KIND
#define OPENMP_ATOMIC_DEFAULT_MEM_ORDER_KIND(Name)
#endif
+#ifndef OPENMP_ATOMIC_FAIL_MODIFIER
+#define OPENMP_ATOMIC_FAIL_MODIFIER(Name)
+#endif
+#ifndef OPENMP_AT_KIND
+#define OPENMP_AT_KIND(Name)
+#endif
+#ifndef OPENMP_SEVERITY_KIND
+#define OPENMP_SEVERITY_KIND(Name)
+#endif
#ifndef OPENMP_DEFAULTMAP_MODIFIER
#define OPENMP_DEFAULTMAP_MODIFIER(Name)
#endif
@@ -53,12 +62,30 @@
#ifndef OPENMP_ORDER_KIND
#define OPENMP_ORDER_KIND(Name)
#endif
+#ifndef OPENMP_ORDER_MODIFIER
+#define OPENMP_ORDER_MODIFIER(Name)
+#endif
#ifndef OPENMP_DEVICE_MODIFIER
#define OPENMP_DEVICE_MODIFIER(Name)
#endif
#ifndef OPENMP_REDUCTION_MODIFIER
#define OPENMP_REDUCTION_MODIFIER(Name)
#endif
+#ifndef OPENMP_ADJUST_ARGS_KIND
+#define OPENMP_ADJUST_ARGS_KIND(Name)
+#endif
+#ifndef OPENMP_BIND_KIND
+#define OPENMP_BIND_KIND(Name)
+#endif
+#ifndef OPENMP_GRAINSIZE_MODIFIER
+#define OPENMP_GRAINSIZE_MODIFIER(Name)
+#endif
+#ifndef OPENMP_NUMTASKS_MODIFIER
+#define OPENMP_NUMTASKS_MODIFIER(Name)
+#endif
+#ifndef OPENMP_DOACROSS_MODIFIER
+#define OPENMP_DOACROSS_MODIFIER(Name)
+#endif
// Static attributes for 'schedule' clause.
OPENMP_SCHEDULE_KIND(static)
@@ -99,17 +126,34 @@ OPENMP_DEPEND_KIND(mutexinoutset)
OPENMP_DEPEND_KIND(depobj)
OPENMP_DEPEND_KIND(source)
OPENMP_DEPEND_KIND(sink)
+OPENMP_DEPEND_KIND(inoutset)
+OPENMP_DEPEND_KIND(outallmemory)
+OPENMP_DEPEND_KIND(inoutallmemory)
// Modifiers for 'linear' clause.
OPENMP_LINEAR_KIND(val)
OPENMP_LINEAR_KIND(ref)
OPENMP_LINEAR_KIND(uval)
+OPENMP_LINEAR_KIND(step)
// Modifiers for 'atomic_default_mem_order' clause.
OPENMP_ATOMIC_DEFAULT_MEM_ORDER_KIND(seq_cst)
OPENMP_ATOMIC_DEFAULT_MEM_ORDER_KIND(acq_rel)
OPENMP_ATOMIC_DEFAULT_MEM_ORDER_KIND(relaxed)
+// Modifiers for atomic 'fail' clause.
+OPENMP_ATOMIC_FAIL_MODIFIER(seq_cst)
+OPENMP_ATOMIC_FAIL_MODIFIER(acquire)
+OPENMP_ATOMIC_FAIL_MODIFIER(relaxed)
+
+// Modifiers for 'at' clause.
+OPENMP_AT_KIND(compilation)
+OPENMP_AT_KIND(execution)
+
+// Modifiers for 'severity' clause.
+OPENMP_SEVERITY_KIND(fatal)
+OPENMP_SEVERITY_KIND(warning)
+
// Map types for 'map' clause.
OPENMP_MAP_KIND(alloc)
OPENMP_MAP_KIND(to)
@@ -122,7 +166,10 @@ OPENMP_MAP_KIND(release)
OPENMP_MAP_MODIFIER_KIND(always)
OPENMP_MAP_MODIFIER_KIND(close)
OPENMP_MAP_MODIFIER_KIND(mapper)
+OPENMP_MAP_MODIFIER_KIND(iterator)
OPENMP_MAP_MODIFIER_KIND(present)
+// This is an OpenMP extension for the sake of OpenACC support.
+OPENMP_MAP_MODIFIER_KIND(ompx_hold)
// Modifiers for 'to' or 'from' clause.
OPENMP_MOTION_MODIFIER_KIND(mapper)
@@ -142,14 +189,44 @@ OPENMP_LASTPRIVATE_KIND(conditional)
// Type of the 'order' clause.
OPENMP_ORDER_KIND(concurrent)
+// Modifiers for the 'order' clause.
+OPENMP_ORDER_MODIFIER(reproducible)
+OPENMP_ORDER_MODIFIER(unconstrained)
+
// Modifiers for 'reduction' clause.
OPENMP_REDUCTION_MODIFIER(default)
OPENMP_REDUCTION_MODIFIER(inscan)
OPENMP_REDUCTION_MODIFIER(task)
+// Adjust-op kinds for the 'adjust_args' clause.
+OPENMP_ADJUST_ARGS_KIND(nothing)
+OPENMP_ADJUST_ARGS_KIND(need_device_ptr)
+
+// Binding kinds for the 'bind' clause.
+OPENMP_BIND_KIND(teams)
+OPENMP_BIND_KIND(parallel)
+OPENMP_BIND_KIND(thread)
+
+// Modifiers for the 'grainsize' clause.
+OPENMP_GRAINSIZE_MODIFIER(strict)
+
+// Modifiers for the 'num_tasks' clause.
+OPENMP_NUMTASKS_MODIFIER(strict)
+
+// Modifiers for the 'doacross' clause.
+OPENMP_DOACROSS_MODIFIER(source)
+OPENMP_DOACROSS_MODIFIER(sink)
+OPENMP_DOACROSS_MODIFIER(sink_omp_cur_iteration)
+OPENMP_DOACROSS_MODIFIER(source_omp_cur_iteration)
+
+#undef OPENMP_NUMTASKS_MODIFIER
+#undef OPENMP_GRAINSIZE_MODIFIER
+#undef OPENMP_BIND_KIND
+#undef OPENMP_ADJUST_ARGS_KIND
#undef OPENMP_REDUCTION_MODIFIER
#undef OPENMP_DEVICE_MODIFIER
#undef OPENMP_ORDER_KIND
+#undef OPENMP_ORDER_MODIFIER
#undef OPENMP_LASTPRIVATE_KIND
#undef OPENMP_DEVICE_TYPE_KIND
#undef OPENMP_LINEAR_KIND
@@ -157,10 +234,14 @@ OPENMP_REDUCTION_MODIFIER(task)
#undef OPENMP_SCHEDULE_MODIFIER
#undef OPENMP_SCHEDULE_KIND
#undef OPENMP_ATOMIC_DEFAULT_MEM_ORDER_KIND
+#undef OPENMP_ATOMIC_FAIL_MODIFIER
+#undef OPENMP_AT_KIND
+#undef OPENMP_SEVERITY_KIND
#undef OPENMP_MAP_KIND
#undef OPENMP_MAP_MODIFIER_KIND
#undef OPENMP_MOTION_MODIFIER_KIND
#undef OPENMP_DIST_SCHEDULE_KIND
#undef OPENMP_DEFAULTMAP_KIND
#undef OPENMP_DEFAULTMAP_MODIFIER
+#undef OPENMP_DOACROSS_MODIFIER
diff --git a/contrib/llvm-project/clang/include/clang/Basic/OpenMPKinds.h b/contrib/llvm-project/clang/include/clang/Basic/OpenMPKinds.h
index c7a2591de26c..d127498774c7 100644
--- a/contrib/llvm-project/clang/include/clang/Basic/OpenMPKinds.h
+++ b/contrib/llvm-project/clang/include/clang/Basic/OpenMPKinds.h
@@ -14,6 +14,7 @@
#ifndef LLVM_CLANG_BASIC_OPENMPKINDS_H
#define LLVM_CLANG_BASIC_OPENMPKINDS_H
+#include "clang/Basic/LangOptions.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Frontend/OpenMP/OMPConstants.h"
@@ -82,7 +83,7 @@ enum OpenMPMapModifierKind {
OMPC_MAP_MODIFIER_last
};
- /// Number of allowed map-type-modifiers.
+/// Number of allowed map-type-modifiers.
static constexpr unsigned NumberOfOMPMapClauseModifiers =
OMPC_MAP_MODIFIER_last - OMPC_MAP_MODIFIER_unknown - 1;
@@ -130,6 +131,20 @@ enum OpenMPAtomicDefaultMemOrderClauseKind {
OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown
};
+/// OpenMP attributes for 'at' clause.
+enum OpenMPAtClauseKind {
+#define OPENMP_AT_KIND(Name) OMPC_AT_##Name,
+#include "clang/Basic/OpenMPKinds.def"
+ OMPC_AT_unknown
+};
+
+/// OpenMP attributes for 'severity' clause.
+enum OpenMPSeverityClauseKind {
+#define OPENMP_SEVERITY_KIND(Name) OMPC_SEVERITY_##Name,
+#include "clang/Basic/OpenMPKinds.def"
+ OMPC_SEVERITY_unknown
+};
+
/// OpenMP device type for 'device_type' clause.
enum OpenMPDeviceType {
#define OPENMP_DEVICE_TYPE_KIND(Name) \
@@ -152,6 +167,14 @@ enum OpenMPOrderClauseKind {
OMPC_ORDER_unknown,
};
+/// OpenMP modifiers for 'order' clause.
+enum OpenMPOrderClauseModifier {
+ OMPC_ORDER_MODIFIER_unknown = OMPC_ORDER_unknown,
+#define OPENMP_ORDER_MODIFIER(Name) OMPC_ORDER_MODIFIER_##Name,
+#include "clang/Basic/OpenMPKinds.def"
+ OMPC_ORDER_MODIFIER_last
+};
+
/// Scheduling data for loop-based OpenMP directives.
struct OpenMPScheduleTy final {
OpenMPScheduleClauseKind Schedule = OMPC_SCHEDULE_unknown;
@@ -166,8 +189,51 @@ enum OpenMPReductionClauseModifier {
OMPC_REDUCTION_unknown,
};
+/// OpenMP adjust-op kinds for 'adjust_args' clause.
+enum OpenMPAdjustArgsOpKind {
+#define OPENMP_ADJUST_ARGS_KIND(Name) OMPC_ADJUST_ARGS_##Name,
+#include "clang/Basic/OpenMPKinds.def"
+ OMPC_ADJUST_ARGS_unknown,
+};
+
+/// OpenMP bindings for the 'bind' clause.
+enum OpenMPBindClauseKind {
+#define OPENMP_BIND_KIND(Name) OMPC_BIND_##Name,
+#include "clang/Basic/OpenMPKinds.def"
+ OMPC_BIND_unknown
+};
+
+enum OpenMPGrainsizeClauseModifier {
+#define OPENMP_GRAINSIZE_MODIFIER(Name) OMPC_GRAINSIZE_##Name,
+#include "clang/Basic/OpenMPKinds.def"
+ OMPC_GRAINSIZE_unknown
+};
+
+enum OpenMPNumTasksClauseModifier {
+#define OPENMP_NUMTASKS_MODIFIER(Name) OMPC_NUMTASKS_##Name,
+#include "clang/Basic/OpenMPKinds.def"
+ OMPC_NUMTASKS_unknown
+};
+
+/// OpenMP dependence types for 'doacross' clause.
+enum OpenMPDoacrossClauseModifier {
+#define OPENMP_DOACROSS_MODIFIER(Name) OMPC_DOACROSS_##Name,
+#include "clang/Basic/OpenMPKinds.def"
+ OMPC_DOACROSS_unknown
+};
+
+/// Contains 'interop' data for 'append_args' and 'init' clauses.
+class Expr;
+struct OMPInteropInfo final {
+ OMPInteropInfo(bool IsTarget = false, bool IsTargetSync = false)
+ : IsTarget(IsTarget), IsTargetSync(IsTargetSync) {}
+ bool IsTarget;
+ bool IsTargetSync;
+ llvm::SmallVector<Expr *, 4> PreferTypes;
+};
+
unsigned getOpenMPSimpleClauseType(OpenMPClauseKind Kind, llvm::StringRef Str,
- unsigned OpenMPVersion);
+ const LangOptions &LangOpts);
const char *getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind, unsigned Type);
/// Checks if the specified directive is a directive with an associated
@@ -245,6 +311,13 @@ bool isOpenMPDistributeDirective(OpenMPDirectiveKind DKind);
/// otherwise - false.
bool isOpenMPNestingDistributeDirective(OpenMPDirectiveKind DKind);
+/// Checks if the specified directive constitutes a 'loop' directive in the
+/// outermost nest. For example, 'omp teams loop' or 'omp loop'.
+/// \param DKind Specified directive.
+/// \return true - the directive has loop on the outermost nest.
+/// otherwise - false.
+bool isOpenMPGenericLoopDirective(OpenMPDirectiveKind DKind);
+
/// Checks if the specified clause is one of private clauses like
/// 'private', 'firstprivate', 'reduction' etc..
/// \param Kind Clause kind.
@@ -276,6 +349,25 @@ bool isOpenMPLoopTransformationDirective(OpenMPDirectiveKind DKind);
void getOpenMPCaptureRegions(
llvm::SmallVectorImpl<OpenMPDirectiveKind> &CaptureRegions,
OpenMPDirectiveKind DKind);
+
+/// Checks if the specified directive is a combined construct for which
+/// the first construct is a parallel construct.
+/// \param DKind Specified directive.
+/// \return true - if the above condition is met for this directive
+/// otherwise - false.
+bool isOpenMPCombinedParallelADirective(OpenMPDirectiveKind DKind);
+
+/// Checks if the specified target directive, combined or not, needs task based
+/// thread_limit
+/// \param DKind Specified directive.
+/// \return true - if the above condition is met for this directive
+/// otherwise - false.
+bool needsTaskBasedThreadLimit(OpenMPDirectiveKind DKind);
+
+/// Checks if the parameter to the fail clause in "#pragma atomic compare fail"
+/// is restricted only to memory order clauses of "OMPC_acquire",
+/// "OMPC_relaxed" and "OMPC_seq_cst".
+bool checkFailClauseParameter(OpenMPClauseKind FailClauseParameter);
}
#endif
diff --git a/contrib/llvm-project/clang/include/clang/Basic/OperatorKinds.def b/contrib/llvm-project/clang/include/clang/Basic/OperatorKinds.def
index d464db29274e..fab777349ede 100644
--- a/contrib/llvm-project/clang/include/clang/Basic/OperatorKinds.def
+++ b/contrib/llvm-project/clang/include/clang/Basic/OperatorKinds.def
@@ -38,8 +38,8 @@
/// "operator*") can be both unary and binary.
///
/// MemberOnly: True if this operator can only be declared as a
-/// non-static member function. False if the operator can be both a
-/// non-member function and a non-static member function.
+/// member function. False if the operator can be both a
+/// non-member function and a member function.
///
/// OVERLOADED_OPERATOR_MULTI is used to enumerate the multi-token
/// overloaded operator names, e.g., "operator delete []". The macro
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/ParsedAttrInfo.h b/contrib/llvm-project/clang/include/clang/Basic/ParsedAttrInfo.h
new file mode 100644
index 000000000000..537d8f3391d5
--- /dev/null
+++ b/contrib/llvm-project/clang/include/clang/Basic/ParsedAttrInfo.h
@@ -0,0 +1,168 @@
+//===- ParsedAttrInfo.h - Info needed to parse an attribute -----*- 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 the ParsedAttrInfo class, which dictates how to
+// parse an attribute. This class is the one that plugins derive to
+// define a new attribute.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_BASIC_PARSEDATTRINFO_H
+#define LLVM_CLANG_BASIC_PARSEDATTRINFO_H
+
+#include "clang/Basic/AttrSubjectMatchRules.h"
+#include "clang/Basic/AttributeCommonInfo.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/Support/Registry.h"
+#include <climits>
+#include <list>
+
+namespace clang {
+
+class Decl;
+class LangOptions;
+class ParsedAttr;
+class Sema;
+class Stmt;
+class TargetInfo;
+
+struct ParsedAttrInfo {
+ /// Corresponds to the Kind enum.
+ LLVM_PREFERRED_TYPE(AttributeCommonInfo::Kind)
+ unsigned AttrKind : 16;
+ /// The number of required arguments of this attribute.
+ unsigned NumArgs : 4;
+ /// The number of optional arguments of this attributes.
+ unsigned OptArgs : 4;
+ /// The number of non-fake arguments specified in the attribute definition.
+ unsigned NumArgMembers : 4;
+ /// True if the parsing does not match the semantic content.
+ LLVM_PREFERRED_TYPE(bool)
+ unsigned HasCustomParsing : 1;
+ // True if this attribute accepts expression parameter pack expansions.
+ LLVM_PREFERRED_TYPE(bool)
+ unsigned AcceptsExprPack : 1;
+ /// True if this attribute is only available for certain targets.
+ LLVM_PREFERRED_TYPE(bool)
+ unsigned IsTargetSpecific : 1;
+ /// True if this attribute applies to types.
+ LLVM_PREFERRED_TYPE(bool)
+ unsigned IsType : 1;
+ /// True if this attribute applies to statements.
+ LLVM_PREFERRED_TYPE(bool)
+ unsigned IsStmt : 1;
+ /// True if this attribute has any spellings that are known to gcc.
+ LLVM_PREFERRED_TYPE(bool)
+ unsigned IsKnownToGCC : 1;
+ /// True if this attribute is supported by #pragma clang attribute.
+ LLVM_PREFERRED_TYPE(bool)
+ unsigned IsSupportedByPragmaAttribute : 1;
+ /// The syntaxes supported by this attribute and how they're spelled.
+ struct Spelling {
+ AttributeCommonInfo::Syntax Syntax;
+ const char *NormalizedFullName;
+ };
+ ArrayRef<Spelling> Spellings;
+ // The names of the known arguments of this attribute.
+ ArrayRef<const char *> ArgNames;
+
+protected:
+ constexpr ParsedAttrInfo(AttributeCommonInfo::Kind AttrKind =
+ AttributeCommonInfo::NoSemaHandlerAttribute)
+ : AttrKind(AttrKind), NumArgs(0), OptArgs(0), NumArgMembers(0),
+ HasCustomParsing(0), AcceptsExprPack(0), IsTargetSpecific(0), IsType(0),
+ IsStmt(0), IsKnownToGCC(0), IsSupportedByPragmaAttribute(0) {}
+
+ constexpr ParsedAttrInfo(AttributeCommonInfo::Kind AttrKind, unsigned NumArgs,
+ unsigned OptArgs, unsigned NumArgMembers,
+ unsigned HasCustomParsing, unsigned AcceptsExprPack,
+ unsigned IsTargetSpecific, unsigned IsType,
+ unsigned IsStmt, unsigned IsKnownToGCC,
+ unsigned IsSupportedByPragmaAttribute,
+ ArrayRef<Spelling> Spellings,
+ ArrayRef<const char *> ArgNames)
+ : AttrKind(AttrKind), NumArgs(NumArgs), OptArgs(OptArgs),
+ NumArgMembers(NumArgMembers), HasCustomParsing(HasCustomParsing),
+ AcceptsExprPack(AcceptsExprPack), IsTargetSpecific(IsTargetSpecific),
+ IsType(IsType), IsStmt(IsStmt), IsKnownToGCC(IsKnownToGCC),
+ IsSupportedByPragmaAttribute(IsSupportedByPragmaAttribute),
+ Spellings(Spellings), ArgNames(ArgNames) {}
+
+public:
+ virtual ~ParsedAttrInfo() = default;
+
+ /// Check if this attribute has specified spelling.
+ bool hasSpelling(AttributeCommonInfo::Syntax Syntax, StringRef Name) const {
+ return llvm::any_of(Spellings, [&](const Spelling &S) {
+ return (S.Syntax == Syntax && S.NormalizedFullName == Name);
+ });
+ }
+
+ /// Check if this attribute appertains to D, and issue a diagnostic if not.
+ virtual bool diagAppertainsToDecl(Sema &S, const ParsedAttr &Attr,
+ const Decl *D) const {
+ return true;
+ }
+ /// Check if this attribute appertains to St, and issue a diagnostic if not.
+ virtual bool diagAppertainsToStmt(Sema &S, const ParsedAttr &Attr,
+ const Stmt *St) const {
+ return true;
+ }
+ /// Check if the given attribute is mutually exclusive with other attributes
+ /// already applied to the given declaration.
+ virtual bool diagMutualExclusion(Sema &S, const ParsedAttr &A,
+ const Decl *D) const {
+ return true;
+ }
+ /// Check if this attribute is allowed by the language we are compiling.
+ virtual bool acceptsLangOpts(const LangOptions &LO) const { return true; }
+
+ /// Check if this attribute is allowed when compiling for the given target.
+ virtual bool existsInTarget(const TargetInfo &Target) const { return true; }
+
+ /// Check if this attribute's spelling is allowed when compiling for the given
+ /// target.
+ virtual bool spellingExistsInTarget(const TargetInfo &Target,
+ const unsigned SpellingListIndex) const {
+ return true;
+ }
+
+ /// Convert the spelling index of Attr to a semantic spelling enum value.
+ virtual unsigned
+ spellingIndexToSemanticSpelling(const ParsedAttr &Attr) const {
+ return UINT_MAX;
+ }
+ /// Returns true if the specified parameter index for this attribute in
+ /// Attr.td is an ExprArgument or VariadicExprArgument, or a subclass thereof;
+ /// returns false otherwise.
+ virtual bool isParamExpr(size_t N) const { return false; }
+ /// Populate Rules with the match rules of this attribute.
+ virtual void getPragmaAttributeMatchRules(
+ llvm::SmallVectorImpl<std::pair<attr::SubjectMatchRule, bool>> &Rules,
+ const LangOptions &LangOpts) const {}
+
+ enum AttrHandling { NotHandled, AttributeApplied, AttributeNotApplied };
+ /// If this ParsedAttrInfo knows how to handle this ParsedAttr applied to this
+ /// Decl then do so and return either AttributeApplied if it was applied or
+ /// AttributeNotApplied if it wasn't. Otherwise return NotHandled.
+ virtual AttrHandling handleDeclAttribute(Sema &S, Decl *D,
+ const ParsedAttr &Attr) const {
+ return NotHandled;
+ }
+
+ static const ParsedAttrInfo &get(const AttributeCommonInfo &A);
+ static ArrayRef<const ParsedAttrInfo *> getAllBuiltin();
+};
+
+typedef llvm::Registry<ParsedAttrInfo> ParsedAttrInfoRegistry;
+
+const std::list<std::unique_ptr<ParsedAttrInfo>> &getAttributePluginInstances();
+
+} // namespace clang
+
+#endif // LLVM_CLANG_BASIC_PARSEDATTRINFO_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..507d789c54ff 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
@@ -67,8 +64,8 @@ public:
// It is necessary to limit this to rvalue reference to avoid calling this
// function with a bitfield lvalue argument since non-const reference to
// bitfield is not allowed.
- template <typename T, typename = typename std::enable_if<
- !std::is_lvalue_reference<T>::value>::type>
+ template <typename T,
+ typename = std::enable_if_t<!std::is_lvalue_reference<T>::value>>
const PartialDiagnostic &operator<<(T &&V) const {
const StreamingDiagnostic &DB = *this;
DB << std::move(V);
diff --git a/contrib/llvm-project/clang/include/clang/Basic/PlistSupport.h b/contrib/llvm-project/clang/include/clang/Basic/PlistSupport.h
index 557462a5b90d..d52d196019cf 100644
--- a/contrib/llvm-project/clang/include/clang/Basic/PlistSupport.h
+++ b/contrib/llvm-project/clang/include/clang/Basic/PlistSupport.h
@@ -77,8 +77,7 @@ inline raw_ostream &EmitInteger(raw_ostream &o, int64_t value) {
inline raw_ostream &EmitString(raw_ostream &o, StringRef s) {
o << "<string>";
- for (StringRef::const_iterator I = s.begin(), E = s.end(); I != E; ++I) {
- char c = *I;
+ for (char c : s) {
switch (c) {
default:
o << c;
diff --git a/contrib/llvm-project/clang/include/clang/Basic/PragmaKinds.h b/contrib/llvm-project/clang/include/clang/Basic/PragmaKinds.h
index 82c0d5f0a551..42f049f7323d 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 {
@@ -34,6 +34,14 @@ enum PragmaFloatControlKind {
PFC_Push, // #pragma float_control(push)
PFC_Pop // #pragma float_control(pop)
};
+
+enum PragmaFPKind {
+ PFK_Contract, // #pragma clang fp contract
+ PFK_Reassociate, // #pragma clang fp reassociate
+ PFK_Reciprocal, // #pragma clang fp reciprocal
+ PFK_Exceptions, // #pragma clang fp exceptions
+ PFK_EvalMethod // #pragma clang fp eval_method
+};
}
#endif
diff --git a/contrib/llvm-project/clang/include/clang/Basic/ProfileList.h b/contrib/llvm-project/clang/include/clang/Basic/ProfileList.h
index 989c36549a3d..b4217e49c18a 100644
--- a/contrib/llvm-project/clang/include/clang/Basic/ProfileList.h
+++ b/contrib/llvm-project/clang/include/clang/Basic/ProfileList.h
@@ -10,45 +10,54 @@
// 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"
#include "clang/Basic/SourceLocation.h"
#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/Optional.h"
#include "llvm/ADT/StringRef.h"
#include <memory>
-
-namespace llvm {
-class SpecialCaseList;
-}
+#include <optional>
namespace clang {
class ProfileSpecialCaseList;
class ProfileList {
+public:
+ /// Represents if an how something should be excluded from profiling.
+ enum ExclusionType {
+ /// Profiling is allowed.
+ Allow,
+ /// Profiling is skipped using the \p skipprofile attribute.
+ Skip,
+ /// Profiling is forbidden using the \p noprofile attribute.
+ Forbid,
+ };
+
+private:
std::unique_ptr<ProfileSpecialCaseList> SCL;
const bool Empty;
- const bool Default;
SourceManager &SM;
+ std::optional<ExclusionType> inSection(StringRef Section, StringRef Prefix,
+ StringRef Query) const;
public:
ProfileList(ArrayRef<std::string> Paths, SourceManager &SM);
~ProfileList();
bool isEmpty() const { return Empty; }
- bool getDefault() const { return Default; }
+ ExclusionType getDefault(CodeGenOptions::ProfileInstrKind Kind) const;
- llvm::Optional<bool>
+ std::optional<ExclusionType>
isFunctionExcluded(StringRef FunctionName,
CodeGenOptions::ProfileInstrKind Kind) const;
- llvm::Optional<bool>
+ std::optional<ExclusionType>
isLocationExcluded(SourceLocation Loc,
CodeGenOptions::ProfileInstrKind Kind) const;
- llvm::Optional<bool>
+ std::optional<ExclusionType>
isFileExcluded(StringRef FileName,
CodeGenOptions::ProfileInstrKind Kind) const;
};
diff --git a/contrib/llvm-project/clang/include/clang/Basic/RISCVVTypes.def b/contrib/llvm-project/clang/include/clang/Basic/RISCVVTypes.def
index f6ef62a64636..6620de8ad50e 100644
--- a/contrib/llvm-project/clang/include/clang/Basic/RISCVVTypes.def
+++ b/contrib/llvm-project/clang/include/clang/Basic/RISCVVTypes.def
@@ -12,7 +12,8 @@
// A builtin type that has not been covered by any other #define
// Defining this macro covers all the builtins.
//
-// - RVV_VECTOR_TYPE(Name, Id, SingletonId, NumEls, ElBits, IsSigned, IsFP)
+// - RVV_VECTOR_TYPE(Name, Id, SingletonId, NumEls, ElBits, IsSigned, IsFP,
+// IsBF)
// A RISC-V V scalable vector.
//
// - RVV_PREDICATE_TYPE(Name, Id, SingletonId, NumEls)
@@ -30,8 +31,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.
@@ -40,8 +41,13 @@
//
//===----------------------------------------------------------------------===//
+#ifndef RVV_TYPE
+#define RVV_TYPE(Name, Id, SingletonId)
+#endif
+
#ifndef RVV_VECTOR_TYPE
-#define RVV_VECTOR_TYPE(Name, Id, SingletonId, NumEls, ElBits, NF, IsSigned, IsFP)\
+#define RVV_VECTOR_TYPE(Name, Id, SingletonId, NumEls, ElBits, NF, IsSigned, \
+ IsFP, IsBF) \
RVV_TYPE(Name, Id, SingletonId)
#endif
@@ -51,13 +57,20 @@
#endif
#ifndef RVV_VECTOR_TYPE_INT
-#define RVV_VECTOR_TYPE_INT(Name, Id, SingletonId, NumEls, ElBits, NF, IsSigned) \
- RVV_VECTOR_TYPE(Name, Id, SingletonId, NumEls, ElBits, NF, IsSigned, false)
+#define RVV_VECTOR_TYPE_INT(Name, Id, SingletonId, NumEls, ElBits, NF, \
+ IsSigned) \
+ RVV_VECTOR_TYPE(Name, Id, SingletonId, NumEls, ElBits, NF, IsSigned, false, \
+ false)
#endif
#ifndef RVV_VECTOR_TYPE_FLOAT
-#define RVV_VECTOR_TYPE_FLOAT(Name, Id, SingletonId, NumEls, ElBits, NF) \
- RVV_VECTOR_TYPE(Name, Id, SingletonId, NumEls, ElBits, NF, false, true)
+#define RVV_VECTOR_TYPE_FLOAT(Name, Id, SingletonId, NumEls, ElBits, NF) \
+ RVV_VECTOR_TYPE(Name, Id, SingletonId, NumEls, ElBits, NF, false, true, false)
+#endif
+
+#ifndef RVV_VECTOR_TYPE_BFLOAT
+#define RVV_VECTOR_TYPE_BFLOAT(Name, Id, SingletonId, NumEls, ElBits, NF) \
+ RVV_VECTOR_TYPE(Name, Id, SingletonId, NumEls, ElBits, NF, false, false, true)
#endif
//===- Vector types -------------------------------------------------------===//
@@ -121,6 +134,19 @@ RVV_VECTOR_TYPE_FLOAT("__rvv_float16m2_t", RvvFloat16m2, RvvFloat16m2Ty, 8, 16,
RVV_VECTOR_TYPE_FLOAT("__rvv_float16m4_t", RvvFloat16m4, RvvFloat16m4Ty, 16, 16, 1)
RVV_VECTOR_TYPE_FLOAT("__rvv_float16m8_t", RvvFloat16m8, RvvFloat16m8Ty, 32, 16, 1)
+RVV_VECTOR_TYPE_BFLOAT("__rvv_bfloat16mf4_t", RvvBFloat16mf4, RvvBFloat16mf4Ty,
+ 1, 16, 1)
+RVV_VECTOR_TYPE_BFLOAT("__rvv_bfloat16mf2_t", RvvBFloat16mf2, RvvBFloat16mf2Ty,
+ 2, 16, 1)
+RVV_VECTOR_TYPE_BFLOAT("__rvv_bfloat16m1_t", RvvBFloat16m1, RvvBFloat16m1Ty, 4,
+ 16, 1)
+RVV_VECTOR_TYPE_BFLOAT("__rvv_bfloat16m2_t", RvvBFloat16m2, RvvBFloat16m2Ty, 8,
+ 16, 1)
+RVV_VECTOR_TYPE_BFLOAT("__rvv_bfloat16m4_t", RvvBFloat16m4, RvvBFloat16m4Ty, 16,
+ 16, 1)
+RVV_VECTOR_TYPE_BFLOAT("__rvv_bfloat16m8_t", RvvBFloat16m8, RvvBFloat16m8Ty, 32,
+ 16, 1)
+
RVV_VECTOR_TYPE_FLOAT("__rvv_float32mf2_t",RvvFloat32mf2,RvvFloat32mf2Ty,1, 32, 1)
RVV_VECTOR_TYPE_FLOAT("__rvv_float32m1_t", RvvFloat32m1, RvvFloat32m1Ty, 2, 32, 1)
RVV_VECTOR_TYPE_FLOAT("__rvv_float32m2_t", RvvFloat32m2, RvvFloat32m2Ty, 4, 32, 1)
@@ -140,6 +166,349 @@ RVV_PREDICATE_TYPE("__rvv_bool16_t", RvvBool16, RvvBool16Ty, 4)
RVV_PREDICATE_TYPE("__rvv_bool32_t", RvvBool32, RvvBool32Ty, 2)
RVV_PREDICATE_TYPE("__rvv_bool64_t", RvvBool64, RvvBool64Ty, 1)
+//===- Tuple vector types -------------------------------------------------===//
+//===- Int8 tuple types --------------------------------------------------===//
+RVV_VECTOR_TYPE_INT("__rvv_int8mf8x2_t", RvvInt8mf8x2, RvvInt8mf8x2Ty, 1, 8, 2, true)
+RVV_VECTOR_TYPE_INT("__rvv_int8mf8x3_t", RvvInt8mf8x3, RvvInt8mf8x3Ty, 1, 8, 3, true)
+RVV_VECTOR_TYPE_INT("__rvv_int8mf8x4_t", RvvInt8mf8x4, RvvInt8mf8x4Ty, 1, 8, 4, true)
+RVV_VECTOR_TYPE_INT("__rvv_int8mf8x5_t", RvvInt8mf8x5, RvvInt8mf8x5Ty, 1, 8, 5, true)
+RVV_VECTOR_TYPE_INT("__rvv_int8mf8x6_t", RvvInt8mf8x6, RvvInt8mf8x6Ty, 1, 8, 6, true)
+RVV_VECTOR_TYPE_INT("__rvv_int8mf8x7_t", RvvInt8mf8x7, RvvInt8mf8x7Ty, 1, 8, 7, true)
+RVV_VECTOR_TYPE_INT("__rvv_int8mf8x8_t", RvvInt8mf8x8, RvvInt8mf8x8Ty, 1, 8, 8, true)
+
+RVV_VECTOR_TYPE_INT("__rvv_int8mf4x2_t", RvvInt8mf4x2, RvvInt8mf4x2Ty, 2, 8, 2, true)
+RVV_VECTOR_TYPE_INT("__rvv_int8mf4x3_t", RvvInt8mf4x3, RvvInt8mf4x3Ty, 2, 8, 3, true)
+RVV_VECTOR_TYPE_INT("__rvv_int8mf4x4_t", RvvInt8mf4x4, RvvInt8mf4x4Ty, 2, 8, 4, true)
+RVV_VECTOR_TYPE_INT("__rvv_int8mf4x5_t", RvvInt8mf4x5, RvvInt8mf4x5Ty, 2, 8, 5, true)
+RVV_VECTOR_TYPE_INT("__rvv_int8mf4x6_t", RvvInt8mf4x6, RvvInt8mf4x6Ty, 2, 8, 6, true)
+RVV_VECTOR_TYPE_INT("__rvv_int8mf4x7_t", RvvInt8mf4x7, RvvInt8mf4x7Ty, 2, 8, 7, true)
+RVV_VECTOR_TYPE_INT("__rvv_int8mf4x8_t", RvvInt8mf4x8, RvvInt8mf4x8Ty, 2, 8, 8, true)
+
+RVV_VECTOR_TYPE_INT("__rvv_int8mf2x2_t", RvvInt8mf2x2, RvvInt8mf2x2Ty, 4, 8, 2, true)
+RVV_VECTOR_TYPE_INT("__rvv_int8mf2x3_t", RvvInt8mf2x3, RvvInt8mf2x3Ty, 4, 8, 3, true)
+RVV_VECTOR_TYPE_INT("__rvv_int8mf2x4_t", RvvInt8mf2x4, RvvInt8mf2x4Ty, 4, 8, 4, true)
+RVV_VECTOR_TYPE_INT("__rvv_int8mf2x5_t", RvvInt8mf2x5, RvvInt8mf2x5Ty, 4, 8, 5, true)
+RVV_VECTOR_TYPE_INT("__rvv_int8mf2x6_t", RvvInt8mf2x6, RvvInt8mf2x6Ty, 4, 8, 6, true)
+RVV_VECTOR_TYPE_INT("__rvv_int8mf2x7_t", RvvInt8mf2x7, RvvInt8mf2x7Ty, 4, 8, 7, true)
+RVV_VECTOR_TYPE_INT("__rvv_int8mf2x8_t", RvvInt8mf2x8, RvvInt8mf2x8Ty, 4, 8, 8, true)
+
+RVV_VECTOR_TYPE_INT("__rvv_int8m1x2_t", RvvInt8m1x2, RvvInt8m1x2Ty, 8, 8, 2, true)
+RVV_VECTOR_TYPE_INT("__rvv_int8m1x3_t", RvvInt8m1x3, RvvInt8m1x3Ty, 8, 8, 3, true)
+RVV_VECTOR_TYPE_INT("__rvv_int8m1x4_t", RvvInt8m1x4, RvvInt8m1x4Ty, 8, 8, 4, true)
+RVV_VECTOR_TYPE_INT("__rvv_int8m1x5_t", RvvInt8m1x5, RvvInt8m1x5Ty, 8, 8, 5, true)
+RVV_VECTOR_TYPE_INT("__rvv_int8m1x6_t", RvvInt8m1x6, RvvInt8m1x6Ty, 8, 8, 6, true)
+RVV_VECTOR_TYPE_INT("__rvv_int8m1x7_t", RvvInt8m1x7, RvvInt8m1x7Ty, 8, 8, 7, true)
+RVV_VECTOR_TYPE_INT("__rvv_int8m1x8_t", RvvInt8m1x8, RvvInt8m1x8Ty, 8, 8, 8, true)
+
+RVV_VECTOR_TYPE_INT("__rvv_int8m2x2_t", RvvInt8m2x2, RvvInt8m2x2Ty, 16, 8, 2, true)
+RVV_VECTOR_TYPE_INT("__rvv_int8m2x3_t", RvvInt8m2x3, RvvInt8m2x3Ty, 16, 8, 3, true)
+RVV_VECTOR_TYPE_INT("__rvv_int8m2x4_t", RvvInt8m2x4, RvvInt8m2x4Ty, 16, 8, 4, true)
+
+RVV_VECTOR_TYPE_INT("__rvv_int8m4x2_t", RvvInt8m4x2, RvvInt8m4x2Ty, 32, 8, 2, true)
+
+//===- Uint8 tuple types -------------------------------------------------===//
+RVV_VECTOR_TYPE_INT("__rvv_uint8mf8x2_t", RvvUint8mf8x2, RvvUint8mf8x2Ty, 1, 8, 2, false)
+RVV_VECTOR_TYPE_INT("__rvv_uint8mf8x3_t", RvvUint8mf8x3, RvvUint8mf8x3Ty, 1, 8, 3, false)
+RVV_VECTOR_TYPE_INT("__rvv_uint8mf8x4_t", RvvUint8mf8x4, RvvUint8mf8x4Ty, 1, 8, 4, false)
+RVV_VECTOR_TYPE_INT("__rvv_uint8mf8x5_t", RvvUint8mf8x5, RvvUint8mf8x5Ty, 1, 8, 5, false)
+RVV_VECTOR_TYPE_INT("__rvv_uint8mf8x6_t", RvvUint8mf8x6, RvvUint8mf8x6Ty, 1, 8, 6, false)
+RVV_VECTOR_TYPE_INT("__rvv_uint8mf8x7_t", RvvUint8mf8x7, RvvUint8mf8x7Ty, 1, 8, 7, false)
+RVV_VECTOR_TYPE_INT("__rvv_uint8mf8x8_t", RvvUint8mf8x8, RvvUint8mf8x8Ty, 1, 8, 8, false)
+
+RVV_VECTOR_TYPE_INT("__rvv_uint8mf4x2_t", RvvUint8mf4x2, RvvUint8mf4x2Ty, 2, 8, 2, false)
+RVV_VECTOR_TYPE_INT("__rvv_uint8mf4x3_t", RvvUint8mf4x3, RvvUint8mf4x3Ty, 2, 8, 3, false)
+RVV_VECTOR_TYPE_INT("__rvv_uint8mf4x4_t", RvvUint8mf4x4, RvvUint8mf4x4Ty, 2, 8, 4, false)
+RVV_VECTOR_TYPE_INT("__rvv_uint8mf4x5_t", RvvUint8mf4x5, RvvUint8mf4x5Ty, 2, 8, 5, false)
+RVV_VECTOR_TYPE_INT("__rvv_uint8mf4x6_t", RvvUint8mf4x6, RvvUint8mf4x6Ty, 2, 8, 6, false)
+RVV_VECTOR_TYPE_INT("__rvv_uint8mf4x7_t", RvvUint8mf4x7, RvvUint8mf4x7Ty, 2, 8, 7, false)
+RVV_VECTOR_TYPE_INT("__rvv_uint8mf4x8_t", RvvUint8mf4x8, RvvUint8mf4x8Ty, 2, 8, 8, false)
+
+RVV_VECTOR_TYPE_INT("__rvv_uint8mf2x2_t", RvvUint8mf2x2, RvvUint8mf2x2Ty, 4, 8, 2, false)
+RVV_VECTOR_TYPE_INT("__rvv_uint8mf2x3_t", RvvUint8mf2x3, RvvUint8mf2x3Ty, 4, 8, 3, false)
+RVV_VECTOR_TYPE_INT("__rvv_uint8mf2x4_t", RvvUint8mf2x4, RvvUint8mf2x4Ty, 4, 8, 4, false)
+RVV_VECTOR_TYPE_INT("__rvv_uint8mf2x5_t", RvvUint8mf2x5, RvvUint8mf2x5Ty, 4, 8, 5, false)
+RVV_VECTOR_TYPE_INT("__rvv_uint8mf2x6_t", RvvUint8mf2x6, RvvUint8mf2x6Ty, 4, 8, 6, false)
+RVV_VECTOR_TYPE_INT("__rvv_uint8mf2x7_t", RvvUint8mf2x7, RvvUint8mf2x7Ty, 4, 8, 7, false)
+RVV_VECTOR_TYPE_INT("__rvv_uint8mf2x8_t", RvvUint8mf2x8, RvvUint8mf2x8Ty, 4, 8, 8, false)
+
+RVV_VECTOR_TYPE_INT("__rvv_uint8m1x2_t", RvvUint8m1x2, RvvUint8m1x2Ty, 8, 8, 2, false)
+RVV_VECTOR_TYPE_INT("__rvv_uint8m1x3_t", RvvUint8m1x3, RvvUint8m1x3Ty, 8, 8, 3, false)
+RVV_VECTOR_TYPE_INT("__rvv_uint8m1x4_t", RvvUint8m1x4, RvvUint8m1x4Ty, 8, 8, 4, false)
+RVV_VECTOR_TYPE_INT("__rvv_uint8m1x5_t", RvvUint8m1x5, RvvUint8m1x5Ty, 8, 8, 5, false)
+RVV_VECTOR_TYPE_INT("__rvv_uint8m1x6_t", RvvUint8m1x6, RvvUint8m1x6Ty, 8, 8, 6, false)
+RVV_VECTOR_TYPE_INT("__rvv_uint8m1x7_t", RvvUint8m1x7, RvvUint8m1x7Ty, 8, 8, 7, false)
+RVV_VECTOR_TYPE_INT("__rvv_uint8m1x8_t", RvvUint8m1x8, RvvUint8m1x8Ty, 8, 8, 8, false)
+
+RVV_VECTOR_TYPE_INT("__rvv_uint8m2x2_t", RvvUint8m2x2, RvvUint8m2x2Ty, 16, 8, 2, false)
+RVV_VECTOR_TYPE_INT("__rvv_uint8m2x3_t", RvvUint8m2x3, RvvUint8m2x3Ty, 16, 8, 3, false)
+RVV_VECTOR_TYPE_INT("__rvv_uint8m2x4_t", RvvUint8m2x4, RvvUint8m2x4Ty, 16, 8, 4, false)
+
+RVV_VECTOR_TYPE_INT("__rvv_uint8m4x2_t", RvvUint8m4x2, RvvUint8m4x2Ty, 32, 8, 2, false)
+
+//===- Int16 tuple types --------------------------------------------------===//
+RVV_VECTOR_TYPE_INT("__rvv_int16mf4x2_t", RvvInt16mf4x2, RvvInt16mf4x2Ty, 1, 16, 2, true)
+RVV_VECTOR_TYPE_INT("__rvv_int16mf4x3_t", RvvInt16mf4x3, RvvInt16mf4x3Ty, 1, 16, 3, true)
+RVV_VECTOR_TYPE_INT("__rvv_int16mf4x4_t", RvvInt16mf4x4, RvvInt16mf4x4Ty, 1, 16, 4, true)
+RVV_VECTOR_TYPE_INT("__rvv_int16mf4x5_t", RvvInt16mf4x5, RvvInt16mf4x5Ty, 1, 16, 5, true)
+RVV_VECTOR_TYPE_INT("__rvv_int16mf4x6_t", RvvInt16mf4x6, RvvInt16mf4x6Ty, 1, 16, 6, true)
+RVV_VECTOR_TYPE_INT("__rvv_int16mf4x7_t", RvvInt16mf4x7, RvvInt16mf4x7Ty, 1, 16, 7, true)
+RVV_VECTOR_TYPE_INT("__rvv_int16mf4x8_t", RvvInt16mf4x8, RvvInt16mf4x8Ty, 1, 16, 8, true)
+
+RVV_VECTOR_TYPE_INT("__rvv_int16mf2x2_t", RvvInt16mf2x2, RvvInt16mf2x2Ty, 2, 16, 2, true)
+RVV_VECTOR_TYPE_INT("__rvv_int16mf2x3_t", RvvInt16mf2x3, RvvInt16mf2x3Ty, 2, 16, 3, true)
+RVV_VECTOR_TYPE_INT("__rvv_int16mf2x4_t", RvvInt16mf2x4, RvvInt16mf2x4Ty, 2, 16, 4, true)
+RVV_VECTOR_TYPE_INT("__rvv_int16mf2x5_t", RvvInt16mf2x5, RvvInt16mf2x5Ty, 2, 16, 5, true)
+RVV_VECTOR_TYPE_INT("__rvv_int16mf2x6_t", RvvInt16mf2x6, RvvInt16mf2x6Ty, 2, 16, 6, true)
+RVV_VECTOR_TYPE_INT("__rvv_int16mf2x7_t", RvvInt16mf2x7, RvvInt16mf2x7Ty, 2, 16, 7, true)
+RVV_VECTOR_TYPE_INT("__rvv_int16mf2x8_t", RvvInt16mf2x8, RvvInt16mf2x8Ty, 2, 16, 8, true)
+
+RVV_VECTOR_TYPE_INT("__rvv_int16m1x2_t", RvvInt16m1x2, RvvInt16m1x2Ty, 4, 16, 2, true)
+RVV_VECTOR_TYPE_INT("__rvv_int16m1x3_t", RvvInt16m1x3, RvvInt16m1x3Ty, 4, 16, 3, true)
+RVV_VECTOR_TYPE_INT("__rvv_int16m1x4_t", RvvInt16m1x4, RvvInt16m1x4Ty, 4, 16, 4, true)
+RVV_VECTOR_TYPE_INT("__rvv_int16m1x5_t", RvvInt16m1x5, RvvInt16m1x5Ty, 4, 16, 5, true)
+RVV_VECTOR_TYPE_INT("__rvv_int16m1x6_t", RvvInt16m1x6, RvvInt16m1x6Ty, 4, 16, 6, true)
+RVV_VECTOR_TYPE_INT("__rvv_int16m1x7_t", RvvInt16m1x7, RvvInt16m1x7Ty, 4, 16, 7, true)
+RVV_VECTOR_TYPE_INT("__rvv_int16m1x8_t", RvvInt16m1x8, RvvInt16m1x8Ty, 4, 16, 8, true)
+
+RVV_VECTOR_TYPE_INT("__rvv_int16m2x2_t", RvvInt16m2x2, RvvInt16m2x2Ty, 8, 16, 2, true)
+RVV_VECTOR_TYPE_INT("__rvv_int16m2x3_t", RvvInt16m2x3, RvvInt16m2x3Ty, 8, 16, 3, true)
+RVV_VECTOR_TYPE_INT("__rvv_int16m2x4_t", RvvInt16m2x4, RvvInt16m2x4Ty, 8, 16, 4, true)
+
+RVV_VECTOR_TYPE_INT("__rvv_int16m4x2_t", RvvInt16m4x2, RvvInt16m4x2Ty, 16, 16, 2, true)
+
+//===- Uint16 tuple types -------------------------------------------------===//
+RVV_VECTOR_TYPE_INT("__rvv_uint16mf4x2_t", RvvUint16mf4x2, RvvUint16mf4x2Ty, 1, 16, 2, false)
+RVV_VECTOR_TYPE_INT("__rvv_uint16mf4x3_t", RvvUint16mf4x3, RvvUint16mf4x3Ty, 1, 16, 3, false)
+RVV_VECTOR_TYPE_INT("__rvv_uint16mf4x4_t", RvvUint16mf4x4, RvvUint16mf4x4Ty, 1, 16, 4, false)
+RVV_VECTOR_TYPE_INT("__rvv_uint16mf4x5_t", RvvUint16mf4x5, RvvUint16mf4x5Ty, 1, 16, 5, false)
+RVV_VECTOR_TYPE_INT("__rvv_uint16mf4x6_t", RvvUint16mf4x6, RvvUint16mf4x6Ty, 1, 16, 6, false)
+RVV_VECTOR_TYPE_INT("__rvv_uint16mf4x7_t", RvvUint16mf4x7, RvvUint16mf4x7Ty, 1, 16, 7, false)
+RVV_VECTOR_TYPE_INT("__rvv_uint16mf4x8_t", RvvUint16mf4x8, RvvUint16mf4x8Ty, 1, 16, 8, false)
+
+RVV_VECTOR_TYPE_INT("__rvv_uint16mf2x2_t", RvvUint16mf2x2, RvvUint16mf2x2Ty, 2, 16, 2, false)
+RVV_VECTOR_TYPE_INT("__rvv_uint16mf2x3_t", RvvUint16mf2x3, RvvUint16mf2x3Ty, 2, 16, 3, false)
+RVV_VECTOR_TYPE_INT("__rvv_uint16mf2x4_t", RvvUint16mf2x4, RvvUint16mf2x4Ty, 2, 16, 4, false)
+RVV_VECTOR_TYPE_INT("__rvv_uint16mf2x5_t", RvvUint16mf2x5, RvvUint16mf2x5Ty, 2, 16, 5, false)
+RVV_VECTOR_TYPE_INT("__rvv_uint16mf2x6_t", RvvUint16mf2x6, RvvUint16mf2x6Ty, 2, 16, 6, false)
+RVV_VECTOR_TYPE_INT("__rvv_uint16mf2x7_t", RvvUint16mf2x7, RvvUint16mf2x7Ty, 2, 16, 7, false)
+RVV_VECTOR_TYPE_INT("__rvv_uint16mf2x8_t", RvvUint16mf2x8, RvvUint16mf2x8Ty, 2, 16, 8, false)
+
+RVV_VECTOR_TYPE_INT("__rvv_uint16m1x2_t", RvvUint16m1x2, RvvUint16m1x2Ty, 4, 16, 2, false)
+RVV_VECTOR_TYPE_INT("__rvv_uint16m1x3_t", RvvUint16m1x3, RvvUint16m1x3Ty, 4, 16, 3, false)
+RVV_VECTOR_TYPE_INT("__rvv_uint16m1x4_t", RvvUint16m1x4, RvvUint16m1x4Ty, 4, 16, 4, false)
+RVV_VECTOR_TYPE_INT("__rvv_uint16m1x5_t", RvvUint16m1x5, RvvUint16m1x5Ty, 4, 16, 5, false)
+RVV_VECTOR_TYPE_INT("__rvv_uint16m1x6_t", RvvUint16m1x6, RvvUint16m1x6Ty, 4, 16, 6, false)
+RVV_VECTOR_TYPE_INT("__rvv_uint16m1x7_t", RvvUint16m1x7, RvvUint16m1x7Ty, 4, 16, 7, false)
+RVV_VECTOR_TYPE_INT("__rvv_uint16m1x8_t", RvvUint16m1x8, RvvUint16m1x8Ty, 4, 16, 8, false)
+
+RVV_VECTOR_TYPE_INT("__rvv_uint16m2x2_t", RvvUint16m2x2, RvvUint16m2x2Ty, 8, 16, 2, false)
+RVV_VECTOR_TYPE_INT("__rvv_uint16m2x3_t", RvvUint16m2x3, RvvUint16m2x3Ty, 8, 16, 3, false)
+RVV_VECTOR_TYPE_INT("__rvv_uint16m2x4_t", RvvUint16m2x4, RvvUint16m2x4Ty, 8, 16, 4, false)
+
+RVV_VECTOR_TYPE_INT("__rvv_uint16m4x2_t", RvvUint16m4x2, RvvUint16m4x2Ty, 16, 16, 2, false)
+
+//===- Int32 tuple types --------------------------------------------------===//
+RVV_VECTOR_TYPE_INT("__rvv_int32mf2x2_t", RvvInt32mf2x2, RvvInt32mf2x2Ty, 1, 32, 2, true)
+RVV_VECTOR_TYPE_INT("__rvv_int32mf2x3_t", RvvInt32mf2x3, RvvInt32mf2x3Ty, 1, 32, 3, true)
+RVV_VECTOR_TYPE_INT("__rvv_int32mf2x4_t", RvvInt32mf2x4, RvvInt32mf2x4Ty, 1, 32, 4, true)
+RVV_VECTOR_TYPE_INT("__rvv_int32mf2x5_t", RvvInt32mf2x5, RvvInt32mf2x5Ty, 1, 32, 5, true)
+RVV_VECTOR_TYPE_INT("__rvv_int32mf2x6_t", RvvInt32mf2x6, RvvInt32mf2x6Ty, 1, 32, 6, true)
+RVV_VECTOR_TYPE_INT("__rvv_int32mf2x7_t", RvvInt32mf2x7, RvvInt32mf2x7Ty, 1, 32, 7, true)
+RVV_VECTOR_TYPE_INT("__rvv_int32mf2x8_t", RvvInt32mf2x8, RvvInt32mf2x8Ty, 1, 32, 8, true)
+
+RVV_VECTOR_TYPE_INT("__rvv_int32m1x2_t", RvvInt32m1x2, RvvInt32m1x2Ty, 2, 32, 2, true)
+RVV_VECTOR_TYPE_INT("__rvv_int32m1x3_t", RvvInt32m1x3, RvvInt32m1x3Ty, 2, 32, 3, true)
+RVV_VECTOR_TYPE_INT("__rvv_int32m1x4_t", RvvInt32m1x4, RvvInt32m1x4Ty, 2, 32, 4, true)
+RVV_VECTOR_TYPE_INT("__rvv_int32m1x5_t", RvvInt32m1x5, RvvInt32m1x5Ty, 2, 32, 5, true)
+RVV_VECTOR_TYPE_INT("__rvv_int32m1x6_t", RvvInt32m1x6, RvvInt32m1x6Ty, 2, 32, 6, true)
+RVV_VECTOR_TYPE_INT("__rvv_int32m1x7_t", RvvInt32m1x7, RvvInt32m1x7Ty, 2, 32, 7, true)
+RVV_VECTOR_TYPE_INT("__rvv_int32m1x8_t", RvvInt32m1x8, RvvInt32m1x8Ty, 2, 32, 8, true)
+
+RVV_VECTOR_TYPE_INT("__rvv_int32m2x2_t", RvvInt32m2x2, RvvInt32m2x2Ty, 4, 32, 2, true)
+RVV_VECTOR_TYPE_INT("__rvv_int32m2x3_t", RvvInt32m2x3, RvvInt32m2x3Ty, 4, 32, 3, true)
+RVV_VECTOR_TYPE_INT("__rvv_int32m2x4_t", RvvInt32m2x4, RvvInt32m2x4Ty, 4, 32, 4, true)
+
+RVV_VECTOR_TYPE_INT("__rvv_int32m4x2_t", RvvInt32m4x2, RvvInt32m4x2Ty, 8, 32, 2, true)
+
+//===- Uint32 tuple types -------------------------------------------------===//
+RVV_VECTOR_TYPE_INT("__rvv_uint32mf2x2_t", RvvUint32mf2x2, RvvUint32mf2x2Ty, 1, 32, 2, false)
+RVV_VECTOR_TYPE_INT("__rvv_uint32mf2x3_t", RvvUint32mf2x3, RvvUint32mf2x3Ty, 1, 32, 3, false)
+RVV_VECTOR_TYPE_INT("__rvv_uint32mf2x4_t", RvvUint32mf2x4, RvvUint32mf2x4Ty, 1, 32, 4, false)
+RVV_VECTOR_TYPE_INT("__rvv_uint32mf2x5_t", RvvUint32mf2x5, RvvUint32mf2x5Ty, 1, 32, 5, false)
+RVV_VECTOR_TYPE_INT("__rvv_uint32mf2x6_t", RvvUint32mf2x6, RvvUint32mf2x6Ty, 1, 32, 6, false)
+RVV_VECTOR_TYPE_INT("__rvv_uint32mf2x7_t", RvvUint32mf2x7, RvvUint32mf2x7Ty, 1, 32, 7, false)
+RVV_VECTOR_TYPE_INT("__rvv_uint32mf2x8_t", RvvUint32mf2x8, RvvUint32mf2x8Ty, 1, 32, 8, false)
+
+RVV_VECTOR_TYPE_INT("__rvv_uint32m1x2_t", RvvUint32m1x2, RvvUint32m1x2Ty, 2, 32, 2, false)
+RVV_VECTOR_TYPE_INT("__rvv_uint32m1x3_t", RvvUint32m1x3, RvvUint32m1x3Ty, 2, 32, 3, false)
+RVV_VECTOR_TYPE_INT("__rvv_uint32m1x4_t", RvvUint32m1x4, RvvUint32m1x4Ty, 2, 32, 4, false)
+RVV_VECTOR_TYPE_INT("__rvv_uint32m1x5_t", RvvUint32m1x5, RvvUint32m1x5Ty, 2, 32, 5, false)
+RVV_VECTOR_TYPE_INT("__rvv_uint32m1x6_t", RvvUint32m1x6, RvvUint32m1x6Ty, 2, 32, 6, false)
+RVV_VECTOR_TYPE_INT("__rvv_uint32m1x7_t", RvvUint32m1x7, RvvUint32m1x7Ty, 2, 32, 7, false)
+RVV_VECTOR_TYPE_INT("__rvv_uint32m1x8_t", RvvUint32m1x8, RvvUint32m1x8Ty, 2, 32, 8, false)
+
+RVV_VECTOR_TYPE_INT("__rvv_uint32m2x2_t", RvvUint32m2x2, RvvUint32m2x2Ty, 4, 32, 2, false)
+RVV_VECTOR_TYPE_INT("__rvv_uint32m2x3_t", RvvUint32m2x3, RvvUint32m2x3Ty, 4, 32, 3, false)
+RVV_VECTOR_TYPE_INT("__rvv_uint32m2x4_t", RvvUint32m2x4, RvvUint32m2x4Ty, 4, 32, 4, false)
+
+RVV_VECTOR_TYPE_INT("__rvv_uint32m4x2_t", RvvUint32m4x2, RvvUint32m4x2Ty, 8, 32, 2, false)
+
+//===- Int64 tuple types -------------------------------------------------===//
+RVV_VECTOR_TYPE_INT("__rvv_int64m1x2_t", RvvInt64m1x2, RvvInt64m1x2Ty, 1, 64, 2, true)
+RVV_VECTOR_TYPE_INT("__rvv_int64m1x3_t", RvvInt64m1x3, RvvInt64m1x3Ty, 1, 64, 3, true)
+RVV_VECTOR_TYPE_INT("__rvv_int64m1x4_t", RvvInt64m1x4, RvvInt64m1x4Ty, 1, 64, 4, true)
+RVV_VECTOR_TYPE_INT("__rvv_int64m1x5_t", RvvInt64m1x5, RvvInt64m1x5Ty, 1, 64, 5, true)
+RVV_VECTOR_TYPE_INT("__rvv_int64m1x6_t", RvvInt64m1x6, RvvInt64m1x6Ty, 1, 64, 6, true)
+RVV_VECTOR_TYPE_INT("__rvv_int64m1x7_t", RvvInt64m1x7, RvvInt64m1x7Ty, 1, 64, 7, true)
+RVV_VECTOR_TYPE_INT("__rvv_int64m1x8_t", RvvInt64m1x8, RvvInt64m1x8Ty, 1, 64, 8, true)
+
+RVV_VECTOR_TYPE_INT("__rvv_int64m2x2_t", RvvInt64m2x2, RvvInt64m2x2Ty, 2, 64, 2, true)
+RVV_VECTOR_TYPE_INT("__rvv_int64m2x3_t", RvvInt64m2x3, RvvInt64m2x3Ty, 2, 64, 3, true)
+RVV_VECTOR_TYPE_INT("__rvv_int64m2x4_t", RvvInt64m2x4, RvvInt64m2x4Ty, 2, 64, 4, true)
+
+RVV_VECTOR_TYPE_INT("__rvv_int64m4x2_t", RvvInt64m4x2, RvvInt64m4x2Ty, 4, 64, 2, true)
+
+//===- Uint64 tuple types -------------------------------------------------===//
+RVV_VECTOR_TYPE_INT("__rvv_uint64m1x2_t", RvvUint64m1x2, RvvUint64m1x2Ty, 1, 64, 2, false)
+RVV_VECTOR_TYPE_INT("__rvv_uint64m1x3_t", RvvUint64m1x3, RvvUint64m1x3Ty, 1, 64, 3, false)
+RVV_VECTOR_TYPE_INT("__rvv_uint64m1x4_t", RvvUint64m1x4, RvvUint64m1x4Ty, 1, 64, 4, false)
+RVV_VECTOR_TYPE_INT("__rvv_uint64m1x5_t", RvvUint64m1x5, RvvUint64m1x5Ty, 1, 64, 5, false)
+RVV_VECTOR_TYPE_INT("__rvv_uint64m1x6_t", RvvUint64m1x6, RvvUint64m1x6Ty, 1, 64, 6, false)
+RVV_VECTOR_TYPE_INT("__rvv_uint64m1x7_t", RvvUint64m1x7, RvvUint64m1x7Ty, 1, 64, 7, false)
+RVV_VECTOR_TYPE_INT("__rvv_uint64m1x8_t", RvvUint64m1x8, RvvUint64m1x8Ty, 1, 64, 8, false)
+
+RVV_VECTOR_TYPE_INT("__rvv_uint64m2x2_t", RvvUint64m2x2, RvvUint64m2x2Ty, 2, 64, 2, false)
+RVV_VECTOR_TYPE_INT("__rvv_uint64m2x3_t", RvvUint64m2x3, RvvUint64m2x3Ty, 2, 64, 3, false)
+RVV_VECTOR_TYPE_INT("__rvv_uint64m2x4_t", RvvUint64m2x4, RvvUint64m2x4Ty, 2, 64, 4, false)
+
+RVV_VECTOR_TYPE_INT("__rvv_uint64m4x2_t", RvvUint64m4x2, RvvUint64m4x2Ty, 4, 64, 2, false)
+
+//===- Float16 tuple types --------------------------------------------------===//
+RVV_VECTOR_TYPE_FLOAT("__rvv_float16mf4x2_t", RvvFloat16mf4x2, RvvFloat16mf4x2Ty, 1, 16, 2)
+RVV_VECTOR_TYPE_FLOAT("__rvv_float16mf4x3_t", RvvFloat16mf4x3, RvvFloat16mf4x3Ty, 1, 16, 3)
+RVV_VECTOR_TYPE_FLOAT("__rvv_float16mf4x4_t", RvvFloat16mf4x4, RvvFloat16mf4x4Ty, 1, 16, 4)
+RVV_VECTOR_TYPE_FLOAT("__rvv_float16mf4x5_t", RvvFloat16mf4x5, RvvFloat16mf4x5Ty, 1, 16, 5)
+RVV_VECTOR_TYPE_FLOAT("__rvv_float16mf4x6_t", RvvFloat16mf4x6, RvvFloat16mf4x6Ty, 1, 16, 6)
+RVV_VECTOR_TYPE_FLOAT("__rvv_float16mf4x7_t", RvvFloat16mf4x7, RvvFloat16mf4x7Ty, 1, 16, 7)
+RVV_VECTOR_TYPE_FLOAT("__rvv_float16mf4x8_t", RvvFloat16mf4x8, RvvFloat16mf4x8Ty, 1, 16, 8)
+
+RVV_VECTOR_TYPE_FLOAT("__rvv_float16mf2x2_t", RvvFloat16mf2x2, RvvFloat16mf2x2Ty, 2, 16, 2)
+RVV_VECTOR_TYPE_FLOAT("__rvv_float16mf2x3_t", RvvFloat16mf2x3, RvvFloat16mf2x3Ty, 2, 16, 3)
+RVV_VECTOR_TYPE_FLOAT("__rvv_float16mf2x4_t", RvvFloat16mf2x4, RvvFloat16mf2x4Ty, 2, 16, 4)
+RVV_VECTOR_TYPE_FLOAT("__rvv_float16mf2x5_t", RvvFloat16mf2x5, RvvFloat16mf2x5Ty, 2, 16, 5)
+RVV_VECTOR_TYPE_FLOAT("__rvv_float16mf2x6_t", RvvFloat16mf2x6, RvvFloat16mf2x6Ty, 2, 16, 6)
+RVV_VECTOR_TYPE_FLOAT("__rvv_float16mf2x7_t", RvvFloat16mf2x7, RvvFloat16mf2x7Ty, 2, 16, 7)
+RVV_VECTOR_TYPE_FLOAT("__rvv_float16mf2x8_t", RvvFloat16mf2x8, RvvFloat16mf2x8Ty, 2, 16, 8)
+
+RVV_VECTOR_TYPE_FLOAT("__rvv_float16m1x2_t", RvvFloat16m1x2, RvvFloat16m1x2Ty, 4, 16, 2)
+RVV_VECTOR_TYPE_FLOAT("__rvv_float16m1x3_t", RvvFloat16m1x3, RvvFloat16m1x3Ty, 4, 16, 3)
+RVV_VECTOR_TYPE_FLOAT("__rvv_float16m1x4_t", RvvFloat16m1x4, RvvFloat16m1x4Ty, 4, 16, 4)
+RVV_VECTOR_TYPE_FLOAT("__rvv_float16m1x5_t", RvvFloat16m1x5, RvvFloat16m1x5Ty, 4, 16, 5)
+RVV_VECTOR_TYPE_FLOAT("__rvv_float16m1x6_t", RvvFloat16m1x6, RvvFloat16m1x6Ty, 4, 16, 6)
+RVV_VECTOR_TYPE_FLOAT("__rvv_float16m1x7_t", RvvFloat16m1x7, RvvFloat16m1x7Ty, 4, 16, 7)
+RVV_VECTOR_TYPE_FLOAT("__rvv_float16m1x8_t", RvvFloat16m1x8, RvvFloat16m1x8Ty, 4, 16, 8)
+
+RVV_VECTOR_TYPE_FLOAT("__rvv_float16m2x2_t", RvvFloat16m2x2, RvvFloat16m2x2Ty, 8, 16, 2)
+RVV_VECTOR_TYPE_FLOAT("__rvv_float16m2x3_t", RvvFloat16m2x3, RvvFloat16m2x3Ty, 8, 16, 3)
+RVV_VECTOR_TYPE_FLOAT("__rvv_float16m2x4_t", RvvFloat16m2x4, RvvFloat16m2x4Ty, 8, 16, 4)
+
+RVV_VECTOR_TYPE_FLOAT("__rvv_float16m4x2_t", RvvFloat16m4x2, RvvFloat16m4x2Ty, 16, 16, 2)
+
+//===- Float32 tuple types --------------------------------------------------===//
+RVV_VECTOR_TYPE_FLOAT("__rvv_float32mf2x2_t", RvvFloat32mf2x2, RvvFloat32mf2x2Ty, 1, 32, 2)
+RVV_VECTOR_TYPE_FLOAT("__rvv_float32mf2x3_t", RvvFloat32mf2x3, RvvFloat32mf2x3Ty, 1, 32, 3)
+RVV_VECTOR_TYPE_FLOAT("__rvv_float32mf2x4_t", RvvFloat32mf2x4, RvvFloat32mf2x4Ty, 1, 32, 4)
+RVV_VECTOR_TYPE_FLOAT("__rvv_float32mf2x5_t", RvvFloat32mf2x5, RvvFloat32mf2x5Ty, 1, 32, 5)
+RVV_VECTOR_TYPE_FLOAT("__rvv_float32mf2x6_t", RvvFloat32mf2x6, RvvFloat32mf2x6Ty, 1, 32, 6)
+RVV_VECTOR_TYPE_FLOAT("__rvv_float32mf2x7_t", RvvFloat32mf2x7, RvvFloat32mf2x7Ty, 1, 32, 7)
+RVV_VECTOR_TYPE_FLOAT("__rvv_float32mf2x8_t", RvvFloat32mf2x8, RvvFloat32mf2x8Ty, 1, 32, 8)
+
+RVV_VECTOR_TYPE_FLOAT("__rvv_float32m1x2_t", RvvFloat32m1x2, RvvFloat32m1x2Ty, 2, 32, 2)
+RVV_VECTOR_TYPE_FLOAT("__rvv_float32m1x3_t", RvvFloat32m1x3, RvvFloat32m1x3Ty, 2, 32, 3)
+RVV_VECTOR_TYPE_FLOAT("__rvv_float32m1x4_t", RvvFloat32m1x4, RvvFloat32m1x4Ty, 2, 32, 4)
+RVV_VECTOR_TYPE_FLOAT("__rvv_float32m1x5_t", RvvFloat32m1x5, RvvFloat32m1x5Ty, 2, 32, 5)
+RVV_VECTOR_TYPE_FLOAT("__rvv_float32m1x6_t", RvvFloat32m1x6, RvvFloat32m1x6Ty, 2, 32, 6)
+RVV_VECTOR_TYPE_FLOAT("__rvv_float32m1x7_t", RvvFloat32m1x7, RvvFloat32m1x7Ty, 2, 32, 7)
+RVV_VECTOR_TYPE_FLOAT("__rvv_float32m1x8_t", RvvFloat32m1x8, RvvFloat32m1x8Ty, 2, 32, 8)
+
+RVV_VECTOR_TYPE_FLOAT("__rvv_float32m2x2_t", RvvFloat32m2x2, RvvFloat32m2x2Ty, 4, 32, 2)
+RVV_VECTOR_TYPE_FLOAT("__rvv_float32m2x3_t", RvvFloat32m2x3, RvvFloat32m2x3Ty, 4, 32, 3)
+RVV_VECTOR_TYPE_FLOAT("__rvv_float32m2x4_t", RvvFloat32m2x4, RvvFloat32m2x4Ty, 4, 32, 4)
+
+RVV_VECTOR_TYPE_FLOAT("__rvv_float32m4x2_t", RvvFloat32m4x2, RvvFloat32m4x2Ty, 8, 32, 2)
+
+//===- Float64 tuple types -------------------------------------------------===//
+RVV_VECTOR_TYPE_FLOAT("__rvv_float64m1x2_t", RvvFloat64m1x2, RvvFloat64m1x2Ty, 1, 64, 2)
+RVV_VECTOR_TYPE_FLOAT("__rvv_float64m1x3_t", RvvFloat64m1x3, RvvFloat64m1x3Ty, 1, 64, 3)
+RVV_VECTOR_TYPE_FLOAT("__rvv_float64m1x4_t", RvvFloat64m1x4, RvvFloat64m1x4Ty, 1, 64, 4)
+RVV_VECTOR_TYPE_FLOAT("__rvv_float64m1x5_t", RvvFloat64m1x5, RvvFloat64m1x5Ty, 1, 64, 5)
+RVV_VECTOR_TYPE_FLOAT("__rvv_float64m1x6_t", RvvFloat64m1x6, RvvFloat64m1x6Ty, 1, 64, 6)
+RVV_VECTOR_TYPE_FLOAT("__rvv_float64m1x7_t", RvvFloat64m1x7, RvvFloat64m1x7Ty, 1, 64, 7)
+RVV_VECTOR_TYPE_FLOAT("__rvv_float64m1x8_t", RvvFloat64m1x8, RvvFloat64m1x8Ty, 1, 64, 8)
+
+RVV_VECTOR_TYPE_FLOAT("__rvv_float64m2x2_t", RvvFloat64m2x2, RvvFloat64m2x2Ty, 2, 64, 2)
+RVV_VECTOR_TYPE_FLOAT("__rvv_float64m2x3_t", RvvFloat64m2x3, RvvFloat64m2x3Ty, 2, 64, 3)
+RVV_VECTOR_TYPE_FLOAT("__rvv_float64m2x4_t", RvvFloat64m2x4, RvvFloat64m2x4Ty, 2, 64, 4)
+
+RVV_VECTOR_TYPE_FLOAT("__rvv_float64m4x2_t", RvvFloat64m4x2, RvvFloat64m4x2Ty, 4, 64, 2)
+
+//===- BFloat16 tuple types -------------------------------------------------===//
+RVV_VECTOR_TYPE_BFLOAT("__rvv_bfloat16mf4x2_t", RvvBFloat16mf4x2, RvvBFloat16mf4x2Ty,
+ 1, 16, 2)
+RVV_VECTOR_TYPE_BFLOAT("__rvv_bfloat16mf4x3_t", RvvBFloat16mf4x3, RvvBFloat16mf4x3Ty,
+ 1, 16, 3)
+RVV_VECTOR_TYPE_BFLOAT("__rvv_bfloat16mf4x4_t", RvvBFloat16mf4x4, RvvBFloat16mf4x4Ty,
+ 1, 16, 4)
+RVV_VECTOR_TYPE_BFLOAT("__rvv_bfloat16mf4x5_t", RvvBFloat16mf4x5, RvvBFloat16mf4x5Ty,
+ 1, 16, 5)
+RVV_VECTOR_TYPE_BFLOAT("__rvv_bfloat16mf4x6_t", RvvBFloat16mf4x6, RvvBFloat16mf4x6Ty,
+ 1, 16, 6)
+RVV_VECTOR_TYPE_BFLOAT("__rvv_bfloat16mf4x7_t", RvvBFloat16mf4x7, RvvBFloat16mf4x7Ty,
+ 1, 16, 7)
+RVV_VECTOR_TYPE_BFLOAT("__rvv_bfloat16mf4x8_t", RvvBFloat16mf4x8, RvvBFloat16mf4x8Ty,
+ 1, 16, 8)
+
+RVV_VECTOR_TYPE_BFLOAT("__rvv_bfloat16mf2x2_t", RvvBFloat16mf2x2, RvvBFloat16mf2x2Ty,
+ 2, 16, 2)
+RVV_VECTOR_TYPE_BFLOAT("__rvv_bfloat16mf2x3_t", RvvBFloat16mf2x3, RvvBFloat16mf2x3Ty,
+ 2, 16, 3)
+RVV_VECTOR_TYPE_BFLOAT("__rvv_bfloat16mf2x4_t", RvvBFloat16mf2x4, RvvBFloat16mf2x4Ty,
+ 2, 16, 4)
+RVV_VECTOR_TYPE_BFLOAT("__rvv_bfloat16mf2x5_t", RvvBFloat16mf2x5, RvvBFloat16mf2x5Ty,
+ 2, 16, 5)
+RVV_VECTOR_TYPE_BFLOAT("__rvv_bfloat16mf2x6_t", RvvBFloat16mf2x6, RvvBFloat16mf2x6Ty,
+ 2, 16, 6)
+RVV_VECTOR_TYPE_BFLOAT("__rvv_bfloat16mf2x7_t", RvvBFloat16mf2x7, RvvBFloat16mf2x7Ty,
+ 2, 16, 7)
+RVV_VECTOR_TYPE_BFLOAT("__rvv_bfloat16mf2x8_t", RvvBFloat16mf2x8, RvvBFloat16mf2x8Ty,
+ 2, 16, 8)
+
+RVV_VECTOR_TYPE_BFLOAT("__rvv_bfloat16m1x2_t", RvvBFloat16m1x2, RvvBFloat16m1x2Ty,
+ 4, 16, 2)
+RVV_VECTOR_TYPE_BFLOAT("__rvv_bfloat16m1x3_t", RvvBFloat16m1x3, RvvBFloat16m1x3Ty,
+ 4, 16, 3)
+RVV_VECTOR_TYPE_BFLOAT("__rvv_bfloat16m1x4_t", RvvBFloat16m1x4, RvvBFloat16m1x4Ty,
+ 4, 16, 4)
+RVV_VECTOR_TYPE_BFLOAT("__rvv_bfloat16m1x5_t", RvvBFloat16m1x5, RvvBFloat16m1x5Ty,
+ 4, 16, 5)
+RVV_VECTOR_TYPE_BFLOAT("__rvv_bfloat16m1x6_t", RvvBFloat16m1x6, RvvBFloat16m1x6Ty,
+ 4, 16, 6)
+RVV_VECTOR_TYPE_BFLOAT("__rvv_bfloat16m1x7_t", RvvBFloat16m1x7, RvvBFloat16m1x7Ty,
+ 4, 16, 7)
+RVV_VECTOR_TYPE_BFLOAT("__rvv_bfloat16m1x8_t", RvvBFloat16m1x8, RvvBFloat16m1x8Ty,
+ 4, 16, 8)
+
+RVV_VECTOR_TYPE_BFLOAT("__rvv_bfloat16m2x2_t", RvvBFloat16m2x2, RvvBFloat16m2x2Ty,
+ 8, 16, 2)
+RVV_VECTOR_TYPE_BFLOAT("__rvv_bfloat16m2x3_t", RvvBFloat16m2x3, RvvBFloat16m2x3Ty,
+ 8, 16, 3)
+RVV_VECTOR_TYPE_BFLOAT("__rvv_bfloat16m2x4_t", RvvBFloat16m2x4, RvvBFloat16m2x4Ty,
+ 8, 16, 4)
+
+RVV_VECTOR_TYPE_BFLOAT("__rvv_bfloat16m4x2_t", RvvBFloat16m4x2, RvvBFloat16m4x2Ty,
+ 16, 16, 2)
+
+#undef RVV_VECTOR_TYPE_BFLOAT
#undef RVV_VECTOR_TYPE_FLOAT
#undef RVV_VECTOR_TYPE_INT
#undef RVV_VECTOR_TYPE
diff --git a/contrib/llvm-project/clang/include/clang/Basic/Sanitizers.def b/contrib/llvm-project/clang/include/clang/Basic/Sanitizers.def
index 9b8936cc520c..c2137e3f61f6 100644
--- a/contrib/llvm-project/clang/include/clang/Basic/Sanitizers.def
+++ b/contrib/llvm-project/clang/include/clang/Basic/Sanitizers.def
@@ -56,7 +56,10 @@ SANITIZER("hwaddress", HWAddress)
SANITIZER("kernel-hwaddress", KernelHWAddress)
// A variant of AddressSanitizer using AArch64 MTE extension.
-SANITIZER("memtag", MemTag)
+SANITIZER("memtag-stack", MemtagStack)
+SANITIZER("memtag-heap", MemtagHeap)
+SANITIZER("memtag-globals", MemtagGlobals)
+SANITIZER_GROUP("memtag", MemTag, MemtagStack | MemtagHeap | MemtagGlobals)
// MemorySanitizer
SANITIZER("memory", Memory)
@@ -124,6 +127,9 @@ SANITIZER_GROUP("cfi", CFI,
CFIDerivedCast | CFIICall | CFIMFCall | CFIUnrelatedCast |
CFINVCall | CFIVCall)
+// Kernel Control Flow Integrity
+SANITIZER("kcfi", KCFI)
+
// Safe Stack
SANITIZER("safe-stack", SafeStack)
diff --git a/contrib/llvm-project/clang/include/clang/Basic/Sanitizers.h b/contrib/llvm-project/clang/include/clang/Basic/Sanitizers.h
index b12a3b7821d7..c890242269b3 100644
--- a/contrib/llvm-project/clang/include/clang/Basic/Sanitizers.h
+++ b/contrib/llvm-project/clang/include/clang/Basic/Sanitizers.h
@@ -16,13 +16,18 @@
#include "clang/Basic/LLVM.h"
#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/HashBuilder.h"
#include "llvm/Transforms/Instrumentation/AddressSanitizerOptions.h"
#include <cassert>
#include <cstdint>
namespace llvm {
class hash_code;
+class Triple;
+namespace opt {
+class ArgList;
}
+} // namespace llvm
namespace clang {
@@ -72,6 +77,12 @@ public:
llvm::hash_code hash_value() const;
+ template <typename HasherT, llvm::endianness Endianness>
+ friend void addHash(llvm::HashBuilder<HasherT, Endianness> &HBuilder,
+ const SanitizerMask &SM) {
+ HBuilder.addRange(&SM.maskLoToHigh[0], &SM.maskLoToHigh[kNumElem]);
+ }
+
constexpr explicit operator bool() const {
return maskLoToHigh[0] || maskLoToHigh[1];
}
@@ -159,6 +170,8 @@ struct SanitizerSet {
Mask = Value ? (Mask | K) : (Mask & ~K);
}
+ void set(SanitizerMask K) { Mask = K; }
+
/// Disable the sanitizers specified in \p K.
void clear(SanitizerMask K = SanitizerKind::All) { Mask &= ~K; }
diff --git a/contrib/llvm-project/clang/include/clang/Basic/Sarif.h b/contrib/llvm-project/clang/include/clang/Basic/Sarif.h
new file mode 100644
index 000000000000..e6c46224b316
--- /dev/null
+++ b/contrib/llvm-project/clang/include/clang/Basic/Sarif.h
@@ -0,0 +1,513 @@
+//== clang/Basic/Sarif.h - SARIF Diagnostics Object Model -------*- 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
+/// Defines clang::SarifDocumentWriter, clang::SarifRule, clang::SarifResult.
+///
+/// The document built can be accessed as a JSON Object.
+/// Several value semantic types are also introduced which represent properties
+/// of the SARIF standard, such as 'artifact', 'result', 'rule'.
+///
+/// A SARIF (Static Analysis Results Interchange Format) document is JSON
+/// document that describes in detail the results of running static analysis
+/// tools on a project. Each (non-trivial) document consists of at least one
+/// "run", which are themselves composed of details such as:
+/// * Tool: The tool that was run
+/// * Rules: The rules applied during the tool run, represented by
+/// \c reportingDescriptor objects in SARIF
+/// * Results: The matches for the rules applied against the project(s) being
+/// evaluated, represented by \c result objects in SARIF
+///
+/// Reference:
+/// 1. <a href="https://docs.oasis-open.org/sarif/sarif/v2.1.0/os/sarif-v2.1.0-os.html">The SARIF standard</a>
+/// 2. <a href="https://docs.oasis-open.org/sarif/sarif/v2.1.0/os/sarif-v2.1.0-os.html#_Toc34317836">SARIF<pre>reportingDescriptor</pre></a>
+/// 3. <a href="https://docs.oasis-open.org/sarif/sarif/v2.1.0/os/sarif-v2.1.0-os.html#_Toc34317638">SARIF<pre>result</pre></a>
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_BASIC_SARIF_H
+#define LLVM_CLANG_BASIC_SARIF_H
+
+#include "clang/Basic/SourceLocation.h"
+#include "clang/Basic/Version.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/JSON.h"
+#include <cassert>
+#include <cstddef>
+#include <cstdint>
+#include <initializer_list>
+#include <optional>
+#include <string>
+
+namespace clang {
+
+class SarifDocumentWriter;
+class SourceManager;
+
+namespace detail {
+
+/// \internal
+/// An artifact location is SARIF's way of describing the complete location
+/// of an artifact encountered during analysis. The \c artifactLocation object
+/// typically consists of a URI, and/or an index to reference the artifact it
+/// locates.
+///
+/// This builder makes an additional assumption: that every artifact encountered
+/// by \c clang will be a physical, top-level artifact. Which is why the static
+/// creation method \ref SarifArtifactLocation::create takes a mandatory URI
+/// parameter. The official standard states that either a \c URI or \c Index
+/// must be available in the object, \c clang picks the \c URI as a reasonable
+/// default, because it intends to deal in physical artifacts for now.
+///
+/// Reference:
+/// 1. <a href="https://docs.oasis-open.org/sarif/sarif/v2.1.0/os/sarif-v2.1.0-os.html#_Toc34317427">artifactLocation object</a>
+/// 2. \ref SarifArtifact
+class SarifArtifactLocation {
+private:
+ friend class clang::SarifDocumentWriter;
+
+ std::optional<uint32_t> Index;
+ std::string URI;
+
+ SarifArtifactLocation() = delete;
+ explicit SarifArtifactLocation(const std::string &URI) : URI(URI) {}
+
+public:
+ static SarifArtifactLocation create(llvm::StringRef URI) {
+ return SarifArtifactLocation{URI.str()};
+ }
+
+ SarifArtifactLocation setIndex(uint32_t Idx) {
+ Index = Idx;
+ return *this;
+ }
+};
+
+/// \internal
+/// An artifact in SARIF is any object (a sequence of bytes) addressable by
+/// a URI (RFC 3986). The most common type of artifact for clang's use-case
+/// would be source files. SARIF's artifact object is described in detail in
+/// section 3.24.
+//
+/// Since every clang artifact MUST have a location (there being no nested
+/// artifacts), the creation method \ref SarifArtifact::create requires a
+/// \ref SarifArtifactLocation object.
+///
+/// Reference:
+/// 1. <a href="https://docs.oasis-open.org/sarif/sarif/v2.1.0/os/sarif-v2.1.0-os.html#_Toc34317611">artifact object</a>
+class SarifArtifact {
+private:
+ friend class clang::SarifDocumentWriter;
+
+ std::optional<uint32_t> Offset;
+ std::optional<size_t> Length;
+ std::string MimeType;
+ SarifArtifactLocation Location;
+ llvm::SmallVector<std::string, 4> Roles;
+
+ SarifArtifact() = delete;
+
+ explicit SarifArtifact(const SarifArtifactLocation &Loc) : Location(Loc) {}
+
+public:
+ static SarifArtifact create(const SarifArtifactLocation &Loc) {
+ return SarifArtifact{Loc};
+ }
+
+ SarifArtifact setOffset(uint32_t ArtifactOffset) {
+ Offset = ArtifactOffset;
+ return *this;
+ }
+
+ SarifArtifact setLength(size_t NumBytes) {
+ Length = NumBytes;
+ return *this;
+ }
+
+ SarifArtifact setRoles(std::initializer_list<llvm::StringRef> ArtifactRoles) {
+ Roles.assign(ArtifactRoles.begin(), ArtifactRoles.end());
+ return *this;
+ }
+
+ SarifArtifact setMimeType(llvm::StringRef ArtifactMimeType) {
+ MimeType = ArtifactMimeType.str();
+ return *this;
+ }
+};
+
+} // namespace detail
+
+enum class ThreadFlowImportance { Important, Essential, Unimportant };
+
+/// The level of severity associated with a \ref SarifResult.
+///
+/// Of all the levels, \c None is the only one that is not associated with
+/// a failure.
+///
+/// A typical mapping for clang's DiagnosticKind to SarifResultLevel would look
+/// like:
+/// * \c None: \ref clang::DiagnosticsEngine::Level::Remark, \ref clang::DiagnosticsEngine::Level::Ignored
+/// * \c Note: \ref clang::DiagnosticsEngine::Level::Note
+/// * \c Warning: \ref clang::DiagnosticsEngine::Level::Warning
+/// * \c Error could be generated from one of:
+/// - \ref clang::DiagnosticsEngine::Level::Warning with \c -Werror
+/// - \ref clang::DiagnosticsEngine::Level::Error
+/// - \ref clang::DiagnosticsEngine::Level::Fatal when \ref clang::DiagnosticsEngine::ErrorsAsFatal is set.
+///
+/// Reference:
+/// 1. <a href="https://docs.oasis-open.org/sarif/sarif/v2.1.0/os/sarif-v2.1.0-os.html#_Toc34317648">level property</a>
+enum class SarifResultLevel { None, Note, Warning, Error };
+
+/// A thread flow is a sequence of code locations that specify a possible path
+/// through a single thread of execution.
+/// A thread flow in SARIF is related to a code flow which describes
+/// the progress of one or more programs through one or more thread flows.
+///
+/// Reference:
+/// 1. <a href="https://docs.oasis-open.org/sarif/sarif/v2.1.0/os/sarif-v2.1.0-os.html#_Toc34317744">threadFlow object</a>
+/// 2. <a href="https://docs.oasis-open.org/sarif/sarif/v2.1.0/os/sarif-v2.1.0-os.html#_Toc34317740">codeFlow object</a>
+class ThreadFlow {
+ friend class SarifDocumentWriter;
+
+ CharSourceRange Range;
+ ThreadFlowImportance Importance;
+ std::string Message;
+
+ ThreadFlow() = default;
+
+public:
+ static ThreadFlow create() { return {}; }
+
+ ThreadFlow setRange(const CharSourceRange &ItemRange) {
+ assert(ItemRange.isCharRange() &&
+ "ThreadFlows require a character granular source range!");
+ Range = ItemRange;
+ return *this;
+ }
+
+ ThreadFlow setImportance(const ThreadFlowImportance &ItemImportance) {
+ Importance = ItemImportance;
+ return *this;
+ }
+
+ ThreadFlow setMessage(llvm::StringRef ItemMessage) {
+ Message = ItemMessage.str();
+ return *this;
+ }
+};
+
+/// A SARIF Reporting Configuration (\c reportingConfiguration) object contains
+/// properties for a \ref SarifRule that can be configured at runtime before
+/// analysis begins.
+///
+/// Reference:
+/// 1. <a href="https://docs.oasis-open.org/sarif/sarif/v2.1.0/os/sarif-v2.1.0-os.html#_Toc34317852">reportingConfiguration object</a>
+class SarifReportingConfiguration {
+ friend class clang::SarifDocumentWriter;
+
+ bool Enabled = true;
+ SarifResultLevel Level = SarifResultLevel::Warning;
+ float Rank = -1.0f;
+
+ SarifReportingConfiguration() = default;
+
+public:
+ static SarifReportingConfiguration create() { return {}; };
+
+ SarifReportingConfiguration disable() {
+ Enabled = false;
+ return *this;
+ }
+
+ SarifReportingConfiguration enable() {
+ Enabled = true;
+ return *this;
+ }
+
+ SarifReportingConfiguration setLevel(SarifResultLevel TheLevel) {
+ Level = TheLevel;
+ return *this;
+ }
+
+ SarifReportingConfiguration setRank(float TheRank) {
+ assert(TheRank >= 0.0f && "Rule rank cannot be smaller than 0.0");
+ assert(TheRank <= 100.0f && "Rule rank cannot be larger than 100.0");
+ Rank = TheRank;
+ return *this;
+ }
+};
+
+/// A SARIF rule (\c reportingDescriptor object) contains information that
+/// describes a reporting item generated by a tool. A reporting item is
+/// either a result of analysis or notification of a condition encountered by
+/// the tool. Rules are arbitrary but are identifiable by a hierarchical
+/// rule-id.
+///
+/// This builder provides an interface to create SARIF \c reportingDescriptor
+/// objects via the \ref SarifRule::create static method.
+///
+/// Reference:
+/// 1. <a href="https://docs.oasis-open.org/sarif/sarif/v2.1.0/os/sarif-v2.1.0-os.html#_Toc34317836">reportingDescriptor object</a>
+class SarifRule {
+ friend class clang::SarifDocumentWriter;
+
+ std::string Name;
+ std::string Id;
+ std::string Description;
+ std::string HelpURI;
+ SarifReportingConfiguration DefaultConfiguration;
+
+ SarifRule() : DefaultConfiguration(SarifReportingConfiguration::create()) {}
+
+public:
+ static SarifRule create() { return {}; }
+
+ SarifRule setName(llvm::StringRef RuleName) {
+ Name = RuleName.str();
+ return *this;
+ }
+
+ SarifRule setRuleId(llvm::StringRef RuleId) {
+ Id = RuleId.str();
+ return *this;
+ }
+
+ SarifRule setDescription(llvm::StringRef RuleDesc) {
+ Description = RuleDesc.str();
+ return *this;
+ }
+
+ SarifRule setHelpURI(llvm::StringRef RuleHelpURI) {
+ HelpURI = RuleHelpURI.str();
+ return *this;
+ }
+
+ SarifRule
+ setDefaultConfiguration(const SarifReportingConfiguration &Configuration) {
+ DefaultConfiguration = Configuration;
+ return *this;
+ }
+};
+
+/// A SARIF result (also called a "reporting item") is a unit of output
+/// produced when one of the tool's \c reportingDescriptor encounters a match
+/// on the file being analysed by the tool.
+///
+/// This builder provides a \ref SarifResult::create static method that can be
+/// used to create an empty shell onto which attributes can be added using the
+/// \c setX(...) methods.
+///
+/// For example:
+/// \code{.cpp}
+/// SarifResult result = SarifResult::create(...)
+/// .setRuleId(...)
+/// .setDiagnosticMessage(...);
+/// \endcode
+///
+/// Reference:
+/// 1. <a href="https://docs.oasis-open.org/sarif/sarif/v2.1.0/os/sarif-v2.1.0-os.html#_Toc34317638">SARIF<pre>result</pre></a>
+class SarifResult {
+ friend class clang::SarifDocumentWriter;
+
+ // NOTE:
+ // This type cannot fit all possible indexes representable by JSON, but is
+ // chosen because it is the largest unsigned type that can be safely
+ // converted to an \c int64_t.
+ uint32_t RuleIdx;
+ std::string RuleId;
+ std::string DiagnosticMessage;
+ llvm::SmallVector<CharSourceRange, 8> Locations;
+ llvm::SmallVector<ThreadFlow, 8> ThreadFlows;
+ std::optional<SarifResultLevel> LevelOverride;
+
+ SarifResult() = delete;
+ explicit SarifResult(uint32_t RuleIdx) : RuleIdx(RuleIdx) {}
+
+public:
+ static SarifResult create(uint32_t RuleIdx) { return SarifResult{RuleIdx}; }
+
+ SarifResult setIndex(uint32_t Idx) {
+ RuleIdx = Idx;
+ return *this;
+ }
+
+ SarifResult setRuleId(llvm::StringRef Id) {
+ RuleId = Id.str();
+ return *this;
+ }
+
+ SarifResult setDiagnosticMessage(llvm::StringRef Message) {
+ DiagnosticMessage = Message.str();
+ return *this;
+ }
+
+ SarifResult setLocations(llvm::ArrayRef<CharSourceRange> DiagLocs) {
+#ifndef NDEBUG
+ for (const auto &Loc : DiagLocs) {
+ assert(Loc.isCharRange() &&
+ "SARIF Results require character granular source ranges!");
+ }
+#endif
+ Locations.assign(DiagLocs.begin(), DiagLocs.end());
+ return *this;
+ }
+ SarifResult setThreadFlows(llvm::ArrayRef<ThreadFlow> ThreadFlowResults) {
+ ThreadFlows.assign(ThreadFlowResults.begin(), ThreadFlowResults.end());
+ return *this;
+ }
+
+ SarifResult setDiagnosticLevel(const SarifResultLevel &TheLevel) {
+ LevelOverride = TheLevel;
+ return *this;
+ }
+};
+
+/// This class handles creating a valid SARIF document given various input
+/// attributes. However, it requires an ordering among certain method calls:
+///
+/// 1. Because every SARIF document must contain at least 1 \c run, callers
+/// must ensure that \ref SarifDocumentWriter::createRun is called before
+/// any other methods.
+/// 2. If SarifDocumentWriter::endRun is called, callers MUST call
+/// SarifDocumentWriter::createRun, before invoking any of the result
+/// aggregation methods such as SarifDocumentWriter::appendResult etc.
+class SarifDocumentWriter {
+private:
+ const llvm::StringRef SchemaURI{
+ "https://docs.oasis-open.org/sarif/sarif/v2.1.0/cos02/schemas/"
+ "sarif-schema-2.1.0.json"};
+ const llvm::StringRef SchemaVersion{"2.1.0"};
+
+ /// \internal
+ /// Return a pointer to the current tool. Asserts that a run exists.
+ llvm::json::Object &getCurrentTool();
+
+ /// \internal
+ /// Checks if there is a run associated with this document.
+ ///
+ /// \return true on success
+ bool hasRun() const;
+
+ /// \internal
+ /// Reset portions of the internal state so that the document is ready to
+ /// receive data for a new run.
+ void reset();
+
+ /// \internal
+ /// Return a mutable reference to the current run, after asserting it exists.
+ ///
+ /// \note It is undefined behavior to call this if a run does not exist in
+ /// the SARIF document.
+ llvm::json::Object &getCurrentRun();
+
+ /// Create a code flow object for the given threadflows.
+ /// See \ref ThreadFlow.
+ ///
+ /// \note It is undefined behavior to call this if a run does not exist in
+ /// the SARIF document.
+ llvm::json::Object
+ createCodeFlow(const llvm::ArrayRef<ThreadFlow> ThreadFlows);
+
+ /// Add the given threadflows to the ones this SARIF document knows about.
+ llvm::json::Array
+ createThreadFlows(const llvm::ArrayRef<ThreadFlow> ThreadFlows);
+
+ /// Add the given \ref CharSourceRange to the SARIF document as a physical
+ /// location, with its corresponding artifact.
+ llvm::json::Object createPhysicalLocation(const CharSourceRange &R);
+
+public:
+ SarifDocumentWriter() = delete;
+
+ /// Create a new empty SARIF document with the given source manager.
+ SarifDocumentWriter(const SourceManager &SourceMgr) : SourceMgr(SourceMgr) {}
+
+ /// Release resources held by this SARIF document.
+ ~SarifDocumentWriter() = default;
+
+ /// Create a new run with which any upcoming analysis will be associated.
+ /// Each run requires specifying the tool that is generating reporting items.
+ void createRun(const llvm::StringRef ShortToolName,
+ const llvm::StringRef LongToolName,
+ const llvm::StringRef ToolVersion = CLANG_VERSION_STRING);
+
+ /// If there is a current run, end it.
+ ///
+ /// This method collects various book-keeping required to clear and close
+ /// resources associated with the current run, but may also allocate some
+ /// for the next run.
+ ///
+ /// Calling \ref endRun before associating a run through \ref createRun leads
+ /// to undefined behaviour.
+ void endRun();
+
+ /// Associate the given rule with the current run.
+ ///
+ /// Returns an integer rule index for the created rule that is unique within
+ /// the current run, which can then be used to create a \ref SarifResult
+ /// to add to the current run. Note that a rule must exist before being
+ /// referenced by a result.
+ ///
+ /// \pre
+ /// There must be a run associated with the document, failing to do so will
+ /// cause undefined behaviour.
+ size_t createRule(const SarifRule &Rule);
+
+ /// Append a new result to the currently in-flight run.
+ ///
+ /// \pre
+ /// There must be a run associated with the document, failing to do so will
+ /// cause undefined behaviour.
+ /// \pre
+ /// \c RuleIdx used to create the result must correspond to a rule known by
+ /// the SARIF document. It must be the value returned by a previous call
+ /// to \ref createRule.
+ void appendResult(const SarifResult &SarifResult);
+
+ /// Return the SARIF document in its current state.
+ /// Calling this will trigger a copy of the internal state including all
+ /// reported diagnostics, resulting in an expensive call.
+ llvm::json::Object createDocument();
+
+private:
+ /// Source Manager to use for the current SARIF document.
+ const SourceManager &SourceMgr;
+
+ /// Flag to track the state of this document:
+ /// A closed document is one on which a new runs must be created.
+ /// This could be a document that is freshly created, or has recently
+ /// finished writing to a previous run.
+ bool Closed = true;
+
+ /// A sequence of SARIF runs.
+ /// Each run object describes a single run of an analysis tool and contains
+ /// the output of that run.
+ ///
+ /// Reference: <a href="https://docs.oasis-open.org/sarif/sarif/v2.1.0/os/sarif-v2.1.0-os.html#_Toc34317484">run object</a>
+ llvm::json::Array Runs;
+
+ /// The list of rules associated with the most recent active run. These are
+ /// defined using the diagnostics passed to the SarifDocument. Each rule
+ /// need not be unique through the result set. E.g. there may be several
+ /// 'syntax' errors throughout code under analysis, each of which has its
+ /// own specific diagnostic message (and consequently, RuleId). Rules are
+ /// also known as "reportingDescriptor" objects in SARIF.
+ ///
+ /// Reference: <a href="https://docs.oasis-open.org/sarif/sarif/v2.1.0/os/sarif-v2.1.0-os.html#_Toc34317556">rules property</a>
+ llvm::SmallVector<SarifRule, 32> CurrentRules;
+
+ /// The list of artifacts that have been encountered on the most recent active
+ /// run. An artifact is defined in SARIF as a sequence of bytes addressable
+ /// by a URI. A common example for clang's case would be files named by
+ /// filesystem paths.
+ llvm::StringMap<detail::SarifArtifact> CurrentArtifacts;
+};
+} // namespace clang
+
+#endif // LLVM_CLANG_BASIC_SARIF_H
diff --git a/contrib/llvm-project/clang/include/clang/Basic/SourceLocation.h b/contrib/llvm-project/clang/include/clang/Basic/SourceLocation.h
index 540de23b9f55..00b1e0fa855b 100644
--- a/contrib/llvm-project/clang/include/clang/Basic/SourceLocation.h
+++ b/contrib/llvm-project/clang/include/clang/Basic/SourceLocation.h
@@ -14,6 +14,7 @@
#ifndef LLVM_CLANG_BASIC_SOURCELOCATION_H
#define LLVM_CLANG_BASIC_SOURCELOCATION_H
+#include "clang/Basic/FileEntry.h"
#include "clang/Basic/LLVM.h"
#include "llvm/ADT/StringRef.h"
#include <cassert>
@@ -23,10 +24,8 @@
namespace llvm {
-template <typename T> struct DenseMapInfo;
-
class FoldingSetNodeID;
-template <typename T> struct FoldingSetTrait;
+template <typename T, typename Enable> struct FoldingSetTrait;
} // namespace llvm
@@ -60,6 +59,7 @@ private:
friend class ASTWriter;
friend class ASTReader;
friend class SourceManager;
+ friend class SourceManagerTestHelper;
static FileID get(int V) {
FileID F;
@@ -89,7 +89,7 @@ class SourceLocation {
friend class ASTReader;
friend class ASTWriter;
friend class SourceManager;
- friend struct llvm::FoldingSetTrait<SourceLocation>;
+ friend struct llvm::FoldingSetTrait<SourceLocation, void>;
public:
using UIntTy = uint32_t;
@@ -358,11 +358,13 @@ public:
}
};
-class FileEntry;
-
/// A SourceLocation and its associated SourceManager.
///
/// This is useful for argument passing to functions that expect both objects.
+///
+/// This class does not guarantee the presence of either the SourceManager or
+/// a valid SourceLocation. Clients should use `isValid()` and `hasManager()`
+/// before calling the member functions.
class FullSourceLoc : public SourceLocation {
const SourceManager *SrcMgr = nullptr;
@@ -373,13 +375,10 @@ public:
explicit FullSourceLoc(SourceLocation Loc, const SourceManager &SM)
: SourceLocation(Loc), SrcMgr(&SM) {}
- bool hasManager() const {
- bool hasSrcMgr = SrcMgr != nullptr;
- assert(hasSrcMgr == isValid() && "FullSourceLoc has location but no manager");
- return hasSrcMgr;
- }
+ /// Checks whether the SourceManager is present.
+ bool hasManager() const { return SrcMgr != nullptr; }
- /// \pre This FullSourceLoc has an associated SourceManager.
+ /// \pre hasManager()
const SourceManager &getManager() const {
assert(SrcMgr && "SourceManager is NULL.");
return *SrcMgr;
@@ -399,6 +398,12 @@ public:
unsigned getExpansionLineNumber(bool *Invalid = nullptr) const;
unsigned getExpansionColumnNumber(bool *Invalid = nullptr) const;
+ /// Decompose the underlying \c SourceLocation into a raw (FileID + Offset)
+ /// pair, after walking through all expansion records.
+ ///
+ /// \see SourceManager::getDecomposedExpansionLoc
+ std::pair<FileID, unsigned> getDecomposedExpansionLoc() const;
+
unsigned getSpellingLineNumber(bool *Invalid = nullptr) const;
unsigned getSpellingColumnNumber(bool *Invalid = nullptr) const;
@@ -408,6 +413,7 @@ public:
unsigned getColumnNumber(bool *Invalid = nullptr) const;
const FileEntry *getFileEntry() const;
+ OptionalFileEntryRef getFileEntryRef() const;
/// Return a StringRef to the source buffer data for the
/// specified FileID.
@@ -466,7 +472,7 @@ namespace llvm {
/// Define DenseMapInfo so that FileID's can be used as keys in DenseMap and
/// DenseSets.
template <>
- struct DenseMapInfo<clang::FileID> {
+ struct DenseMapInfo<clang::FileID, void> {
static clang::FileID getEmptyKey() {
return {};
}
@@ -487,7 +493,7 @@ namespace llvm {
/// Define DenseMapInfo so that SourceLocation's can be used as keys in
/// DenseMap and DenseSet. This trait class is eqivalent to
/// DenseMapInfo<unsigned> which uses SourceLocation::ID is used as a key.
- template <> struct DenseMapInfo<clang::SourceLocation> {
+ template <> struct DenseMapInfo<clang::SourceLocation, void> {
static clang::SourceLocation getEmptyKey() {
constexpr clang::SourceLocation::UIntTy Zero = 0;
return clang::SourceLocation::getFromRawEncoding(~Zero);
@@ -508,7 +514,7 @@ namespace llvm {
};
// Allow calling FoldingSetNodeID::Add with SourceLocation object as parameter
- template <> struct FoldingSetTrait<clang::SourceLocation> {
+ template <> struct FoldingSetTrait<clang::SourceLocation, void> {
static void Profile(const clang::SourceLocation &X, FoldingSetNodeID &ID);
};
diff --git a/contrib/llvm-project/clang/include/clang/Basic/SourceManager.h b/contrib/llvm-project/clang/include/clang/Basic/SourceManager.h
index cc29c24f5a35..d2ece14da0b1 100644
--- a/contrib/llvm-project/clang/include/clang/Basic/SourceManager.h
+++ b/contrib/llvm-project/clang/include/clang/Basic/SourceManager.h
@@ -36,12 +36,14 @@
#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/FileEntry.h"
+#include "clang/Basic/FileManager.h"
#include "clang/Basic/SourceLocation.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/BitVector.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/IntrusiveRefCntPtr.h"
+#include "llvm/ADT/PagedVector.h"
#include "llvm/ADT/PointerIntPair.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
@@ -52,6 +54,7 @@
#include <cstddef>
#include <map>
#include <memory>
+#include <optional>
#include <string>
#include <utility>
#include <vector>
@@ -138,14 +141,15 @@ public:
/// It is possible for this to be NULL if the ContentCache encapsulates
/// an imaginary text buffer.
///
- /// FIXME: Turn this into a FileEntryRef and remove Filename.
- const FileEntry *OrigEntry;
+ /// FIXME: Make non-optional using a virtual file as needed, remove \c
+ /// Filename and use \c OrigEntry.getNameAsRequested() instead.
+ OptionalFileEntryRef OrigEntry;
/// References the file which the contents were actually loaded from.
///
/// Can be different from 'Entry' if we overridden the contents of one file
/// with the contents of another file.
- const FileEntry *ContentsEntry;
+ OptionalFileEntryRef ContentsEntry;
/// The filename that is used to access OrigEntry.
///
@@ -163,22 +167,31 @@ public:
///
/// When true, the original entry may be a virtual file that does not
/// exist.
+ LLVM_PREFERRED_TYPE(bool)
unsigned BufferOverridden : 1;
/// True if this content cache was initially created for a source file
/// considered to be volatile (likely to change between stat and open).
+ LLVM_PREFERRED_TYPE(bool)
unsigned IsFileVolatile : 1;
/// True if this file may be transient, that is, if it might not
/// exist at some later point in time when this content entry is used,
/// after serialization and deserialization.
+ LLVM_PREFERRED_TYPE(bool)
unsigned IsTransient : 1;
+ LLVM_PREFERRED_TYPE(bool)
mutable unsigned IsBufferInvalid : 1;
- ContentCache(const FileEntry *Ent = nullptr) : ContentCache(Ent, Ent) {}
+ ContentCache()
+ : OrigEntry(std::nullopt), ContentsEntry(std::nullopt),
+ BufferOverridden(false), IsFileVolatile(false), IsTransient(false),
+ IsBufferInvalid(false) {}
- ContentCache(const FileEntry *Ent, const FileEntry *contentEnt)
+ ContentCache(FileEntryRef Ent) : ContentCache(Ent, Ent) {}
+
+ ContentCache(FileEntryRef Ent, FileEntryRef contentEnt)
: OrigEntry(Ent), ContentsEntry(contentEnt), BufferOverridden(false),
IsFileVolatile(false), IsTransient(false), IsBufferInvalid(false) {}
@@ -204,7 +217,7 @@ public:
///
/// \param Loc If specified, is the location that invalid file diagnostics
/// will be emitted at.
- llvm::Optional<llvm::MemoryBufferRef>
+ std::optional<llvm::MemoryBufferRef>
getBufferOrNone(DiagnosticsEngine &Diag, FileManager &FM,
SourceLocation Loc = SourceLocation()) const;
@@ -227,18 +240,18 @@ public:
llvm::MemoryBuffer::BufferKind getMemoryBufferKind() const;
/// Return the buffer, only if it has been loaded.
- llvm::Optional<llvm::MemoryBufferRef> getBufferIfLoaded() const {
+ std::optional<llvm::MemoryBufferRef> getBufferIfLoaded() const {
if (Buffer)
return Buffer->getMemBufferRef();
- return None;
+ return std::nullopt;
}
/// Return a StringRef to the source buffer data, only if it has already
/// been loaded.
- llvm::Optional<StringRef> getBufferDataIfLoaded() const {
+ std::optional<StringRef> getBufferDataIfLoaded() const {
if (Buffer)
return Buffer->getBuffer();
- return None;
+ return std::nullopt;
}
/// Set the buffer.
@@ -250,7 +263,7 @@ public:
/// Set the buffer to one that's not owned (or to nullptr).
///
/// \pre Buffer cannot already be set.
- void setUnownedBuffer(llvm::Optional<llvm::MemoryBufferRef> B) {
+ void setUnownedBuffer(std::optional<llvm::MemoryBufferRef> B) {
assert(!Buffer && "Expected to be called right after construction");
if (B)
setBuffer(llvm::MemoryBuffer::getMemBuffer(*B));
@@ -296,6 +309,7 @@ class FileInfo {
unsigned NumCreatedFIDs : 31;
/// Whether this FileInfo has any \#line directives.
+ LLVM_PREFERRED_TYPE(bool)
unsigned HasLineDirectives : 1;
/// The content cache and the characteristic of the file.
@@ -467,6 +481,7 @@ static_assert(sizeof(FileInfo) <= sizeof(ExpansionInfo),
class SLocEntry {
static constexpr int OffsetBits = 8 * sizeof(SourceLocation::UIntTy) - 1;
SourceLocation::UIntTy Offset : OffsetBits;
+ LLVM_PREFERRED_TYPE(bool)
SourceLocation::UIntTy IsExpansion : 1;
union {
FileInfo File;
@@ -491,6 +506,14 @@ public:
return Expansion;
}
+ /// Creates an incomplete SLocEntry that is only able to report its offset.
+ static SLocEntry getOffsetOnly(SourceLocation::UIntTy Offset) {
+ assert(!(Offset & (1ULL << OffsetBits)) && "Offset is too large");
+ SLocEntry E;
+ E.Offset = Offset;
+ return E;
+ }
+
static SLocEntry get(SourceLocation::UIntTy Offset, const FileInfo &FI) {
assert(!(Offset & (1ULL << OffsetBits)) && "Offset is too large");
SLocEntry E;
@@ -525,6 +548,12 @@ public:
/// entry from being loaded.
virtual bool ReadSLocEntry(int ID) = 0;
+ /// Get the index ID for the loaded SourceLocation offset.
+ ///
+ /// \returns Invalid index ID (0) if an error occurred that prevented the
+ /// SLocEntry from being loaded.
+ virtual int getSLocEntryID(SourceLocation::UIntTy SLocOffset) = 0;
+
/// Retrieve the module import location and name for the given ID, if
/// in fact it was loaded from a module (rather than, say, a precompiled
/// header).
@@ -541,10 +570,10 @@ class InBeforeInTUCacheEntry {
/// If these match up with a subsequent query, the result can be reused.
FileID LQueryFID, RQueryFID;
- /// True if LQueryFID was created before RQueryFID.
+ /// The relative order of FileIDs that the CommonFID *immediately* includes.
///
/// This is used to compare macro expansion locations.
- bool IsLQFIDBeforeRQFID;
+ bool LChildBeforeRChild;
/// The file found in common between the two \#include traces, i.e.,
/// the nearest common ancestor of the \#include tree.
@@ -558,12 +587,17 @@ class InBeforeInTUCacheEntry {
unsigned LCommonOffset, RCommonOffset;
public:
+ InBeforeInTUCacheEntry() = default;
+ InBeforeInTUCacheEntry(FileID L, FileID R) : LQueryFID(L), RQueryFID(R) {
+ assert(L != R);
+ }
+
/// Return true if the currently cached values match up with
/// the specified LHS/RHS query.
///
/// If not, we can't use the cache.
- bool isCacheValid(FileID LHS, FileID RHS) const {
- return LQueryFID == LHS && RQueryFID == RHS;
+ bool isCacheValid() const {
+ return CommonFID.isValid();
}
/// If the cache is valid, compute the result given the
@@ -580,29 +614,28 @@ public:
// one of the locations points at the inclusion/expansion point of the other
// in which case its FileID will come before the other.
if (LOffset == ROffset)
- return IsLQFIDBeforeRQFID;
+ return LChildBeforeRChild;
return LOffset < ROffset;
}
/// Set up a new query.
- void setQueryFIDs(FileID LHS, FileID RHS, bool isLFIDBeforeRFID) {
+ /// If it matches the old query, we can keep the cached answer.
+ void setQueryFIDs(FileID LHS, FileID RHS) {
assert(LHS != RHS);
- LQueryFID = LHS;
- RQueryFID = RHS;
- IsLQFIDBeforeRQFID = isLFIDBeforeRFID;
- }
-
- void clear() {
- LQueryFID = RQueryFID = FileID();
- IsLQFIDBeforeRQFID = false;
+ if (LQueryFID != LHS || RQueryFID != RHS) {
+ LQueryFID = LHS;
+ RQueryFID = RHS;
+ CommonFID = FileID();
+ }
}
void setCommonLoc(FileID commonFID, unsigned lCommonOffset,
- unsigned rCommonOffset) {
+ unsigned rCommonOffset, bool LParentBeforeRParent) {
CommonFID = commonFID;
LCommonOffset = lCommonOffset;
RCommonOffset = rCommonOffset;
+ LChildBeforeRChild = LParentBeforeRParent;
}
};
@@ -637,7 +670,7 @@ class SourceManager : public RefCountedBase<SourceManager> {
/// This map allows us to merge ContentCache entries based
/// on their FileEntry*. All ContentCache objects will thus have unique,
/// non-null, FileEntry pointers.
- llvm::DenseMap<const FileEntry*, SrcMgr::ContentCache*> FileInfos;
+ llvm::DenseMap<FileEntryRef, SrcMgr::ContentCache*> FileInfos;
/// True if the ContentCache for files that are overridden by other
/// files, should report the original file name. Defaults to true.
@@ -655,7 +688,7 @@ class SourceManager : public RefCountedBase<SourceManager> {
struct OverriddenFilesInfoTy {
/// Files that have been overridden with the contents from another
/// file.
- llvm::DenseMap<const FileEntry *, const FileEntry *> OverriddenFiles;
+ llvm::DenseMap<const FileEntry *, FileEntryRef> OverriddenFiles;
/// Files that were overridden with a memory buffer.
llvm::DenseSet<const FileEntry *> OverriddenFilesWithBuffer;
@@ -687,7 +720,12 @@ class SourceManager : public RefCountedBase<SourceManager> {
///
/// Negative FileIDs are indexes into this table. To get from ID to an index,
/// use (-ID - 2).
- SmallVector<SrcMgr::SLocEntry, 0> LoadedSLocEntryTable;
+ llvm::PagedVector<SrcMgr::SLocEntry> LoadedSLocEntryTable;
+
+ /// For each allocation in LoadedSLocEntryTable, we keep the first FileID.
+ /// We assume exactly one allocation per AST file, and use that to determine
+ /// whether two FileIDs come from the same AST file.
+ SmallVector<FileID, 0> LoadedSLocEntryAllocBegin;
/// The starting offset of the next local SLocEntry.
///
@@ -700,7 +738,7 @@ class SourceManager : public RefCountedBase<SourceManager> {
/// not have been loaded, so that value would be unknown.
SourceLocation::UIntTy CurrentLoadedOffset;
- /// The highest possible offset is 2^32-1 (2^63-1 for 64-bit source
+ /// The highest possible offset is 2^31-1 (2^63-1 for 64-bit source
/// locations), so CurrentLoadedOffset starts at 2^31 (2^63 resp.).
static const SourceLocation::UIntTy MaxLoadedOffset =
1ULL << (8 * sizeof(SourceLocation::UIntTy) - 1);
@@ -711,6 +749,12 @@ class SourceManager : public RefCountedBase<SourceManager> {
/// Same indexing as LoadedSLocEntryTable.
llvm::BitVector SLocEntryLoaded;
+ /// A bitmap that indicates whether the entries of LoadedSLocEntryTable
+ /// have already had their offset loaded from the external source.
+ ///
+ /// Superset of SLocEntryLoaded. Same indexing as SLocEntryLoaded.
+ llvm::BitVector SLocEntryOffsetLoaded;
+
/// An external source for source location entries.
ExternalSLocEntrySource *ExternalSLocEntries = nullptr;
@@ -864,13 +908,6 @@ public:
/// Create a new FileID that represents the specified file
/// being \#included from the specified IncludePosition.
- ///
- /// This translates NULL into standard input.
- FileID createFileID(const FileEntry *SourceFile, SourceLocation IncludePos,
- SrcMgr::CharacteristicKind FileCharacter,
- int LoadedID = 0,
- SourceLocation::UIntTy LoadedOffset = 0);
-
FileID createFileID(FileEntryRef SourceFile, SourceLocation IncludePos,
SrcMgr::CharacteristicKind FileCharacter,
int LoadedID = 0,
@@ -896,25 +933,29 @@ public:
/// Get the FileID for \p SourceFile if it exists. Otherwise, create a
/// new FileID for the \p SourceFile.
- FileID getOrCreateFileID(const FileEntry *SourceFile,
+ FileID getOrCreateFileID(FileEntryRef SourceFile,
SrcMgr::CharacteristicKind FileCharacter);
- /// Return a new SourceLocation that encodes the
- /// fact that a token from SpellingLoc should actually be referenced from
- /// ExpansionLoc, and that it represents the expansion of a macro argument
- /// into the function-like macro body.
- SourceLocation createMacroArgExpansionLoc(SourceLocation Loc,
+ /// Creates an expansion SLocEntry for the substitution of an argument into a
+ /// function-like macro's body. Returns the start of the expansion.
+ ///
+ /// The macro argument was written at \p SpellingLoc with length \p Length.
+ /// \p ExpansionLoc is the parameter name in the (expanded) macro body.
+ SourceLocation createMacroArgExpansionLoc(SourceLocation SpellingLoc,
SourceLocation ExpansionLoc,
- unsigned TokLength);
+ unsigned Length);
- /// Return a new SourceLocation that encodes the fact
- /// that a token from SpellingLoc should actually be referenced from
- /// ExpansionLoc.
- SourceLocation
- createExpansionLoc(SourceLocation Loc, SourceLocation ExpansionLocStart,
- SourceLocation ExpansionLocEnd, unsigned TokLength,
- bool ExpansionIsTokenRange = true, int LoadedID = 0,
- SourceLocation::UIntTy LoadedOffset = 0);
+ /// Creates an expansion SLocEntry for a macro use. Returns its start.
+ ///
+ /// The macro body begins at \p SpellingLoc with length \p Length.
+ /// The macro use spans [ExpansionLocStart, ExpansionLocEnd].
+ SourceLocation createExpansionLoc(SourceLocation SpellingLoc,
+ SourceLocation ExpansionLocStart,
+ SourceLocation ExpansionLocEnd,
+ unsigned Length,
+ bool ExpansionIsTokenRange = true,
+ int LoadedID = 0,
+ SourceLocation::UIntTy LoadedOffset = 0);
/// Return a new SourceLocation that encodes that the token starting
/// at \p TokenStart ends prematurely at \p TokenEnd.
@@ -924,14 +965,14 @@ public:
/// Retrieve the memory buffer associated with the given file.
///
- /// Returns None if the buffer is not valid.
- llvm::Optional<llvm::MemoryBufferRef>
- getMemoryBufferForFileOrNone(const FileEntry *File);
+ /// Returns std::nullopt if the buffer is not valid.
+ std::optional<llvm::MemoryBufferRef>
+ getMemoryBufferForFileOrNone(FileEntryRef File);
/// Retrieve the memory buffer associated with the given file.
///
/// Returns a fake buffer if there isn't a real one.
- llvm::MemoryBufferRef getMemoryBufferForFileOrFake(const FileEntry *File) {
+ llvm::MemoryBufferRef getMemoryBufferForFileOrFake(FileEntryRef File) {
if (auto B = getMemoryBufferForFileOrNone(File))
return *B;
return getFakeBufferForRecovery();
@@ -944,7 +985,7 @@ public:
///
/// \param Buffer the memory buffer whose contents will be used as the
/// data in the given source file.
- void overrideFileContents(const FileEntry *SourceFile,
+ void overrideFileContents(FileEntryRef SourceFile,
const llvm::MemoryBufferRef &Buffer) {
overrideFileContents(SourceFile, llvm::MemoryBuffer::getMemBuffer(Buffer));
}
@@ -956,12 +997,8 @@ public:
///
/// \param Buffer the memory buffer whose contents will be used as the
/// data in the given source file.
- void overrideFileContents(const FileEntry *SourceFile,
- std::unique_ptr<llvm::MemoryBuffer> Buffer);
void overrideFileContents(FileEntryRef SourceFile,
- std::unique_ptr<llvm::MemoryBuffer> Buffer) {
- overrideFileContents(&SourceFile.getFileEntry(), std::move(Buffer));
- }
+ std::unique_ptr<llvm::MemoryBuffer> Buffer);
/// Override the given source file with another one.
///
@@ -969,30 +1006,28 @@ public:
///
/// \param NewFile the file whose contents will be used as the
/// data instead of the contents of the given source file.
- void overrideFileContents(const FileEntry *SourceFile,
- const FileEntry *NewFile);
+ void overrideFileContents(const FileEntry *SourceFile, FileEntryRef NewFile);
/// Returns true if the file contents have been overridden.
bool isFileOverridden(const FileEntry *File) const {
if (OverriddenFilesInfo) {
if (OverriddenFilesInfo->OverriddenFilesWithBuffer.count(File))
return true;
- if (OverriddenFilesInfo->OverriddenFiles.find(File) !=
- OverriddenFilesInfo->OverriddenFiles.end())
+ if (OverriddenFilesInfo->OverriddenFiles.contains(File))
return true;
}
return false;
}
/// Bypass the overridden contents of a file. This creates a new FileEntry
- /// and initializes the content cache for it. Returns None if there is no
- /// such file in the filesystem.
+ /// and initializes the content cache for it. Returns std::nullopt if there
+ /// is no such file in the filesystem.
///
/// This should be called before parsing has begun.
- Optional<FileEntryRef> bypassFileContentsOverride(FileEntryRef File);
+ OptionalFileEntryRef bypassFileContentsOverride(FileEntryRef File);
/// Specify that a file is transient.
- void setFileIsTransient(const FileEntry *SourceFile);
+ void setFileIsTransient(FileEntryRef SourceFile);
/// Specify that all files that are read during this compilation are
/// transient.
@@ -1006,13 +1041,14 @@ public:
/// Return the buffer for the specified FileID.
///
- /// If there is an error opening this buffer the first time, return None.
- llvm::Optional<llvm::MemoryBufferRef>
+ /// If there is an error opening this buffer the first time, return
+ /// std::nullopt.
+ std::optional<llvm::MemoryBufferRef>
getBufferOrNone(FileID FID, SourceLocation Loc = SourceLocation()) const {
if (auto *Entry = getSLocEntryForFile(FID))
return Entry->getFile().getContentCache().getBufferOrNone(
Diag, getFileManager(), Loc);
- return None;
+ return std::nullopt;
}
/// Return the buffer for the specified FileID.
@@ -1028,28 +1064,30 @@ public:
/// Returns the FileEntry record for the provided FileID.
const FileEntry *getFileEntryForID(FileID FID) const {
- if (auto *Entry = getSLocEntryForFile(FID))
- return Entry->getFile().getContentCache().OrigEntry;
+ if (auto FE = getFileEntryRefForID(FID))
+ return *FE;
return nullptr;
}
/// Returns the FileEntryRef for the provided FileID.
- Optional<FileEntryRef> getFileEntryRefForID(FileID FID) const {
- if (auto *Entry = getFileEntryForID(FID))
- return Entry->getLastRef();
- return None;
+ OptionalFileEntryRef getFileEntryRefForID(FileID FID) const {
+ if (auto *Entry = getSLocEntryForFile(FID))
+ return Entry->getFile().getContentCache().OrigEntry;
+ return std::nullopt;
}
/// Returns the filename for the provided FileID, unless it's a built-in
/// buffer that's not represented by a filename.
///
- /// Returns None for non-files and built-in files.
- Optional<StringRef> getNonBuiltinFilenameForID(FileID FID) const;
+ /// Returns std::nullopt for non-files and built-in files.
+ std::optional<StringRef> getNonBuiltinFilenameForID(FileID FID) const;
/// Returns the FileEntry record for the provided SLocEntry.
- const FileEntry *getFileEntryForSLocEntry(const SrcMgr::SLocEntry &sloc) const
- {
- return sloc.getFile().getContentCache().OrigEntry;
+ const FileEntry *
+ getFileEntryForSLocEntry(const SrcMgr::SLocEntry &SLocEntry) const {
+ if (auto FE = SLocEntry.getFile().getContentCache().OrigEntry)
+ return *FE;
+ return nullptr;
}
/// Return a StringRef to the source buffer data for the
@@ -1060,16 +1098,16 @@ public:
StringRef getBufferData(FileID FID, bool *Invalid = nullptr) const;
/// Return a StringRef to the source buffer data for the
- /// specified FileID, returning None if invalid.
+ /// specified FileID, returning std::nullopt if invalid.
///
/// \param FID The file ID whose contents will be returned.
- llvm::Optional<StringRef> getBufferDataOrNone(FileID FID) const;
+ std::optional<StringRef> getBufferDataOrNone(FileID FID) const;
/// Return a StringRef to the source buffer data for the
- /// specified FileID, returning None if it's not yet loaded.
+ /// specified FileID, returning std::nullopt if it's not yet loaded.
///
/// \param FID The file ID whose contents will be returned.
- llvm::Optional<StringRef> getBufferDataIfLoaded(FileID FID) const;
+ std::optional<StringRef> getBufferDataIfLoaded(FileID FID) const;
/// Get the number of FileIDs (files and macros) that were created
/// during preprocessing of \p FID, including it.
@@ -1101,13 +1139,7 @@ public:
/// the entry in SLocEntryTable which contains the specified location.
///
FileID getFileID(SourceLocation SpellingLoc) const {
- SourceLocation::UIntTy SLocOffset = SpellingLoc.getOffset();
-
- // If our one-entry cache covers this offset, just return it.
- if (isOffsetInFileID(LastFileIDLookup, SLocOffset))
- return LastFileIDLookup;
-
- return getFileIDSlow(SLocOffset);
+ return getFileID(SpellingLoc.getOffset());
}
/// Return the filename of the file containing a SourceLocation.
@@ -1468,24 +1500,35 @@ public:
/// Returns whether \p Loc is located in a <built-in> file.
bool isWrittenInBuiltinFile(SourceLocation Loc) const {
- StringRef Filename(getPresumedLoc(Loc).getFilename());
+ PresumedLoc Presumed = getPresumedLoc(Loc);
+ if (Presumed.isInvalid())
+ return false;
+ StringRef Filename(Presumed.getFilename());
return Filename.equals("<built-in>");
}
/// Returns whether \p Loc is located in a <command line> file.
bool isWrittenInCommandLineFile(SourceLocation Loc) const {
- StringRef Filename(getPresumedLoc(Loc).getFilename());
+ PresumedLoc Presumed = getPresumedLoc(Loc);
+ if (Presumed.isInvalid())
+ return false;
+ StringRef Filename(Presumed.getFilename());
return Filename.equals("<command line>");
}
/// Returns whether \p Loc is located in a <scratch space> file.
bool isWrittenInScratchSpace(SourceLocation Loc) const {
- StringRef Filename(getPresumedLoc(Loc).getFilename());
+ PresumedLoc Presumed = getPresumedLoc(Loc);
+ if (Presumed.isInvalid())
+ return false;
+ StringRef Filename(Presumed.getFilename());
return Filename.equals("<scratch space>");
}
/// Returns if a SourceLocation is in a system header.
bool isInSystemHeader(SourceLocation Loc) const {
+ if (Loc.isInvalid())
+ return false;
return isSystem(getFileCharacteristic(Loc));
}
@@ -1629,6 +1672,11 @@ public:
isInTheSameTranslationUnit(std::pair<FileID, unsigned> &LOffs,
std::pair<FileID, unsigned> &ROffs) const;
+ /// Determines whether the two decomposed source location is in the same TU.
+ bool isInTheSameTranslationUnitImpl(
+ const std::pair<FileID, unsigned> &LOffs,
+ const std::pair<FileID, unsigned> &ROffs) const;
+
/// Determines the order of 2 source locations in the "source location
/// address space".
bool isBeforeInSLocAddrSpace(SourceLocation LHS, SourceLocation RHS) const {
@@ -1660,12 +1708,12 @@ public:
// Iterators over FileInfos.
using fileinfo_iterator =
- llvm::DenseMap<const FileEntry*, SrcMgr::ContentCache*>::const_iterator;
+ llvm::DenseMap<FileEntryRef, SrcMgr::ContentCache *>::const_iterator;
fileinfo_iterator fileinfo_begin() const { return FileInfos.begin(); }
fileinfo_iterator fileinfo_end() const { return FileInfos.end(); }
bool hasFileInfo(const FileEntry *File) const {
- return FileInfos.find(File) != FileInfos.end();
+ return FileInfos.find_as(File) != FileInfos.end();
}
/// Print statistics to stderr.
@@ -1673,6 +1721,10 @@ public:
void dump() const;
+ // Produce notes describing the current source location address space usage.
+ void noteSLocAddressSpaceUsage(DiagnosticsEngine &Diag,
+ std::optional<unsigned> MaxNotes = 32) const;
+
/// Get the number of local SLocEntries we have.
unsigned local_sloc_entry_size() const { return LocalSLocEntryTable.size(); }
@@ -1723,12 +1775,12 @@ public:
/// Returns true if \p Loc came from a PCH/Module.
bool isLoadedSourceLocation(SourceLocation Loc) const {
- return Loc.getOffset() >= CurrentLoadedOffset;
+ return isLoadedOffset(Loc.getOffset());
}
/// Returns true if \p Loc did not come from a PCH/Module.
bool isLocalSourceLocation(SourceLocation Loc) const {
- return Loc.getOffset() < NextLocalOffset;
+ return isLocalOffset(Loc.getOffset());
}
/// Returns true if \p FID came from a PCH/Module.
@@ -1798,11 +1850,27 @@ private:
return getLoadedSLocEntry(static_cast<unsigned>(-ID - 2), Invalid);
}
+ FileID getFileID(SourceLocation::UIntTy SLocOffset) const {
+ // If our one-entry cache covers this offset, just return it.
+ if (isOffsetInFileID(LastFileIDLookup, SLocOffset))
+ return LastFileIDLookup;
+
+ return getFileIDSlow(SLocOffset);
+ }
+
+ bool isLocalOffset(SourceLocation::UIntTy SLocOffset) const {
+ return SLocOffset < CurrentLoadedOffset;
+ }
+
+ bool isLoadedOffset(SourceLocation::UIntTy SLocOffset) const {
+ return SLocOffset >= CurrentLoadedOffset;
+ }
+
/// Implements the common elements of storing an expansion info struct into
/// the SLocEntry table and producing a source location that refers to it.
SourceLocation
createExpansionLocImpl(const SrcMgr::ExpansionInfo &Expansion,
- unsigned TokLength, int LoadedID = 0,
+ unsigned Length, int LoadedID = 0,
SourceLocation::UIntTy LoadedOffset = 0);
/// Return true if the specified FileID contains the
@@ -1902,11 +1970,11 @@ public:
}
};
-/// SourceManager and necessary depdencies (e.g. VFS, FileManager) for a single
-/// in-memorty file.
+/// SourceManager and necessary dependencies (e.g. VFS, FileManager) for a
+/// single in-memorty file.
class SourceManagerForFile {
public:
- /// Creates SourceManager and necessary depdencies (e.g. VFS, FileManager).
+ /// Creates SourceManager and necessary dependencies (e.g. VFS, FileManager).
/// The main file in the SourceManager will be \p FileName with \p Content.
SourceManagerForFile(StringRef FileName, StringRef Content);
diff --git a/contrib/llvm-project/clang/include/clang/Basic/SourceMgrAdapter.h b/contrib/llvm-project/clang/include/clang/Basic/SourceMgrAdapter.h
new file mode 100644
index 000000000000..be7f9d5051fb
--- /dev/null
+++ b/contrib/llvm-project/clang/include/clang/Basic/SourceMgrAdapter.h
@@ -0,0 +1,85 @@
+//=== SourceMgrAdapter.h - SourceMgr to SourceManager Adapter ---*- 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 provides an adapter that maps diagnostics from llvm::SourceMgr
+// to Clang's SourceManager.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_SOURCEMGRADAPTER_H
+#define LLVM_CLANG_SOURCEMGRADAPTER_H
+
+#include "clang/Basic/SourceManager.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/Support/SourceMgr.h"
+#include <string>
+#include <utility>
+
+namespace clang {
+
+class DiagnosticsEngine;
+class FileEntry;
+
+/// An adapter that can be used to translate diagnostics from one or more
+/// llvm::SourceMgr instances to a ,
+class SourceMgrAdapter {
+ /// Clang source manager.
+ SourceManager &SrcMgr;
+
+ /// Clang diagnostics engine.
+ DiagnosticsEngine &Diagnostics;
+
+ /// Diagnostic IDs for errors, warnings, and notes.
+ unsigned ErrorDiagID, WarningDiagID, NoteDiagID;
+
+ /// The default file to use when mapping buffers.
+ OptionalFileEntryRef DefaultFile;
+
+ /// A mapping from (LLVM source manager, buffer ID) pairs to the
+ /// corresponding file ID within the Clang source manager.
+ llvm::DenseMap<std::pair<const llvm::SourceMgr *, unsigned>, FileID>
+ FileIDMapping;
+
+ /// Diagnostic handler.
+ static void handleDiag(const llvm::SMDiagnostic &Diag, void *Context);
+
+public:
+ /// Create a new \c SourceMgr adaptor that maps to the given source
+ /// manager and diagnostics engine.
+ SourceMgrAdapter(SourceManager &SM, DiagnosticsEngine &Diagnostics,
+ unsigned ErrorDiagID, unsigned WarningDiagID,
+ unsigned NoteDiagID,
+ OptionalFileEntryRef DefaultFile = std::nullopt);
+
+ ~SourceMgrAdapter();
+
+ /// Map a source location in the given LLVM source manager to its
+ /// corresponding location in the Clang source manager.
+ SourceLocation mapLocation(const llvm::SourceMgr &LLVMSrcMgr,
+ llvm::SMLoc Loc);
+
+ /// Map a source range in the given LLVM source manager to its corresponding
+ /// range in the Clang source manager.
+ SourceRange mapRange(const llvm::SourceMgr &LLVMSrcMgr, llvm::SMRange Range);
+
+ /// Handle the given diagnostic from an LLVM source manager.
+ void handleDiag(const llvm::SMDiagnostic &Diag);
+
+ /// Retrieve the diagnostic handler to use with the underlying SourceMgr.
+ llvm::SourceMgr::DiagHandlerTy getDiagHandler() {
+ return &SourceMgrAdapter::handleDiag;
+ }
+
+ /// Retrieve the context to use with the diagnostic handler produced by
+ /// \c getDiagHandler().
+ void *getDiagContext() { return this; }
+};
+
+} // end namespace clang
+
+#endif
diff --git a/contrib/llvm-project/clang/include/clang/Basic/Specifiers.h b/contrib/llvm-project/clang/include/clang/Basic/Specifiers.h
index 1c38b411e083..87f29c8ae10b 100644
--- a/contrib/llvm-project/clang/include/clang/Basic/Specifiers.h
+++ b/contrib/llvm-project/clang/include/clang/Basic/Specifiers.h
@@ -19,6 +19,9 @@
#include "llvm/Support/DataTypes.h"
#include "llvm/Support/ErrorHandling.h"
+namespace llvm {
+class raw_ostream;
+} // namespace llvm
namespace clang {
/// Define the meaning of possible values of the kind in ExplicitSpecifier.
@@ -31,6 +34,15 @@ namespace clang {
/// Define the kind of constexpr specifier.
enum class ConstexprSpecKind { Unspecified, Constexpr, Consteval, Constinit };
+ /// In an if statement, this denotes whether the statement is
+ /// a constexpr or consteval if statement.
+ enum class IfStatementKind : unsigned {
+ Ordinary,
+ Constexpr,
+ ConstevalNonNegated,
+ ConstevalNegated
+ };
+
/// Specifies the width of a type, e.g., short, long, or long long.
enum class TypeSpecifierWidth { Unspecified, Short, Long, LongLong };
@@ -44,40 +56,44 @@ namespace clang {
TST_unspecified,
TST_void,
TST_char,
- TST_wchar, // C++ wchar_t
- TST_char8, // C++20 char8_t (proposed)
- TST_char16, // C++11 char16_t
- TST_char32, // C++11 char32_t
+ TST_wchar, // C++ wchar_t
+ TST_char8, // C++20 char8_t (proposed)
+ TST_char16, // C++11 char16_t
+ TST_char32, // C++11 char32_t
TST_int,
TST_int128,
- TST_extint, // Extended Int types.
- TST_half, // OpenCL half, ARM NEON __fp16
- TST_Float16, // C11 extension ISO/IEC TS 18661-3
- TST_Accum, // ISO/IEC JTC1 SC22 WG14 N1169 Extension
+ TST_bitint, // Bit-precise integer types.
+ TST_half, // OpenCL half, ARM NEON __fp16
+ TST_Float16, // C11 extension ISO/IEC TS 18661-3
+ TST_Accum, // ISO/IEC JTC1 SC22 WG14 N1169 Extension
TST_Fract,
TST_BFloat16,
TST_float,
TST_double,
TST_float128,
- TST_bool, // _Bool
- TST_decimal32, // _Decimal32
- TST_decimal64, // _Decimal64
- TST_decimal128, // _Decimal128
+ TST_ibm128,
+ TST_bool, // _Bool
+ TST_decimal32, // _Decimal32
+ TST_decimal64, // _Decimal64
+ TST_decimal128, // _Decimal128
TST_enum,
TST_union,
TST_struct,
- TST_class, // C++ class type
- TST_interface, // C++ (Microsoft-specific) __interface type
- TST_typename, // Typedef, C++ class-name or enum name, etc.
- TST_typeofType,
- TST_typeofExpr,
- TST_decltype, // C++11 decltype
- TST_underlyingType, // __underlying_type for C++11
- TST_auto, // C++11 auto
- TST_decltype_auto, // C++1y decltype(auto)
- TST_auto_type, // __auto_type extension
- TST_unknown_anytype, // __unknown_anytype extension
- TST_atomic, // C11 _Atomic
+ TST_class, // C++ class type
+ TST_interface, // C++ (Microsoft-specific) __interface type
+ TST_typename, // Typedef, C++ class-name or enum name, etc.
+ TST_typeofType, // C23 (and GNU extension) typeof(type-name)
+ TST_typeofExpr, // C23 (and GNU extension) typeof(expression)
+ TST_typeof_unqualType, // C23 typeof_unqual(type-name)
+ TST_typeof_unqualExpr, // C23 typeof_unqual(expression)
+ TST_decltype, // C++11 decltype
+#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) TST_##Trait,
+#include "clang/Basic/TransformTypeTraits.def"
+ TST_auto, // C++11 auto
+ TST_decltype_auto, // C++1y decltype(auto)
+ TST_auto_type, // __auto_type extension
+ TST_unknown_anytype, // __unknown_anytype extension
+ TST_atomic, // C11 _Atomic
#define GENERIC_IMAGE_TYPE(ImgType, Id) TST_##ImgType##_t, // OpenCL image types
#include "clang/Basic/OpenCLImageTypes.def"
TST_error // erroneous type
@@ -86,10 +102,14 @@ namespace clang {
/// Structure that packs information about the type specifiers that
/// were written in a particular type specifier sequence.
struct WrittenBuiltinSpecs {
- static_assert(TST_error < 1 << 6, "Type bitfield not wide enough for TST");
- /*DeclSpec::TST*/ unsigned Type : 6;
- /*DeclSpec::TSS*/ unsigned Sign : 2;
- /*TypeSpecifierWidth*/ unsigned Width : 2;
+ static_assert(TST_error < 1 << 7, "Type bitfield not wide enough for TST");
+ LLVM_PREFERRED_TYPE(TypeSpecifierType)
+ unsigned Type : 7;
+ LLVM_PREFERRED_TYPE(TypeSpecifierSign)
+ unsigned Sign : 2;
+ LLVM_PREFERRED_TYPE(TypeSpecifierWidth)
+ unsigned Width : 2;
+ LLVM_PREFERRED_TYPE(bool)
unsigned ModeAttr : 1;
};
@@ -270,6 +290,9 @@ namespace clang {
CC_PreserveMost, // __attribute__((preserve_most))
CC_PreserveAll, // __attribute__((preserve_all))
CC_AArch64VectorCall, // __attribute__((aarch64_vector_pcs))
+ CC_AArch64SVEPCS, // __attribute__((aarch64_sve_pcs))
+ CC_AMDGPUKernelCall, // __attribute__((amdgpu_kernel))
+ CC_M68kRTD, // __attribute__((m68k_rtd))
};
/// Checks whether the given calling convention supports variadic
@@ -286,6 +309,7 @@ namespace clang {
case CC_OpenCLKernel:
case CC_Swift:
case CC_SwiftAsync:
+ case CC_M68kRTD:
return false;
default:
return true;
@@ -314,10 +338,12 @@ namespace clang {
Unspecified,
// Generally behaves like Nullable, except when used in a block parameter
// that was imported into a swift async method. There, swift will assume
- // that the parameter can get null even if no error occured. _Nullable
+ // that the parameter can get null even if no error occurred. _Nullable
// parameters are assumed to only get null on error.
NullableResult,
};
+ /// Prints human-readable debug representation.
+ llvm::raw_ostream &operator<<(llvm::raw_ostream&, NullabilityKind);
/// Return true if \p L has a weaker nullability annotation than \p R. The
/// ordering is: Unspecified < Nullable < NonNull.
diff --git a/contrib/llvm-project/clang/include/clang/Basic/Stack.h b/contrib/llvm-project/clang/include/clang/Basic/Stack.h
index 3418c3bad11b..30ebd94aedd1 100644
--- a/contrib/llvm-project/clang/include/clang/Basic/Stack.h
+++ b/contrib/llvm-project/clang/include/clang/Basic/Stack.h
@@ -39,7 +39,7 @@ namespace clang {
/// is insufficient, calls Diag to emit a diagnostic before calling Fn.
inline void runWithSufficientStackSpace(llvm::function_ref<void()> Diag,
llvm::function_ref<void()> Fn) {
-#ifdef LLVM_ENABLE_THREADS
+#if LLVM_ENABLE_THREADS
if (LLVM_UNLIKELY(isStackNearlyExhausted()))
runWithSufficientStackSpaceSlow(Diag, Fn);
else
diff --git a/contrib/llvm-project/clang/include/clang/Basic/StmtNodes.td b/contrib/llvm-project/clang/include/clang/Basic/StmtNodes.td
index 508f1fddf1b3..cec301dfca28 100644
--- a/contrib/llvm-project/clang/include/clang/Basic/StmtNodes.td
+++ b/contrib/llvm-project/clang/include/clang/Basic/StmtNodes.td
@@ -50,7 +50,7 @@ def CXXCatchStmt : StmtNode<Stmt>;
def CXXTryStmt : StmtNode<Stmt>;
def CXXForRangeStmt : StmtNode<Stmt>;
-// C++ Coroutines TS statements
+// C++ Coroutines statements
def CoroutineBodyStmt : StmtNode<Stmt>;
def CoreturnStmt : StmtNode<Stmt>;
@@ -160,8 +160,9 @@ def FunctionParmPackExpr : StmtNode<Expr>;
def MaterializeTemporaryExpr : StmtNode<Expr>;
def LambdaExpr : StmtNode<Expr>;
def CXXFoldExpr : StmtNode<Expr>;
+def CXXParenListInitExpr: StmtNode<Expr>;
-// C++ Coroutines TS expressions
+// C++ Coroutines expressions
def CoroutineSuspendExpr : StmtNode<Expr, 1>;
def CoawaitExpr : StmtNode<CoroutineSuspendExpr>;
def DependentCoawaitExpr : StmtNode<Expr>;
@@ -219,12 +220,14 @@ def AsTypeExpr : StmtNode<Expr>;
// OpenMP Directives.
def OMPCanonicalLoop : StmtNode<Stmt>;
def OMPExecutableDirective : StmtNode<Stmt, 1>;
+def OMPMetaDirective : StmtNode<OMPExecutableDirective>;
def OMPLoopBasedDirective : StmtNode<OMPExecutableDirective, 1>;
def OMPLoopDirective : StmtNode<OMPLoopBasedDirective, 1>;
def OMPParallelDirective : StmtNode<OMPExecutableDirective>;
def OMPSimdDirective : StmtNode<OMPLoopDirective>;
-def OMPTileDirective : StmtNode<OMPLoopBasedDirective>;
-def OMPUnrollDirective : StmtNode<OMPLoopBasedDirective>;
+def OMPLoopTransformationDirective : StmtNode<OMPLoopBasedDirective, 1>;
+def OMPTileDirective : StmtNode<OMPLoopTransformationDirective>;
+def OMPUnrollDirective : StmtNode<OMPLoopTransformationDirective>;
def OMPForDirective : StmtNode<OMPLoopDirective>;
def OMPForSimdDirective : StmtNode<OMPLoopDirective>;
def OMPSectionsDirective : StmtNode<OMPExecutableDirective>;
@@ -256,12 +259,17 @@ def OMPTargetUpdateDirective : StmtNode<OMPExecutableDirective>;
def OMPTeamsDirective : StmtNode<OMPExecutableDirective>;
def OMPCancellationPointDirective : StmtNode<OMPExecutableDirective>;
def OMPCancelDirective : StmtNode<OMPExecutableDirective>;
+def OMPScopeDirective : StmtNode<OMPExecutableDirective>;
def OMPTaskLoopDirective : StmtNode<OMPLoopDirective>;
def OMPTaskLoopSimdDirective : StmtNode<OMPLoopDirective>;
def OMPMasterTaskLoopDirective : StmtNode<OMPLoopDirective>;
def OMPMasterTaskLoopSimdDirective : StmtNode<OMPLoopDirective>;
def OMPParallelMasterTaskLoopDirective : StmtNode<OMPLoopDirective>;
def OMPParallelMasterTaskLoopSimdDirective : StmtNode<OMPLoopDirective>;
+def OMPMaskedTaskLoopDirective : StmtNode<OMPLoopDirective>;
+def OMPMaskedTaskLoopSimdDirective : StmtNode<OMPLoopDirective>;
+def OMPParallelMaskedTaskLoopDirective : StmtNode<OMPLoopDirective>;
+def OMPParallelMaskedTaskLoopSimdDirective : StmtNode<OMPLoopDirective>;
def OMPDistributeDirective : StmtNode<OMPLoopDirective>;
def OMPDistributeParallelForDirective : StmtNode<OMPLoopDirective>;
def OMPDistributeParallelForSimdDirective : StmtNode<OMPLoopDirective>;
@@ -280,3 +288,10 @@ def OMPTargetTeamsDistributeSimdDirective : StmtNode<OMPLoopDirective>;
def OMPInteropDirective : StmtNode<OMPExecutableDirective>;
def OMPDispatchDirective : StmtNode<OMPExecutableDirective>;
def OMPMaskedDirective : StmtNode<OMPExecutableDirective>;
+def OMPParallelMaskedDirective : StmtNode<OMPExecutableDirective>;
+def OMPGenericLoopDirective : StmtNode<OMPLoopDirective>;
+def OMPTeamsGenericLoopDirective : StmtNode<OMPLoopDirective>;
+def OMPTargetTeamsGenericLoopDirective : StmtNode<OMPLoopDirective>;
+def OMPParallelGenericLoopDirective : StmtNode<OMPLoopDirective>;
+def OMPTargetParallelGenericLoopDirective : StmtNode<OMPLoopDirective>;
+def OMPErrorDirective : StmtNode<OMPExecutableDirective>;
diff --git a/contrib/llvm-project/clang/include/clang/Basic/SyncScope.h b/contrib/llvm-project/clang/include/clang/Basic/SyncScope.h
index ce8fb9cbed13..bc7ec7b5cf77 100644
--- a/contrib/llvm-project/clang/include/clang/Basic/SyncScope.h
+++ b/contrib/llvm-project/clang/include/clang/Basic/SyncScope.h
@@ -40,6 +40,16 @@ namespace clang {
/// Update getAsString.
///
enum class SyncScope {
+ SystemScope,
+ DeviceScope,
+ WorkgroupScope,
+ WavefrontScope,
+ SingleScope,
+ HIPSingleThread,
+ HIPWavefront,
+ HIPWorkgroup,
+ HIPAgent,
+ HIPSystem,
OpenCLWorkGroup,
OpenCLDevice,
OpenCLAllSVMDevices,
@@ -49,6 +59,26 @@ enum class SyncScope {
inline llvm::StringRef getAsString(SyncScope S) {
switch (S) {
+ case SyncScope::SystemScope:
+ return "system_scope";
+ case SyncScope::DeviceScope:
+ return "device_scope";
+ case SyncScope::WorkgroupScope:
+ return "workgroup_scope";
+ case SyncScope::WavefrontScope:
+ return "wavefront_scope";
+ case SyncScope::SingleScope:
+ return "single_scope";
+ case SyncScope::HIPSingleThread:
+ return "hip_singlethread";
+ case SyncScope::HIPWavefront:
+ return "hip_wavefront";
+ case SyncScope::HIPWorkgroup:
+ return "hip_workgroup";
+ case SyncScope::HIPAgent:
+ return "hip_agent";
+ case SyncScope::HIPSystem:
+ return "hip_system";
case SyncScope::OpenCLWorkGroup:
return "opencl_workgroup";
case SyncScope::OpenCLDevice:
@@ -62,7 +92,7 @@ inline llvm::StringRef getAsString(SyncScope S) {
}
/// Defines the kind of atomic scope models.
-enum class AtomicScopeModelKind { None, OpenCL };
+enum class AtomicScopeModelKind { None, OpenCL, HIP, Generic };
/// Defines the interface for synch scope model.
class AtomicScopeModel {
@@ -130,7 +160,7 @@ public:
static const unsigned Scopes[] = {
static_cast<unsigned>(WorkGroup), static_cast<unsigned>(Device),
static_cast<unsigned>(AllSVMDevices), static_cast<unsigned>(SubGroup)};
- return llvm::makeArrayRef(Scopes);
+ return llvm::ArrayRef(Scopes);
}
unsigned getFallBackValue() const override {
@@ -138,6 +168,108 @@ public:
}
};
+/// Defines the synch scope model for HIP.
+class AtomicScopeHIPModel : public AtomicScopeModel {
+public:
+ /// The enum values match the pre-defined macros
+ /// __HIP_MEMORY_SCOPE_*, which are used to define memory_scope_*
+ /// enums in hip-c.h.
+ enum ID {
+ SingleThread = 1,
+ Wavefront = 2,
+ Workgroup = 3,
+ Agent = 4,
+ System = 5,
+ Last = System
+ };
+
+ AtomicScopeHIPModel() {}
+
+ SyncScope map(unsigned S) const override {
+ switch (static_cast<ID>(S)) {
+ case SingleThread:
+ return SyncScope::HIPSingleThread;
+ case Wavefront:
+ return SyncScope::HIPWavefront;
+ case Workgroup:
+ return SyncScope::HIPWorkgroup;
+ case Agent:
+ return SyncScope::HIPAgent;
+ case System:
+ return SyncScope::HIPSystem;
+ }
+ llvm_unreachable("Invalid language synch scope value");
+ }
+
+ bool isValid(unsigned S) const override {
+ return S >= static_cast<unsigned>(SingleThread) &&
+ S <= static_cast<unsigned>(Last);
+ }
+
+ ArrayRef<unsigned> getRuntimeValues() const override {
+ static_assert(Last == System, "Does not include all synch scopes");
+ static const unsigned Scopes[] = {
+ static_cast<unsigned>(SingleThread), static_cast<unsigned>(Wavefront),
+ static_cast<unsigned>(Workgroup), static_cast<unsigned>(Agent),
+ static_cast<unsigned>(System)};
+ return llvm::ArrayRef(Scopes);
+ }
+
+ unsigned getFallBackValue() const override {
+ return static_cast<unsigned>(System);
+ }
+};
+
+/// Defines the generic atomic scope model.
+class AtomicScopeGenericModel : public AtomicScopeModel {
+public:
+ /// The enum values match predefined built-in macros __ATOMIC_SCOPE_*.
+ enum ID {
+ System = 0,
+ Device = 1,
+ Workgroup = 2,
+ Wavefront = 3,
+ Single = 4,
+ Last = Single
+ };
+
+ AtomicScopeGenericModel() = default;
+
+ SyncScope map(unsigned S) const override {
+ switch (static_cast<ID>(S)) {
+ case Device:
+ return SyncScope::DeviceScope;
+ case System:
+ return SyncScope::SystemScope;
+ case Workgroup:
+ return SyncScope::WorkgroupScope;
+ case Wavefront:
+ return SyncScope::WavefrontScope;
+ case Single:
+ return SyncScope::SingleScope;
+ }
+ llvm_unreachable("Invalid language sync scope value");
+ }
+
+ bool isValid(unsigned S) const override {
+ return S >= static_cast<unsigned>(System) &&
+ S <= static_cast<unsigned>(Last);
+ }
+
+ ArrayRef<unsigned> getRuntimeValues() const override {
+ static_assert(Last == Single, "Does not include all sync scopes");
+ static const unsigned Scopes[] = {
+ static_cast<unsigned>(Device), static_cast<unsigned>(System),
+ static_cast<unsigned>(Workgroup), static_cast<unsigned>(Wavefront),
+ static_cast<unsigned>(Single)};
+ return llvm::ArrayRef(Scopes);
+ }
+
+ unsigned getFallBackValue() const override {
+ return static_cast<unsigned>(System);
+ }
+};
+
inline std::unique_ptr<AtomicScopeModel>
AtomicScopeModel::create(AtomicScopeModelKind K) {
switch (K) {
@@ -145,9 +277,13 @@ AtomicScopeModel::create(AtomicScopeModelKind K) {
return std::unique_ptr<AtomicScopeModel>{};
case AtomicScopeModelKind::OpenCL:
return std::make_unique<AtomicScopeOpenCLModel>();
+ case AtomicScopeModelKind::HIP:
+ return std::make_unique<AtomicScopeHIPModel>();
+ case AtomicScopeModelKind::Generic:
+ return std::make_unique<AtomicScopeGenericModel>();
}
llvm_unreachable("Invalid atomic scope model kind");
}
-}
+} // namespace clang
#endif
diff --git a/contrib/llvm-project/clang/include/clang/Basic/TargetBuiltins.h b/contrib/llvm-project/clang/include/clang/Basic/TargetBuiltins.h
index ed53b10f61ef..c31834fb52a9 100644
--- a/contrib/llvm-project/clang/include/clang/Basic/TargetBuiltins.h
+++ b/contrib/llvm-project/clang/include/clang/Basic/TargetBuiltins.h
@@ -27,6 +27,7 @@ namespace clang {
enum {
LastTIBuiltin = clang::Builtin::FirstTSBuiltin - 1,
#define BUILTIN(ID, TYPE, ATTRS) BI##ID,
+#define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) BI##ID,
#include "clang/Basic/BuiltinsNEON.def"
FirstTSBuiltin
};
@@ -47,11 +48,22 @@ namespace clang {
enum {
LastNEONBuiltin = NEON::FirstTSBuiltin - 1,
#define BUILTIN(ID, TYPE, ATTRS) BI##ID,
+#define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) BI##ID,
#include "clang/Basic/BuiltinsSVE.def"
FirstTSBuiltin,
};
}
+ namespace SME {
+ enum {
+ LastSVEBuiltin = SVE::FirstTSBuiltin - 1,
+#define BUILTIN(ID, TYPE, ATTRS) BI##ID,
+#define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) BI##ID,
+#include "clang/Basic/BuiltinsSME.def"
+ FirstTSBuiltin,
+ };
+ }
+
/// AArch64 builtins
namespace AArch64 {
enum {
@@ -59,6 +71,8 @@ namespace clang {
LastNEONBuiltin = NEON::FirstTSBuiltin - 1,
FirstSVEBuiltin = NEON::FirstTSBuiltin,
LastSVEBuiltin = SVE::FirstTSBuiltin - 1,
+ FirstSMEBuiltin = SVE::FirstTSBuiltin,
+ LastSMEBuiltin = SME::FirstTSBuiltin - 1,
#define BUILTIN(ID, TYPE, ATTRS) BI##ID,
#include "clang/Basic/BuiltinsAArch64.def"
LastTSBuiltin
@@ -121,19 +135,45 @@ namespace clang {
/// VE builtins
namespace VE {
- enum { LastTIBuiltin = clang::Builtin::FirstTSBuiltin - 1, LastTSBuiltin };
+ enum {
+ LastTIBuiltin = clang::Builtin::FirstTSBuiltin - 1,
+#define BUILTIN(ID, TYPE, ATTRS) BI##ID,
+#include "clang/Basic/BuiltinsVE.def"
+ LastTSBuiltin
+ };
+ }
+
+ namespace RISCVVector {
+ enum {
+ LastTIBuiltin = clang::Builtin::FirstTSBuiltin - 1,
+#define BUILTIN(ID, TYPE, ATTRS) BI##ID,
+#include "clang/Basic/BuiltinsRISCVVector.def"
+ FirstTSBuiltin,
+ };
}
/// RISCV builtins
namespace RISCV {
enum {
LastTIBuiltin = clang::Builtin::FirstTSBuiltin - 1,
+ FirstRVVBuiltin = clang::Builtin::FirstTSBuiltin,
+ LastRVVBuiltin = RISCVVector::FirstTSBuiltin - 1,
#define BUILTIN(ID, TYPE, ATTRS) BI##ID,
#include "clang/Basic/BuiltinsRISCV.def"
LastTSBuiltin
};
} // namespace RISCV
+ /// LoongArch builtins
+ namespace LoongArch {
+ enum {
+ LastTIBuiltin = clang::Builtin::FirstTSBuiltin - 1,
+#define BUILTIN(ID, TYPE, ATTRS) BI##ID,
+#include "clang/Basic/BuiltinsLoongArch.def"
+ LastTSBuiltin
+ };
+ } // namespace LoongArch
+
/// Flags to identify the types for overloaded Neon builtins.
///
/// These must be kept in sync with the flags in utils/TableGen/NeonEmitter.h.
@@ -216,10 +256,10 @@ namespace clang {
};
SVETypeFlags(uint64_t F) : Flags(F) {
- EltTypeShift = llvm::countTrailingZeros(EltTypeMask);
- MemEltTypeShift = llvm::countTrailingZeros(MemEltTypeMask);
- MergeTypeShift = llvm::countTrailingZeros(MergeTypeMask);
- SplatOperandMaskShift = llvm::countTrailingZeros(SplatOperandMask);
+ EltTypeShift = llvm::countr_zero(EltTypeMask);
+ MemEltTypeShift = llvm::countr_zero(MemEltTypeMask);
+ MergeTypeShift = llvm::countr_zero(MergeTypeMask);
+ SplatOperandMaskShift = llvm::countr_zero(SplatOperandMask);
}
EltType getEltType() const {
@@ -251,7 +291,9 @@ namespace clang {
bool isZExtReturn() const { return Flags & IsZExtReturn; }
bool isByteIndexed() const { return Flags & IsByteIndexed; }
bool isOverloadNone() const { return Flags & IsOverloadNone; }
- bool isOverloadWhile() const { return Flags & IsOverloadWhile; }
+ bool isOverloadWhileOrMultiVecCvt() const {
+ return Flags & IsOverloadWhileOrMultiVecCvt;
+ }
bool isOverloadDefault() const { return !(Flags & OverloadKindMask); }
bool isOverloadWhileRW() const { return Flags & IsOverloadWhileRW; }
bool isOverloadCvt() const { return Flags & IsOverloadCvt; }
@@ -261,11 +303,15 @@ namespace clang {
bool isInsertOp1SVALL() const { return Flags & IsInsertOp1SVALL; }
bool isGatherPrefetch() const { return Flags & IsGatherPrefetch; }
bool isReverseUSDOT() const { return Flags & ReverseUSDOT; }
+ bool isReverseMergeAnyBinOp() const { return Flags & ReverseMergeAnyBinOp; }
+ bool isReverseMergeAnyAccOp() const { return Flags & ReverseMergeAnyAccOp; }
bool isUndef() const { return Flags & IsUndef; }
bool isTupleCreate() const { return Flags & IsTupleCreate; }
bool isTupleGet() const { return Flags & IsTupleGet; }
bool isTupleSet() const { return Flags & IsTupleSet; }
-
+ bool isReadZA() const { return Flags & IsReadZA; }
+ bool isWriteZA() const { return Flags & IsWriteZA; }
+ bool isReductionQV() const { return Flags & IsReductionQV; }
uint64_t getBits() const { return Flags; }
bool isFlagSet(uint64_t Flag) const { return Flags & Flag; }
};
diff --git a/contrib/llvm-project/clang/include/clang/Basic/TargetCXXABI.h b/contrib/llvm-project/clang/include/clang/Basic/TargetCXXABI.h
index e727f85edad7..c113a6a048ad 100644
--- a/contrib/llvm-project/clang/include/clang/Basic/TargetCXXABI.h
+++ b/contrib/llvm-project/clang/include/clang/Basic/TargetCXXABI.h
@@ -19,8 +19,8 @@
#include "clang/Basic/LLVM.h"
#include "llvm/ADT/StringMap.h"
-#include "llvm/ADT/Triple.h"
#include "llvm/Support/ErrorHandling.h"
+#include "llvm/TargetParser/Triple.h"
namespace clang {
@@ -60,9 +60,7 @@ public:
static const auto &getSpelling(Kind ABIKind) {
return getSpellingMap().find(ABIKind)->second;
}
- static bool isABI(StringRef Name) {
- return getABIMap().find(Name) != getABIMap().end();
- }
+ static bool isABI(StringRef Name) { return getABIMap().contains(Name); }
// Return true if this target should use the relative vtables C++ ABI by
// default.
diff --git a/contrib/llvm-project/clang/include/clang/Basic/TargetID.h b/contrib/llvm-project/clang/include/clang/Basic/TargetID.h
index 1a9785574d06..cef9cb5f0fb2 100644
--- a/contrib/llvm-project/clang/include/clang/Basic/TargetID.h
+++ b/contrib/llvm-project/clang/include/clang/Basic/TargetID.h
@@ -6,12 +6,13 @@
//
//===----------------------------------------------------------------------===//
-#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"
-#include "llvm/ADT/Triple.h"
+#include "llvm/TargetParser/Triple.h"
+#include <optional>
#include <set>
namespace clang {
@@ -21,7 +22,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);
@@ -31,15 +32,15 @@ llvm::StringRef getProcessorFromTargetID(const llvm::Triple &T,
llvm::StringRef OffloadArch);
/// Parse a target ID to get processor and feature map.
-/// Returns canonicalized processor name or None if the target ID is invalid.
-/// Returns target ID features in \p FeatureMap if it is not null pointer.
-/// This function assumes \p OffloadArch is a valid target ID.
+/// Returns canonicalized processor name or std::nullopt if the target ID is
+/// invalid. Returns target ID features in \p FeatureMap if it is not null
+/// pointer. This function assumes \p OffloadArch is a valid target ID.
/// If the target ID contains feature+, map it to true.
/// If the target ID contains feature-, map it to false.
/// If the target ID does not contain a feature (default), do not map it.
-llvm::Optional<llvm::StringRef>
-parseTargetID(const llvm::Triple &T, llvm::StringRef OffloadArch,
- llvm::StringMap<bool> *FeatureMap);
+std::optional<llvm::StringRef> parseTargetID(const llvm::Triple &T,
+ llvm::StringRef OffloadArch,
+ llvm::StringMap<bool> *FeatureMap);
/// Returns canonical target ID, assuming \p Processor is canonical and all
/// entries in \p Features are valid.
@@ -48,9 +49,13 @@ std::string getCanonicalTargetID(llvm::StringRef Processor,
/// Get the conflicted pair of target IDs for a compilation or a bundled code
/// object, assuming \p TargetIDs are canonicalized. If there is no conflicts,
-/// returns None.
-llvm::Optional<std::pair<llvm::StringRef, llvm::StringRef>>
+/// returns std::nullopt.
+std::optional<std::pair<llvm::StringRef, llvm::StringRef>>
getConflictTargetIDCombination(const std::set<llvm::StringRef> &TargetIDs);
+
+/// Check whether the provided target ID is compatible with the requested
+/// target ID.
+bool isCompatibleTargetID(llvm::StringRef Provided, llvm::StringRef Requested);
} // namespace clang
#endif
diff --git a/contrib/llvm-project/clang/include/clang/Basic/TargetInfo.h b/contrib/llvm-project/clang/include/clang/Basic/TargetInfo.h
index 4f0cbf986b31..3eb23ebdacf0 100644
--- a/contrib/llvm-project/clang/include/clang/Basic/TargetInfo.h
+++ b/contrib/llvm-project/clang/include/clang/Basic/TargetInfo.h
@@ -15,6 +15,7 @@
#define LLVM_CLANG_BASIC_TARGETINFO_H
#include "clang/Basic/AddressSpaces.h"
+#include "clang/Basic/BitmaskEnum.h"
#include "clang/Basic/CodeGenOptions.h"
#include "clang/Basic/LLVM.h"
#include "clang/Basic/LangOptions.h"
@@ -25,16 +26,18 @@
#include "llvm/ADT/APInt.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/IntrusiveRefCntPtr.h"
-#include "llvm/ADT/Optional.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
-#include "llvm/ADT/Triple.h"
+#include "llvm/ADT/StringSet.h"
#include "llvm/Frontend/OpenMP/OMPGridValues.h"
+#include "llvm/IR/DerivedTypes.h"
#include "llvm/Support/DataTypes.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/VersionTuple.h"
+#include "llvm/TargetParser/Triple.h"
#include <cassert>
+#include <optional>
#include <string>
#include <vector>
@@ -47,12 +50,34 @@ class DiagnosticsEngine;
class LangOptions;
class CodeGenOptions;
class MacroBuilder;
-class QualType;
-class SourceLocation;
-class SourceManager;
+
+/// Contains information gathered from parsing the contents of TargetAttr.
+struct ParsedTargetAttr {
+ std::vector<std::string> Features;
+ StringRef CPU;
+ StringRef Tune;
+ StringRef BranchProtection;
+ StringRef Duplicate;
+ bool operator ==(const ParsedTargetAttr &Other) const {
+ return Duplicate == Other.Duplicate && CPU == Other.CPU &&
+ Tune == Other.Tune && BranchProtection == Other.BranchProtection &&
+ Features == Other.Features;
+ }
+};
namespace Builtin { struct Info; }
+enum class FloatModeKind {
+ NoFloat = 0,
+ Half = 1 << 0,
+ Float = 1 << 1,
+ Double = 1 << 2,
+ LongDouble = 1 << 3,
+ Float128 = 1 << 4,
+ Ibm128 = 1 << 5,
+ LLVM_MARK_AS_BITMASK_ENUM(Ibm128)
+};
+
/// Fields controlling how types are laid out in memory; these may need to
/// be copied for targets like AMDGPU that base their ABIs on an auxiliary
/// CPU target.
@@ -64,10 +89,11 @@ struct TransferrableTargetInfo {
unsigned char BFloat16Width, BFloat16Align;
unsigned char FloatWidth, FloatAlign;
unsigned char DoubleWidth, DoubleAlign;
- unsigned char LongDoubleWidth, LongDoubleAlign, Float128Align;
+ unsigned char LongDoubleWidth, LongDoubleAlign, Float128Align, Ibm128Align;
unsigned char LargeArrayMinWidth, LargeArrayAlign;
unsigned char LongWidth, LongAlign;
unsigned char LongLongWidth, LongLongAlign;
+ unsigned char Int128Align;
// Fixed point bit widths
unsigned char ShortAccumWidth, ShortAccumAlign;
@@ -95,16 +121,16 @@ struct TransferrableTargetInfo {
unsigned char AccumScale;
unsigned char LongAccumScale;
- unsigned char SuitableAlign;
unsigned char DefaultAlignForAttributeAligned;
unsigned char MinGlobalAlign;
+ unsigned short SuitableAlign;
unsigned short NewAlign;
unsigned MaxVectorAlign;
unsigned MaxTLSAlign;
const llvm::fltSemantics *HalfFormat, *BFloat16Format, *FloatFormat,
- *DoubleFormat, *LongDoubleFormat, *Float128Format;
+ *DoubleFormat, *LongDoubleFormat, *Float128Format, *Ibm128Format;
///===---- Target Data Type Query Methods -------------------------------===//
enum IntType {
@@ -121,13 +147,6 @@ struct TransferrableTargetInfo {
UnsignedLongLong
};
- enum RealType {
- NoFloat = 255,
- Float = 0,
- Double,
- LongDouble,
- Float128
- };
protected:
IntType SizeType, IntMaxType, PtrDiffType, IntPtrType, WCharType, WIntType,
Char16Type, Char32Type, Int64Type, Int16Type, SigAtomicType,
@@ -137,6 +156,7 @@ protected:
///
/// Otherwise, when this flag is not set, the normal built-in boolean type is
/// used.
+ LLVM_PREFERRED_TYPE(bool)
unsigned UseSignedCharForObjCBool : 1;
/// Control whether the alignment of bit-field types is respected when laying
@@ -144,6 +164,7 @@ protected:
/// used to (a) impact the alignment of the containing structure, and (b)
/// ensure that the individual bit-field will not straddle an alignment
/// boundary.
+ LLVM_PREFERRED_TYPE(bool)
unsigned UseBitFieldTypeAlignment : 1;
/// Whether zero length bitfields (e.g., int : 0;) force alignment of
@@ -152,13 +173,16 @@ protected:
/// If the alignment of the zero length bitfield is greater than the member
/// that follows it, `bar', `bar' will be aligned as the type of the
/// zero-length bitfield.
+ LLVM_PREFERRED_TYPE(bool)
unsigned UseZeroLengthBitfieldAlignment : 1;
/// Whether zero length bitfield alignment is respected if they are the
/// leading members.
+ LLVM_PREFERRED_TYPE(bool)
unsigned UseLeadingZeroLengthBitfield : 1;
/// Whether explicit bit field alignment attributes are honored.
+ LLVM_PREFERRED_TYPE(bool)
unsigned UseExplicitBitFieldAlignment : 1;
/// If non-zero, specifies a fixed alignment value for bitfields that follow
@@ -184,7 +208,7 @@ enum OpenCLTypeKind : uint8_t {
/// Exposes information about the current target.
///
-class TargetInfo : public virtual TransferrableTargetInfo,
+class TargetInfo : public TransferrableTargetInfo,
public RefCountedBase<TargetInfo> {
std::shared_ptr<TargetOptions> TargetOpts;
llvm::Triple Triple;
@@ -197,44 +221,59 @@ protected:
bool NoAsmVariants; // True if {|} are normal characters.
bool HasLegalHalfType; // True if the backend supports operations on the half
// LLVM IR type.
+ bool HalfArgsAndReturns;
bool HasFloat128;
bool HasFloat16;
bool HasBFloat16;
+ bool HasFullBFloat16; // True if the backend supports native bfloat16
+ // arithmetic. Used to determine excess precision
+ // support in the frontend.
+ bool HasIbm128;
+ bool HasLongDouble;
+ bool HasFPReturn;
bool HasStrictFP;
unsigned char MaxAtomicPromoteWidth, MaxAtomicInlineWidth;
- unsigned short SimdDefaultAlign;
std::string DataLayoutString;
const char *UserLabelPrefix;
const char *MCountName;
unsigned char RegParmMax, SSERegParmMax;
TargetCXXABI TheCXXABI;
const LangASMap *AddrSpaceMap;
- const unsigned *GridValues =
- nullptr; // Array of target-specific GPU grid values that must be
- // consistent between host RTL (plugin), device RTL, and clang.
mutable StringRef PlatformName;
mutable VersionTuple PlatformMinVersion;
+ LLVM_PREFERRED_TYPE(bool)
unsigned HasAlignMac68kSupport : 1;
- unsigned RealTypeUsesObjCFPRet : 3;
+ LLVM_PREFERRED_TYPE(FloatModeKind)
+ unsigned RealTypeUsesObjCFPRetMask : llvm::BitWidth<FloatModeKind>;
+ LLVM_PREFERRED_TYPE(bool)
unsigned ComplexLongDoubleUsesFP2Ret : 1;
+ LLVM_PREFERRED_TYPE(bool)
unsigned HasBuiltinMSVaList : 1;
+ LLVM_PREFERRED_TYPE(bool)
unsigned IsRenderScriptTarget : 1;
+ LLVM_PREFERRED_TYPE(bool)
unsigned HasAArch64SVETypes : 1;
+ LLVM_PREFERRED_TYPE(bool)
unsigned HasRISCVVTypes : 1;
+ LLVM_PREFERRED_TYPE(bool)
unsigned AllowAMDGPUUnsafeFPAtomics : 1;
unsigned ARMCDECoprocMask : 8;
unsigned MaxOpenCLWorkGroupSize;
+ std::optional<unsigned> MaxBitIntWidth;
+
+ std::optional<llvm::Triple> DarwinTargetVariantTriple;
+
// TargetInfo Constructor. Default initializes all fields.
TargetInfo(const llvm::Triple &T);
@@ -242,6 +281,12 @@ protected:
// as a DataLayout object.
void resetDataLayout(StringRef DL, const char *UserLabelPrefix = "");
+ // Target features that are read-only and should not be disabled/enabled
+ // by command line options. Such features are for emitting predefined
+ // macros or checking availability of builtin functions and can be omitted
+ // in function attributes in IR.
+ llvm::StringSet<> ReadOnlyFeatures;
+
public:
/// Construct a target for the given options.
///
@@ -333,10 +378,11 @@ public:
IntType getUIntMaxType() const {
return getCorrespondingUnsignedType(IntMaxType);
}
- IntType getPtrDiffType(unsigned AddrSpace) const {
- return AddrSpace == 0 ? PtrDiffType : getPtrDiffTypeV(AddrSpace);
+ IntType getPtrDiffType(LangAS AddrSpace) const {
+ return AddrSpace == LangAS::Default ? PtrDiffType
+ : getPtrDiffTypeV(AddrSpace);
}
- IntType getUnsignedPtrDiffType(unsigned AddrSpace) const {
+ IntType getUnsignedPtrDiffType(LangAS AddrSpace) const {
return getCorrespondingUnsignedType(getPtrDiffType(AddrSpace));
}
IntType getIntPtrType() const { return IntPtrType; }
@@ -401,7 +447,8 @@ public:
/// is represented as one of those two). At this time, there is no support
/// for an explicit "PPC double-double" type (i.e. __ibm128) so we only
/// need to differentiate between "long double" and IEEE quad precision.
- RealType getRealTypeByWidth(unsigned BitWidth, bool ExplicitIEEE) const;
+ FloatModeKind getRealTypeByWidth(unsigned BitWidth,
+ FloatModeKind ExplicitType) const;
/// Return the alignment (in bits) of the specified integer type enum.
///
@@ -413,11 +460,13 @@ public:
/// Return the width of pointers on this target, for the
/// specified address space.
- uint64_t getPointerWidth(unsigned AddrSpace) const {
- return AddrSpace == 0 ? PointerWidth : getPointerWidthV(AddrSpace);
+ uint64_t getPointerWidth(LangAS AddrSpace) const {
+ return AddrSpace == LangAS::Default ? PointerWidth
+ : getPointerWidthV(AddrSpace);
}
- uint64_t getPointerAlign(unsigned AddrSpace) const {
- return AddrSpace == 0 ? PointerAlign : getPointerAlignV(AddrSpace);
+ uint64_t getPointerAlign(LangAS AddrSpace) const {
+ return AddrSpace == LangAS::Default ? PointerAlign
+ : getPointerAlignV(AddrSpace);
}
/// Return the maximum width of pointers on this target.
@@ -461,6 +510,9 @@ public:
unsigned getLongLongWidth() const { return LongLongWidth; }
unsigned getLongLongAlign() const { return LongLongAlign; }
+ /// getInt128Align() - Returns the alignment of Int128.
+ unsigned getInt128Align() const { return Int128Align; }
+
/// getShortAccumWidth/Align - Return the size of 'signed short _Accum' and
/// 'unsigned short _Accum' for this target, in bits.
unsigned getShortAccumWidth() const { return ShortAccumWidth; }
@@ -576,18 +628,42 @@ public:
/// Determine whether the __int128 type is supported on this target.
virtual bool hasInt128Type() const {
- return (getPointerWidth(0) >= 64) || getTargetOpts().ForceEnableInt128;
+ return (getPointerWidth(LangAS::Default) >= 64) ||
+ getTargetOpts().ForceEnableInt128;
} // FIXME
- /// Determine whether the _ExtInt type is supported on this target. This
+ /// Determine whether the _BitInt type is supported on this target. This
/// limitation is put into place for ABI reasons.
- virtual bool hasExtIntType() const {
+ /// FIXME: _BitInt is a required type in C23, so there's not much utility in
+ /// asking whether the target supported it or not; I think this should be
+ /// removed once backends have been alerted to the type and have had the
+ /// chance to do implementation work if needed.
+ virtual bool hasBitIntType() const {
return false;
}
+ // Different targets may support a different maximum width for the _BitInt
+ // type, depending on what operations are supported.
+ virtual size_t getMaxBitIntWidth() const {
+ // Consider -fexperimental-max-bitint-width= first.
+ if (MaxBitIntWidth)
+ return std::min<size_t>(*MaxBitIntWidth, llvm::IntegerType::MAX_INT_BITS);
+
+ // FIXME: this value should be llvm::IntegerType::MAX_INT_BITS, which is
+ // maximum bit width that LLVM claims its IR can support. However, most
+ // backends currently have a bug where they only support float to int
+ // conversion (and vice versa) on types that are <= 128 bits and crash
+ // otherwise. We're setting the max supported value to 128 to be
+ // conservative.
+ return 128;
+ }
+
/// Determine whether _Float16 is supported on this target.
virtual bool hasLegalHalfType() const { return HasLegalHalfType; }
+ /// Whether half args and returns are supported.
+ virtual bool allowHalfArgsAndReturns() const { return HalfArgsAndReturns; }
+
/// Determine whether the __float128 type is supported on this target.
virtual bool hasFloat128Type() const { return HasFloat128; }
@@ -595,7 +671,23 @@ public:
virtual bool hasFloat16Type() const { return HasFloat16; }
/// Determine whether the _BFloat16 type is supported on this target.
- virtual bool hasBFloat16Type() const { return HasBFloat16; }
+ virtual bool hasBFloat16Type() const {
+ return HasBFloat16 || HasFullBFloat16;
+ }
+
+ /// Determine whether the BFloat type is fully supported on this target, i.e
+ /// arithemtic operations.
+ virtual bool hasFullBFloat16Type() const { return HasFullBFloat16; }
+
+ /// Determine whether the __ibm128 type is supported on this target.
+ virtual bool hasIbm128Type() const { return HasIbm128; }
+
+ /// Determine whether the long double type is supported on this target.
+ virtual bool hasLongDoubleType() const { return HasLongDouble; }
+
+ /// Determine whether return of a floating point value is supported
+ /// on this target.
+ virtual bool hasFPReturn() const { return HasFPReturn; }
/// Determine whether constrained floating point is supported on this target.
virtual bool hasStrictFP() const { return HasStrictFP; }
@@ -618,8 +710,8 @@ public:
}
/// Return the largest alignment for which a suitably-sized allocation with
- /// '::operator new(size_t)' or 'malloc' is guaranteed to produce a
- /// correctly-aligned pointer.
+ /// '::operator new(size_t)' is guaranteed to produce a correctly-aligned
+ /// pointer.
unsigned getNewAlign() const {
return NewAlign ? NewAlign : std::max(LongDoubleAlign, LongLongAlign);
}
@@ -675,19 +767,32 @@ public:
return *Float128Format;
}
+ /// getIbm128Width/Align/Format - Return the size/align/format of
+ /// '__ibm128'.
+ unsigned getIbm128Width() const { return 128; }
+ unsigned getIbm128Align() const { return Ibm128Align; }
+ const llvm::fltSemantics &getIbm128Format() const { return *Ibm128Format; }
+
/// Return the mangled code of long double.
virtual const char *getLongDoubleMangling() const { return "e"; }
/// Return the mangled code of __float128.
virtual const char *getFloat128Mangling() const { return "g"; }
- /// Return the mangled code of bfloat.
- virtual const char *getBFloat16Mangling() const {
- llvm_unreachable("bfloat not implemented on this target");
+ /// Return the mangled code of __ibm128.
+ virtual const char *getIbm128Mangling() const {
+ llvm_unreachable("ibm128 not implemented on this target");
}
+ /// Return the mangled code of bfloat.
+ virtual const char *getBFloat16Mangling() const { return "DF16b"; }
+
/// Return the value for the C99 FLT_EVAL_METHOD macro.
- virtual unsigned getFloatEvalMethod() const { return 0; }
+ virtual LangOptions::FPEvalMethodKind getFPEvalMethod() const {
+ return LangOptions::FPEvalMethodKind::FEM_Source;
+ }
+
+ virtual bool supportSourceEvalMethod() const { return true; }
// getLargeArrayMinWidth/Align - Return the minimum array size that is
// 'large' and its alignment.
@@ -715,10 +820,6 @@ public:
/// Return the maximum vector alignment supported for the given target.
unsigned getMaxVectorAlign() const { return MaxVectorAlign; }
- /// Return default simd alignment for the given target. Generally, this
- /// value is type-specific, but this alignment can be used for most of the
- /// types for the given target.
- unsigned getSimdDefaultAlign() const { return SimdDefaultAlign; }
unsigned getMaxOpenCLWorkGroupSize() const { return MaxOpenCLWorkGroupSize; }
@@ -743,7 +844,9 @@ public:
}
// Return the size of unwind_word for this target.
- virtual unsigned getUnwindWordWidth() const { return getPointerWidth(0); }
+ virtual unsigned getUnwindWordWidth() const {
+ return getPointerWidth(LangAS::Default);
+ }
/// Return the "preferred" register width on this target.
virtual unsigned getRegisterWidth() const {
@@ -833,8 +936,8 @@ public:
/// Check whether the given real type should use the "fpret" flavor of
/// Objective-C message passing on this target.
- bool useObjCFPRetForRealType(RealType T) const {
- return RealTypeUsesObjCFPRet & (1 << T);
+ bool useObjCFPRetForRealType(FloatModeKind T) const {
+ return (int)((FloatModeKind)RealTypeUsesObjCFPRetMask & T);
}
/// Check whether _Complex long double should use the "fp2ret" flavor
@@ -870,6 +973,11 @@ public:
/// across the current set of primary and secondary targets.
virtual ArrayRef<Builtin::Info> getTargetBuiltins() const = 0;
+ /// Returns target-specific min and max values VScale_Range.
+ virtual std::optional<std::pair<unsigned, unsigned>>
+ getVScaleRange(const LangOptions &LangOpts) const {
+ return std::nullopt;
+ }
/// The __builtin_clz* and __builtin_ctz* built-in
/// functions are specified to have undefined results for zero inputs, but
/// on targets that support these operations in a way that provides
@@ -993,8 +1101,7 @@ public:
}
bool isValidAsmImmediate(const llvm::APInt &Value) const {
if (!ImmSet.empty())
- return Value.isSignedIntN(32) &&
- ImmSet.count(Value.getZExtValue()) != 0;
+ return Value.isSignedIntN(32) && ImmSet.contains(Value.getZExtValue());
return !ImmRange.isConstrained ||
(Value.sge(ImmRange.Min) && Value.sle(ImmRange.Max));
}
@@ -1093,12 +1200,12 @@ public:
/// Replace some escaped characters with another string based on
/// target-specific rules
- virtual llvm::Optional<std::string> handleAsmEscapedChar(char C) const {
- return llvm::None;
+ virtual std::optional<std::string> handleAsmEscapedChar(char C) const {
+ return std::nullopt;
}
/// Returns a string of target-specific clobbers, in LLVM format.
- virtual const char *getClobbers() const = 0;
+ virtual std::string_view getClobbers() const = 0;
/// Returns true if NaN encoding is IEEE 754-2008.
/// Only MIPS allows a different encoding.
@@ -1112,7 +1219,9 @@ public:
}
/// Returns the target ID if supported.
- virtual llvm::Optional<std::string> getTargetID() const { return llvm::None; }
+ virtual std::optional<std::string> getTargetID() const {
+ return std::nullopt;
+ }
const char *getDataLayoutString() const {
assert(!DataLayoutString.empty() && "Uninitialized DataLayout!");
@@ -1145,12 +1254,12 @@ public:
/// Microsoft C++ code using dllimport/export attributes?
virtual bool shouldDLLImportComdatSymbols() const {
return getTriple().isWindowsMSVCEnvironment() ||
- getTriple().isWindowsItaniumEnvironment() || getTriple().isPS4CPU();
+ getTriple().isWindowsItaniumEnvironment() || getTriple().isPS();
}
// Does this target have PS4 specific dllimport/export handling?
virtual bool hasPS4DLLImportExport() const {
- return getTriple().isPS4CPU() ||
+ return getTriple().isPS() ||
// Windows Itanium support allows for testing the SCEI flavour of
// dllimport/export handling on a Windows system.
(getTriple().isWindowsItaniumEnvironment() &&
@@ -1164,10 +1273,6 @@ public:
/// the language based on the target options where applicable.
virtual void adjust(DiagnosticsEngine &Diags, LangOptions &Opts);
- /// Adjust target options based on codegen options.
- virtual void adjustTargetOptions(const CodeGenOptions &CGOpts,
- TargetOptions &TargetOpts) const {}
-
/// Initialize the map with the default set of target features for the
/// CPU this should include all legal feature strings on the target.
///
@@ -1199,18 +1304,20 @@ public:
fillValidCPUList(Values);
}
- /// brief Determine whether this TargetInfo supports the given CPU name.
+ /// Determine whether this TargetInfo supports the given CPU name.
virtual bool isValidCPUName(StringRef Name) const {
return true;
}
- /// brief Determine whether this TargetInfo supports the given CPU name for
- // tuning.
+ /// Determine whether this TargetInfo supports the given CPU name for
+ /// tuning.
virtual bool isValidTuneCPUName(StringRef Name) const {
return isValidCPUName(Name);
}
- /// brief Determine whether this TargetInfo supports tune in target attribute.
+ virtual ParsedTargetAttr parseTargetAttr(StringRef Str) const;
+
+ /// Determine whether this TargetInfo supports tune in target attribute.
virtual bool supportsTargetAttributeTune() const {
return false;
}
@@ -1248,17 +1355,36 @@ public:
return true;
}
+ /// Returns true if feature has an impact on target code
+ /// generation.
+ virtual bool doesFeatureAffectCodeGen(StringRef Feature) const {
+ return true;
+ }
+
+ /// For given feature return dependent ones.
+ virtual StringRef getFeatureDependencies(StringRef Feature) const {
+ return StringRef();
+ }
+
struct BranchProtectionInfo {
LangOptions::SignReturnAddressScopeKind SignReturnAddr =
LangOptions::SignReturnAddressScopeKind::None;
LangOptions::SignReturnAddressKeyKind SignKey =
LangOptions::SignReturnAddressKeyKind::AKey;
bool BranchTargetEnforcement = false;
+ bool BranchProtectionPAuthLR = false;
+ bool GuardedControlStack = false;
};
+ /// Determine if the Architecture in this TargetInfo supports branch
+ /// protection
+ virtual bool isBranchProtectionSupportedArch(StringRef Arch) const {
+ return false;
+ }
+
/// Determine if this TargetInfo supports the given branch protection
/// specification
- virtual bool validateBranchProtection(StringRef Spec,
+ virtual bool validateBranchProtection(StringRef Spec, StringRef Arch,
BranchProtectionInfo &BPI,
StringRef &Err) const {
Err = "";
@@ -1286,12 +1412,25 @@ public:
return false;
}
+ /// Determine whether the given target feature is read only.
+ bool isReadOnlyFeature(StringRef Feature) const {
+ return ReadOnlyFeatures.count(Feature);
+ }
+
/// Identify whether this target supports multiversioning of functions,
/// which requires support for cpu_supports and cpu_is functionality.
- bool supportsMultiVersioning() const { return getTriple().isX86(); }
+ bool supportsMultiVersioning() const {
+ return getTriple().isX86() || getTriple().isAArch64();
+ }
/// Identify whether this target supports IFuncs.
- bool supportsIFunc() const { return getTriple().isOSBinFormatELF(); }
+ bool supportsIFunc() const {
+ if (getTriple().isOSBinFormatMachO())
+ return true;
+ return getTriple().isOSBinFormatELF() &&
+ ((getTriple().isOSLinux() && !getTriple().isMusl()) ||
+ getTriple().isOSFreeBSD());
+ }
// Validate the contents of the __builtin_cpu_supports(const char*)
// argument.
@@ -1303,6 +1442,10 @@ public:
return 0;
}
+ // Return the target-specific cost for feature
+ // that taken into account in priority sorting.
+ virtual unsigned multiVersionFeatureCost() const { return 0; }
+
// Validate the contents of the __builtin_cpu_is(const char*)
// argument.
virtual bool validateCpuIs(StringRef Name) const { return false; }
@@ -1319,6 +1462,13 @@ public:
"cpu_specific Multiversioning not implemented on this target");
}
+ // Get the value for the 'tune-cpu' flag for a cpu_specific variant with the
+ // programmer-specified 'Name'.
+ virtual StringRef getCPUSpecificTuneName(StringRef Name) const {
+ llvm_unreachable(
+ "cpu_specific Multiversioning not implemented on this target");
+ }
+
// Get a list of the features that make up the CPU option for
// cpu_specific/cpu_dispatch so that it can be passed to llvm as optimization
// options.
@@ -1329,8 +1479,10 @@ public:
}
// Get the cache line size of a given cpu. This method switches over
- // the given cpu and returns "None" if the CPU is not found.
- virtual Optional<unsigned> getCPUCacheLineSize() const { return None; }
+ // the given cpu and returns "std::nullopt" if the CPU is not found.
+ virtual std::optional<unsigned> getCPUCacheLineSize() const {
+ return std::nullopt;
+ }
// Returns maximal number of args passed in registers.
unsigned getRegParmMax() const {
@@ -1383,6 +1535,11 @@ public:
}
const LangASMap &getAddressSpaceMap() const { return *AddrSpaceMap; }
+ unsigned getTargetAddressSpace(LangAS AS) const {
+ if (isTargetAddressSpace(AS))
+ return toTargetAddressSpace(AS);
+ return getAddressSpaceMap()[(unsigned)AS];
+ }
/// Map from the address space field in builtin description strings to the
/// language address space.
@@ -1399,15 +1556,15 @@ public:
/// Return an AST address space which can be used opportunistically
/// for constant global memory. It must be possible to convert pointers into
/// this address space to LangAS::Default. If no such address space exists,
- /// this may return None, and such optimizations will be disabled.
- virtual llvm::Optional<LangAS> getConstantAddressSpace() const {
+ /// this may return std::nullopt, and such optimizations will be disabled.
+ virtual std::optional<LangAS> getConstantAddressSpace() const {
return LangAS::Default;
}
- /// Return a target-specific GPU grid value based on the GVIDX enum \p gv
- unsigned getGridValue(llvm::omp::GVIDX gv) const {
- assert(GridValues != nullptr && "GridValues not initialized");
- return GridValues[gv];
+ // access target-specific GPU grid values that must be consistent between
+ // host RTL (plugin), deviceRTL and clang.
+ virtual const llvm::omp::GV &getGridValue() const {
+ llvm_unreachable("getGridValue not implemented on this target");
}
/// Retrieve the name of the platform as it is used in the
@@ -1464,6 +1621,14 @@ public:
virtual CallingConvKind getCallingConvKind(bool ClangABICompat4) const;
+ /// Controls whether explicitly defaulted (`= default`) special member
+ /// functions disqualify something from being POD-for-the-purposes-of-layout.
+ /// Historically, Clang didn't consider these acceptable for POD, but GCC
+ /// does. So in newer Clang ABIs they are acceptable for POD to be compatible
+ /// with GCC/Itanium ABI, and remains disqualifying for targets that need
+ /// Clang backwards compatibility rather than GCC/Itanium ABI compatibility.
+ virtual bool areDefaultedSMFStillPOD(const LangOptions&) const;
+
/// Controls if __builtin_longjmp / __builtin_setjmp can be lowered to
/// llvm.eh.sjlj.longjmp / llvm.eh.sjlj.setjmp.
virtual bool hasSjLjLowering() const {
@@ -1474,7 +1639,7 @@ public:
virtual bool
checkCFProtectionBranchSupported(DiagnosticsEngine &Diags) const;
- /// Check if the target supports CFProtection branch.
+ /// Check if the target supports CFProtection return.
virtual bool
checkCFProtectionReturnSupported(DiagnosticsEngine &Diags) const;
@@ -1531,10 +1696,11 @@ public:
/// space \p AddressSpace to be converted in order to be used, then return the
/// corresponding target specific DWARF address space.
///
- /// \returns Otherwise return None and no conversion will be emitted in the
- /// DWARF.
- virtual Optional<unsigned> getDWARFAddressSpace(unsigned AddressSpace) const {
- return None;
+ /// \returns Otherwise return std::nullopt and no conversion will be emitted
+ /// in the DWARF.
+ virtual std::optional<unsigned> getDWARFAddressSpace(unsigned AddressSpace)
+ const {
+ return std::nullopt;
}
/// \returns The version of the SDK which was used during the compilation if
@@ -1558,22 +1724,39 @@ public:
/// Whether target allows debuginfo types for decl only variables/functions.
virtual bool allowDebugInfoForExternalRef() const { return false; }
+ /// Returns the darwin target variant triple, the variant of the deployment
+ /// target for which the code is being compiled.
+ const llvm::Triple *getDarwinTargetVariantTriple() const {
+ return DarwinTargetVariantTriple ? &*DarwinTargetVariantTriple : nullptr;
+ }
+
+ /// Returns the version of the darwin target variant SDK which was used during
+ /// the compilation if one was specified, or an empty version otherwise.
+ const std::optional<VersionTuple> getDarwinTargetVariantSDKVersion() const {
+ return !getTargetOpts().DarwinTargetVariantSDKVersion.empty()
+ ? getTargetOpts().DarwinTargetVariantSDKVersion
+ : std::optional<VersionTuple>();
+ }
+
+ /// Whether to support HIP image/texture API's.
+ virtual bool hasHIPImageSupport() const { return true; }
+
protected:
/// Copy type and layout related info.
void copyAuxTarget(const TargetInfo *Aux);
- virtual uint64_t getPointerWidthV(unsigned AddrSpace) const {
+ virtual uint64_t getPointerWidthV(LangAS AddrSpace) const {
return PointerWidth;
}
- virtual uint64_t getPointerAlignV(unsigned AddrSpace) const {
+ virtual uint64_t getPointerAlignV(LangAS AddrSpace) const {
return PointerAlign;
}
- virtual enum IntType getPtrDiffTypeV(unsigned AddrSpace) const {
+ virtual enum IntType getPtrDiffTypeV(LangAS AddrSpace) const {
return PtrDiffType;
}
virtual ArrayRef<const char *> getGCCRegNames() const = 0;
virtual ArrayRef<GCCRegAlias> getGCCRegAliases() const = 0;
virtual ArrayRef<AddlRegName> getGCCAddlRegNames() const {
- return None;
+ return std::nullopt;
}
private:
diff --git a/contrib/llvm-project/clang/include/clang/Basic/TargetOSMacros.def b/contrib/llvm-project/clang/include/clang/Basic/TargetOSMacros.def
new file mode 100644
index 000000000000..dfc2e033f6fd
--- /dev/null
+++ b/contrib/llvm-project/clang/include/clang/Basic/TargetOSMacros.def
@@ -0,0 +1,55 @@
+//===--- TargetOSMacros.def - Target OS macros ------------------*- 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 specifies the predefined TARGET_OS_* conditional macros.
+// A target macro `Name` should be defined if `Predicate` evaluates to true.
+// The macro expects `const llvm::Triple &Triple` and the class `llvm::Triple`
+// to be available for the predicate.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef TARGET_OS
+#define TARGET_OS(Name, Predicate)
+#endif
+
+// Windows targets.
+TARGET_OS(TARGET_OS_WIN32, Triple.isOSWindows())
+TARGET_OS(TARGET_OS_WINDOWS, Triple.isOSWindows())
+
+// Linux target.
+TARGET_OS(TARGET_OS_LINUX, Triple.isOSLinux())
+
+// Unix target.
+TARGET_OS(TARGET_OS_UNIX, Triple.isOSNetBSD() ||
+ Triple.isOSFreeBSD() ||
+ Triple.isOSOpenBSD() ||
+ Triple.isOSSolaris())
+
+// Apple (Mac) targets.
+TARGET_OS(TARGET_OS_MAC, Triple.isOSDarwin())
+TARGET_OS(TARGET_OS_OSX, Triple.isMacOSX())
+TARGET_OS(TARGET_OS_IPHONE, Triple.isiOS() || Triple.isTvOS() ||
+ Triple.isWatchOS())
+// Triple::isiOS() also includes tvOS
+TARGET_OS(TARGET_OS_IOS, Triple.getOS() == llvm::Triple::IOS)
+TARGET_OS(TARGET_OS_TV, Triple.isTvOS())
+TARGET_OS(TARGET_OS_WATCH, Triple.isWatchOS())
+TARGET_OS(TARGET_OS_DRIVERKIT, Triple.isDriverKit())
+TARGET_OS(TARGET_OS_MACCATALYST, Triple.isMacCatalystEnvironment())
+TARGET_OS(TARGET_OS_SIMULATOR, Triple.isSimulatorEnvironment())
+
+// Deprecated Apple target conditionals.
+TARGET_OS(TARGET_OS_EMBEDDED, (Triple.isiOS() || Triple.isTvOS() \
+ || Triple.isWatchOS()) \
+ && !Triple.isMacCatalystEnvironment() \
+ && !Triple.isSimulatorEnvironment())
+TARGET_OS(TARGET_OS_NANO, Triple.isWatchOS())
+TARGET_OS(TARGET_IPHONE_SIMULATOR, Triple.isSimulatorEnvironment())
+TARGET_OS(TARGET_OS_UIKITFORMAC, Triple.isMacCatalystEnvironment())
+
+#undef TARGET_OS
diff --git a/contrib/llvm-project/clang/include/clang/Basic/TargetOptions.h b/contrib/llvm-project/clang/include/clang/Basic/TargetOptions.h
index 81c15adb8248..2049f03b2889 100644
--- a/contrib/llvm-project/clang/include/clang/Basic/TargetOptions.h
+++ b/contrib/llvm-project/clang/include/clang/Basic/TargetOptions.h
@@ -45,7 +45,7 @@ public:
std::string ABI;
/// The EABI version to use
- llvm::EABI EABIVersion;
+ llvm::EABI EABIVersion = llvm::EABI::Default;
/// If given, the version string of the linker in use.
std::string LinkerVersion;
@@ -78,12 +78,33 @@ public:
/// \brief If enabled, allow AMDGPU unsafe floating point atomics.
bool AllowAMDGPUUnsafeFPAtomics = false;
+ /// \brief Code object version for AMDGPU.
+ llvm::CodeObjectVersionKind CodeObjectVersion =
+ llvm::CodeObjectVersionKind::COV_None;
+
+ /// \brief Enumeration values for AMDGPU printf lowering scheme
+ enum class AMDGPUPrintfKind {
+ /// printf lowering scheme involving hostcalls, currently used by HIP
+ /// programs by default
+ Hostcall = 0,
+
+ /// printf lowering scheme involving implicit printf buffers,
+ Buffered = 1,
+ };
+
+ /// \brief AMDGPU Printf lowering scheme
+ AMDGPUPrintfKind AMDGPUPrintfKindVal = AMDGPUPrintfKind::Hostcall;
+
// The code model to be used as specified by the user. Corresponds to
// CodeModel::Model enum defined in include/llvm/Support/CodeGen.h, plus
// "default" for the case when the user has not explicitly specified a
// code model.
std::string CodeModel;
+ // The large data threshold used for certain code models on certain
+ // architectures.
+ uint64_t LargeDataThreshold;
+
/// The version of the SDK which was used during the compilation.
/// The option is used for two different purposes:
/// * on darwin the version is propagated to LLVM where it's used
@@ -91,8 +112,21 @@ public:
/// * CUDA compilation uses it to control parts of CUDA compilation
/// in clang that depend on specific version of the CUDA SDK.
llvm::VersionTuple SDKVersion;
+
+ /// The name of the darwin target- ariant triple to compile for.
+ std::string DarwinTargetVariantTriple;
+
+ /// The version of the darwin target variant SDK which was used during the
+ /// compilation.
+ llvm::VersionTuple DarwinTargetVariantSDKVersion;
+
+ /// The validator version for dxil.
+ std::string DxilValidatorVersion;
+
+ /// The entry point name for HLSL shader being compiled as specified by -E.
+ std::string HLSLEntry;
};
-} // end namespace clang
+} // end namespace clang
#endif
diff --git a/contrib/llvm-project/clang/include/clang/Basic/Thunk.h b/contrib/llvm-project/clang/include/clang/Basic/Thunk.h
index 91088be6ae73..0247e279408f 100644
--- a/contrib/llvm-project/clang/include/clang/Basic/Thunk.h
+++ b/contrib/llvm-project/clang/include/clang/Basic/Thunk.h
@@ -26,7 +26,7 @@ class CXXMethodDecl;
struct ReturnAdjustment {
/// The non-virtual adjustment from the derived object to its
/// nearest virtual base.
- int64_t NonVirtual;
+ int64_t NonVirtual = 0;
/// Holds the ABI-specific information about the virtual return
/// adjustment, if needed.
@@ -64,7 +64,7 @@ struct ReturnAdjustment {
}
} Virtual;
- ReturnAdjustment() : NonVirtual(0) {}
+ ReturnAdjustment() = default;
bool isEmpty() const { return !NonVirtual && Virtual.isEmpty(); }
@@ -91,7 +91,7 @@ struct ReturnAdjustment {
struct ThisAdjustment {
/// The non-virtual adjustment from the derived object to its
/// nearest virtual base.
- int64_t NonVirtual;
+ int64_t NonVirtual = 0;
/// Holds the ABI-specific information about the virtual this
/// adjustment, if needed.
@@ -131,7 +131,7 @@ struct ThisAdjustment {
}
} Virtual;
- ThisAdjustment() : NonVirtual(0) {}
+ ThisAdjustment() = default;
bool isEmpty() const { return !NonVirtual && Virtual.isEmpty(); }
diff --git a/contrib/llvm-project/clang/include/clang/Basic/TokenKinds.def b/contrib/llvm-project/clang/include/clang/Basic/TokenKinds.def
index 48a664e3494e..c10e2adfbe6e 100644
--- a/contrib/llvm-project/clang/include/clang/Basic/TokenKinds.def
+++ b/contrib/llvm-project/clang/include/clang/Basic/TokenKinds.def
@@ -9,8 +9,7 @@
// This file defines the TokenKind database. This includes normal tokens like
// tok::ampamp (corresponding to the && token) as well as keywords for various
// languages. Users of this file must optionally #define the TOK, KEYWORD,
-// CXX11_KEYWORD, CONCEPTS_KEYWORD, ALIAS, or PPKEYWORD macros to make use of
-// this file.
+// CXX11_KEYWORD, ALIAS, or PPKEYWORD macros to make use of this file.
//
//===----------------------------------------------------------------------===//
@@ -29,8 +28,11 @@
#ifndef CXX20_KEYWORD
#define CXX20_KEYWORD(X,Y) KEYWORD(X,KEYCXX20|(Y))
#endif
-#ifndef CONCEPTS_KEYWORD
-#define CONCEPTS_KEYWORD(X) CXX20_KEYWORD(X,KEYCONCEPTS)
+#ifndef C99_KEYWORD
+#define C99_KEYWORD(X,Y) KEYWORD(X,KEYC99|(Y))
+#endif
+#ifndef C23_KEYWORD
+#define C23_KEYWORD(X,Y) KEYWORD(X,KEYC23|(Y))
#endif
#ifndef COROUTINES_KEYWORD
#define COROUTINES_KEYWORD(X) CXX20_KEYWORD(X,KEYCOROUTINES)
@@ -83,6 +85,9 @@
#ifndef PRAGMA_ANNOTATION
#define PRAGMA_ANNOTATION(X) ANNOTATION(X)
#endif
+#ifndef INTERESTING_IDENTIFIER
+#define INTERESTING_IDENTIFIER(X)
+#endif
//===----------------------------------------------------------------------===//
// Preprocessor keywords.
@@ -254,13 +259,12 @@ PUNCTUATOR(caretcaret, "^^")
// always be treated as a keyword
// KEYC99 - This is a keyword introduced to C in C99
// KEYC11 - This is a keyword introduced to C in C11
+// KEYC23 - This is a keyword introduced to C in C23
// KEYCXX - This is a C++ keyword, or a C++-specific keyword in the
// implementation namespace
// KEYNOCXX - This is a keyword in every non-C++ dialect.
// KEYCXX11 - This is a C++ keyword introduced to C++ in C++11
// KEYCXX20 - This is a C++ keyword introduced to C++ in C++20
-// KEYCONCEPTS - This is a keyword if the C++ extensions for concepts
-// are enabled.
// KEYMODULES - This is a keyword if the C++ extensions for modules
// are enabled.
// KEYGNU - This is a keyword if GNU extensions are enabled
@@ -280,6 +284,8 @@ PUNCTUATOR(caretcaret, "^^")
// HALFSUPPORT - This is a keyword if 'half' is a built-in type
// WCHARSUPPORT - This is a keyword if 'wchar_t' is a built-in type
// CHAR8SUPPORT - This is a keyword if 'char8_t' is a built-in type
+// KEYFIXEDPOINT - This is a keyword according to the N1169 fixed point
+// extension.
//
KEYWORD(auto , KEYALL)
KEYWORD(break , KEYALL)
@@ -297,16 +303,16 @@ KEYWORD(float , KEYALL)
KEYWORD(for , KEYALL)
KEYWORD(goto , KEYALL)
KEYWORD(if , KEYALL)
-KEYWORD(inline , KEYC99|KEYCXX|KEYGNU)
KEYWORD(int , KEYALL)
KEYWORD(_ExtInt , KEYALL)
+KEYWORD(_BitInt , KEYALL)
KEYWORD(long , KEYALL)
KEYWORD(register , KEYALL)
-KEYWORD(restrict , KEYC99)
KEYWORD(return , KEYALL)
KEYWORD(short , KEYALL)
KEYWORD(signed , KEYALL)
UNARY_EXPR_OR_TYPE_TRAIT(sizeof, SizeOf, KEYALL)
+UNARY_EXPR_OR_TYPE_TRAIT(__datasizeof, DataSizeOf, KEYCXX)
KEYWORD(static , KEYALL)
KEYWORD(struct , KEYALL)
KEYWORD(switch , KEYALL)
@@ -333,7 +339,7 @@ KEYWORD(__objc_no , KEYALL)
// C++ 2.11p1: Keywords.
KEYWORD(asm , KEYCXX|KEYGNU)
-KEYWORD(bool , BOOLSUPPORT)
+KEYWORD(bool , BOOLSUPPORT|KEYC23)
KEYWORD(catch , KEYCXX)
KEYWORD(class , KEYCXX)
KEYWORD(const_cast , KEYCXX)
@@ -341,7 +347,7 @@ KEYWORD(delete , KEYCXX)
KEYWORD(dynamic_cast , KEYCXX)
KEYWORD(explicit , KEYCXX)
KEYWORD(export , KEYCXX)
-KEYWORD(false , BOOLSUPPORT)
+KEYWORD(false , BOOLSUPPORT|KEYC23)
KEYWORD(friend , KEYCXX)
KEYWORD(mutable , KEYCXX)
KEYWORD(namespace , KEYCXX)
@@ -355,7 +361,7 @@ KEYWORD(static_cast , KEYCXX)
KEYWORD(template , KEYCXX)
KEYWORD(this , KEYCXX)
KEYWORD(throw , KEYCXX)
-KEYWORD(true , BOOLSUPPORT)
+KEYWORD(true , BOOLSUPPORT|KEYC23)
KEYWORD(try , KEYCXX)
KEYWORD(typename , KEYCXX)
KEYWORD(typeid , KEYCXX)
@@ -376,45 +382,53 @@ CXX_KEYWORD_OPERATOR(or_eq , pipeequal)
CXX_KEYWORD_OPERATOR(xor , caret)
CXX_KEYWORD_OPERATOR(xor_eq , caretequal)
+// C99 Keywords.
+C99_KEYWORD(restrict , 0)
+C99_KEYWORD(inline , KEYCXX|KEYGNU)
+
+
// C++11 keywords
-CXX11_KEYWORD(alignas , 0)
+CXX11_KEYWORD(alignas , KEYC23)
// alignof and _Alignof return the required ABI alignment
-CXX11_UNARY_EXPR_OR_TYPE_TRAIT(alignof, AlignOf, 0)
+CXX11_UNARY_EXPR_OR_TYPE_TRAIT(alignof, AlignOf, KEYC23)
CXX11_KEYWORD(char16_t , KEYNOMS18)
CXX11_KEYWORD(char32_t , KEYNOMS18)
CXX11_KEYWORD(constexpr , 0)
CXX11_KEYWORD(decltype , 0)
CXX11_KEYWORD(noexcept , 0)
-CXX11_KEYWORD(nullptr , 0)
-CXX11_KEYWORD(static_assert , KEYMSCOMPAT)
-CXX11_KEYWORD(thread_local , 0)
+CXX11_KEYWORD(nullptr , KEYC23)
+CXX11_KEYWORD(static_assert , KEYMSCOMPAT|KEYC23)
+CXX11_KEYWORD(thread_local , KEYC23)
-// C++20 keywords
-CONCEPTS_KEYWORD(concept)
-CONCEPTS_KEYWORD(requires)
-
-// C++20 / coroutines TS keywords
+// C++20 / coroutines keywords
COROUTINES_KEYWORD(co_await)
COROUTINES_KEYWORD(co_return)
COROUTINES_KEYWORD(co_yield)
-// C++ modules TS keywords
+// C++20 keywords
MODULES_KEYWORD(module)
MODULES_KEYWORD(import)
// C++20 keywords.
CXX20_KEYWORD(consteval , 0)
CXX20_KEYWORD(constinit , 0)
+CXX20_KEYWORD(concept , 0)
+CXX20_KEYWORD(requires , 0)
+
// Not a CXX20_KEYWORD because it is disabled by -fno-char8_t.
KEYWORD(char8_t , CHAR8SUPPORT)
// C11 Extension
KEYWORD(_Float16 , KEYALL)
+// C23 keywords
+C23_KEYWORD(typeof , KEYGNU)
+C23_KEYWORD(typeof_unqual , 0)
+
// ISO/IEC JTC1 SC22 WG14 N1169 Extension
-KEYWORD(_Accum , KEYNOCXX)
-KEYWORD(_Fract , KEYNOCXX)
-KEYWORD(_Sat , KEYNOCXX)
+KEYWORD(_Accum , KEYFIXEDPOINT)
+KEYWORD(_Fract , KEYFIXEDPOINT)
+KEYWORD(_Sat , KEYFIXEDPOINT)
// GNU Extensions (in impl-reserved namespace)
KEYWORD(_Decimal32 , KEYALL)
@@ -428,9 +442,12 @@ KEYWORD(__attribute , KEYALL)
KEYWORD(__builtin_choose_expr , KEYALL)
KEYWORD(__builtin_offsetof , KEYALL)
KEYWORD(__builtin_FILE , KEYALL)
+KEYWORD(__builtin_FILE_NAME , KEYALL)
KEYWORD(__builtin_FUNCTION , KEYALL)
+KEYWORD(__builtin_FUNCSIG , KEYMS)
KEYWORD(__builtin_LINE , KEYALL)
KEYWORD(__builtin_COLUMN , KEYALL)
+KEYWORD(__builtin_source_location , KEYCXX)
// __builtin_types_compatible_p is a GNU C extension that we handle like a C++
// type trait.
@@ -438,6 +455,7 @@ TYPE_TRAIT_2(__builtin_types_compatible_p, TypeCompatible, KEYNOCXX)
KEYWORD(__builtin_va_arg , KEYALL)
KEYWORD(__extension__ , KEYALL)
KEYWORD(__float128 , KEYALL)
+KEYWORD(__ibm128 , KEYALL)
KEYWORD(__imag , KEYALL)
KEYWORD(__int128 , KEYALL)
KEYWORD(__label__ , KEYALL)
@@ -447,9 +465,6 @@ KEYWORD(__FUNCTION__ , KEYALL)
KEYWORD(__PRETTY_FUNCTION__ , KEYALL)
KEYWORD(__auto_type , KEYALL)
-// GNU Extensions (outside impl-reserved namespace)
-KEYWORD(typeof , KEYGNU)
-
// MS Extensions
KEYWORD(__FUNCDNAME__ , KEYMS)
KEYWORD(__FUNCSIG__ , KEYMS)
@@ -459,9 +474,9 @@ TYPE_TRAIT_1(__is_interface_class, IsInterfaceClass, KEYMS)
TYPE_TRAIT_1(__is_sealed, IsSealed, KEYMS)
// MSVC12.0 / VS2013 Type Traits
-TYPE_TRAIT_1(__is_destructible, IsDestructible, KEYMS)
+TYPE_TRAIT_1(__is_destructible, IsDestructible, KEYALL)
TYPE_TRAIT_1(__is_trivially_destructible, IsTriviallyDestructible, KEYCXX)
-TYPE_TRAIT_1(__is_nothrow_destructible, IsNothrowDestructible, KEYMS)
+TYPE_TRAIT_1(__is_nothrow_destructible, IsNothrowDestructible, KEYALL)
TYPE_TRAIT_2(__is_nothrow_assignable, IsNothrowAssignable, KEYCXX)
TYPE_TRAIT_N(__is_constructible, IsConstructible, KEYCXX)
TYPE_TRAIT_N(__is_nothrow_constructible, IsNothrowConstructible, KEYCXX)
@@ -505,10 +520,21 @@ TYPE_TRAIT_1(__is_trivially_copyable, IsTriviallyCopyable, KEYCXX)
TYPE_TRAIT_1(__is_union, IsUnion, KEYCXX)
TYPE_TRAIT_1(__has_unique_object_representations,
HasUniqueObjectRepresentations, KEYCXX)
-KEYWORD(__underlying_type , KEYCXX)
+
+#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) KEYWORD(__##Trait, KEYCXX)
+#include "clang/Basic/TransformTypeTraits.def"
// Clang-only C++ Type Traits
+TYPE_TRAIT_1(__is_trivially_relocatable, IsTriviallyRelocatable, KEYCXX)
+TYPE_TRAIT_1(__is_trivially_equality_comparable, IsTriviallyEqualityComparable, KEYCXX)
+TYPE_TRAIT_1(__is_bounded_array, IsBoundedArray, KEYCXX)
+TYPE_TRAIT_1(__is_unbounded_array, IsUnboundedArray, KEYCXX)
+TYPE_TRAIT_1(__is_nullptr, IsNullPointer, KEYCXX)
+TYPE_TRAIT_1(__is_scoped_enum, IsScopedEnum, KEYCXX)
+TYPE_TRAIT_1(__is_referenceable, IsReferenceable, KEYCXX)
+TYPE_TRAIT_1(__can_pass_in_regs, CanPassInRegs, KEYCXX)
TYPE_TRAIT_2(__reference_binds_to_temporary, ReferenceBindsToTemporary, KEYCXX)
+TYPE_TRAIT_2(__reference_constructs_from_temporary, ReferenceConstructsFromTemporary, KEYCXX)
// Embarcadero Expression Traits
EXPRESSION_TRAIT(__is_lvalue_expr, IsLValueExpr, KEYCXX)
@@ -595,6 +621,17 @@ KEYWORD(pipe , KEYOPENCLC | KEYOPENCLCXX)
// C++ for OpenCL s2.3.1: addrspace_cast operator
KEYWORD(addrspace_cast , KEYOPENCLCXX)
+// CUDA/HIP function attributes
+KEYWORD(__noinline__ , KEYCUDA)
+
+// HLSL keywords.
+KEYWORD(cbuffer , KEYHLSL)
+KEYWORD(tbuffer , KEYHLSL)
+KEYWORD(groupshared , KEYHLSL)
+KEYWORD(in , KEYHLSL)
+KEYWORD(inout , KEYHLSL)
+KEYWORD(out , KEYHLSL)
+
// OpenMP Type Traits
UNARY_EXPR_OR_TYPE_TRAIT(__builtin_omp_required_simd_align, OpenMPRequiredSimdAlign, KEYALL)
@@ -655,6 +692,9 @@ KEYWORD(_Nullable , KEYALL)
KEYWORD(_Nullable_result , KEYALL)
KEYWORD(_Null_unspecified , KEYALL)
+// WebAssembly Type Extension
+KEYWORD(__funcref , KEYALL)
+
// Microsoft extensions which should be disabled in strict conformance mode
KEYWORD(__ptr64 , KEYMS)
KEYWORD(__ptr32 , KEYMS)
@@ -673,36 +713,59 @@ KEYWORD(__multiple_inheritance , KEYMS)
KEYWORD(__virtual_inheritance , KEYMS)
KEYWORD(__interface , KEYMS)
ALIAS("__int8" , char , KEYMS)
-ALIAS("_int8" , char , KEYMS)
ALIAS("__int16" , short , KEYMS)
-ALIAS("_int16" , short , KEYMS)
ALIAS("__int32" , int , KEYMS)
-ALIAS("_int32" , int , KEYMS)
-ALIAS("_int64" , __int64 , KEYMS)
ALIAS("__wchar_t" , wchar_t , KEYMS)
-ALIAS("_asm" , asm , KEYMS)
-ALIAS("_alignof" , __alignof , KEYMS)
ALIAS("__builtin_alignof", __alignof , KEYMS)
-ALIAS("_cdecl" , __cdecl , KEYMS | KEYBORLAND)
-ALIAS("_fastcall" , __fastcall , KEYMS | KEYBORLAND)
-ALIAS("_stdcall" , __stdcall , KEYMS | KEYBORLAND)
-ALIAS("_thiscall" , __thiscall , KEYMS)
-ALIAS("_vectorcall" , __vectorcall, KEYMS)
-ALIAS("_uuidof" , __uuidof , KEYMS | KEYBORLAND)
-ALIAS("_inline" , inline , KEYMS)
-ALIAS("_declspec" , __declspec , KEYMS)
+
+// Microsoft single-underscore prefixed aliases for double-underscore prefixed
+// keywords.
+ALIAS("_asm" , asm , KEYMS)
+ALIAS("_alignof" , __alignof , KEYMS)
+ALIAS("_cdecl" , __cdecl , KEYMS | KEYBORLAND)
+ALIAS("_declspec" , __declspec , KEYMS)
+ALIAS("_fastcall" , __fastcall , KEYMS | KEYBORLAND)
+ALIAS("_finally" , __finally , KEYMSCOMPAT)
+ALIAS("_forceinline" , __forceinline, KEYMSCOMPAT)
+ALIAS("_inline" , inline , KEYMS)
+ALIAS("_int8" , char , KEYMS)
+ALIAS("_int16" , short , KEYMS)
+ALIAS("_int32" , int , KEYMS)
+ALIAS("_int64" , __int64 , KEYMS)
+ALIAS("_leave" , __leave , KEYMSCOMPAT)
+ALIAS("_multiple_inheritance", __multiple_inheritance, KEYMSCOMPAT)
+ALIAS("_ptr32" , __ptr32 , KEYMSCOMPAT)
+ALIAS("_ptr64" , __ptr64 , KEYMSCOMPAT)
+ALIAS("_restrict" , restrict , KEYMSCOMPAT)
+ALIAS("_stdcall" , __stdcall , KEYMS | KEYBORLAND)
+ALIAS("_thiscall" , __thiscall , KEYMS)
+ALIAS("_try" , __try , KEYMSCOMPAT)
+ALIAS("_vectorcall" , __vectorcall , KEYMS)
+ALIAS("_unaligned" , __unaligned , KEYMSCOMPAT)
+ALIAS("_uptr" , __uptr , KEYMSCOMPAT)
+ALIAS("_uuidof" , __uuidof , KEYMS | KEYBORLAND)
+ALIAS("_virtual_inheritance", __virtual_inheritance, KEYMSCOMPAT)
+ALIAS("_w64" , __w64 , KEYMSCOMPAT)
// Borland Extensions which should be disabled in strict conformance mode.
ALIAS("_pascal" , __pascal , KEYBORLAND)
// Clang Extensions.
KEYWORD(__builtin_convertvector , KEYALL)
+UNARY_EXPR_OR_TYPE_TRAIT(__builtin_vectorelements, VectorElements, KEYALL)
ALIAS("__char16_t" , char16_t , KEYCXX)
ALIAS("__char32_t" , char32_t , KEYCXX)
KEYWORD(__builtin_bit_cast , KEYALL)
KEYWORD(__builtin_available , KEYALL)
KEYWORD(__builtin_sycl_unique_stable_name, KEYSYCL)
+// Keywords defined by Attr.td.
+// The "EMPTY ## X" is used to prevent early macro-expansion of the keyword.
+#ifndef KEYWORD_ATTRIBUTE
+#define KEYWORD_ATTRIBUTE(X, HASARG, EMPTY) KEYWORD(EMPTY ## X, KEYALL)
+#endif
+#include "clang/Basic/RegularKeywordAttrInfo.inc"
+
// Clang-specific keywords enabled only in testing.
TESTING_KEYWORD(__unknown_anytype , KEYALL)
@@ -743,6 +806,17 @@ OBJC_AT_KEYWORD(dynamic)
OBJC_AT_KEYWORD(import)
OBJC_AT_KEYWORD(available)
+//===----------------------------------------------------------------------===//
+// Interesting identifiers.
+//===----------------------------------------------------------------------===//
+INTERESTING_IDENTIFIER(not_interesting)
+INTERESTING_IDENTIFIER(FILE)
+INTERESTING_IDENTIFIER(jmp_buf)
+INTERESTING_IDENTIFIER(sigjmp_buf)
+INTERESTING_IDENTIFIER(ucontext_t)
+INTERESTING_IDENTIFIER(float_t)
+INTERESTING_IDENTIFIER(double_t)
+
// TODO: What to do about context-sensitive keywords like:
// bycopy/byref/in/inout/oneway/out?
@@ -827,16 +901,22 @@ PRAGMA_ANNOTATION(pragma_redefine_extname)
// handles them.
PRAGMA_ANNOTATION(pragma_fp_contract)
-// Annotation for #pragma STDC FENV_ACCESS
+// Annotations for #pragma STDC FENV_ACCESS and #pragma fenv_access (MS compat)
// The lexer produces these so that they only take effect when the parser
// handles them.
PRAGMA_ANNOTATION(pragma_fenv_access)
+PRAGMA_ANNOTATION(pragma_fenv_access_ms)
// Annotation for #pragma STDC FENV_ROUND
// The lexer produces these so that they only take effect when the parser
// handles them.
PRAGMA_ANNOTATION(pragma_fenv_round)
+// Annotation for #pragma STDC CX_LIMITED_RANGE
+// The lexer produces these so that they only take effect when the parser
+// handles them.
+PRAGMA_ANNOTATION(pragma_cx_limited_range)
+
// Annotation for #pragma float_control
// The lexer produces these so that they only take effect when the parser
// handles them.
@@ -875,6 +955,12 @@ ANNOTATION(attr_openmp)
PRAGMA_ANNOTATION(pragma_openmp)
PRAGMA_ANNOTATION(pragma_openmp_end)
+// Annotations for OpenACC pragma directives - #pragma acc.
+// Like with OpenMP, these are produced by the lexer when it parses a
+// #pragma acc directive so it can be handled during parsing of the directives.
+PRAGMA_ANNOTATION(pragma_openacc)
+PRAGMA_ANNOTATION(pragma_openacc_end)
+
// Annotations for loop pragma directives #pragma clang loop ...
// The lexer produces these so that they only take effect when the parser
// handles #pragma loop ... directives.
@@ -885,6 +971,9 @@ PRAGMA_ANNOTATION(pragma_fp)
// Annotation for the attribute pragma directives - #pragma clang attribute ...
PRAGMA_ANNOTATION(pragma_attribute)
+// Annotation for the riscv pragma directives - #pragma clang riscv intrinsic ...
+PRAGMA_ANNOTATION(pragma_riscv)
+
// Annotations for module import translated from #include etc.
ANNOTATION(module_include)
ANNOTATION(module_begin)
@@ -894,6 +983,9 @@ ANNOTATION(module_end)
// into the name of a header unit.
ANNOTATION(header_unit)
+// Annotation for end of input in clang-repl.
+ANNOTATION(repl_input_end)
+
#undef PRAGMA_ANNOTATION
#undef ANNOTATION
#undef TESTING_KEYWORD
@@ -909,9 +1001,11 @@ ANNOTATION(header_unit)
#undef TYPE_TRAIT_2
#undef TYPE_TRAIT_1
#undef TYPE_TRAIT
-#undef CONCEPTS_KEYWORD
#undef CXX20_KEYWORD
#undef CXX11_KEYWORD
#undef KEYWORD
#undef PUNCTUATOR
#undef TOK
+#undef C99_KEYWORD
+#undef C23_KEYWORD
+#undef INTERESTING_IDENTIFIER
diff --git a/contrib/llvm-project/clang/include/clang/Basic/TokenKinds.h b/contrib/llvm-project/clang/include/clang/Basic/TokenKinds.h
index 4e66aa1c8c2d..7529b922619a 100644
--- a/contrib/llvm-project/clang/include/clang/Basic/TokenKinds.h
+++ b/contrib/llvm-project/clang/include/clang/Basic/TokenKinds.h
@@ -44,6 +44,14 @@ enum ObjCKeywordKind {
NUM_OBJC_KEYWORDS
};
+/// Provides a namespace for interesting identifers such as float_t and
+/// double_t.
+enum InterestingIdentifierKind {
+#define INTERESTING_IDENTIFIER(X) X,
+#include "clang/Basic/TokenKinds.def"
+ NUM_INTERESTING_IDENTIFIERS
+};
+
/// Defines the possible values of an on-off-switch (C99 6.10.6p2).
enum OnOffSwitch {
OOS_ON, OOS_OFF, OOS_DEFAULT
@@ -68,6 +76,9 @@ const char *getPunctuatorSpelling(TokenKind Kind) LLVM_READNONE;
/// tokens like 'int' and 'dynamic_cast'. Returns NULL for other token kinds.
const char *getKeywordSpelling(TokenKind Kind) LLVM_READNONE;
+/// Returns the spelling of preprocessor keywords, such as "else".
+const char *getPPKeywordSpelling(PPKeywordKind Kind) LLVM_READNONE;
+
/// Return true if this is a raw identifier or an identifier kind.
inline bool isAnyIdentifier(TokenKind K) {
return (K == tok::identifier) || (K == tok::raw_identifier);
@@ -96,6 +107,13 @@ bool isAnnotation(TokenKind K);
/// Return true if this is an annotation token representing a pragma.
bool isPragmaAnnotation(TokenKind K);
+inline constexpr bool isRegularKeywordAttribute(TokenKind K) {
+ return (false
+#define KEYWORD_ATTRIBUTE(X, ...) || (K == tok::kw_##X)
+#include "clang/Basic/RegularKeywordAttrInfo.inc"
+ );
+}
+
} // end namespace tok
} // end namespace clang
diff --git a/contrib/llvm-project/clang/include/clang/Basic/TransformTypeTraits.def b/contrib/llvm-project/clang/include/clang/Basic/TransformTypeTraits.def
new file mode 100644
index 000000000000..e27a2719a968
--- /dev/null
+++ b/contrib/llvm-project/clang/include/clang/Basic/TransformTypeTraits.def
@@ -0,0 +1,29 @@
+//==--- TransformTypeTraits.def - type trait transformations --------------===//
+//
+// 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 transform type traits' names.
+//
+//===----------------------------------------------------------------------===//
+
+TRANSFORM_TYPE_TRAIT_DEF(AddLvalueReference, add_lvalue_reference)
+TRANSFORM_TYPE_TRAIT_DEF(AddPointer, add_pointer)
+TRANSFORM_TYPE_TRAIT_DEF(AddRvalueReference, add_rvalue_reference)
+TRANSFORM_TYPE_TRAIT_DEF(Decay, decay)
+TRANSFORM_TYPE_TRAIT_DEF(MakeSigned, make_signed)
+TRANSFORM_TYPE_TRAIT_DEF(MakeUnsigned, make_unsigned)
+TRANSFORM_TYPE_TRAIT_DEF(RemoveAllExtents, remove_all_extents)
+TRANSFORM_TYPE_TRAIT_DEF(RemoveConst, remove_const)
+TRANSFORM_TYPE_TRAIT_DEF(RemoveCV, remove_cv)
+TRANSFORM_TYPE_TRAIT_DEF(RemoveCVRef, remove_cvref)
+TRANSFORM_TYPE_TRAIT_DEF(RemoveExtent, remove_extent)
+TRANSFORM_TYPE_TRAIT_DEF(RemovePointer, remove_pointer)
+TRANSFORM_TYPE_TRAIT_DEF(RemoveReference, remove_reference_t)
+TRANSFORM_TYPE_TRAIT_DEF(RemoveRestrict, remove_restrict)
+TRANSFORM_TYPE_TRAIT_DEF(RemoveVolatile, remove_volatile)
+TRANSFORM_TYPE_TRAIT_DEF(EnumUnderlyingType, underlying_type)
+#undef TRANSFORM_TYPE_TRAIT_DEF
diff --git a/contrib/llvm-project/clang/include/clang/Basic/TypeNodes.td b/contrib/llvm-project/clang/include/clang/Basic/TypeNodes.td
index 011394c3ef45..649b071cebb9 100644
--- a/contrib/llvm-project/clang/include/clang/Basic/TypeNodes.td
+++ b/contrib/llvm-project/clang/include/clang/Basic/TypeNodes.td
@@ -3,7 +3,7 @@ include "clang/Basic/ASTNode.td"
class TypeNode<TypeNode base, bit abstract = 0> : ASTNode {
TypeNode Base = base;
bit Abstract = abstract;
-}
+}
/// A type node that is only used to represent dependent types in C++. For
/// example, DependentTemplateSpecializationType is used to represent types
@@ -75,6 +75,7 @@ def DependentSizedMatrixType : TypeNode<MatrixType>, AlwaysDependent;
def FunctionType : TypeNode<Type, 1>;
def FunctionProtoType : TypeNode<FunctionType>;
def FunctionNoProtoType : TypeNode<FunctionType>;
+def UsingType : TypeNode<Type>, NeverCanonical;
def UnresolvedUsingType : TypeNode<Type>, AlwaysDependent;
def ParenType : TypeNode<Type>, NeverCanonical;
def TypedefType : TypeNode<Type>, NeverCanonical;
@@ -90,6 +91,7 @@ def RecordType : TypeNode<TagType>, LeafType;
def EnumType : TypeNode<TagType>, LeafType;
def ElaboratedType : TypeNode<Type>, NeverCanonical;
def AttributedType : TypeNode<Type>, NeverCanonical;
+def BTFTagAttributedType : TypeNode<Type>, NeverCanonical;
def TemplateTypeParmType : TypeNode<Type>, AlwaysDependent, LeafType;
def SubstTemplateTypeParmType : TypeNode<Type>, NeverCanonical;
def SubstTemplateTypeParmPackType : TypeNode<Type>, AlwaysDependent;
@@ -107,5 +109,5 @@ def ObjCInterfaceType : TypeNode<ObjCObjectType>, LeafType;
def ObjCObjectPointerType : TypeNode<Type>;
def PipeType : TypeNode<Type>;
def AtomicType : TypeNode<Type>;
-def ExtIntType : TypeNode<Type>;
-def DependentExtIntType : TypeNode<Type>, AlwaysDependent;
+def BitIntType : TypeNode<Type>;
+def DependentBitIntType : TypeNode<Type>, AlwaysDependent;
diff --git a/contrib/llvm-project/clang/include/clang/Basic/TypeTraits.h b/contrib/llvm-project/clang/include/clang/Basic/TypeTraits.h
index a0f06bec6697..eb8b1923152d 100644
--- a/contrib/llvm-project/clang/include/clang/Basic/TypeTraits.h
+++ b/contrib/llvm-project/clang/include/clang/Basic/TypeTraits.h
@@ -67,6 +67,10 @@ const char *getTraitName(UnaryExprOrTypeTrait T) LLVM_READONLY;
const char *getTraitSpelling(TypeTrait T) LLVM_READONLY;
const char *getTraitSpelling(ArrayTypeTrait T) LLVM_READONLY;
const char *getTraitSpelling(UnaryExprOrTypeTrait T) LLVM_READONLY;
+
+/// Return the arity of the type trait \p T.
+unsigned getTypeTraitArity(TypeTrait T) LLVM_READONLY;
+
} // namespace clang
#endif
diff --git a/contrib/llvm-project/clang/include/clang/Basic/Version.h b/contrib/llvm-project/clang/include/clang/Basic/Version.h
index 2881d8db954e..8e4e6928fded 100644
--- a/contrib/llvm-project/clang/include/clang/Basic/Version.h
+++ b/contrib/llvm-project/clang/include/clang/Basic/Version.h
@@ -40,6 +40,9 @@ namespace clang {
/// string as getClangRevision.
std::string getLLVMRevision();
+ /// Retrieves the Clang vendor tag.
+ std::string getClangVendor();
+
/// Retrieves the full repository version that is an amalgamation of
/// the information in getClangRepositoryPath() and getClangRevision().
std::string getClangFullRepositoryVersion();
diff --git a/contrib/llvm-project/clang/include/clang/Basic/Visibility.h b/contrib/llvm-project/clang/include/clang/Basic/Visibility.h
index 57d9754ae4a9..1e196300be42 100644
--- a/contrib/llvm-project/clang/include/clang/Basic/Visibility.h
+++ b/contrib/llvm-project/clang/include/clang/Basic/Visibility.h
@@ -15,6 +15,7 @@
#define LLVM_CLANG_BASIC_VISIBILITY_H
#include "clang/Basic/Linkage.h"
+#include "llvm/ADT/STLForwardCompat.h"
#include <cassert>
#include <cstdint>
@@ -56,10 +57,11 @@ class LinkageInfo {
void setVisibility(Visibility V, bool E) { visibility_ = V; explicit_ = E; }
public:
- LinkageInfo() : linkage_(ExternalLinkage), visibility_(DefaultVisibility),
- explicit_(false) {}
+ LinkageInfo()
+ : linkage_(llvm::to_underlying(Linkage::External)),
+ visibility_(DefaultVisibility), explicit_(false) {}
LinkageInfo(Linkage L, Visibility V, bool E)
- : linkage_(L), visibility_(V), explicit_(E) {
+ : linkage_(llvm::to_underlying(L)), visibility_(V), explicit_(E) {
assert(getLinkage() == L && getVisibility() == V &&
isVisibilityExplicit() == E && "Enum truncated!");
}
@@ -68,23 +70,23 @@ public:
return LinkageInfo();
}
static LinkageInfo internal() {
- return LinkageInfo(InternalLinkage, DefaultVisibility, false);
+ return LinkageInfo(Linkage::Internal, DefaultVisibility, false);
}
static LinkageInfo uniqueExternal() {
- return LinkageInfo(UniqueExternalLinkage, DefaultVisibility, false);
+ return LinkageInfo(Linkage::UniqueExternal, DefaultVisibility, false);
}
static LinkageInfo none() {
- return LinkageInfo(NoLinkage, DefaultVisibility, false);
+ return LinkageInfo(Linkage::None, DefaultVisibility, false);
}
static LinkageInfo visible_none() {
- return LinkageInfo(VisibleNoLinkage, DefaultVisibility, false);
+ return LinkageInfo(Linkage::VisibleNone, DefaultVisibility, false);
}
- Linkage getLinkage() const { return (Linkage)linkage_; }
+ Linkage getLinkage() const { return static_cast<Linkage>(linkage_); }
Visibility getVisibility() const { return (Visibility)visibility_; }
bool isVisibilityExplicit() const { return explicit_; }
- void setLinkage(Linkage L) { linkage_ = L; }
+ void setLinkage(Linkage L) { linkage_ = llvm::to_underlying(L); }
void mergeLinkage(Linkage L) {
setLinkage(minLinkage(getLinkage(), L));
@@ -96,10 +98,10 @@ public:
void mergeExternalVisibility(Linkage L) {
Linkage ThisL = getLinkage();
if (!isExternallyVisible(L)) {
- if (ThisL == VisibleNoLinkage)
- ThisL = NoLinkage;
- else if (ThisL == ExternalLinkage)
- ThisL = UniqueExternalLinkage;
+ if (ThisL == Linkage::VisibleNone)
+ ThisL = Linkage::None;
+ else if (ThisL == Linkage::External)
+ ThisL = Linkage::UniqueExternal;
}
setLinkage(ThisL);
}
diff --git a/contrib/llvm-project/clang/include/clang/Basic/WebAssemblyReferenceTypes.def b/contrib/llvm-project/clang/include/clang/Basic/WebAssemblyReferenceTypes.def
new file mode 100644
index 000000000000..7c83da15150c
--- /dev/null
+++ b/contrib/llvm-project/clang/include/clang/Basic/WebAssemblyReferenceTypes.def
@@ -0,0 +1,40 @@
+//===-- WebAssemblyReferenceTypes.def - Wasm reference types ----*- 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 externref_t. The macros are:
+//
+// WASM_TYPE(Name, Id, SingletonId)
+// WASM_REF_TYPE(Name, MangledName, Id, SingletonId, AS)
+//
+// where:
+//
+// - Name is the name of the builtin type.
+//
+// - MangledNameBase is the base used for name mangling.
+//
+// - BuiltinType::Id is the enumerator defining the type.
+//
+// - Context.SingletonId is the global singleton of this type.
+//
+// - AS indicates the address space for values of this type.
+//
+// To include this file, define either WASM_REF_TYPE or WASM_TYPE, depending on
+// how much information you want. The macros will be undefined after inclusion.
+//
+//===----------------------------------------------------------------------===//
+
+
+#ifndef WASM_REF_TYPE
+#define WASM_REF_TYPE(Name, MangledNameBase, Id, SingletonId, AS) \
+ WASM_TYPE(Name, Id, SingletonId)
+#endif
+
+WASM_REF_TYPE("__externref_t", "externref_t", WasmExternRef, WasmExternRefTy, 10)
+
+#undef WASM_TYPE
+#undef WASM_REF_TYPE
diff --git a/contrib/llvm-project/clang/include/clang/Basic/X86Target.def b/contrib/llvm-project/clang/include/clang/Basic/X86Target.def
deleted file mode 100644
index 70f3879f33a1..000000000000
--- a/contrib/llvm-project/clang/include/clang/Basic/X86Target.def
+++ /dev/null
@@ -1,110 +0,0 @@
-//===--- X86Target.def - X86 Feature/Processor Database ---------*- 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 the X86-specific Features and Processors, as used by
-// the X86 Targets.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef FEATURE
-#define FEATURE(ENUM)
-#endif
-
-#ifndef CPU_SPECIFIC
-#define CPU_SPECIFIC(NAME, MANGLING, FEATURES)
-#endif
-
-#ifndef CPU_SPECIFIC_ALIAS
-#define CPU_SPECIFIC_ALIAS(NEW_NAME, NAME)
-#endif
-
-// List of CPU Supports features in order. These need to remain in the order
-// required by attribute 'target' checking. Note that not all are supported/
-// prioritized by GCC, so synchronization with GCC's implementation may require
-// changing some existing values.
-FEATURE(FEATURE_CMOV)
-FEATURE(FEATURE_MMX)
-FEATURE(FEATURE_SSE)
-FEATURE(FEATURE_SSE2)
-FEATURE(FEATURE_SSE3)
-FEATURE(FEATURE_SSSE3)
-FEATURE(FEATURE_SSE4_A)
-FEATURE(FEATURE_SSE4_1)
-FEATURE(FEATURE_SSE4_2)
-FEATURE(FEATURE_POPCNT)
-FEATURE(FEATURE_AES)
-FEATURE(FEATURE_PCLMUL)
-FEATURE(FEATURE_AVX)
-FEATURE(FEATURE_BMI)
-FEATURE(FEATURE_FMA4)
-FEATURE(FEATURE_XOP)
-FEATURE(FEATURE_FMA)
-FEATURE(FEATURE_BMI2)
-FEATURE(FEATURE_AVX2)
-FEATURE(FEATURE_AVX512F)
-FEATURE(FEATURE_AVX512VL)
-FEATURE(FEATURE_AVX512BW)
-FEATURE(FEATURE_AVX512DQ)
-FEATURE(FEATURE_AVX512CD)
-FEATURE(FEATURE_AVX512ER)
-FEATURE(FEATURE_AVX512PF)
-FEATURE(FEATURE_AVX512VBMI)
-FEATURE(FEATURE_AVX512IFMA)
-FEATURE(FEATURE_AVX5124VNNIW)
-FEATURE(FEATURE_AVX5124FMAPS)
-FEATURE(FEATURE_AVX512VPOPCNTDQ)
-FEATURE(FEATURE_AVX512VBMI2)
-FEATURE(FEATURE_GFNI)
-FEATURE(FEATURE_VPCLMULQDQ)
-FEATURE(FEATURE_AVX512VNNI)
-FEATURE(FEATURE_AVX512BITALG)
-FEATURE(FEATURE_AVX512BF16)
-FEATURE(FEATURE_AVX512VP2INTERSECT)
-
-
-// FIXME: When commented out features are supported in LLVM, enable them here.
-CPU_SPECIFIC("generic", 'A', "")
-CPU_SPECIFIC("pentium", 'B', "")
-CPU_SPECIFIC("pentium_pro", 'C', "+cmov")
-CPU_SPECIFIC("pentium_mmx", 'D', "+mmx")
-CPU_SPECIFIC("pentium_ii", 'E', "+cmov,+mmx")
-CPU_SPECIFIC("pentium_iii", 'H', "+cmov,+mmx,+sse")
-CPU_SPECIFIC_ALIAS("pentium_iii_no_xmm_regs", "pentium_iii")
-CPU_SPECIFIC("pentium_4", 'J', "+cmov,+mmx,+sse,+sse2")
-CPU_SPECIFIC("pentium_m", 'K', "+cmov,+mmx,+sse,+sse2")
-CPU_SPECIFIC("pentium_4_sse3", 'L', "+cmov,+mmx,+sse,+sse2,+sse3")
-CPU_SPECIFIC("core_2_duo_ssse3", 'M', "+cmov,+mmx,+sse,+sse2,+sse3,+ssse3")
-CPU_SPECIFIC("core_2_duo_sse4_1", 'N', "+cmov,+mmx,+sse,+sse2,+sse3,+ssse3,+sse4.1")
-CPU_SPECIFIC("atom", 'O', "+cmov,+mmx,+sse,+sse2,+sse3,+ssse3,+movbe")
-CPU_SPECIFIC("atom_sse4_2", 'c', "+cmov,+mmx,+sse,+sse2,+sse3,+ssse3,+sse4.1,+sse4.2,+popcnt")
-CPU_SPECIFIC("core_i7_sse4_2", 'P', "+cmov,+mmx,+sse,+sse2,+sse3,+ssse3,+sse4.1,+sse4.2,+popcnt")
-CPU_SPECIFIC("core_aes_pclmulqdq", 'Q', "+cmov,+mmx,+sse,+sse2,+sse3,+ssse3,+sse4.1,+sse4.2,+popcnt")
-CPU_SPECIFIC("atom_sse4_2_movbe", 'd', "+cmov,+mmx,+sse,+sse2,+sse3,+ssse3,+sse4.1,+sse4.2,+movbe,+popcnt")
-CPU_SPECIFIC("goldmont", 'i', "+cmov,+mmx,+sse,+sse2,+sse3,+ssse3,+sse4.1,+sse4.2,+movbe,+popcnt")
-CPU_SPECIFIC("sandybridge", 'R', "+cmov,+mmx,+sse,+sse2,+sse3,+ssse3,+sse4.1,+sse4.2,+popcnt,+avx")
-CPU_SPECIFIC_ALIAS("core_2nd_gen_avx", "sandybridge")
-CPU_SPECIFIC("ivybridge", 'S', "+cmov,+mmx,+sse,+sse2,+sse3,+ssse3,+sse4.1,+sse4.2,+popcnt,+f16c,+avx")
-CPU_SPECIFIC_ALIAS("core_3rd_gen_avx", "ivybridge")
-CPU_SPECIFIC("haswell", 'V', "+cmov,+mmx,+sse,+sse2,+sse3,+ssse3,+sse4.1,+sse4.2,+movbe,+popcnt,+f16c,+avx,+fma,+bmi,+lzcnt,+avx2")
-CPU_SPECIFIC_ALIAS("core_4th_gen_avx", "haswell")
-CPU_SPECIFIC("core_4th_gen_avx_tsx", 'W', "+cmov,+mmx,+sse,+sse2,+sse3,+ssse3,+sse4.1,+sse4.2,+movbe,+popcnt,+f16c,+avx,+fma,+bmi,+lzcnt,+avx2")
-CPU_SPECIFIC("broadwell", 'X', "+cmov,+mmx,+sse,+sse2,+sse3,+ssse3,+sse4.1,+sse4.2,+movbe,+popcnt,+f16c,+avx,+fma,+bmi,+lzcnt,+avx2,+adx")
-CPU_SPECIFIC_ALIAS("core_5th_gen_avx", "broadwell")
-CPU_SPECIFIC("core_5th_gen_avx_tsx", 'Y', "+cmov,+mmx,+sse,+sse2,+sse3,+ssse3,+sse4.1,+sse4.2,+movbe,+popcnt,+f16c,+avx,+fma,+bmi,+lzcnt,+avx2,+adx")
-CPU_SPECIFIC("knl", 'Z', "+cmov,+mmx,+sse,+sse2,+sse3,+ssse3,+sse4.1,+sse4.2,+movbe,+popcnt,+f16c,+avx,+fma,+bmi,+lzcnt,+avx2,+avx512f,+adx,+avx512er,+avx512pf,+avx512cd")
-CPU_SPECIFIC_ALIAS("mic_avx512", "knl")
-CPU_SPECIFIC("skylake", 'b', "+cmov,+mmx,+sse,+sse2,+sse3,+ssse3,+sse4.1,+sse4.2,+movbe,+popcnt,+f16c,+avx,+fma,+bmi,+lzcnt,+avx2,+adx,+mpx")
-CPU_SPECIFIC( "skylake_avx512", 'a', "+cmov,+mmx,+sse,+sse2,+sse3,+ssse3,+sse4.1,+sse4.2,+movbe,+popcnt,+f16c,+avx,+fma,+bmi,+lzcnt,+avx2,+avx512dq,+avx512f,+adx,+avx512cd,+avx512bw,+avx512vl,+clwb")
-CPU_SPECIFIC("cannonlake", 'e', "+cmov,+mmx,+sse,+sse2,+sse3,+ssse3,+sse4.1,+sse4.2,+movbe,+popcnt,+f16c,+avx,+fma,+bmi,+lzcnt,+avx2,+avx512dq,+avx512f,+adx,+avx512ifma,+avx512cd,+avx512bw,+avx512vl,+avx512vbmi")
-CPU_SPECIFIC("knm", 'j', "+cmov,+mmx,+sse,+sse2,+sse3,+ssse3,+sse4.1,+sse4.2,+movbe,+popcnt,+f16c,+avx,+fma,+bmi,+lzcnt,+avx2,+avx512f,+adx,+avx512er,+avx512pf,+avx512cd,+avx5124fmaps,+avx5124vnniw,+avx512vpopcntdq")
-
-#undef CPU_SPECIFIC_ALIAS
-#undef CPU_SPECIFIC
-#undef PROC_64_BIT
-#undef PROC_32_BIT
-#undef FEATURE
diff --git a/contrib/llvm-project/clang/include/clang/Basic/arm_bf16.td b/contrib/llvm-project/clang/include/clang/Basic/arm_bf16.td
index d837a7666d40..f70c7221f8d6 100644
--- a/contrib/llvm-project/clang/include/clang/Basic/arm_bf16.td
+++ b/contrib/llvm-project/clang/include/clang/Basic/arm_bf16.td
@@ -1,4 +1,4 @@
-//===--- arm_fp16.td - ARM BF16 compiler interface ------------------------===//
+//===--- arm_bf16.td - ARM BF16 compiler interface ------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
diff --git a/contrib/llvm-project/clang/include/clang/Basic/arm_fp16.td b/contrib/llvm-project/clang/include/clang/Basic/arm_fp16.td
index 79cd16233c10..cb2a09303e8e 100644
--- a/contrib/llvm-project/clang/include/clang/Basic/arm_fp16.td
+++ b/contrib/llvm-project/clang/include/clang/Basic/arm_fp16.td
@@ -14,7 +14,7 @@
include "arm_neon_incl.td"
// ARMv8.2-A FP16 intrinsics.
-let ArchGuard = "defined(__ARM_FEATURE_FP16_SCALAR_ARITHMETIC) && defined(__aarch64__)" in {
+let ArchGuard = "defined(__aarch64__)", TargetGuard = "fullfp16" in {
// Negate
def VNEGSH : SInst<"vneg", "11", "Sh">;
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..9cb7e0981384 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",
@@ -291,7 +289,7 @@ def SPLATQ : WInst<"splat_laneq", ".(!Q)I",
"UcUsUicsilPcPsfQUcQUsQUiQcQsQiQPcQPsQflUlQlQUlhdQhQdPlQPl"> {
let isLaneQ = 1;
}
-let ArchGuard = "defined(__ARM_FEATURE_BF16_VECTOR_ARITHMETIC)" in {
+let TargetGuard = "bf16" in {
def SPLAT_BF : WInst<"splat_lane", ".(!q)I", "bQb">;
def SPLATQ_BF : WInst<"splat_laneq", ".(!Q)I", "bQb"> {
let isLaneQ = 1;
@@ -325,9 +323,9 @@ def VMLSL : SOpInst<"vmlsl", "(>Q)(>Q)..", "csiUcUsUi", OP_MLSL>;
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>;
+let TargetGuard = "v8.1a" in {
+def VQRDMLAH : SInst<"vqrdmlah", "....", "siQsQi">;
+def VQRDMLSH : SInst<"vqrdmlsh", "....", "siQsQi">;
}
def VQDMLAL : SInst<"vqdmlal", "(>Q)(>Q)..", "si">;
@@ -532,7 +530,7 @@ def VMOV_N : WOpInst<"vmov_n", ".1",
}
let InstName = "" in
def VDUP_LANE: WOpInst<"vdup_lane", ".qI",
- "UcUsUicsiPcPsfQUcQUsQUiQcQsQiQPcQPsQflUlQlQUl",
+ "UcUsUicsiPcPshfQUcQUsQUiQcQsQiQPcQPsQhQflUlQlQUl",
OP_DUP_LN>;
////////////////////////////////////////////////////////////////////////////////
@@ -616,7 +614,7 @@ def A64_VQDMULH_LANE : SInst<"vqdmulh_lane", "..(!q)I", "siQsQi">;
def A64_VQRDMULH_LANE : SInst<"vqrdmulh_lane", "..(!q)I", "siQsQi">;
}
-let ArchGuard = "defined(__ARM_FEATURE_QRDMX)" in {
+let TargetGuard = "v8.1a" in {
def VQRDMLAH_LANE : SOpInst<"vqrdmlah_lane", "...qI", "siQsQi", OP_QRDMLAH_LN>;
def VQRDMLSH_LANE : SOpInst<"vqrdmlsh_lane", "...qI", "siQsQi", OP_QRDMLSH_LN>;
}
@@ -959,8 +957,10 @@ def VQDMLAL_HIGH : SOpInst<"vqdmlal_high", "(>Q)(>Q)QQ", "si", OP_QDMLALHi>;
def VQDMLAL_HIGH_N : SOpInst<"vqdmlal_high_n", "(>Q)(>Q)Q1", "si", OP_QDMLALHi_N>;
def VQDMLSL_HIGH : SOpInst<"vqdmlsl_high", "(>Q)(>Q)QQ", "si", OP_QDMLSLHi>;
def VQDMLSL_HIGH_N : SOpInst<"vqdmlsl_high_n", "(>Q)(>Q)Q1", "si", OP_QDMLSLHi_N>;
-def VMULL_P64 : SInst<"vmull", "(1>)11", "Pl">;
-def VMULL_HIGH_P64 : SOpInst<"vmull_high", "(1>)..", "HPl", OP_MULLHi_P64>;
+let TargetGuard = "aes" in {
+ def VMULL_P64 : SInst<"vmull", "(1>)11", "Pl">;
+ def VMULL_HIGH_P64 : SOpInst<"vmull_high", "(1>)..", "HPl", OP_MULLHi_P64>;
+}
////////////////////////////////////////////////////////////////////////////////
@@ -982,7 +982,7 @@ def COPYQ_LANEQ : IOpInst<"vcopy_laneq", "..I.I",
////////////////////////////////////////////////////////////////////////////////
// Set all lanes to same value
-def VDUP_LANE1: WOpInst<"vdup_lane", ".qI", "hdQhQdPlQPl", OP_DUP_LN>;
+def VDUP_LANE1: WOpInst<"vdup_lane", ".qI", "dQdPlQPl", OP_DUP_LN>;
def VDUP_LANE2: WOpInst<"vdup_laneq", ".QI",
"csilUcUsUiUlPcPshfdQcQsQiQlQPcQPsQUcQUsQUiQUlQhQfQdPlQPl",
OP_DUP_LN> {
@@ -1091,14 +1091,14 @@ let isLaneQ = 1 in {
def VQDMULH_LANEQ : SInst<"vqdmulh_laneq", "..QI", "siQsQi">;
def VQRDMULH_LANEQ : SInst<"vqrdmulh_laneq", "..QI", "siQsQi">;
}
-let ArchGuard = "defined(__ARM_FEATURE_QRDMX) && defined(__aarch64__)" in {
+let ArchGuard = "defined(__aarch64__)", TargetGuard = "v8.1a" in {
def VQRDMLAH_LANEQ : SOpInst<"vqrdmlah_laneq", "...QI", "siQsQi", OP_QRDMLAH_LN> {
let isLaneQ = 1;
}
def VQRDMLSH_LANEQ : SOpInst<"vqrdmlsh_laneq", "...QI", "siQsQi", OP_QRDMLSH_LN> {
let isLaneQ = 1;
}
-}
+} // ArchGuard = "defined(__aarch64__)", TargetGuard = "v8.1a"
// Note: d type implemented by SCALAR_VMULX_LANE
def VMULX_LANE : IOpInst<"vmulx_lane", "..qI", "fQfQd", OP_MULX_LN>;
@@ -1122,14 +1122,14 @@ def VEXT_A64 : WInst<"vext", "...I", "dQdPlQPl">;
////////////////////////////////////////////////////////////////////////////////
// Crypto
-let ArchGuard = "__ARM_ARCH >= 8 && defined(__ARM_FEATURE_AES)" in {
+let ArchGuard = "__ARM_ARCH >= 8", TargetGuard = "aes" in {
def AESE : SInst<"vaese", "...", "QUc">;
def AESD : SInst<"vaesd", "...", "QUc">;
def AESMC : SInst<"vaesmc", "..", "QUc">;
def AESIMC : SInst<"vaesimc", "..", "QUc">;
}
-let ArchGuard = "__ARM_ARCH >= 8 && defined(__ARM_FEATURE_SHA2)" in {
+let ArchGuard = "__ARM_ARCH >= 8", TargetGuard = "sha2" in {
def SHA1H : SInst<"vsha1h", "11", "Ui">;
def SHA1SU1 : SInst<"vsha1su1", "...", "QUi">;
def SHA256SU0 : SInst<"vsha256su0", "...", "QUi">;
@@ -1143,7 +1143,7 @@ def SHA256H2 : SInst<"vsha256h2", "....", "QUi">;
def SHA256SU1 : SInst<"vsha256su1", "....", "QUi">;
}
-let ArchGuard = "__ARM_ARCH >= 8 && defined(__ARM_FEATURE_SHA3) && defined(__aarch64__)" in {
+let ArchGuard = "defined(__aarch64__)", TargetGuard = "sha3" in {
def BCAX : SInst<"vbcax", "....", "QUcQUsQUiQUlQcQsQiQl">;
def EOR3 : SInst<"veor3", "....", "QUcQUsQUiQUlQcQsQiQl">;
def RAX1 : SInst<"vrax1", "...", "QUl">;
@@ -1153,15 +1153,14 @@ def XAR : SInst<"vxar", "...I", "QUl">;
}
}
-let ArchGuard = "__ARM_ARCH >= 8 && defined(__ARM_FEATURE_SHA512) && defined(__aarch64__)" in {
-
+let ArchGuard = "defined(__aarch64__)", TargetGuard = "sha3" in {
def SHA512SU0 : SInst<"vsha512su0", "...", "QUl">;
def SHA512su1 : SInst<"vsha512su1", "....", "QUl">;
def SHA512H : SInst<"vsha512h", "....", "QUl">;
def SHA512H2 : SInst<"vsha512h2", "....", "QUl">;
}
-let ArchGuard = "__ARM_ARCH >= 8 && defined(__ARM_FEATURE_SM3) && defined(__aarch64__)" in {
+let ArchGuard = "defined(__aarch64__)", TargetGuard = "sm4" in {
def SM3SS1 : SInst<"vsm3ss1", "....", "QUi">;
def SM3TT1A : SInst<"vsm3tt1a", "....I", "QUi">;
def SM3TT1B : SInst<"vsm3tt1b", "....I", "QUi">;
@@ -1171,7 +1170,7 @@ def SM3PARTW1 : SInst<"vsm3partw1", "....", "QUi">;
def SM3PARTW2 : SInst<"vsm3partw2", "....", "QUi">;
}
-let ArchGuard = "__ARM_ARCH >= 8 && defined(__ARM_FEATURE_SM4) && defined(__aarch64__)" in {
+let ArchGuard = "defined(__aarch64__)", TargetGuard = "sm4" in {
def SM4E : SInst<"vsm4e", "...", "QUi">;
def SM4EKEY : SInst<"vsm4ekey", "...", "QUi">;
}
@@ -1194,7 +1193,7 @@ def FCVTAS_S32 : SInst<"vcvta_s32", "S.", "fQf">;
def FCVTAU_S32 : SInst<"vcvta_u32", "U.", "fQf">;
}
-let ArchGuard = "__ARM_ARCH >= 8 && defined(__aarch64__)" in {
+let ArchGuard = "defined(__aarch64__)" in {
def FCVTNS_S64 : SInst<"vcvtn_s64", "S.", "dQd">;
def FCVTNU_S64 : SInst<"vcvtn_u64", "U.", "dQd">;
def FCVTPS_S64 : SInst<"vcvtp_s64", "S.", "dQd">;
@@ -1218,7 +1217,7 @@ def FRINTZ_S32 : SInst<"vrnd", "..", "fQf">;
def FRINTI_S32 : SInst<"vrndi", "..", "fQf">;
}
-let ArchGuard = "__ARM_ARCH >= 8 && defined(__aarch64__) && defined(__ARM_FEATURE_DIRECTED_ROUNDING)" in {
+let ArchGuard = "defined(__aarch64__) && defined(__ARM_FEATURE_DIRECTED_ROUNDING)" in {
def FRINTN_S64 : SInst<"vrndn", "..", "dQd">;
def FRINTA_S64 : SInst<"vrnda", "..", "dQd">;
def FRINTP_S64 : SInst<"vrndp", "..", "dQd">;
@@ -1228,11 +1227,16 @@ def FRINTZ_S64 : SInst<"vrnd", "..", "dQd">;
def FRINTI_S64 : SInst<"vrndi", "..", "dQd">;
}
-let ArchGuard = "__ARM_ARCH >= 8 && defined(__aarch64__) && defined(__ARM_FEATURE_FRINT)" in {
+let ArchGuard = "defined(__aarch64__)", TargetGuard = "v8.5a" in {
def FRINT32X_S32 : SInst<"vrnd32x", "..", "fQf">;
def FRINT32Z_S32 : SInst<"vrnd32z", "..", "fQf">;
def FRINT64X_S32 : SInst<"vrnd64x", "..", "fQf">;
def FRINT64Z_S32 : SInst<"vrnd64z", "..", "fQf">;
+
+def FRINT32X_S64 : SInst<"vrnd32x", "..", "dQd">;
+def FRINT32Z_S64 : SInst<"vrnd32z", "..", "dQd">;
+def FRINT64X_S64 : SInst<"vrnd64x", "..", "dQd">;
+def FRINT64Z_S64 : SInst<"vrnd64z", "..", "dQd">;
}
////////////////////////////////////////////////////////////////////////////////
@@ -1243,7 +1247,7 @@ def FMAXNM_S32 : SInst<"vmaxnm", "...", "fQf">;
def FMINNM_S32 : SInst<"vminnm", "...", "fQf">;
}
-let ArchGuard = "__ARM_ARCH >= 8 && defined(__aarch64__) && defined(__ARM_FEATURE_NUMERIC_MAXMIN)" in {
+let ArchGuard = "defined(__aarch64__) && defined(__ARM_FEATURE_NUMERIC_MAXMIN)" in {
def FMAXNM_S64 : SInst<"vmaxnm", "...", "dQd">;
def FMINNM_S64 : SInst<"vminnm", "...", "dQd">;
}
@@ -1285,7 +1289,7 @@ def VQTBX4_A64 : WInst<"vqtbx4", "..(4Q)U", "UccPcQUcQcQPc">;
// itself during generation so, unlike all other intrinsics, this one should
// include *all* types, not just additional ones.
def VVREINTERPRET : REINTERPRET_CROSS_SELF<"csilUcUsUiUlhfdPcPsPlQcQsQiQlQUcQUsQUiQUlQhQfQdQPcQPsQPlQPk"> {
- let ArchGuard = "__ARM_ARCH >= 8 && defined(__aarch64__)";
+ let ArchGuard = "defined(__aarch64__)";
let BigEndianSafe = 1;
}
@@ -1397,15 +1401,15 @@ def SCALAR_SQDMULH : SInst<"vqdmulh", "111", "SsSi">;
// Scalar Integer Saturating Rounding Doubling Multiply Half High
def SCALAR_SQRDMULH : SInst<"vqrdmulh", "111", "SsSi">;
-let ArchGuard = "defined(__ARM_FEATURE_QRDMX) && defined(__aarch64__)" in {
+let ArchGuard = "defined(__aarch64__)", TargetGuard = "v8.1a" 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">;
+} // ArchGuard = "defined(__aarch64__)", TargetGuard = "v8.1a"
////////////////////////////////////////////////////////////////////////////////
// Scalar Floating-point Multiply Extended
@@ -1628,7 +1632,7 @@ def SCALAR_SQRDMULH_LANEQ : SOpInst<"vqrdmulh_laneq", "11QI", "SsSi", OP_SCALAR_
let isLaneQ = 1;
}
-let ArchGuard = "defined(__ARM_FEATURE_QRDMX) && defined(__aarch64__)" in {
+let TargetGuard = "v8.1a" in {
// Signed Saturating Rounding Doubling Multiply Accumulate Returning High Half
def SCALAR_SQRDMLAH_LANE : SOpInst<"vqrdmlah_lane", "111.I", "SsSi", OP_SCALAR_QRDMLAH_LN>;
def SCALAR_SQRDMLAH_LANEQ : SOpInst<"vqrdmlah_laneq", "111QI", "SsSi", OP_SCALAR_QRDMLAH_LN> {
@@ -1640,16 +1644,17 @@ def SCALAR_SQRDMLSH_LANE : SOpInst<"vqrdmlsh_lane", "111.I", "SsSi", OP_SCALAR_Q
def SCALAR_SQRDMLSH_LANEQ : SOpInst<"vqrdmlsh_laneq", "111QI", "SsSi", OP_SCALAR_QRDMLSH_LN> {
let isLaneQ = 1;
}
-}
+} // TargetGuard = "v8.1a"
def SCALAR_VDUP_LANE : IInst<"vdup_lane", "1.I", "ScSsSiSlSfSdSUcSUsSUiSUlSPcSPs">;
def SCALAR_VDUP_LANEQ : IInst<"vdup_laneq", "1QI", "ScSsSiSlSfSdSUcSUsSUiSUlSPcSPs"> {
let isLaneQ = 1;
}
-}
+
+} // ArchGuard = "defined(__aarch64__)"
// ARMv8.2-A FP16 vector intrinsics for A32/A64.
-let ArchGuard = "defined(__ARM_FEATURE_FP16_VECTOR_ARITHMETIC)" in {
+let TargetGuard = "fullfp16" in {
// ARMv8.2-A FP16 one-operand vector intrinsics.
@@ -1674,7 +1679,7 @@ let ArchGuard = "defined(__ARM_FEATURE_FP16_VECTOR_ARITHMETIC)" in {
def VCVTP_U16 : SInst<"vcvtp_u16", "U.", "hQh">;
// Vector rounding
- let ArchGuard = "__ARM_ARCH >= 8 && defined(__ARM_FEATURE_DIRECTED_ROUNDING) && defined(__ARM_FEATURE_FP16_VECTOR_ARITHMETIC)" in {
+ let ArchGuard = "__ARM_ARCH >= 8 && defined(__ARM_FEATURE_DIRECTED_ROUNDING)", TargetGuard = "fullfp16" in {
def FRINTZH : SInst<"vrnd", "..", "hQh">;
def FRINTNH : SInst<"vrndn", "..", "hQh">;
def FRINTAH : SInst<"vrnda", "..", "hQh">;
@@ -1723,7 +1728,7 @@ let ArchGuard = "defined(__ARM_FEATURE_FP16_VECTOR_ARITHMETIC)" in {
// Max/Min
def VMAXH : SInst<"vmax", "...", "hQh">;
def VMINH : SInst<"vmin", "...", "hQh">;
- let ArchGuard = "__ARM_ARCH >= 8 && defined(__ARM_FEATURE_NUMERIC_MAXMIN) && defined(__ARM_FEATURE_FP16_VECTOR_ARITHMETIC)" in {
+ let ArchGuard = "__ARM_ARCH >= 8 && defined(__ARM_FEATURE_NUMERIC_MAXMIN)", TargetGuard = "fullfp16" in {
def FMAXNMH : SInst<"vmaxnm", "...", "hQh">;
def FMINNMH : SInst<"vminnm", "...", "hQh">;
}
@@ -1765,15 +1770,6 @@ let ArchGuard = "defined(__ARM_FEATURE_FP16_VECTOR_ARITHMETIC)" in {
def VUZPH : WInst<"vuzp", "2..", "hQh">;
def VTRNH : WInst<"vtrn", "2..", "hQh">;
-
- let ArchGuard = "!defined(__aarch64__)" in {
- // Set all lanes to same value.
- // Already implemented prior to ARMv8.2-A.
- def VMOV_NH : WOpInst<"vmov_n", ".1", "hQh", OP_DUP>;
- def VDUP_NH : WOpInst<"vdup_n", ".1", "hQh", OP_DUP>;
- def VDUP_LANE1H : WOpInst<"vdup_lane", ".qI", "hQh", OP_DUP_LN>;
- }
-
// Vector Extract
def VEXTH : WInst<"vext", "...I", "hQh">;
@@ -1782,7 +1778,7 @@ let ArchGuard = "defined(__ARM_FEATURE_FP16_VECTOR_ARITHMETIC)" in {
}
// ARMv8.2-A FP16 vector intrinsics for A64 only.
-let ArchGuard = "defined(__ARM_FEATURE_FP16_VECTOR_ARITHMETIC) && defined(__aarch64__)" in {
+let ArchGuard = "defined(__aarch64__)", TargetGuard = "fullfp16" in {
// Vector rounding
def FRINTIH : SInst<"vrndi", "..", "hQh">;
@@ -1877,11 +1873,11 @@ let ArchGuard = "defined(__ARM_FEATURE_FP16_VECTOR_ARITHMETIC) && defined(__aarc
}
// v8.2-A dot product instructions.
-let ArchGuard = "defined(__ARM_FEATURE_DOTPROD)" in {
+let TargetGuard = "dotprod" in {
def DOT : SInst<"vdot", "..(<<)(<<)", "iQiUiQUi">;
def DOT_LANE : SOpInst<"vdot_lane", "..(<<)(<<q)I", "iUiQiQUi", OP_DOT_LN>;
}
-let ArchGuard = "defined(__ARM_FEATURE_DOTPROD) && defined(__aarch64__)" in {
+let ArchGuard = "defined(__aarch64__)", TargetGuard = "dotprod" in {
// Variants indexing into a 128-bit vector are A64 only.
def UDOT_LANEQ : SOpInst<"vdot_laneq", "..(<<)(<<Q)I", "iUiQiQUi", OP_DOT_LNQ> {
let isLaneQ = 1;
@@ -1889,7 +1885,7 @@ let ArchGuard = "defined(__ARM_FEATURE_DOTPROD) && defined(__aarch64__)" in {
}
// v8.2-A FP16 fused multiply-add long instructions.
-let ArchGuard = "defined(__ARM_FEATURE_FP16_FML) && defined(__aarch64__)" in {
+let ArchGuard = "defined(__aarch64__)", TargetGuard = "fp16fml" in {
def VFMLAL_LOW : SInst<"vfmlal_low", ">>..", "hQh">;
def VFMLSL_LOW : SInst<"vfmlsl_low", ">>..", "hQh">;
def VFMLAL_HIGH : SInst<"vfmlal_high", ">>..", "hQh">;
@@ -1914,7 +1910,7 @@ let ArchGuard = "defined(__ARM_FEATURE_FP16_FML) && defined(__aarch64__)" in {
}
}
-let ArchGuard = "defined(__ARM_FEATURE_MATMUL_INT8)" in {
+let TargetGuard = "i8mm" in {
def VMMLA : SInst<"vmmla", "..(<<)(<<)", "QUiQi">;
def VUSMMLA : SInst<"vusmmla", "..(<<U)(<<)", "Qi">;
@@ -1931,7 +1927,7 @@ let ArchGuard = "defined(__ARM_FEATURE_MATMUL_INT8)" in {
}
}
-let ArchGuard = "defined(__ARM_FEATURE_BF16_VECTOR_ARITHMETIC)" in {
+let TargetGuard = "bf16" in {
def VDOT_BF : SInst<"vbfdot", "..BB", "fQf">;
def VDOT_LANE_BF : SOpInst<"vbfdot_lane", "..B(Bq)I", "fQf", OP_BFDOT_LN>;
def VDOT_LANEQ_BF : SOpInst<"vbfdot_laneq", "..B(BQ)I", "fQf", OP_BFDOT_LNQ> {
@@ -1975,7 +1971,7 @@ multiclass VCMLA_ROTS<string type, string lanety, string laneqty> {
}
// v8.3-A Vector complex addition intrinsics
-let ArchGuard = "defined(__ARM_FEATURE_COMPLEX) && defined(__ARM_FEATURE_FP16_VECTOR_ARITHMETIC)" in {
+let TargetGuard = "v8.3a,fullfp16" in {
def VCADD_ROT90_FP16 : SInst<"vcadd_rot90", "...", "h">;
def VCADD_ROT270_FP16 : SInst<"vcadd_rot270", "...", "h">;
def VCADDQ_ROT90_FP16 : SInst<"vcaddq_rot90", "QQQ", "h">;
@@ -1983,7 +1979,7 @@ let ArchGuard = "defined(__ARM_FEATURE_COMPLEX) && defined(__ARM_FEATURE_FP16_VE
defm VCMLA_FP16 : VCMLA_ROTS<"h", "uint32x2_t", "uint32x4_t">;
}
-let ArchGuard = "defined(__ARM_FEATURE_COMPLEX)" in {
+let TargetGuard = "v8.3a" in {
def VCADD_ROT90 : SInst<"vcadd_rot90", "...", "f">;
def VCADD_ROT270 : SInst<"vcadd_rot270", "...", "f">;
def VCADDQ_ROT90 : SInst<"vcaddq_rot90", "QQQ", "f">;
@@ -1991,7 +1987,7 @@ let ArchGuard = "defined(__ARM_FEATURE_COMPLEX)" in {
defm VCMLA_F32 : VCMLA_ROTS<"f", "uint64x1_t", "uint64x2_t">;
}
-let ArchGuard = "defined(__ARM_FEATURE_COMPLEX) && defined(__aarch64__)" in {
+let ArchGuard = "defined(__aarch64__)", TargetGuard = "v8.3a" in {
def VCADDQ_ROT90_FP64 : SInst<"vcaddq_rot90", "QQQ", "d">;
def VCADDQ_ROT270_FP64 : SInst<"vcaddq_rot270", "QQQ", "d">;
@@ -1999,7 +1995,7 @@ let ArchGuard = "defined(__ARM_FEATURE_COMPLEX) && defined(__aarch64__)" in {
}
// V8.2-A BFloat intrinsics
-let ArchGuard = "defined(__ARM_FEATURE_BF16_VECTOR_ARITHMETIC)" in {
+let TargetGuard = "bf16" in {
def VCREATE_BF : NoTestOpInst<"vcreate", ".(IU>)", "b", OP_CAST> {
let BigEndianSafe = 1;
}
@@ -2063,14 +2059,14 @@ let ArchGuard = "defined(__ARM_FEATURE_BF16_VECTOR_ARITHMETIC)" in {
def SCALAR_CVT_F32_BF16 : SOpInst<"vcvtah_f32", "(1F>)(1!)", "b", OP_CVT_F32_BF16>;
}
-let ArchGuard = "defined(__ARM_FEATURE_BF16_VECTOR_ARITHMETIC) && !defined(__aarch64__)" in {
+let ArchGuard = "!defined(__aarch64__)", TargetGuard = "bf16" in {
def VCVT_BF16_F32_A32_INTERNAL : WInst<"__a32_vcvt_bf16", "BQ", "f">;
def VCVT_BF16_F32_A32 : SOpInst<"vcvt_bf16", "BQ", "f", OP_VCVT_BF16_F32_A32>;
def VCVT_LOW_BF16_F32_A32 : SOpInst<"vcvt_low_bf16", "BQ", "Qf", OP_VCVT_BF16_F32_LO_A32>;
def VCVT_HIGH_BF16_F32_A32 : SOpInst<"vcvt_high_bf16", "BBQ", "Qf", OP_VCVT_BF16_F32_HI_A32>;
}
-let ArchGuard = "defined(__ARM_FEATURE_BF16_VECTOR_ARITHMETIC) && defined(__aarch64__)" in {
+let ArchGuard = "defined(__aarch64__)", TargetGuard = "bf16" in {
def VCVT_LOW_BF16_F32_A64_INTERNAL : WInst<"__a64_vcvtq_low_bf16", "BQ", "Hf">;
def VCVT_LOW_BF16_F32_A64 : SOpInst<"vcvt_low_bf16", "BQ", "Qf", OP_VCVT_BF16_F32_LO_A64>;
def VCVT_HIGH_BF16_F32_A64 : SInst<"vcvt_high_bf16", "BBQ", "Qf">;
@@ -2082,16 +2078,22 @@ let ArchGuard = "defined(__ARM_FEATURE_BF16_VECTOR_ARITHMETIC) && defined(__aarc
def COPYQ_LANEQ_BF16 : IOpInst<"vcopy_laneq", "..I.I", "Qb", OP_COPY_LN>;
}
-let ArchGuard = "defined(__ARM_FEATURE_BF16) && !defined(__aarch64__)" in {
+let ArchGuard = "!defined(__aarch64__)", TargetGuard = "bf16" in {
let BigEndianSafe = 1 in {
defm VREINTERPRET_BF : REINTERPRET_CROSS_TYPES<
"csilUcUsUiUlhfPcPsPlQcQsQiQlQUcQUsQUiQUlQhQfQPcQPsQPl", "bQb">;
}
}
-let ArchGuard = "defined(__ARM_FEATURE_BF16) && defined(__aarch64__)" in {
+let ArchGuard = "defined(__aarch64__)", TargetGuard = "bf16" in {
let BigEndianSafe = 1 in {
defm VVREINTERPRET_BF : REINTERPRET_CROSS_TYPES<
"csilUcUsUiUlhfdPcPsPlQcQsQiQlQUcQUsQUiQUlQhQfQdQPcQPsQPlQPk", "bQb">;
}
}
+
+// v8.9a/v9.4a LRCPC3 intrinsics
+let ArchGuard = "defined(__aarch64__)", TargetGuard = "rcpc3" in {
+ def VLDAP1_LANE : WInst<"vldap1_lane", ".(c*!).I", "QUlQlUlldQdPlQPl">;
+ def VSTL1_LANE : WInst<"vstl1_lane", "v*(.!)I", "QUlQlUlldQdPlQPl">;
+}
diff --git a/contrib/llvm-project/clang/include/clang/Basic/arm_neon_incl.td b/contrib/llvm-project/clang/include/clang/Basic/arm_neon_incl.td
index 60dbea627d58..4f969ac1c78a 100644
--- a/contrib/llvm-project/clang/include/clang/Basic/arm_neon_incl.td
+++ b/contrib/llvm-project/clang/include/clang/Basic/arm_neon_incl.td
@@ -265,6 +265,7 @@ class Inst <string n, string p, string t, Operation o> {
string Prototype = p;
string Types = t;
string ArchGuard = "";
+ string TargetGuard = "";
Operation Operation = o;
bit BigEndianSafe = 0;
diff --git a/contrib/llvm-project/clang/include/clang/Basic/arm_sme.td b/contrib/llvm-project/clang/include/clang/Basic/arm_sme.td
new file mode 100644
index 000000000000..2da0e8d2aba9
--- /dev/null
+++ b/contrib/llvm-project/clang/include/clang/Basic/arm_sme.td
@@ -0,0 +1,676 @@
+//===--- arm_sme.td - ARM SME compiler interface ------------------------===//
+//
+// 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 the TableGen definitions from which the ARM SME header
+// file will be generated. See:
+//
+// https://developer.arm.com/architectures/system-architectures/software-standards/acle
+//
+//===----------------------------------------------------------------------===//
+
+include "arm_sve_sme_incl.td"
+
+////////////////////////////////////////////////////////////////////////////////
+// Loads
+
+multiclass ZALoad<string n_suffix, string t, string i_prefix, list<ImmCheck> ch> {
+ let TargetGuard = "sme" in {
+ def NAME # _H : MInst<"svld1_hor_" # n_suffix, "vimPQ", t,
+ [IsLoad, IsOverloadNone, IsStreaming, IsInOutZA],
+ MemEltTyDefault, i_prefix # "_horiz", ch>;
+
+ def NAME # _H_VNUM : MInst<"svld1_hor_vnum_" # n_suffix, "vimPQl", t,
+ [IsLoad, IsOverloadNone, IsStreaming, IsInOutZA],
+ MemEltTyDefault, i_prefix # "_horiz", ch>;
+
+ def NAME # _V : MInst<"svld1_ver_" # n_suffix, "vimPQ", t,
+ [IsLoad, IsOverloadNone, IsStreaming, IsInOutZA],
+ MemEltTyDefault, i_prefix # "_vert", ch>;
+
+ def NAME # _V_VNUM : MInst<"svld1_ver_vnum_" # n_suffix, "vimPQl", t,
+ [IsLoad, IsOverloadNone, IsStreaming, IsInOutZA],
+ MemEltTyDefault, i_prefix # "_vert", ch>;
+ }
+}
+
+defm SVLD1_ZA8 : ZALoad<"za8", "c", "aarch64_sme_ld1b", [ImmCheck<0, ImmCheck0_0>]>;
+defm SVLD1_ZA16 : ZALoad<"za16", "s", "aarch64_sme_ld1h", [ImmCheck<0, ImmCheck0_1>]>;
+defm SVLD1_ZA32 : ZALoad<"za32", "i", "aarch64_sme_ld1w", [ImmCheck<0, ImmCheck0_3>]>;
+defm SVLD1_ZA64 : ZALoad<"za64", "l", "aarch64_sme_ld1d", [ImmCheck<0, ImmCheck0_7>]>;
+defm SVLD1_ZA128 : ZALoad<"za128", "q", "aarch64_sme_ld1q", [ImmCheck<0, ImmCheck0_15>]>;
+
+let TargetGuard = "sme" in {
+def SVLDR_VNUM_ZA : MInst<"svldr_vnum_za", "vmQl", "",
+ [IsOverloadNone, IsStreamingCompatible, IsInOutZA],
+ MemEltTyDefault, "aarch64_sme_ldr">;
+
+def SVLDR_ZA : MInst<"svldr_za", "vmQ", "",
+ [IsOverloadNone, IsStreamingCompatible, IsInOutZA],
+ MemEltTyDefault, "aarch64_sme_ldr", []>;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// Stores
+
+multiclass ZAStore<string n_suffix, string t, string i_prefix, list<ImmCheck> ch> {
+ let TargetGuard = "sme" in {
+ def NAME # _H : MInst<"svst1_hor_" # n_suffix, "vimP%", t,
+ [IsStore, IsOverloadNone, IsStreaming, IsInZA],
+ MemEltTyDefault, i_prefix # "_horiz", ch>;
+
+ def NAME # _H_VNUM : MInst<"svst1_hor_vnum_" # n_suffix, "vimP%l", t,
+ [IsStore, IsOverloadNone, IsStreaming, IsInZA],
+ MemEltTyDefault, i_prefix # "_horiz", ch>;
+
+ def NAME # _V : MInst<"svst1_ver_" # n_suffix, "vimP%", t,
+ [IsStore, IsOverloadNone, IsStreaming, IsInZA],
+ MemEltTyDefault, i_prefix # "_vert", ch>;
+
+ def NAME # _V_VNUM : MInst<"svst1_ver_vnum_" # n_suffix, "vimP%l", t,
+ [IsStore, IsOverloadNone, IsStreaming, IsInZA],
+ MemEltTyDefault, i_prefix # "_vert", ch>;
+ }
+}
+
+defm SVST1_ZA8 : ZAStore<"za8", "c", "aarch64_sme_st1b", [ImmCheck<0, ImmCheck0_0>]>;
+defm SVST1_ZA16 : ZAStore<"za16", "s", "aarch64_sme_st1h", [ImmCheck<0, ImmCheck0_1>]>;
+defm SVST1_ZA32 : ZAStore<"za32", "i", "aarch64_sme_st1w", [ImmCheck<0, ImmCheck0_3>]>;
+defm SVST1_ZA64 : ZAStore<"za64", "l", "aarch64_sme_st1d", [ImmCheck<0, ImmCheck0_7>]>;
+defm SVST1_ZA128 : ZAStore<"za128", "q", "aarch64_sme_st1q", [ImmCheck<0, ImmCheck0_15>]>;
+
+let TargetGuard = "sme" in {
+def SVSTR_VNUM_ZA : MInst<"svstr_vnum_za", "vm%l", "",
+ [IsOverloadNone, IsStreamingCompatible, IsInZA],
+ MemEltTyDefault, "aarch64_sme_str">;
+
+def SVSTR_ZA : MInst<"svstr_za", "vm%", "",
+ [IsOverloadNone, IsStreamingCompatible, IsInZA],
+ MemEltTyDefault, "aarch64_sme_str", []>;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// Read horizontal/vertical ZA slices
+
+multiclass ZARead<string n_suffix, string t, string i_prefix, list<ImmCheck> ch> {
+ let TargetGuard = "sme" in {
+ def NAME # _H : SInst<"svread_hor_" # n_suffix # "[_{d}]", "ddPim", t,
+ MergeOp1, i_prefix # "_horiz",
+ [IsReadZA, IsStreaming, IsInZA], ch>;
+
+ def NAME # _V : SInst<"svread_ver_" # n_suffix # "[_{d}]", "ddPim", t,
+ MergeOp1, i_prefix # "_vert",
+ [IsReadZA, IsStreaming, IsInZA], ch>;
+ }
+}
+
+defm SVREAD_ZA8 : ZARead<"za8", "cUc", "aarch64_sme_read", [ImmCheck<2, ImmCheck0_0>]>;
+defm SVREAD_ZA16 : ZARead<"za16", "sUshb", "aarch64_sme_read", [ImmCheck<2, ImmCheck0_1>]>;
+defm SVREAD_ZA32 : ZARead<"za32", "iUif", "aarch64_sme_read", [ImmCheck<2, ImmCheck0_3>]>;
+defm SVREAD_ZA64 : ZARead<"za64", "lUld", "aarch64_sme_read", [ImmCheck<2, ImmCheck0_7>]>;
+defm SVREAD_ZA128 : ZARead<"za128", "csilUcUsUiUlhbfd", "aarch64_sme_readq", [ImmCheck<2, ImmCheck0_15>]>;
+
+////////////////////////////////////////////////////////////////////////////////
+// Write horizontal/vertical ZA slices
+
+multiclass ZAWrite<string n_suffix, string t, string i_prefix, list<ImmCheck> ch> {
+ let TargetGuard = "sme" in {
+ def NAME # _H : SInst<"svwrite_hor_" # n_suffix # "[_{d}]", "vimPd", t,
+ MergeOp1, i_prefix # "_horiz",
+ [IsWriteZA, IsStreaming, IsInOutZA], ch>;
+
+ def NAME # _V : SInst<"svwrite_ver_" # n_suffix # "[_{d}]", "vimPd", t,
+ MergeOp1, i_prefix # "_vert",
+ [IsWriteZA, IsStreaming, IsInOutZA], ch>;
+ }
+}
+
+defm SVWRITE_ZA8 : ZAWrite<"za8", "cUc", "aarch64_sme_write", [ImmCheck<0, ImmCheck0_0>]>;
+defm SVWRITE_ZA16 : ZAWrite<"za16", "sUshb", "aarch64_sme_write", [ImmCheck<0, ImmCheck0_1>]>;
+defm SVWRITE_ZA32 : ZAWrite<"za32", "iUif", "aarch64_sme_write", [ImmCheck<0, ImmCheck0_3>]>;
+defm SVWRITE_ZA64 : ZAWrite<"za64", "lUld", "aarch64_sme_write", [ImmCheck<0, ImmCheck0_7>]>;
+defm SVWRITE_ZA128 : ZAWrite<"za128", "csilUcUsUiUlhbfd", "aarch64_sme_writeq", [ImmCheck<0, ImmCheck0_15>]>;
+
+////////////////////////////////////////////////////////////////////////////////
+// SME - Zero
+
+let TargetGuard = "sme" in {
+ def SVZERO_MASK_ZA : SInst<"svzero_mask_za", "vi", "", MergeNone, "aarch64_sme_zero",
+ [IsOverloadNone, IsStreamingCompatible, IsInOutZA],
+ [ImmCheck<0, ImmCheck0_255>]>;
+ def SVZERO_ZA : SInst<"svzero_za", "v", "", MergeNone, "aarch64_sme_zero",
+ [IsOverloadNone, IsStreamingCompatible, IsOutZA]>;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// SME - Counting elements in a streaming vector
+
+multiclass ZACount<string n_suffix> {
+ let TargetGuard = "sme" in {
+ def NAME : SInst<"sv" # n_suffix, "nv", "", MergeNone,
+ "aarch64_sme_" # n_suffix,
+ [IsOverloadNone, IsStreamingCompatible]>;
+ }
+}
+
+defm SVCNTSB : ZACount<"cntsb">;
+defm SVCNTSH : ZACount<"cntsh">;
+defm SVCNTSW : ZACount<"cntsw">;
+defm SVCNTSD : ZACount<"cntsd">;
+
+////////////////////////////////////////////////////////////////////////////////
+// SME - ADDHA/ADDVA
+
+multiclass ZAAdd<string n_suffix> {
+ let TargetGuard = "sme" in {
+ def NAME # _ZA32: SInst<"sv" # n_suffix # "_za32[_{d}]", "viPPd", "iUi", MergeOp1,
+ "aarch64_sme_" # n_suffix, [IsStreaming, IsInOutZA],
+ [ImmCheck<0, ImmCheck0_3>]>;
+ }
+
+ let TargetGuard = "sme-i16i64" in {
+ def NAME # _ZA64: SInst<"sv" # n_suffix # "_za64[_{d}]", "viPPd", "lUl", MergeOp1,
+ "aarch64_sme_" # n_suffix, [IsStreaming, IsInOutZA],
+ [ImmCheck<0, ImmCheck0_7>]>;
+ }
+}
+
+defm SVADDHA : ZAAdd<"addha">;
+defm SVADDVA : ZAAdd<"addva">;
+
+////////////////////////////////////////////////////////////////////////////////
+// SME - SMOPA, SMOPS, UMOPA, UMOPS
+
+multiclass ZAIntOuterProd<string n_suffix1, string n_suffix2> {
+ let TargetGuard = "sme" in {
+ def NAME # _ZA32_B: SInst<"sv" # n_suffix2 # "_za32[_{d}]",
+ "viPPdd", !cond(!eq(n_suffix1, "s") : "", true: "U") # "c",
+ MergeOp1, "aarch64_sme_" # n_suffix1 # n_suffix2 # "_wide",
+ [IsStreaming, IsInOutZA],
+ [ImmCheck<0, ImmCheck0_3>]>;
+ }
+
+ let TargetGuard = "sme-i16i64" in {
+ def NAME # _ZA64_H: SInst<"sv" # n_suffix2 # "_za64[_{d}]",
+ "viPPdd", !cond(!eq(n_suffix1, "s") : "", true: "U") # "s",
+ MergeOp1, "aarch64_sme_" # n_suffix1 # n_suffix2 # "_wide",
+ [IsStreaming, IsInOutZA],
+ [ImmCheck<0, ImmCheck0_7>]>;
+ }
+}
+
+defm SVSMOPA : ZAIntOuterProd<"s", "mopa">;
+defm SVSMOPS : ZAIntOuterProd<"s", "mops">;
+defm SVUMOPA : ZAIntOuterProd<"u", "mopa">;
+defm SVUMOPS : ZAIntOuterProd<"u", "mops">;
+
+////////////////////////////////////////////////////////////////////////////////
+// SME - SUMOPA, SUMOPS, USMOPA, USMOPS
+
+multiclass ZAIntOuterProdMixedSigns<string n_suffix1, string n_suffix2> {
+ let TargetGuard = "sme" in {
+ def NAME # _ZA32_B: SInst<"sv" # n_suffix1 # n_suffix2 # "_za32[_{d}]",
+ "viPPd" # !cond(!eq(n_suffix1, "su") : "u", true: "x"),
+ !cond(!eq(n_suffix1, "su") : "", true: "U") # "c",
+ MergeOp1, "aarch64_sme_" # n_suffix1 # n_suffix2 # "_wide",
+ [IsStreaming, IsInOutZA],
+ [ImmCheck<0, ImmCheck0_3>]>;
+ }
+
+ let TargetGuard = "sme-i16i64" in {
+ def NAME # _ZA64_H: SInst<"sv" # n_suffix1 # n_suffix2 # "_za64[_{d}]",
+ "viPPd" # !cond(!eq(n_suffix1, "su") : "u", true: "x"),
+ !cond(!eq(n_suffix1, "su") : "", true: "U") # "s",
+ MergeOp1, "aarch64_sme_" # n_suffix1 # n_suffix2 # "_wide",
+ [IsStreaming, IsInOutZA],
+ [ImmCheck<0, ImmCheck0_7>]>;
+ }
+}
+
+defm SVSUMOPA : ZAIntOuterProdMixedSigns<"su", "mopa">;
+defm SVSUMOPS : ZAIntOuterProdMixedSigns<"su", "mops">;
+defm SVUSMOPA : ZAIntOuterProdMixedSigns<"us", "mopa">;
+defm SVUSMOPS : ZAIntOuterProdMixedSigns<"us", "mops">;
+
+////////////////////////////////////////////////////////////////////////////////
+// SME - FMOPA, FMOPS
+
+multiclass ZAFPOuterProd<string n_suffix> {
+ let TargetGuard = "sme" in {
+ def NAME # _ZA32_B: SInst<"sv" # n_suffix # "_za32[_{d}]", "viPPdd", "h",
+ MergeOp1, "aarch64_sme_" # n_suffix # "_wide",
+ [IsStreaming, IsInOutZA],
+ [ImmCheck<0, ImmCheck0_3>]>;
+
+ def NAME # _ZA32_H: SInst<"sv" # n_suffix # "_za32[_{d}]", "viPPdd", "b",
+ MergeOp1, "aarch64_sme_" # n_suffix # "_wide",
+ [IsStreaming, IsInOutZA],
+ [ImmCheck<0, ImmCheck0_3>]>;
+
+ def NAME # _ZA32_S: SInst<"sv" # n_suffix # "_za32[_{d}]", "viPPdd", "f",
+ MergeOp1, "aarch64_sme_" # n_suffix,
+ [IsStreaming, IsInOutZA],
+ [ImmCheck<0, ImmCheck0_3>]>;
+ }
+
+ let TargetGuard = "sme-f64f64" in {
+ def NAME # _ZA64_D: SInst<"sv" # n_suffix # "_za64[_{d}]", "viPPdd", "d",
+ MergeOp1, "aarch64_sme_" # n_suffix,
+ [IsStreaming, IsInOutZA],
+ [ImmCheck<0, ImmCheck0_7>]>;
+ }
+}
+
+defm SVMOPA : ZAFPOuterProd<"mopa">;
+defm SVMOPS : ZAFPOuterProd<"mops">;
+
+////////////////////////////////////////////////////////////////////////////////
+// SME2 - ADD, SUB
+
+multiclass ZAAddSub<string n_suffix> {
+ let TargetGuard = "sme2" in {
+ def NAME # _WRITE_SINGLE_ZA32_VG1X2_I32 : Inst<"sv" # n_suffix # "_write[_single]_za32[_{d}]_vg1x2", "vm2d", "iUi", MergeNone, "aarch64_sme_" # n_suffix # "_write_single_za_vg1x2", [IsStreaming, IsInOutZA], []>;
+ def NAME # _WRITE_SINGLE_ZA32_VG1X4_I32 : Inst<"sv" # n_suffix # "_write[_single]_za32[_{d}]_vg1x4", "vm4d", "iUi", MergeNone, "aarch64_sme_" # n_suffix # "_write_single_za_vg1x4", [IsStreaming, IsInOutZA], []>;
+
+ def NAME # _WRITE_ZA32_VG1X2_I32 : Inst<"sv" # n_suffix # "_write_za32[_{d}]_vg1x2", "vm22", "iUi", MergeNone, "aarch64_sme_" # n_suffix # "_write_za_vg1x2", [IsStreaming, IsInOutZA], []>;
+ def NAME # _WRITE_ZA32_VG1X4_I32 : Inst<"sv" # n_suffix # "_write_za32[_{d}]_vg1x4", "vm44", "iUi", MergeNone, "aarch64_sme_" # n_suffix # "_write_za_vg1x4", [IsStreaming, IsInOutZA], []>;
+
+ def NAME # _ZA32_VG1x2_I32 : Inst<"sv" # n_suffix # "_za32[_{d}]_vg1x2", "vm2", "iUif", MergeNone, "aarch64_sme_" # n_suffix # "_za32_vg1x2", [IsStreaming, IsInOutZA], []>;
+ def NAME # _ZA32_VG1X4_I32 : Inst<"sv" # n_suffix # "_za32[_{d}]_vg1x4", "vm4", "iUif", MergeNone, "aarch64_sme_" # n_suffix # "_za32_vg1x4", [IsStreaming, IsInOutZA], []>;
+ }
+
+ let TargetGuard = "sme2,sme-i16i64" in {
+ def NAME # _WRITE_SINGLE_ZA64_VG1X2_I64 : Inst<"sv" # n_suffix # "_write[_single]_za64[_{d}]_vg1x2", "vm2d", "lUl", MergeNone, "aarch64_sme_" # n_suffix # "_write_single_za_vg1x2", [IsStreaming, IsInOutZA], []>;
+ def NAME # _WRITE_SINGLE_ZA64_VG1X4_I64 : Inst<"sv" # n_suffix # "_write[_single]_za64[_{d}]_vg1x4", "vm4d", "lUl", MergeNone, "aarch64_sme_" # n_suffix # "_write_single_za_vg1x4", [IsStreaming, IsInOutZA], []>;
+
+ def NAME # _WRITE_ZA64_VG1x2_I64 : Inst<"sv" # n_suffix # "_write_za64[_{d}]_vg1x2", "vm22", "lUl", MergeNone, "aarch64_sme_" # n_suffix # "_write_za_vg1x2", [IsStreaming, IsInOutZA], []>;
+ def NAME # _WRITE_ZA64_VG1x4_I64 : Inst<"sv" # n_suffix # "_write_za64[_{d}]_vg1x4", "vm44", "lUl", MergeNone, "aarch64_sme_" # n_suffix # "_write_za_vg1x4", [IsStreaming, IsInOutZA], []>;
+
+ def NAME # _ZA64_VG1X2_I64 : Inst<"sv" # n_suffix # "_za64[_{d}]_vg1x2", "vm2", "lUl", MergeNone, "aarch64_sme_" # n_suffix # "_za64_vg1x2", [IsStreaming, IsInOutZA], []>;
+ def NAME # _ZA64_VG1X4_I64 : Inst<"sv" # n_suffix # "_za64[_{d}]_vg1x4", "vm4", "lUl", MergeNone, "aarch64_sme_" # n_suffix # "_za64_vg1x4", [IsStreaming, IsInOutZA], []>;
+ }
+
+ let TargetGuard = "sme2,sme-f64f64" in {
+ def NAME # _ZA64_VG1X2_F64 : Inst<"sv" # n_suffix # "_za64[_{d}]_vg1x2", "vm2", "d", MergeNone, "aarch64_sme_" # n_suffix # "_za64_vg1x2", [IsStreaming, IsInOutZA], []>;
+ def NAME # _ZA64_VG1X4_F64 : Inst<"sv" # n_suffix # "_za64[_{d}]_vg1x4", "vm4", "d", MergeNone, "aarch64_sme_" # n_suffix # "_za64_vg1x4", [IsStreaming, IsInOutZA], []>;
+ }
+}
+
+defm SVADD : ZAAddSub<"add">;
+defm SVSUB : ZAAddSub<"sub">;
+
+// SME2 - MOVA
+
+//
+// Single, 2 and 4 vector-group read/write intrinsics.
+//
+
+multiclass ZAWrite_VG<string n, string t, string i, list<ImmCheck> checks> {
+ def NAME # _VG2_H : Inst<"svwrite_hor_" # n # "[_{d}]_vg2", "vim2", t, MergeNone, i # "_hor_vg2", [IsInOutZA, IsStreaming], checks>;
+ def NAME # _VG2_V : Inst<"svwrite_ver_" # n # "[_{d}]_vg2", "vim2", t, MergeNone, i # "_ver_vg2", [IsInOutZA, IsStreaming], checks>;
+ def NAME # _VG4_H : Inst<"svwrite_hor_" # n # "[_{d}]_vg4", "vim4", t, MergeNone, i # "_hor_vg4", [IsInOutZA, IsStreaming], checks>;
+ def NAME # _VG4_V : Inst<"svwrite_ver_" # n # "[_{d}]_vg4", "vim4", t, MergeNone, i # "_ver_vg4", [IsInOutZA, IsStreaming], checks>;
+ def NAME # _VG1x2 : Inst<"svwrite_" # n # "[_{d}]_vg1x2", "vm2", t, MergeNone, i # "_vg1x2", [IsInOutZA, IsStreaming], []>;
+ def NAME # _VG1x4 : Inst<"svwrite_" # n # "[_{d}]_vg1x4", "vm4", t, MergeNone, i # "_vg1x4", [IsInOutZA, IsStreaming], []>;
+}
+
+let TargetGuard = "sme2" in {
+ defm SVWRITE_ZA8 : ZAWrite_VG<"za8", "cUc", "aarch64_sme_write", [ImmCheck<0, ImmCheck0_0>]>;
+ defm SVWRITE_ZA16 : ZAWrite_VG<"za16", "sUshb", "aarch64_sme_write", [ImmCheck<0, ImmCheck0_1>]>;
+ defm SVWRITE_ZA32 : ZAWrite_VG<"za32", "iUif", "aarch64_sme_write", [ImmCheck<0, ImmCheck0_3>]>;
+ defm SVWRITE_ZA64 : ZAWrite_VG<"za64", "lUld", "aarch64_sme_write", [ImmCheck<0, ImmCheck0_7>]>;
+}
+
+multiclass ZARead_VG<string n, string t, string i, list<ImmCheck> checks> {
+ def NAME # _VG2_H : Inst<"svread_hor_" # n # "_{d}_vg2", "2im", t, MergeNone, i # "_hor_vg2", [IsInZA, IsStreaming], checks>;
+ def NAME # _VG2_V : Inst<"svread_ver_" # n # "_{d}_vg2", "2im", t, MergeNone, i # "_ver_vg2", [IsInZA, IsStreaming], checks>;
+ def NAME # _VG4_H : Inst<"svread_hor_" # n # "_{d}_vg4", "4im", t, MergeNone, i # "_hor_vg4", [IsInZA, IsStreaming], checks>;
+ def NAME # _VG4_V : Inst<"svread_ver_" # n # "_{d}_vg4", "4im", t, MergeNone, i # "_ver_vg4", [IsInZA, IsStreaming], checks>;
+ def NAME # _VG1x2 : Inst<"svread_" # n # "_{d}_vg1x2", "2m", t, MergeNone, i # "_vg1x2", [IsInZA, IsStreaming], []>;
+ def NAME # _VG1x4 : Inst<"svread_" # n # "_{d}_vg1x4", "4m", t, MergeNone, i # "_vg1x4", [IsInZA, IsStreaming], []>;
+}
+
+let TargetGuard = "sme2" in {
+ defm SVREAD_ZA8 : ZARead_VG<"za8", "cUc", "aarch64_sme_read", [ImmCheck<0, ImmCheck0_0>]>;
+ defm SVREAD_ZA16 : ZARead_VG<"za16", "sUshb", "aarch64_sme_read", [ImmCheck<0, ImmCheck0_1>]>;
+ defm SVREAD_ZA32 : ZARead_VG<"za32", "iUif", "aarch64_sme_read", [ImmCheck<0, ImmCheck0_3>]>;
+ defm SVREAD_ZA64 : ZARead_VG<"za64", "lUld", "aarch64_sme_read", [ImmCheck<0, ImmCheck0_7>]>;
+}
+
+//
+// Outer product and accumulate/subtract
+//
+
+let TargetGuard = "sme2" in {
+ def SVSMOPA : Inst<"svmopa_za32[_{d}]_m", "viPPdd", "s", MergeNone, "aarch64_sme_smopa_za32", [IsInOutZA, IsStreaming], [ImmCheck<0, ImmCheck0_3>]>;
+ def SVUSMOPA : Inst<"svmopa_za32[_{d}]_m", "viPPdd", "Us", MergeNone, "aarch64_sme_umopa_za32", [IsInOutZA, IsStreaming], [ImmCheck<0, ImmCheck0_3>]>;
+
+ def SVSMOPS : Inst<"svmops_za32[_{d}]_m", "viPPdd", "s", MergeNone, "aarch64_sme_smops_za32", [IsInOutZA, IsStreaming], [ImmCheck<0, ImmCheck0_3>]>;
+ def SVUSMOPS : Inst<"svmops_za32[_{d}]_m", "viPPdd", "Us", MergeNone, "aarch64_sme_umops_za32", [IsInOutZA, IsStreaming], [ImmCheck<0, ImmCheck0_3>]>;
+
+ def SVBMOPA : Inst<"svbmopa_za32[_{d}]_m", "viPPdd", "iUi", MergeNone, "aarch64_sme_bmopa_za32", [IsInOutZA, IsStreaming], [ImmCheck<0, ImmCheck0_3>]>;
+
+ def SVBMOPS : Inst<"svbmops_za32[_{d}]_m", "viPPdd", "iUi", MergeNone, "aarch64_sme_bmops_za32", [IsInOutZA, IsStreaming], [ImmCheck<0, ImmCheck0_3>]>;
+
+ // VERTICAL DOT-PRODUCT
+ def SVVDOT_LANE_ZA32_VG1x2_S : Inst<"svvdot_lane_za32[_{d}]_vg1x2", "vm2di", "s", MergeNone, "aarch64_sme_svdot_lane_za32_vg1x2", [IsStreaming, IsInOutZA], [ImmCheck<3, ImmCheck0_3>]>;
+ def SVVDOT_LANE_ZA32_VG1x4_S : Inst<"svvdot_lane_za32[_{d}]_vg1x4", "vm4di", "c", MergeNone, "aarch64_sme_svdot_lane_za32_vg1x4", [IsStreaming, IsInOutZA], [ImmCheck<3, ImmCheck0_3>]>;
+ def SVVDOT_LANE_ZA32_VG1x2_U : Inst<"svvdot_lane_za32[_{d}]_vg1x2", "vm2di", "Us", MergeNone, "aarch64_sme_uvdot_lane_za32_vg1x2", [IsStreaming, IsInOutZA], [ImmCheck<3, ImmCheck0_3>]>;
+ def SVVDOT_LANE_ZA32_VG1x4_U : Inst<"svvdot_lane_za32[_{d}]_vg1x4", "vm4di", "Uc", MergeNone, "aarch64_sme_uvdot_lane_za32_vg1x4", [IsStreaming, IsInOutZA], [ImmCheck<3, ImmCheck0_3>]>;
+ def SVVDOT_LANE_ZA32_VG1x2_F : Inst<"svvdot_lane_za32[_{d}]_vg1x2", "vm2di", "hb", MergeNone, "aarch64_sme_fvdot_lane_za32_vg1x2", [IsStreaming, IsInOutZA], [ImmCheck<3, ImmCheck0_3>]>;
+ def SVSUVDOT_LANE_ZA32_VG1x4 : Inst<"svsuvdot_lane_za32[_{d}]_vg1x4", "vm4di", "c", MergeNone, "aarch64_sme_suvdot_lane_za32_vg1x4", [IsStreaming, IsInOutZA], [ImmCheck<3, ImmCheck0_3>]>;
+ def SVUSVDOT_LANE_ZA32_VG1x4 : Inst<"svusvdot_lane_za32[_{d}]_vg1x4", "vm4di", "Uc", MergeNone, "aarch64_sme_usvdot_lane_za32_vg1x4", [IsStreaming, IsInOutZA], [ImmCheck<3, ImmCheck0_3>]>;
+
+ // Multi-vector signed & unsigned integer dot-product
+ def SVDOT_MULTI_ZA32_VG1x2_S : Inst<"svdot_za32[_{d}]_vg1x2", "vm22", "cs", MergeNone, "aarch64_sme_sdot_za32_vg1x2", [IsStreaming, IsInOutZA], []>;
+ def SVDOT_MULTI_ZA32_VG1x4_S : Inst<"svdot_za32[_{d}]_vg1x4", "vm44", "cs", MergeNone, "aarch64_sme_sdot_za32_vg1x4", [IsStreaming, IsInOutZA], []>;
+ def SVDOT_MULTI_ZA32_VG1x2_U : Inst<"svdot_za32[_{d}]_vg1x2", "vm22", "UcUs", MergeNone, "aarch64_sme_udot_za32_vg1x2", [IsStreaming, IsInOutZA], []>;
+ def SVDOT_MULTI_ZA32_VG1x4_U : Inst<"svdot_za32[_{d}]_vg1x4", "vm44", "UcUs", MergeNone, "aarch64_sme_udot_za32_vg1x4", [IsStreaming, IsInOutZA], []>;
+ def SVDOT_SINGLE_ZA32_VG1x2_S : Inst<"svdot[_single]_za32[_{d}]_vg1x2", "vm2d", "cs", MergeNone, "aarch64_sme_sdot_single_za32_vg1x2", [IsStreaming, IsInOutZA], []>;
+ def SVDOT_SINGLE_ZA32_VG1x4_S : Inst<"svdot[_single]_za32[_{d}]_vg1x4", "vm4d", "cs", MergeNone, "aarch64_sme_sdot_single_za32_vg1x4", [IsStreaming, IsInOutZA], []>;
+ def SVDOT_SINGLE_ZA32_VG1x2_U : Inst<"svdot[_single]_za32[_{d}]_vg1x2", "vm2d", "UcUs", MergeNone, "aarch64_sme_udot_single_za32_vg1x2", [IsStreaming, IsInOutZA], []>;
+ def SVDOT_SINGLE_ZA32_VG1x4_U : Inst<"svdot[_single]_za32[_{d}]_vg1x4", "vm4d", "UcUs", MergeNone, "aarch64_sme_udot_single_za32_vg1x4", [IsStreaming, IsInOutZA], []>;
+ def SVDOT_LANE_ZA32_VG1x2_S : Inst<"svdot_lane_za32[_{d}]_vg1x2", "vm2di", "cs", MergeNone, "aarch64_sme_sdot_lane_za32_vg1x2", [IsStreaming, IsInOutZA], [ImmCheck<3, ImmCheck0_3>]>;
+ def SVDOT_LANE_ZA32_VG1x4_S : Inst<"svdot_lane_za32[_{d}]_vg1x4", "vm4di", "cs", MergeNone, "aarch64_sme_sdot_lane_za32_vg1x4", [IsStreaming, IsInOutZA], [ImmCheck<3, ImmCheck0_3>]>;
+ def SVDOT_LANE_ZA32_VG1x2_U : Inst<"svdot_lane_za32[_{d}]_vg1x2", "vm2di", "UcUs", MergeNone, "aarch64_sme_udot_lane_za32_vg1x2", [IsStreaming, IsInOutZA], [ImmCheck<3, ImmCheck0_3>]>;
+ def SVDOT_LANE_ZA32_VG1x4_U : Inst<"svdot_lane_za32[_{d}]_vg1x4", "vm4di", "UcUs", MergeNone, "aarch64_sme_udot_lane_za32_vg1x4", [IsStreaming, IsInOutZA], [ImmCheck<3, ImmCheck0_3>]>;
+
+ def SVUSDOT_SINGLE_ZA32_VG1x2 : Inst<"svusdot[_single]_za32[_{d}]_vg1x2", "vm2.dx", "Uc", MergeNone, "aarch64_sme_usdot_single_za32_vg1x2", [IsStreaming, IsInOutZA], []>;
+ def SVUSDOT_SINGLE_ZA32_VG1x4 : Inst<"svusdot[_single]_za32[_{d}]_vg1x4", "vm4.dx", "Uc", MergeNone, "aarch64_sme_usdot_single_za32_vg1x4", [IsStreaming, IsInOutZA], []>;
+ def SVUSDOT_MULTI_ZA32_VG1x2 : Inst<"svusdot_za32[_{d}]_vg1x2", "vm2.d2.x", "Uc", MergeNone, "aarch64_sme_usdot_za32_vg1x2", [IsStreaming, IsInOutZA], []>;
+ def SVUSDOT_MULTI_ZA32_VG1x4 : Inst<"svusdot_za32[_{d}]_vg1x4", "vm4.d4.x", "Uc", MergeNone, "aarch64_sme_usdot_za32_vg1x4", [IsStreaming, IsInOutZA], []>;
+ def SVUSDOT_LANE_ZA32_VG1x2 : Inst<"svusdot_lane_za32[_{d}]_vg1x2", "vm2.dxi", "Uc", MergeNone, "aarch64_sme_usdot_lane_za32_vg1x2", [IsStreaming, IsInOutZA], [ImmCheck<3, ImmCheck0_3>]>;
+ def SVUSDOT_LANE_ZA32_VG1x4 : Inst<"svusdot_lane_za32[_{d}]_vg1x4", "vm4.dxi", "Uc", MergeNone, "aarch64_sme_usdot_lane_za32_vg1x4", [IsStreaming, IsInOutZA], [ImmCheck<3, ImmCheck0_3>]>;
+
+ def SVSUDOT_SINGLE_ZA32_VG1x2 : Inst<"svsudot[_single]_za32[_{d}]_vg1x2", "vm2.du", "c", MergeNone, "aarch64_sme_sudot_single_za32_vg1x2", [IsStreaming, IsInOutZA], []>;
+ def SVSUDOT_SINGLE_ZA32_VG1x4 : Inst<"svsudot[_single]_za32[_{d}]_vg1x4", "vm4.du", "c", MergeNone, "aarch64_sme_sudot_single_za32_vg1x4", [IsStreaming, IsInOutZA], []>;
+
+ // Multi-multi sudot builtins are mapped to usdot, with zn & zm operands swapped
+ def SVSUDOT_MULTI_ZA32_VG1x2 : Inst<"svsudot_za32[_{d}]_vg1x2", "vm2.d2.u", "c", MergeNone, "aarch64_sme_usdot_za32_vg1x2", [IsStreaming, IsInOutZA], []>;
+ def SVSUDOT_MULTI_ZA32_VG1x4 : Inst<"svsudot_za32[_{d}]_vg1x4", "vm4.d4.u", "c", MergeNone, "aarch64_sme_usdot_za32_vg1x4", [IsStreaming, IsInOutZA], []>;
+
+ def SVSUDOT_LANE_ZA32_VG1x2 : Inst<"svsudot_lane_za32[_{d}]_vg1x2", "vm2.dui", "c", MergeNone, "aarch64_sme_sudot_lane_za32_vg1x2", [IsStreaming, IsInOutZA], [ImmCheck<3, ImmCheck0_3>]>;
+ def SVSUDOT_LANE_ZA32_VG1x4 : Inst<"svsudot_lane_za32[_{d}]_vg1x4", "vm4.dui", "c", MergeNone, "aarch64_sme_sudot_lane_za32_vg1x4", [IsStreaming, IsInOutZA], [ImmCheck<3, ImmCheck0_3>]>;
+
+ // Multi-vector half-precision/BFloat16 floating-point dot-product
+ def SVDOT_MULTI_ZA32_VG1x2_F16 : Inst<"svdot_za32[_{d}]_vg1x2", "vm22", "bh", MergeNone, "aarch64_sme_fdot_za32_vg1x2", [IsStreaming, IsInOutZA], []>;
+ def SVDOT_MULTI_ZA32_VG1x4_F16 : Inst<"svdot_za32[_{d}]_vg1x4", "vm44", "bh", MergeNone, "aarch64_sme_fdot_za32_vg1x4", [IsStreaming, IsInOutZA], []>;
+ def SVDOT_SINGLE_ZA32_VG1x2_F16 : Inst<"svdot[_single]_za32[_{d}]_vg1x2", "vm2d", "bh", MergeNone, "aarch64_sme_fdot_single_za32_vg1x2", [IsStreaming, IsInOutZA], []>;
+ def SVDOT_SINGLE_ZA32_VG1x4_F16 : Inst<"svdot[_single]_za32[_{d}]_vg1x4", "vm4d", "bh", MergeNone, "aarch64_sme_fdot_single_za32_vg1x4", [IsStreaming, IsInOutZA], []>;
+ def SVDOT_LANE_ZA32_VG1x2_F16 : Inst<"svdot_lane_za32[_{d}]_vg1x2", "vm2di", "bh", MergeNone, "aarch64_sme_fdot_lane_za32_vg1x2", [IsStreaming, IsInOutZA], [ImmCheck<3, ImmCheck0_3>]>;
+ def SVDOT_LANE_ZA32_VG1x4_F16 : Inst<"svdot_lane_za32[_{d}]_vg1x4", "vm4di", "bh", MergeNone, "aarch64_sme_fdot_lane_za32_vg1x4", [IsStreaming, IsInOutZA], [ImmCheck<3, ImmCheck0_3>]>;
+}
+
+let TargetGuard = "sme2,sme-i16i64" in {
+ def SVVDOT_LANE_ZA64_VG1x4_S : Inst<"svvdot_lane_za64[_{d}]_vg1x4", "vm4di", "s", MergeNone, "aarch64_sme_svdot_lane_za64_vg1x4", [IsStreaming, IsInOutZA], [ImmCheck<3, ImmCheck0_1>]>;
+ def SVVDOT_LANE_ZA64_VG1x4_U : Inst<"svvdot_lane_za64[_{d}]_vg1x4", "vm4di", "Us", MergeNone, "aarch64_sme_uvdot_lane_za64_vg1x4", [IsStreaming, IsInOutZA], [ImmCheck<3, ImmCheck0_1>]>;
+
+ def SVDOT_MULTI_ZA64_VG1x2_S16 : Inst<"svdot_za64[_{d}]_vg1x2", "vm22", "s", MergeNone, "aarch64_sme_sdot_za64_vg1x2", [IsStreaming, IsInOutZA], []>;
+ def SVDOT_MULTI_ZA64_VG1x4_S16 : Inst<"svdot_za64[_{d}]_vg1x4", "vm44", "s", MergeNone, "aarch64_sme_sdot_za64_vg1x4", [IsStreaming, IsInOutZA], []>;
+ def SVDOT_MULTI_ZA64_VG1x2_U16 : Inst<"svdot_za64[_{d}]_vg1x2", "vm22", "Us", MergeNone, "aarch64_sme_udot_za64_vg1x2", [IsStreaming, IsInOutZA], []>;
+ def SVDOT_MULTI_ZA64_VG1x4_U16 : Inst<"svdot_za64[_{d}]_vg1x4", "vm44", "Us", MergeNone, "aarch64_sme_udot_za64_vg1x4", [IsStreaming, IsInOutZA], []>;
+ def SVDOT_SINGLE_ZA64_VG1x2_S16 : Inst<"svdot[_single]_za64[_{d}]_vg1x2", "vm2d", "s", MergeNone, "aarch64_sme_sdot_single_za64_vg1x2", [IsStreaming, IsInOutZA], []>;
+ def SVDOT_SINGLE_ZA64_VG1x4_S16 : Inst<"svdot[_single]_za64[_{d}]_vg1x4", "vm4d", "s", MergeNone, "aarch64_sme_sdot_single_za64_vg1x4", [IsStreaming, IsInOutZA], []>;
+ def SVDOT_SINGLE_ZA64_VG1x2_U16 : Inst<"svdot[_single]_za64[_{d}]_vg1x2", "vm2d", "Us", MergeNone, "aarch64_sme_udot_single_za64_vg1x2", [IsStreaming, IsInOutZA], []>;
+ def SVDOT_SINGLE_ZA64_VG1x4_U16 : Inst<"svdot[_single]_za64[_{d}]_vg1x4", "vm4d", "Us", MergeNone, "aarch64_sme_udot_single_za64_vg1x4", [IsStreaming, IsInOutZA], []>;
+ def SVDOT_LANE_ZA64_VG1x2_S16 : Inst<"svdot_lane_za64[_{d}]_vg1x2", "vm2di", "s", MergeNone, "aarch64_sme_sdot_lane_za64_vg1x2", [IsStreaming, IsInOutZA], [ImmCheck<3, ImmCheck0_1>]>;
+ def SVDOT_LANE_ZA64_VG1x4_S16 : Inst<"svdot_lane_za64[_{d}]_vg1x4", "vm4di", "s", MergeNone, "aarch64_sme_sdot_lane_za64_vg1x4", [IsStreaming, IsInOutZA], [ImmCheck<3, ImmCheck0_1>]>;
+ def SVDOT_LANE_ZA64_VG1x2_U16 : Inst<"svdot_lane_za64[_{d}]_vg1x2", "vm2di", "Us", MergeNone, "aarch64_sme_udot_lane_za64_vg1x2", [IsStreaming, IsInOutZA], [ImmCheck<3, ImmCheck0_1>]>;
+ def SVDOT_LANE_ZA64_VG1x4_U16 : Inst<"svdot_lane_za64[_{d}]_vg1x4", "vm4di", "Us", MergeNone, "aarch64_sme_udot_lane_za64_vg1x4", [IsStreaming, IsInOutZA], [ImmCheck<3, ImmCheck0_1>]>;
+}
+
+// FMLA/FMLS
+let TargetGuard = "sme2" in {
+ def SVMLA_MULTI_VG1x2_F32 : Inst<"svmla_za32[_{d}]_vg1x2", "vm22", "f", MergeNone, "aarch64_sme_fmla_vg1x2", [IsStreaming, IsInOutZA], []>;
+ def SVMLA_MULTI_VG1x4_F32 : Inst<"svmla_za32[_{d}]_vg1x4", "vm44", "f", MergeNone, "aarch64_sme_fmla_vg1x4", [IsStreaming, IsInOutZA], []>;
+ def SVMLS_MULTI_VG1x2_F32 : Inst<"svmls_za32[_{d}]_vg1x2", "vm22", "f", MergeNone, "aarch64_sme_fmls_vg1x2", [IsStreaming, IsInOutZA], []>;
+ def SVMLS_MULTI_VG1x4_F32 : Inst<"svmls_za32[_{d}]_vg1x4", "vm44", "f", MergeNone, "aarch64_sme_fmls_vg1x4", [IsStreaming, IsInOutZA], []>;
+
+ def SVMLA_SINGLE_VG1x2_F32 : Inst<"svmla[_single]_za32[_{d}]_vg1x2", "vm2d", "f", MergeNone, "aarch64_sme_fmla_single_vg1x2", [IsStreaming, IsInOutZA], []>;
+ def SVMLA_SINGLE_VG1x4_F32 : Inst<"svmla[_single]_za32[_{d}]_vg1x4", "vm4d", "f", MergeNone, "aarch64_sme_fmla_single_vg1x4", [IsStreaming, IsInOutZA], []>;
+ def SVMLS_SINGLE_VG1x2_F32 : Inst<"svmls[_single]_za32[_{d}]_vg1x2", "vm2d", "f", MergeNone, "aarch64_sme_fmls_single_vg1x2", [IsStreaming, IsInOutZA], []>;
+ def SVMLS_SINGLE_VG1x4_F32 : Inst<"svmls[_single]_za32[_{d}]_vg1x4", "vm4d", "f", MergeNone, "aarch64_sme_fmls_single_vg1x4", [IsStreaming, IsInOutZA], []>;
+
+ def SVMLA_LANE_VG1x2_F32 : Inst<"svmla_lane_za32[_{d}]_vg1x2", "vm2di", "f", MergeNone, "aarch64_sme_fmla_lane_vg1x2", [IsStreaming, IsInOutZA], [ImmCheck<3, ImmCheck0_3>]>;
+ def SVMLA_LANE_VG1x4_F32 : Inst<"svmla_lane_za32[_{d}]_vg1x4", "vm4di", "f", MergeNone, "aarch64_sme_fmla_lane_vg1x4", [IsStreaming, IsInOutZA], [ImmCheck<3, ImmCheck0_3>]>;
+ def SVMLS_LANE_VG1x2_F32 : Inst<"svmls_lane_za32[_{d}]_vg1x2", "vm2di", "f", MergeNone, "aarch64_sme_fmls_lane_vg1x2", [IsStreaming, IsInOutZA], [ImmCheck<3, ImmCheck0_3>]>;
+ def SVMLS_LANE_VG1x4_F32 : Inst<"svmls_lane_za32[_{d}]_vg1x4", "vm4di", "f", MergeNone, "aarch64_sme_fmls_lane_vg1x4", [IsStreaming, IsInOutZA], [ImmCheck<3, ImmCheck0_3>]>;
+}
+
+let TargetGuard = "sme2,sme-f64f64" in {
+ def SVMLA_MULTI_VG1x2_F64 : Inst<"svmla_za64[_{d}]_vg1x2", "vm22", "d", MergeNone, "aarch64_sme_fmla_vg1x2", [IsStreaming, IsInOutZA], []>;
+ def SVMLA_MULTI_VG1x4_F64 : Inst<"svmla_za64[_{d}]_vg1x4", "vm44", "d", MergeNone, "aarch64_sme_fmla_vg1x4", [IsStreaming, IsInOutZA], []>;
+ def SVMLS_MULTI_VG1x2_F64 : Inst<"svmls_za64[_{d}]_vg1x2", "vm22", "d", MergeNone, "aarch64_sme_fmls_vg1x2", [IsStreaming, IsInOutZA], []>;
+ def SVMLS_MULTI_VG1x4_F64 : Inst<"svmls_za64[_{d}]_vg1x4", "vm44", "d", MergeNone, "aarch64_sme_fmls_vg1x4", [IsStreaming, IsInOutZA], []>;
+
+ def SVMLA_SINGLE_VG1x2_F64 : Inst<"svmla[_single]_za64[_{d}]_vg1x2", "vm2d", "d", MergeNone, "aarch64_sme_fmla_single_vg1x2", [IsStreaming, IsInOutZA], []>;
+ def SVMLA_SINGLE_VG1x4_F64 : Inst<"svmla[_single]_za64[_{d}]_vg1x4", "vm4d", "d", MergeNone, "aarch64_sme_fmla_single_vg1x4", [IsStreaming, IsInOutZA], []>;
+ def SVMLS_SINGLE_VG1x2_F64 : Inst<"svmls[_single]_za64[_{d}]_vg1x2", "vm2d", "d", MergeNone, "aarch64_sme_fmls_single_vg1x2", [IsStreaming, IsInOutZA], []>;
+ def SVMLS_SINGLE_VG1x4_F64 : Inst<"svmls[_single]_za64[_{d}]_vg1x4", "vm4d", "d", MergeNone, "aarch64_sme_fmls_single_vg1x4", [IsStreaming, IsInOutZA], []>;
+
+ def SVMLA_LANE_VG1x2_F64 : Inst<"svmla_lane_za64[_{d}]_vg1x2", "vm2di", "d", MergeNone, "aarch64_sme_fmla_lane_vg1x2", [IsStreaming, IsInOutZA], [ImmCheck<3, ImmCheck0_1>]>;
+ def SVMLA_LANE_VG1x4_F64 : Inst<"svmla_lane_za64[_{d}]_vg1x4", "vm4di", "d", MergeNone, "aarch64_sme_fmla_lane_vg1x4", [IsStreaming, IsInOutZA], [ImmCheck<3, ImmCheck0_1>]>;
+ def SVMLS_LANE_VG1x2_F64 : Inst<"svmls_lane_za64[_{d}]_vg1x2", "vm2di", "d", MergeNone, "aarch64_sme_fmls_lane_vg1x2", [IsStreaming, IsInOutZA], [ImmCheck<3, ImmCheck0_1>]>;
+ def SVMLS_LANE_VG1x4_F64 : Inst<"svmls_lane_za64[_{d}]_vg1x4", "vm4di", "d", MergeNone, "aarch64_sme_fmls_lane_vg1x4", [IsStreaming, IsInOutZA], [ImmCheck<3, ImmCheck0_1>]>;
+}
+
+// FMLAL/FMLSL/UMLAL/SMLAL
+// SMLALL/UMLALL/USMLALL/SUMLALL
+let TargetGuard = "sme2" in {
+ // MULTI MLAL
+ def SVMLAL_MULTI_VG2x2_F16 : Inst<"svmla_za32[_{d}]_vg2x2", "vm22", "bh", MergeNone, "aarch64_sme_fmlal_vg2x2", [IsStreaming, IsInOutZA], []>;
+ def SVMLAL_MULTI_VG2x4_F16 : Inst<"svmla_za32[_{d}]_vg2x4", "vm44", "bh", MergeNone, "aarch64_sme_fmlal_vg2x4", [IsStreaming, IsInOutZA], []>;
+ def SVMLAL_MULTI_VG2x2_S16 : Inst<"svmla_za32[_{d}]_vg2x2", "vm22", "s", MergeNone, "aarch64_sme_smlal_vg2x2", [IsStreaming, IsInOutZA], []>;
+ def SVMLAL_MULTI_VG2x4_S16 : Inst<"svmla_za32[_{d}]_vg2x4", "vm44", "s", MergeNone, "aarch64_sme_smlal_vg2x4", [IsStreaming, IsInOutZA], []>;
+ def SVMLAL_MULTI_VG2x2_U16 : Inst<"svmla_za32[_{d}]_vg2x2", "vm22", "Us", MergeNone, "aarch64_sme_umlal_vg2x2", [IsStreaming, IsInOutZA], []>;
+ def SVMLAL_MULTI_VG2x4_U16 : Inst<"svmla_za32[_{d}]_vg2x4", "vm44", "Us", MergeNone, "aarch64_sme_umlal_vg2x4", [IsStreaming, IsInOutZA], []>;
+
+ def SVMLAL_MULTI_VG4x2_S8 : Inst<"svmla_za32[_{d}]_vg4x2", "vm22", "c", MergeNone, "aarch64_sme_smla_za32_vg4x2", [IsStreaming, IsInOutZA], []>;
+ def SVMLAL_MULTI_VG4x2_U8 : Inst<"svmla_za32[_{d}]_vg4x2", "vm22", "Uc", MergeNone, "aarch64_sme_umla_za32_vg4x2", [IsStreaming, IsInOutZA], []>;
+ def SVMLAL_MULTI_VG4x4_S8 : Inst<"svmla_za32[_{d}]_vg4x4", "vm44", "c", MergeNone, "aarch64_sme_smla_za32_vg4x4", [IsStreaming, IsInOutZA], []>;
+ def SVMLAL_MULTI_VG4x4_U8 : Inst<"svmla_za32[_{d}]_vg4x4", "vm44", "Uc", MergeNone, "aarch64_sme_umla_za32_vg4x4", [IsStreaming, IsInOutZA], []>;
+
+ // MULTI MLSL
+ def SVMLSL_MULTI_VG2x2_F16 : Inst<"svmls_za32[_{d}]_vg2x2", "vm22", "bh", MergeNone, "aarch64_sme_fmlsl_vg2x2", [IsStreaming, IsInOutZA], []>;
+ def SVMLSL_MULTI_VG2x4_F16 : Inst<"svmls_za32[_{d}]_vg2x4", "vm44", "bh", MergeNone, "aarch64_sme_fmlsl_vg2x4", [IsStreaming, IsInOutZA], []>;
+ def SVMLSL_MULTI_VG2x2_S16 : Inst<"svmls_za32[_{d}]_vg2x2", "vm22", "s", MergeNone, "aarch64_sme_smlsl_vg2x2", [IsStreaming, IsInOutZA], []>;
+ def SVMLSL_MULTI_VG2x4_S16 : Inst<"svmls_za32[_{d}]_vg2x4", "vm44", "s", MergeNone, "aarch64_sme_smlsl_vg2x4", [IsStreaming, IsInOutZA], []>;
+ def SVMLSL_MULTI_VG2x2_U16 : Inst<"svmls_za32[_{d}]_vg2x2", "vm22", "Us", MergeNone, "aarch64_sme_umlsl_vg2x2", [IsStreaming, IsInOutZA], []>;
+ def SVMLSL_MULTI_VG2x4_U16 : Inst<"svmls_za32[_{d}]_vg2x4", "vm44", "Us", MergeNone, "aarch64_sme_umlsl_vg2x4", [IsStreaming, IsInOutZA], []>;
+
+ def SVMLSL_MULTI_VG4x2_S8 : Inst<"svmls_za32[_{d}]_vg4x2", "vm22", "c", MergeNone, "aarch64_sme_smls_za32_vg4x2", [IsStreaming, IsInOutZA], []>;
+ def SVMLSL_MULTI_VG4x2_U8 : Inst<"svmls_za32[_{d}]_vg4x2", "vm22", "Uc", MergeNone, "aarch64_sme_umls_za32_vg4x2", [IsStreaming, IsInOutZA], []>;
+ def SVMLSL_MULTI_VG4x4_S8 : Inst<"svmls_za32[_{d}]_vg4x4", "vm44", "c", MergeNone, "aarch64_sme_smls_za32_vg4x4", [IsStreaming, IsInOutZA], []>;
+ def SVMLSL_MULTI_VG4x4_U8 : Inst<"svmls_za32[_{d}]_vg4x4", "vm44", "Uc", MergeNone, "aarch64_sme_umls_za32_vg4x4", [IsStreaming, IsInOutZA], []>;
+
+ // SINGLE MLAL
+ def SVMLAL_SINGLE_VG2x1_F16 : Inst<"svmla_za32[_{d}]_vg2x1", "vmdd", "bh", MergeNone, "aarch64_sme_fmlal_single_vg2x1", [IsStreaming, IsInOutZA], []>;
+ def SVMLAL_SINGLE_VG2x2_F16 : Inst<"svmla[_single]_za32[_{d}]_vg2x2", "vm2d", "bh", MergeNone, "aarch64_sme_fmlal_single_vg2x2", [IsStreaming, IsInOutZA], []>;
+ def SVMLAL_SINGLE_VG2x4_F16 : Inst<"svmla[_single]_za32[_{d}]_vg2x4", "vm4d", "bh", MergeNone, "aarch64_sme_fmlal_single_vg2x4", [IsStreaming, IsInOutZA], []>;
+ def SVMLAL_SINGLE_VG2x1_S16 : Inst<"svmla_za32[_{d}]_vg2x1", "vmdd", "s", MergeNone, "aarch64_sme_smlal_single_vg2x1", [IsStreaming, IsInOutZA], []>;
+ def SVMLAL_SINGLE_VG2x2_S16 : Inst<"svmla[_single]_za32[_{d}]_vg2x2", "vm2d", "s", MergeNone, "aarch64_sme_smlal_single_vg2x2", [IsStreaming, IsInOutZA], []>;
+ def SVMLAL_SINGLE_VG2x4_S16 : Inst<"svmla[_single]_za32[_{d}]_vg2x4", "vm4d", "s", MergeNone, "aarch64_sme_smlal_single_vg2x4", [IsStreaming, IsInOutZA], []>;
+ def SVMLAL_SINGLE_VG2x1_U16 : Inst<"svmla_za32[_{d}]_vg2x1", "vmdd", "Us", MergeNone, "aarch64_sme_umlal_single_vg2x1", [IsStreaming, IsInOutZA], []>;
+ def SVMLAL_SINGLE_VG2x2_U16 : Inst<"svmla[_single]_za32[_{d}]_vg2x2", "vm2d", "Us", MergeNone, "aarch64_sme_umlal_single_vg2x2", [IsStreaming, IsInOutZA], []>;
+ def SVMLAL_SINGLE_VG2x4_U16 : Inst<"svmla[_single]_za32[_{d}]_vg2x4", "vm4d", "Us", MergeNone, "aarch64_sme_umlal_single_vg2x4", [IsStreaming, IsInOutZA], []>;
+
+ def SVMLAL_SINGLE_VG4x1_S8 : Inst<"svmla_za32[_{d}]_vg4x1", "vmdd", "c", MergeNone, "aarch64_sme_smla_za32_single_vg4x1", [IsStreaming, IsInOutZA], []>;
+ def SVMLAL_SINGLE_VG4x1_U8 : Inst<"svmla_za32[_{d}]_vg4x1", "vmdd", "Uc", MergeNone, "aarch64_sme_umla_za32_single_vg4x1", [IsStreaming, IsInOutZA], []>;
+ def SVMLAL_SINGLE_VG4x2_S8 : Inst<"svmla[_single]_za32[_{d}]_vg4x2", "vm2d", "c", MergeNone, "aarch64_sme_smla_za32_single_vg4x2", [IsStreaming, IsInOutZA], []>;
+ def SVMLAL_SINGLE_VG4x2_U8 : Inst<"svmla[_single]_za32[_{d}]_vg4x2", "vm2d", "Uc", MergeNone, "aarch64_sme_umla_za32_single_vg4x2", [IsStreaming, IsInOutZA], []>;
+ def SVMLAL_SINGLE_VG4x4_S8 : Inst<"svmla[_single]_za32[_{d}]_vg4x4", "vm4d", "c", MergeNone, "aarch64_sme_smla_za32_single_vg4x4", [IsStreaming, IsInOutZA], []>;
+ def SVMLAL_SINGLE_VG4x4_U8 : Inst<"svmla[_single]_za32[_{d}]_vg4x4", "vm4d", "Uc", MergeNone, "aarch64_sme_umla_za32_single_vg4x4", [IsStreaming, IsInOutZA], []>;
+
+ // SINGLE MLSL
+ def SVMLSL_SINGLE_VG2x1_F16 : Inst<"svmls_za32[_{d}]_vg2x1", "vmdd", "bh", MergeNone, "aarch64_sme_fmlsl_single_vg2x1", [IsStreaming, IsInOutZA], []>;
+ def SVMLSL_SINGLE_VG2x2_F16 : Inst<"svmls[_single]_za32[_{d}]_vg2x2", "vm2d", "bh", MergeNone, "aarch64_sme_fmlsl_single_vg2x2", [IsStreaming, IsInOutZA], []>;
+ def SVMLSL_SINGLE_VG2x4_F16 : Inst<"svmls[_single]_za32[_{d}]_vg2x4", "vm4d", "bh", MergeNone, "aarch64_sme_fmlsl_single_vg2x4", [IsStreaming, IsInOutZA], []>;
+ def SVMLSL_SINGLE_VG2x1_S16 : Inst<"svmls_za32[_{d}]_vg2x1", "vmdd", "s", MergeNone, "aarch64_sme_smlsl_single_vg2x1", [IsStreaming, IsInOutZA], []>;
+ def SVMLSL_SINGLE_VG2x2_S16 : Inst<"svmls[_single]_za32[_{d}]_vg2x2", "vm2d", "s", MergeNone, "aarch64_sme_smlsl_single_vg2x2", [IsStreaming, IsInOutZA], []>;
+ def SVMLSL_SINGLE_VG2x4_S16 : Inst<"svmls[_single]_za32[_{d}]_vg2x4", "vm4d", "s", MergeNone, "aarch64_sme_smlsl_single_vg2x4", [IsStreaming, IsInOutZA], []>;
+ def SVMLSL_SINGLE_VG2x1_U16 : Inst<"svmls_za32[_{d}]_vg2x1", "vmdd", "Us", MergeNone, "aarch64_sme_umlsl_single_vg2x1", [IsStreaming, IsInOutZA], []>;
+ def SVMLSL_SINGLE_VG2x2_U16 : Inst<"svmls[_single]_za32[_{d}]_vg2x2", "vm2d", "Us", MergeNone, "aarch64_sme_umlsl_single_vg2x2", [IsStreaming, IsInOutZA], []>;
+ def SVMLSL_SINGLE_VG2x4_U16 : Inst<"svmls[_single]_za32[_{d}]_vg2x4", "vm4d", "Us", MergeNone, "aarch64_sme_umlsl_single_vg2x4", [IsStreaming, IsInOutZA], []>;
+
+ def SVMLSL_SINGLE_VG4x1_S8 : Inst<"svmls_za32[_{d}]_vg4x1", "vmdd", "c", MergeNone, "aarch64_sme_smls_za32_single_vg4x1", [IsStreaming, IsInOutZA], []>;
+ def SVMLSL_SINGLE_VG4x1_U8 : Inst<"svmls_za32[_{d}]_vg4x1", "vmdd", "Uc", MergeNone, "aarch64_sme_umls_za32_single_vg4x1", [IsStreaming, IsInOutZA], []>;
+ def SVMLSL_SINGLE_VG4x2_S8 : Inst<"svmls[_single]_za32[_{d}]_vg4x2", "vm2d", "c", MergeNone, "aarch64_sme_smls_za32_single_vg4x2", [IsStreaming, IsInOutZA], []>;
+ def SVMLSL_SINGLE_VG4x2_U8 : Inst<"svmls[_single]_za32[_{d}]_vg4x2", "vm2d", "Uc", MergeNone, "aarch64_sme_umls_za32_single_vg4x2", [IsStreaming, IsInOutZA], []>;
+ def SVMLSL_SINGLE_VG4x4_S8 : Inst<"svmls[_single]_za32[_{d}]_vg4x4", "vm4d", "c", MergeNone, "aarch64_sme_smls_za32_single_vg4x4", [IsStreaming, IsInOutZA], []>;
+ def SVMLSL_SINGLE_VG4x4_U8 : Inst<"svmls[_single]_za32[_{d}]_vg4x4", "vm4d", "Uc", MergeNone, "aarch64_sme_umls_za32_single_vg4x4", [IsStreaming, IsInOutZA], []>;
+
+ // INDEXED MLAL
+ def SVMLAL_LANE_VG2x1_F16 : Inst<"svmla_lane_za32[_{d}]_vg2x1", "vmddi", "bh", MergeNone, "aarch64_sme_fmlal_lane_vg2x1", [IsStreaming, IsInOutZA], [ImmCheck<3, ImmCheck0_7>]>;
+ def SVMLAL_LANE_VG2x2_F16 : Inst<"svmla_lane_za32[_{d}]_vg2x2", "vm2di", "bh", MergeNone, "aarch64_sme_fmlal_lane_vg2x2", [IsStreaming, IsInOutZA], [ImmCheck<3, ImmCheck0_7>]>;
+ def SVMLAL_LANE_VG2x4_F16 : Inst<"svmla_lane_za32[_{d}]_vg2x4", "vm4di", "bh", MergeNone, "aarch64_sme_fmlal_lane_vg2x4", [IsStreaming, IsInOutZA], [ImmCheck<3, ImmCheck0_7>]>;
+ def SVMLAL_LANE_VG2x1_S16 : Inst<"svmla_lane_za32[_{d}]_vg2x1", "vmddi", "s", MergeNone, "aarch64_sme_smlal_lane_vg2x1", [IsStreaming, IsInOutZA], [ImmCheck<3, ImmCheck0_7>]>;
+ def SVMLAL_LANE_VG2x2_S16 : Inst<"svmla_lane_za32[_{d}]_vg2x2", "vm2di", "s", MergeNone, "aarch64_sme_smlal_lane_vg2x2", [IsStreaming, IsInOutZA], [ImmCheck<3, ImmCheck0_7>]>;
+ def SVMLAL_LANE_VG2x4_S16 : Inst<"svmla_lane_za32[_{d}]_vg2x4", "vm4di", "s", MergeNone, "aarch64_sme_smlal_lane_vg2x4", [IsStreaming, IsInOutZA], [ImmCheck<3, ImmCheck0_7>]>;
+ def SVMLAL_LANE_VG2x1_U16 : Inst<"svmla_lane_za32[_{d}]_vg2x1", "vmddi", "Us", MergeNone, "aarch64_sme_umlal_lane_vg2x1", [IsStreaming, IsInOutZA], [ImmCheck<3, ImmCheck0_7>]>;
+ def SVMLAL_LANE_VG2x2_U16 : Inst<"svmla_lane_za32[_{d}]_vg2x2", "vm2di", "Us", MergeNone, "aarch64_sme_umlal_lane_vg2x2", [IsStreaming, IsInOutZA], [ImmCheck<3, ImmCheck0_7>]>;
+ def SVMLAL_LANE_VG2x4_U16 : Inst<"svmla_lane_za32[_{d}]_vg2x4", "vm4di", "Us", MergeNone, "aarch64_sme_umlal_lane_vg2x4", [IsStreaming, IsInOutZA], [ImmCheck<3, ImmCheck0_7>]>;
+
+ def SVMLAL_LANE_VG4x1_S8 : Inst<"svmla_lane_za32[_{d}]_vg4x1", "vmddi", "c", MergeNone, "aarch64_sme_smla_za32_lane_vg4x1", [IsStreaming, IsInOutZA], [ImmCheck<3, ImmCheck0_15>]>;
+ def SVMLAL_LANE_VG4x1_U8 : Inst<"svmla_lane_za32[_{d}]_vg4x1", "vmddi", "Uc", MergeNone, "aarch64_sme_umla_za32_lane_vg4x1", [IsStreaming, IsInOutZA], [ImmCheck<3, ImmCheck0_15>]>;
+ def SVMLAL_LANE_VG4x2_S8 : Inst<"svmla_lane_za32[_{d}]_vg4x2", "vm2di", "c", MergeNone, "aarch64_sme_smla_za32_lane_vg4x2", [IsStreaming, IsInOutZA], [ImmCheck<3, ImmCheck0_15>]>;
+ def SVMLAL_LANE_VG4x2_U8 : Inst<"svmla_lane_za32[_{d}]_vg4x2", "vm2di", "Uc", MergeNone, "aarch64_sme_umla_za32_lane_vg4x2", [IsStreaming, IsInOutZA], [ImmCheck<3, ImmCheck0_15>]>;
+ def SVMLAL_LANE_VG4x4_S8 : Inst<"svmla_lane_za32[_{d}]_vg4x4", "vm4di", "c", MergeNone, "aarch64_sme_smla_za32_lane_vg4x4", [IsStreaming, IsInOutZA], [ImmCheck<3, ImmCheck0_15>]>;
+ def SVMLAL_LANE_VG4x4_U8 : Inst<"svmla_lane_za32[_{d}]_vg4x4", "vm4di", "Uc", MergeNone, "aarch64_sme_umla_za32_lane_vg4x4", [IsStreaming, IsInOutZA], [ImmCheck<3, ImmCheck0_15>]>;
+
+ // INDEXED MLSL
+ def SVMLSL_LANE_VG2x1_F16 : Inst<"svmls_lane_za32[_{d}]_vg2x1", "vmddi", "bh", MergeNone, "aarch64_sme_fmlsl_lane_vg2x1", [IsStreaming, IsInOutZA], [ImmCheck<3, ImmCheck0_7>]>;
+ def SVMLSL_LANE_VG2x2_F16 : Inst<"svmls_lane_za32[_{d}]_vg2x2", "vm2di", "bh", MergeNone, "aarch64_sme_fmlsl_lane_vg2x2", [IsStreaming, IsInOutZA], [ImmCheck<3, ImmCheck0_7>]>;
+ def SVMLSL_LANE_VG2x4_F16 : Inst<"svmls_lane_za32[_{d}]_vg2x4", "vm4di", "bh", MergeNone, "aarch64_sme_fmlsl_lane_vg2x4", [IsStreaming, IsInOutZA], [ImmCheck<3, ImmCheck0_7>]>;
+ def SVMLSL_LANE_VG2x1_S16 : Inst<"svmls_lane_za32[_{d}]_vg2x1", "vmddi", "s", MergeNone, "aarch64_sme_smlsl_lane_vg2x1", [IsStreaming, IsInOutZA], [ImmCheck<3, ImmCheck0_7>]>;
+ def SVMLSL_LANE_VG2x2_S16 : Inst<"svmls_lane_za32[_{d}]_vg2x2", "vm2di", "s", MergeNone, "aarch64_sme_smlsl_lane_vg2x2", [IsStreaming, IsInOutZA], [ImmCheck<3, ImmCheck0_7>]>;
+ def SVMLSL_LANE_VG2x4_S16 : Inst<"svmls_lane_za32[_{d}]_vg2x4", "vm4di", "s", MergeNone, "aarch64_sme_smlsl_lane_vg2x4", [IsStreaming, IsInOutZA], [ImmCheck<3, ImmCheck0_7>]>;
+ def SVMLSL_LANE_VG2x1_U16 : Inst<"svmls_lane_za32[_{d}]_vg2x1", "vmddi", "Us", MergeNone, "aarch64_sme_umlsl_lane_vg2x1", [IsStreaming, IsInOutZA], [ImmCheck<3, ImmCheck0_7>]>;
+ def SVMLSL_LANE_VG2x2_U16 : Inst<"svmls_lane_za32[_{d}]_vg2x2", "vm2di", "Us", MergeNone, "aarch64_sme_umlsl_lane_vg2x2", [IsStreaming, IsInOutZA], [ImmCheck<3, ImmCheck0_7>]>;
+ def SVMLSL_LANE_VG2x4_U16 : Inst<"svmls_lane_za32[_{d}]_vg2x4", "vm4di", "Us", MergeNone, "aarch64_sme_umlsl_lane_vg2x4", [IsStreaming, IsInOutZA], [ImmCheck<3, ImmCheck0_7>]>;
+
+ def SVMLSL_LANE_VG4x1_S8 : Inst<"svmls_lane_za32[_{d}]_vg4x1", "vmddi", "c", MergeNone, "aarch64_sme_smls_za32_lane_vg4x1", [IsStreaming, IsInOutZA], [ImmCheck<3, ImmCheck0_15>]>;
+ def SVMLSL_LANE_VG4x1_U8 : Inst<"svmls_lane_za32[_{d}]_vg4x1", "vmddi", "Uc", MergeNone, "aarch64_sme_umls_za32_lane_vg4x1", [IsStreaming, IsInOutZA], [ImmCheck<3, ImmCheck0_15>]>;
+ def SVMLSL_LANE_VG4x2_S8 : Inst<"svmls_lane_za32[_{d}]_vg4x2", "vm2di", "c", MergeNone, "aarch64_sme_smls_za32_lane_vg4x2", [IsStreaming, IsInOutZA], [ImmCheck<3, ImmCheck0_15>]>;
+ def SVMLSL_LANE_VG4x2_U8 : Inst<"svmls_lane_za32[_{d}]_vg4x2", "vm2di", "Uc", MergeNone, "aarch64_sme_umls_za32_lane_vg4x2", [IsStreaming, IsInOutZA], [ImmCheck<3, ImmCheck0_15>]>;
+ def SVMLSL_LANE_VG4x4_S8 : Inst<"svmls_lane_za32[_{d}]_vg4x4", "vm4di", "c", MergeNone, "aarch64_sme_smls_za32_lane_vg4x4", [IsStreaming, IsInOutZA], [ImmCheck<3, ImmCheck0_15>]>;
+ def SVMLSL_LANE_VG4x4_U8 : Inst<"svmls_lane_za32[_{d}]_vg4x4", "vm4di", "Uc", MergeNone, "aarch64_sme_umls_za32_lane_vg4x4", [IsStreaming, IsInOutZA], [ImmCheck<3, ImmCheck0_15>]>;
+
+ // SINGLE SUMLALL
+ // Single sumla maps to usmla, with zn & zm operands swapped
+ def SVSUMLALL_SINGLE_VG4x1 : Inst<"svsumla_za32[_{d}]_vg4x1", "vmdu", "c", MergeNone, "aarch64_sme_usmla_za32_single_vg4x1", [IsStreaming, IsInOutZA], []>;
+
+ def SVSUMLALL_SINGLE_VG4x2 : Inst<"svsumla[_single]_za32[_{d}]_vg4x2", "vm2.du", "c", MergeNone, "aarch64_sme_sumla_za32_single_vg4x2", [IsStreaming, IsInOutZA], []>;
+ def SVSUMLALL_SINGLE_VG4x4 : Inst<"svsumla[_single]_za32[_{d}]_vg4x4", "vm4.du", "c", MergeNone, "aarch64_sme_sumla_za32_single_vg4x4", [IsStreaming, IsInOutZA], []>;
+
+ // Multi-multi sumla builtins are mapped to usmla, with zn & zm operands swapped
+ def SVSUMLALL_MULTI_VG4x2 : Inst<"svsumla_za32[_{d}]_vg4x2", "vm2.d2.u", "c", MergeNone, "aarch64_sme_usmla_za32_vg4x2", [IsStreaming, IsInOutZA], []>;
+ def SVSUMLALL_MULTI_VG4x4 : Inst<"svsumla_za32[_{d}]_vg4x4", "vm4.d4.u", "c", MergeNone, "aarch64_sme_usmla_za32_vg4x4", [IsStreaming, IsInOutZA], []>;
+
+ // INDEXED SUMLALL
+ def SVSUMLALL_LANE_VG4x1 : Inst<"svsumla_lane_za32[_{d}]_vg4x1", "vmdui", "c", MergeNone, "aarch64_sme_sumla_za32_lane_vg4x1", [IsStreaming, IsInOutZA], [ImmCheck<3, ImmCheck0_15>]>;
+ def SVSUMLALL_LANE_VG4x2 : Inst<"svsumla_lane_za32[_{d}]_vg4x2", "vm2ui", "c", MergeNone, "aarch64_sme_sumla_za32_lane_vg4x2", [IsStreaming, IsInOutZA], [ImmCheck<3, ImmCheck0_15>]>;
+ def SVSUMLALL_LANE_VG4x4 : Inst<"svsumla_lane_za32[_{d}]_vg4x4", "vm4ui", "c", MergeNone, "aarch64_sme_sumla_za32_lane_vg4x4", [IsStreaming, IsInOutZA], [ImmCheck<3, ImmCheck0_15>]>;
+
+ // SINGLE USMLALL
+ def SVUSMLALL_SINGLE_VG4x1 : Inst<"svusmla_za32[_{d}]_vg4x1", "vmdx", "Uc", MergeNone, "aarch64_sme_usmla_za32_single_vg4x1", [IsStreaming, IsInOutZA], []>;
+ def SVUSMLALL_SINGLE_VG4x2 : Inst<"svusmla[_single]_za32[_{d}]_vg4x2", "vm2.dx", "Uc", MergeNone, "aarch64_sme_usmla_za32_single_vg4x2", [IsStreaming, IsInOutZA], []>;
+ def SVUSMLALL_SINGLE_VG4x4 : Inst<"svusmla[_single]_za32[_{d}]_vg4x4", "vm4.dx", "Uc", MergeNone, "aarch64_sme_usmla_za32_single_vg4x4", [IsStreaming, IsInOutZA], []>;
+
+ // MULTI USMLALL
+ def SVUSMLALL_MULTI_VG4x2 : Inst<"svusmla_za32[_{d}]_vg4x2", "vm2.d2.x", "Uc", MergeNone, "aarch64_sme_usmla_za32_vg4x2", [IsStreaming, IsInOutZA], []>;
+ def SVUSMLALL_MULTI_VG4x4 : Inst<"svusmla_za32[_{d}]_vg4x4", "vm4.d4.x", "Uc", MergeNone, "aarch64_sme_usmla_za32_vg4x4", [IsStreaming, IsInOutZA], []>;
+
+ // INDEXED USMLALL
+ def SVUSMLALL_LANE_VG4x1 : Inst<"svusmla_lane_za32[_{d}]_vg4x1", "vmdxi", "Uc", MergeNone, "aarch64_sme_usmla_za32_lane_vg4x1", [IsStreaming, IsInOutZA], [ImmCheck<3, ImmCheck0_15>]>;
+ def SVUSMLALL_LANE_VG4x2 : Inst<"svusmla_lane_za32[_{d}]_vg4x2", "vm2xi", "Uc", MergeNone, "aarch64_sme_usmla_za32_lane_vg4x2", [IsStreaming, IsInOutZA], [ImmCheck<3, ImmCheck0_15>]>;
+ def SVUSMLALL_LANE_VG4x4 : Inst<"svusmla_lane_za32[_{d}]_vg4x4", "vm4xi", "Uc", MergeNone, "aarch64_sme_usmla_za32_lane_vg4x4", [IsStreaming, IsInOutZA], [ImmCheck<3, ImmCheck0_15>]>;
+}
+
+let TargetGuard = "sme2,sme-i16i64" in {
+ // MULTI MLAL
+ def SVMLAL_MULTI_VG4x2_S16 : Inst<"svmla_za64[_{d}]_vg4x2", "vm22", "s", MergeNone, "aarch64_sme_smla_za64_vg4x2", [IsStreaming, IsInOutZA], []>;
+ def SVMLAL_MULTI_VG4x2_U16 : Inst<"svmla_za64[_{d}]_vg4x2", "vm22", "Us", MergeNone, "aarch64_sme_umla_za64_vg4x2", [IsStreaming, IsInOutZA], []>;
+ def SVMLAL_MULTI_VG4x4_S16 : Inst<"svmla_za64[_{d}]_vg4x4", "vm44", "s", MergeNone, "aarch64_sme_smla_za64_vg4x4", [IsStreaming, IsInOutZA], []>;
+ def SVMLAL_MULTI_VG4x4_U16 : Inst<"svmla_za64[_{d}]_vg4x4", "vm44", "Us", MergeNone, "aarch64_sme_umla_za64_vg4x4", [IsStreaming, IsInOutZA], []>;
+
+ // MULTI MLSL
+ def SVMLSL_MULTI_VG4x2_S16 : Inst<"svmls_za64[_{d}]_vg4x2", "vm22", "s", MergeNone, "aarch64_sme_smls_za64_vg4x2", [IsStreaming, IsInOutZA], []>;
+ def SVMLSL_MULTI_VG4x2_U16 : Inst<"svmls_za64[_{d}]_vg4x2", "vm22", "Us", MergeNone, "aarch64_sme_umls_za64_vg4x2", [IsStreaming, IsInOutZA], []>;
+ def SVMLSL_MULTI_VG4x4_S16 : Inst<"svmls_za64[_{d}]_vg4x4", "vm44", "s", MergeNone, "aarch64_sme_smls_za64_vg4x4", [IsStreaming, IsInOutZA], []>;
+ def SVMLSL_MULTI_VG4x4_U16 : Inst<"svmls_za64[_{d}]_vg4x4", "vm44", "Us", MergeNone, "aarch64_sme_umls_za64_vg4x4", [IsStreaming, IsInOutZA], []>;
+
+ // SINGLE MLAL
+ def SVMLAL_SINGLE_VG4x1_S16 : Inst<"svmla_za64[_{d}]_vg4x1", "vmdd", "s", MergeNone, "aarch64_sme_smla_za64_single_vg4x1", [IsStreaming, IsInOutZA], []>;
+ def SVMLAL_SINGLE_VG4x1_U16 : Inst<"svmla_za64[_{d}]_vg4x1", "vmdd", "Us", MergeNone, "aarch64_sme_umla_za64_single_vg4x1", [IsStreaming, IsInOutZA], []>;
+ def SVMLAL_SINGLE_VG4x2_S16 : Inst<"svmla[_single]_za64[_{d}]_vg4x2", "vm2d", "s", MergeNone, "aarch64_sme_smla_za64_single_vg4x2", [IsStreaming, IsInOutZA], []>;
+ def SVMLAL_SINGLE_VG4x2_U16 : Inst<"svmla[_single]_za64[_{d}]_vg4x2", "vm2d", "Us", MergeNone, "aarch64_sme_umla_za64_single_vg4x2", [IsStreaming, IsInOutZA], []>;
+ def SVMLAL_SINGLE_VG4x4_S16 : Inst<"svmla[_single]_za64[_{d}]_vg4x4", "vm4d", "s", MergeNone, "aarch64_sme_smla_za64_single_vg4x4", [IsStreaming, IsInOutZA], []>;
+ def SVMLAL_SINGLE_VG4x4_U16 : Inst<"svmla[_single]_za64[_{d}]_vg4x4", "vm4d", "Us", MergeNone, "aarch64_sme_umla_za64_single_vg4x4", [IsStreaming, IsInOutZA], []>;
+
+ // SINGLE MLSL
+ def SVMLSL_SINGLE_VG4x1_S16 : Inst<"svmls_za64[_{d}]_vg4x1", "vmdd", "s", MergeNone, "aarch64_sme_smls_za64_single_vg4x1", [IsStreaming, IsInOutZA], []>;
+ def SVMLSL_SINGLE_VG4x1_U16 : Inst<"svmls_za64[_{d}]_vg4x1", "vmdd", "Us", MergeNone, "aarch64_sme_umls_za64_single_vg4x1", [IsStreaming, IsInOutZA], []>;
+ def SVMLSL_SINGLE_VG4x2_S16 : Inst<"svmls[_single]_za64[_{d}]_vg4x2", "vm2d", "s", MergeNone, "aarch64_sme_smls_za64_single_vg4x2", [IsStreaming, IsInOutZA], []>;
+ def SVMLSL_SINGLE_VG4x2_U16 : Inst<"svmls[_single]_za64[_{d}]_vg4x2", "vm2d", "Us", MergeNone, "aarch64_sme_umls_za64_single_vg4x2", [IsStreaming, IsInOutZA], []>;
+ def SVMLSL_SINGLE_VG4x4_S16 : Inst<"svmls[_single]_za64[_{d}]_vg4x4", "vm4d", "s", MergeNone, "aarch64_sme_smls_za64_single_vg4x4", [IsStreaming, IsInOutZA], []>;
+ def SVMLSL_SINGLE_VG4x4_U16 : Inst<"svmls[_single]_za64[_{d}]_vg4x4", "vm4d", "Us", MergeNone, "aarch64_sme_umls_za64_single_vg4x4", [IsStreaming, IsInOutZA], []>;
+
+ // INDEXED MLAL
+ def SVMLAL_LANE_VG4x1_S16 : Inst<"svmla_lane_za64[_{d}]_vg4x1", "vmddi", "s", MergeNone, "aarch64_sme_smla_za64_lane_vg4x1", [IsStreaming, IsInOutZA], [ImmCheck<3, ImmCheck0_7>]>;
+ def SVMLAL_LANE_VG4x1_U16 : Inst<"svmla_lane_za64[_{d}]_vg4x1", "vmddi", "Us", MergeNone, "aarch64_sme_umla_za64_lane_vg4x1", [IsStreaming, IsInOutZA], [ImmCheck<3, ImmCheck0_7>]>;
+ def SVMLAL_LANE_VG4x2_S16 : Inst<"svmla_lane_za64[_{d}]_vg4x2", "vm2di", "s", MergeNone, "aarch64_sme_smla_za64_lane_vg4x2", [IsStreaming, IsInOutZA], [ImmCheck<3, ImmCheck0_7>]>;
+ def SVMLAL_LANE_VG4x2_U16 : Inst<"svmla_lane_za64[_{d}]_vg4x2", "vm2di", "Us", MergeNone, "aarch64_sme_umla_za64_lane_vg4x2", [IsStreaming, IsInOutZA], [ImmCheck<3, ImmCheck0_7>]>;
+ def SVMLAL_LANE_VG4x4_S16 : Inst<"svmla_lane_za64[_{d}]_vg4x4", "vm4di", "s", MergeNone, "aarch64_sme_smla_za64_lane_vg4x4", [IsStreaming, IsInOutZA], [ImmCheck<3, ImmCheck0_7>]>;
+ def SVMLAL_LANE_VG4x4_U16 : Inst<"svmla_lane_za64[_{d}]_vg4x4", "vm4di", "Us", MergeNone, "aarch64_sme_umla_za64_lane_vg4x4", [IsStreaming, IsInOutZA], [ImmCheck<3, ImmCheck0_7>]>;
+
+ // INDEXED MLSL
+ def SVMLSL_LANE_VG4x1_S16 : Inst<"svmls_lane_za64[_{d}]_vg4x1", "vmddi", "s", MergeNone, "aarch64_sme_smls_za64_lane_vg4x1", [IsStreaming, IsInOutZA], [ImmCheck<3, ImmCheck0_7>]>;
+ def SVMLSL_LANE_VG4x1_U16 : Inst<"svmls_lane_za64[_{d}]_vg4x1", "vmddi", "Us", MergeNone, "aarch64_sme_umls_za64_lane_vg4x1", [IsStreaming, IsInOutZA], [ImmCheck<3, ImmCheck0_7>]>;
+ def SVMLSL_LANE_VG4x2_S16 : Inst<"svmls_lane_za64[_{d}]_vg4x2", "vm2di", "s", MergeNone, "aarch64_sme_smls_za64_lane_vg4x2", [IsStreaming, IsInOutZA], [ImmCheck<3, ImmCheck0_7>]>;
+ def SVMLSL_LANE_VG4x2_U16 : Inst<"svmls_lane_za64[_{d}]_vg4x2", "vm2di", "Us", MergeNone, "aarch64_sme_umls_za64_lane_vg4x2", [IsStreaming, IsInOutZA], [ImmCheck<3, ImmCheck0_7>]>;
+ def SVMLSL_LANE_VG4x4_S16 : Inst<"svmls_lane_za64[_{d}]_vg4x4", "vm4di", "s", MergeNone, "aarch64_sme_smls_za64_lane_vg4x4", [IsStreaming, IsInOutZA], [ImmCheck<3, ImmCheck0_7>]>;
+ def SVMLSL_LANE_VG4x4_U16 : Inst<"svmls_lane_za64[_{d}]_vg4x4", "vm4di", "Us", MergeNone, "aarch64_sme_umls_za64_lane_vg4x4", [IsStreaming, IsInOutZA], [ImmCheck<3, ImmCheck0_7>]>;
+}
+
+//
+// Spill and fill of ZT0
+//
+let TargetGuard = "sme2" in {
+ def SVLDR_ZT : Inst<"svldr_zt", "viQ", "", MergeNone, "aarch64_sme_ldr_zt", [IsOverloadNone, IsStreamingCompatible, IsInOutZT0], [ImmCheck<0, ImmCheck0_0>]>;
+ def SVSTR_ZT : Inst<"svstr_zt", "vi%", "", MergeNone, "aarch64_sme_str_zt", [IsOverloadNone, IsStreamingCompatible, IsInZT0], [ImmCheck<0, ImmCheck0_0>]>;
+}
+
+//
+// Zero ZT0
+//
+let TargetGuard = "sme2" in {
+ def SVZERO_ZT : Inst<"svzero_zt", "vi", "", MergeNone, "aarch64_sme_zero_zt", [IsOverloadNone, IsStreamingCompatible, IsOutZT0], [ImmCheck<0, ImmCheck0_0>]>;
+}
+
+//
+// lookup table expand four contiguous registers
+//
+let TargetGuard = "sme2" in {
+ def SVLUTI2_LANE_ZT_X4 : Inst<"svluti2_lane_zt_{d}_x4", "4.di[i", "cUcsUsiUibhf", MergeNone, "aarch64_sme_luti2_lane_zt_x4", [IsStreaming, IsInZT0], [ImmCheck<0, ImmCheck0_0>, ImmCheck<2, ImmCheck0_3>]>;
+ def SVLUTI4_LANE_ZT_X4 : Inst<"svluti4_lane_zt_{d}_x4", "4.di[i", "sUsiUibhf", MergeNone, "aarch64_sme_luti4_lane_zt_x4", [IsStreaming, IsInZT0], [ImmCheck<0, ImmCheck0_0>, ImmCheck<2, ImmCheck0_1>]>;
+}
+
+//
+// lookup table expand one register
+//
+let TargetGuard = "sme2" in {
+ def SVLUTI2_LANE_ZT : Inst<"svluti2_lane_zt_{d}", "di[i", "cUcsUsiUibhf", MergeNone, "aarch64_sme_luti2_lane_zt", [IsStreaming, IsInZT0], [ImmCheck<0, ImmCheck0_0>, ImmCheck<2, ImmCheck0_15>]>;
+ def SVLUTI4_LANE_ZT : Inst<"svluti4_lane_zt_{d}", "di[i", "cUcsUsiUibhf", MergeNone, "aarch64_sme_luti4_lane_zt", [IsStreaming, IsInZT0], [ImmCheck<0, ImmCheck0_0>, ImmCheck<2, ImmCheck0_7>]>;
+}
+
+//
+// lookup table expand two contiguous registers
+//
+let TargetGuard = "sme2" in {
+ def SVLUTI2_LANE_ZT_X2 : Inst<"svluti2_lane_zt_{d}_x2", "2.di[i", "cUcsUsiUibhf", MergeNone, "aarch64_sme_luti2_lane_zt_x2", [IsStreaming, IsInZT0], [ImmCheck<0, ImmCheck0_0>, ImmCheck<2, ImmCheck0_7>]>;
+ def SVLUTI4_LANE_ZT_X2 : Inst<"svluti4_lane_zt_{d}_x2", "2.di[i", "cUcsUsiUibhf", MergeNone, "aarch64_sme_luti4_lane_zt_x2", [IsStreaming, IsInZT0], [ImmCheck<0, ImmCheck0_0>, ImmCheck<2, ImmCheck0_3>]>;
+}
diff --git a/contrib/llvm-project/clang/include/clang/Basic/arm_sve.td b/contrib/llvm-project/clang/include/clang/Basic/arm_sve.td
index 5e9d1c96558b..6da30e08e752 100644
--- a/contrib/llvm-project/clang/include/clang/Basic/arm_sve.td
+++ b/contrib/llvm-project/clang/include/clang/Basic/arm_sve.td
@@ -13,277 +13,33 @@
//
//===----------------------------------------------------------------------===//
-//===----------------------------------------------------------------------===//
-// Instruction definitions
-//===----------------------------------------------------------------------===//
-// Every intrinsic subclasses "Inst". An intrinsic has a name, a prototype and
-// a sequence of typespecs.
-//
-// The name is the base name of the intrinsic, for example "svld1". This is
-// then mangled by the tblgen backend to add type information ("svld1_s16").
-//
-// A typespec is a sequence of uppercase characters (modifiers) followed by one
-// lowercase character. A typespec encodes a particular "base type" of the
-// intrinsic.
-//
-// An example typespec is "Us" - unsigned short - svuint16_t. The available
-// typespec codes are given below.
-//
-// The string given to an Inst class is a sequence of typespecs. The intrinsic
-// is instantiated for every typespec in the sequence. For example "sdUsUd".
-//
-// The prototype is a string that defines the return type of the intrinsic
-// and the type of each argument. The return type and every argument gets a
-// "modifier" that can change in some way the "base type" of the intrinsic.
-//
-// The modifier 'd' means "default" and does not modify the base type in any
-// way. The available modifiers are given below.
-//
-// Typespecs
-// ---------
-// c: char
-// s: short
-// i: int
-// l: long
-// f: float
-// h: half-float
-// d: double
-// b: bfloat
-
-// Typespec modifiers
-// ------------------
-// P: boolean
-// U: unsigned
-
-// Prototype modifiers
-// -------------------
-// prototype: return (arg, arg, ...)
-//
-// 2,3,4: array of default vectors
-// v: void
-// x: vector of signed integers
-// u: vector of unsigned integers
-// d: default
-// c: const pointer type
-// P: predicate type
-// s: scalar of element type
-// a: scalar of element type (splat to vector type)
-// R: scalar of 1/2 width element type (splat to vector type)
-// r: scalar of 1/4 width element type (splat to vector type)
-// @: unsigned scalar of 1/4 width element type (splat to vector type)
-// e: 1/2 width unsigned elements, 2x element count
-// b: 1/4 width unsigned elements, 4x element count
-// h: 1/2 width elements, 2x element count
-// q: 1/4 width elements, 4x element count
-// o: 4x width elements, 1/4 element count
-//
-// w: vector of element type promoted to 64bits, vector maintains
-// signedness of its element type.
-// f: element type promoted to uint64_t (splat to vector type)
-// j: element type promoted to 64bits (splat to vector type)
-// K: element type bitcast to a signed integer (splat to vector type)
-// L: element type bitcast to an unsigned integer (splat to vector type)
-//
-// i: constant uint64_t
-// k: int32_t
-// l: int64_t
-// m: uint32_t
-// n: uint64_t
-
-// t: svint32_t
-// z: svuint32_t
-// g: svuint64_t
-// O: svfloat16_t
-// M: svfloat32_t
-// N: svfloat64_t
-
-// J: Prefetch type (sv_prfop)
-// A: pointer to int8_t
-// B: pointer to int16_t
-// C: pointer to int32_t
-// D: pointer to int64_t
-
-// E: pointer to uint8_t
-// F: pointer to uint16_t
-// G: pointer to uint32_t
-// H: pointer to uint64_t
-
-// Q: const pointer to void
-
-// S: const pointer to int8_t
-// T: const pointer to int16_t
-// U: const pointer to int32_t
-// V: const pointer to int64_t
-//
-// W: const pointer to uint8_t
-// X: const pointer to uint16_t
-// Y: const pointer to uint32_t
-// Z: const pointer to uint64_t
-
-class MergeType<int val, string suffix=""> {
- int Value = val;
- string Suffix = suffix;
-}
-def MergeNone : MergeType<0>;
-def MergeAny : MergeType<1, "_x">;
-def MergeOp1 : MergeType<2, "_m">;
-def MergeZero : MergeType<3, "_z">;
-def MergeAnyExp : MergeType<4, "_x">; // Use merged builtin with explicit
-def MergeZeroExp : MergeType<5, "_z">; // generation of its inactive argument.
-
-class EltType<int val> {
- int Value = val;
-}
-def EltTyInvalid : EltType<0>;
-def EltTyInt8 : EltType<1>;
-def EltTyInt16 : EltType<2>;
-def EltTyInt32 : EltType<3>;
-def EltTyInt64 : EltType<4>;
-def EltTyFloat16 : EltType<5>;
-def EltTyFloat32 : EltType<6>;
-def EltTyFloat64 : EltType<7>;
-def EltTyBool8 : EltType<8>;
-def EltTyBool16 : EltType<9>;
-def EltTyBool32 : EltType<10>;
-def EltTyBool64 : EltType<11>;
-def EltTyBFloat16 : EltType<12>;
-
-class MemEltType<int val> {
- int Value = val;
-}
-def MemEltTyDefault : MemEltType<0>;
-def MemEltTyInt8 : MemEltType<1>;
-def MemEltTyInt16 : MemEltType<2>;
-def MemEltTyInt32 : MemEltType<3>;
-def MemEltTyInt64 : MemEltType<4>;
-
-class FlagType<int val> {
- int Value = val;
-}
-
-// These must be kept in sync with the flags in utils/TableGen/SveEmitter.h
-// and include/clang/Basic/TargetBuiltins.h
-def NoFlags : FlagType<0x00000000>;
-def FirstEltType : FlagType<0x00000001>;
-// : :
-// : :
-def EltTypeMask : FlagType<0x0000000f>;
-def FirstMemEltType : FlagType<0x00000010>;
-// : :
-// : :
-def MemEltTypeMask : FlagType<0x00000070>;
-def FirstMergeTypeMask : FlagType<0x00000080>;
-// : :
-// : :
-def MergeTypeMask : FlagType<0x00000380>;
-def FirstSplatOperand : FlagType<0x00000400>;
-// : :
-// These flags are used to specify which scalar operand
-// needs to be duplicated/splatted into a vector.
-// : :
-def SplatOperandMask : FlagType<0x00001C00>;
-def IsLoad : FlagType<0x00002000>;
-def IsStore : FlagType<0x00004000>;
-def IsGatherLoad : FlagType<0x00008000>;
-def IsScatterStore : FlagType<0x00010000>;
-def IsStructLoad : FlagType<0x00020000>;
-def IsStructStore : FlagType<0x00040000>;
-def IsZExtReturn : FlagType<0x00080000>; // Return value is sign-extend by default
-def IsOverloadNone : FlagType<0x00100000>; // Intrinsic does not take any overloaded types.
-def IsOverloadWhile : FlagType<0x00200000>; // Use {default type, typeof(operand1)} as overloaded types.
-def IsOverloadWhileRW : FlagType<0x00400000>; // Use {pred(default type), typeof(operand0)} as overloaded types.
-def IsOverloadCvt : FlagType<0x00800000>; // Use {typeof(operand0), typeof(last operand)} as overloaded types.
-def OverloadKindMask : FlagType<0x00E00000>; // When the masked values are all '0', the default type is used as overload type.
-def IsByteIndexed : FlagType<0x01000000>;
-def IsAppendSVALL : FlagType<0x02000000>; // Appends SV_ALL as the last operand.
-def IsInsertOp1SVALL : FlagType<0x04000000>; // Inserts SV_ALL as the second operand.
-def IsPrefetch : FlagType<0x08000000>; // Contiguous prefetches.
-def IsGatherPrefetch : FlagType<0x10000000>;
-def ReverseCompare : FlagType<0x20000000>; // Compare operands must be swapped.
-def ReverseUSDOT : FlagType<0x40000000>; // Unsigned/signed operands must be swapped.
-def IsUndef : FlagType<0x80000000>; // Codegen `undef` of given type.
-def IsTupleCreate : FlagType<0x100000000>;
-def IsTupleGet : FlagType<0x200000000>;
-def IsTupleSet : FlagType<0x400000000>;
-
-// These must be kept in sync with the flags in include/clang/Basic/TargetBuiltins.h
-class ImmCheckType<int val> {
- int Value = val;
-}
-def ImmCheck0_31 : ImmCheckType<0>; // 0..31 (used for e.g. predicate patterns)
-def ImmCheck1_16 : ImmCheckType<1>; // 1..16
-def ImmCheckExtract : ImmCheckType<2>; // 0..(2048/sizeinbits(elt) - 1)
-def ImmCheckShiftRight : ImmCheckType<3>; // 1..sizeinbits(elt)
-def ImmCheckShiftRightNarrow : ImmCheckType<4>; // 1..sizeinbits(elt)/2
-def ImmCheckShiftLeft : ImmCheckType<5>; // 0..(sizeinbits(elt) - 1)
-def ImmCheck0_7 : ImmCheckType<6>; // 0..7
-def ImmCheckLaneIndex : ImmCheckType<7>; // 0..(128/(1*sizeinbits(elt)) - 1)
-def ImmCheckLaneIndexCompRotate : ImmCheckType<8>; // 0..(128/(2*sizeinbits(elt)) - 1)
-def ImmCheckLaneIndexDot : ImmCheckType<9>; // 0..(128/(4*sizeinbits(elt)) - 1)
-def ImmCheckComplexRot90_270 : ImmCheckType<10>; // [90,270]
-def ImmCheckComplexRotAll90 : ImmCheckType<11>; // [0, 90, 180,270]
-def ImmCheck0_13 : ImmCheckType<12>; // 0..13
-def ImmCheck0_1 : ImmCheckType<13>; // 0..1
-def ImmCheck0_2 : ImmCheckType<14>; // 0..2
-def ImmCheck0_3 : ImmCheckType<15>; // 0..3
-
-class ImmCheck<int arg, ImmCheckType kind, int eltSizeArg = -1> {
- int Arg = arg;
- int EltSizeArg = eltSizeArg;
- ImmCheckType Kind = kind;
-}
-
-class Inst<string n, string p, string t, MergeType mt, string i,
- list<FlagType> ft, list<ImmCheck> ch, MemEltType met> {
- string Name = n;
- string Prototype = p;
- string Types = t;
- string ArchGuard = "";
- int Merge = mt.Value;
- string MergeSuffix = mt.Suffix;
- string LLVMIntrinsic = i;
- list<FlagType> Flags = ft;
- list<ImmCheck> ImmChecks = ch;
- int MemEltType = met.Value;
-}
-
-// SInst: Instruction with signed/unsigned suffix (e.g., "s8", "u8")
-class SInst<string n, string p, string t, MergeType mt, string i = "",
- list<FlagType> ft = [], list<ImmCheck> ch = []>
- : Inst<n, p, t, mt, i, ft, ch, MemEltTyDefault> {
-}
-
-// MInst: Instructions which access memory
-class MInst<string n, string p, string t, list<FlagType> f,
- MemEltType met = MemEltTyDefault, string i = "">
- : Inst<n, p, t, MergeNone, i, f, [], met> {
-}
+include "arm_sve_sme_incl.td"
////////////////////////////////////////////////////////////////////////////////
// Loads
// Load one vector (scalar base)
-def SVLD1 : MInst<"svld1[_{2}]", "dPc", "csilUcUsUiUlhfd", [IsLoad], MemEltTyDefault, "aarch64_sve_ld1">;
-def SVLD1SB : MInst<"svld1sb_{d}", "dPS", "silUsUiUl", [IsLoad], MemEltTyInt8, "aarch64_sve_ld1">;
-def SVLD1UB : MInst<"svld1ub_{d}", "dPW", "silUsUiUl", [IsLoad, IsZExtReturn], MemEltTyInt8, "aarch64_sve_ld1">;
-def SVLD1SH : MInst<"svld1sh_{d}", "dPT", "ilUiUl", [IsLoad], MemEltTyInt16, "aarch64_sve_ld1">;
-def SVLD1UH : MInst<"svld1uh_{d}", "dPX", "ilUiUl", [IsLoad, IsZExtReturn], MemEltTyInt16, "aarch64_sve_ld1">;
-def SVLD1SW : MInst<"svld1sw_{d}", "dPU", "lUl", [IsLoad], MemEltTyInt32, "aarch64_sve_ld1">;
-def SVLD1UW : MInst<"svld1uw_{d}", "dPY", "lUl", [IsLoad, IsZExtReturn], MemEltTyInt32, "aarch64_sve_ld1">;
+def SVLD1 : MInst<"svld1[_{2}]", "dPc", "csilUcUsUiUlhfd", [IsLoad, IsStreamingCompatible], MemEltTyDefault, "aarch64_sve_ld1">;
+def SVLD1SB : MInst<"svld1sb_{d}", "dPS", "silUsUiUl", [IsLoad, IsStreamingCompatible], MemEltTyInt8, "aarch64_sve_ld1">;
+def SVLD1UB : MInst<"svld1ub_{d}", "dPW", "silUsUiUl", [IsLoad, IsZExtReturn, IsStreamingCompatible], MemEltTyInt8, "aarch64_sve_ld1">;
+def SVLD1SH : MInst<"svld1sh_{d}", "dPT", "ilUiUl", [IsLoad, IsStreamingCompatible], MemEltTyInt16, "aarch64_sve_ld1">;
+def SVLD1UH : MInst<"svld1uh_{d}", "dPX", "ilUiUl", [IsLoad, IsZExtReturn, IsStreamingCompatible], MemEltTyInt16, "aarch64_sve_ld1">;
+def SVLD1SW : MInst<"svld1sw_{d}", "dPU", "lUl", [IsLoad, IsStreamingCompatible], MemEltTyInt32, "aarch64_sve_ld1">;
+def SVLD1UW : MInst<"svld1uw_{d}", "dPY", "lUl", [IsLoad, IsZExtReturn, IsStreamingCompatible], MemEltTyInt32, "aarch64_sve_ld1">;
-let ArchGuard = "defined(__ARM_FEATURE_SVE_BF16)" in {
- def SVLD1_BF : MInst<"svld1[_{2}]", "dPc", "b", [IsLoad], MemEltTyDefault, "aarch64_sve_ld1">;
- def SVLD1_VNUM_BF : MInst<"svld1_vnum[_{2}]", "dPcl", "b", [IsLoad], MemEltTyDefault, "aarch64_sve_ld1">;
+let TargetGuard = "sve,bf16" in {
+ def SVLD1_BF : MInst<"svld1[_{2}]", "dPc", "b", [IsLoad, IsStreamingCompatible], MemEltTyDefault, "aarch64_sve_ld1">;
+ def SVLD1_VNUM_BF : MInst<"svld1_vnum[_{2}]", "dPcl", "b", [IsLoad, IsStreamingCompatible], MemEltTyDefault, "aarch64_sve_ld1">;
}
// Load one vector (scalar base, VL displacement)
-def SVLD1_VNUM : MInst<"svld1_vnum[_{2}]", "dPcl", "csilUcUsUiUlhfd", [IsLoad], MemEltTyDefault, "aarch64_sve_ld1">;
-def SVLD1SB_VNUM : MInst<"svld1sb_vnum_{d}", "dPSl", "silUsUiUl", [IsLoad], MemEltTyInt8, "aarch64_sve_ld1">;
-def SVLD1UB_VNUM : MInst<"svld1ub_vnum_{d}", "dPWl", "silUsUiUl", [IsLoad, IsZExtReturn], MemEltTyInt8, "aarch64_sve_ld1">;
-def SVLD1SH_VNUM : MInst<"svld1sh_vnum_{d}", "dPTl", "ilUiUl", [IsLoad], MemEltTyInt16, "aarch64_sve_ld1">;
-def SVLD1UH_VNUM : MInst<"svld1uh_vnum_{d}", "dPXl", "ilUiUl", [IsLoad, IsZExtReturn], MemEltTyInt16, "aarch64_sve_ld1">;
-def SVLD1SW_VNUM : MInst<"svld1sw_vnum_{d}", "dPUl", "lUl", [IsLoad], MemEltTyInt32, "aarch64_sve_ld1">;
-def SVLD1UW_VNUM : MInst<"svld1uw_vnum_{d}", "dPYl", "lUl", [IsLoad, IsZExtReturn], MemEltTyInt32, "aarch64_sve_ld1">;
+def SVLD1_VNUM : MInst<"svld1_vnum[_{2}]", "dPcl", "csilUcUsUiUlhfd", [IsLoad, IsStreamingCompatible], MemEltTyDefault, "aarch64_sve_ld1">;
+def SVLD1SB_VNUM : MInst<"svld1sb_vnum_{d}", "dPSl", "silUsUiUl", [IsLoad, IsStreamingCompatible], MemEltTyInt8, "aarch64_sve_ld1">;
+def SVLD1UB_VNUM : MInst<"svld1ub_vnum_{d}", "dPWl", "silUsUiUl", [IsLoad, IsZExtReturn, IsStreamingCompatible], MemEltTyInt8, "aarch64_sve_ld1">;
+def SVLD1SH_VNUM : MInst<"svld1sh_vnum_{d}", "dPTl", "ilUiUl", [IsLoad, IsStreamingCompatible], MemEltTyInt16, "aarch64_sve_ld1">;
+def SVLD1UH_VNUM : MInst<"svld1uh_vnum_{d}", "dPXl", "ilUiUl", [IsLoad, IsZExtReturn, IsStreamingCompatible], MemEltTyInt16, "aarch64_sve_ld1">;
+def SVLD1SW_VNUM : MInst<"svld1sw_vnum_{d}", "dPUl", "lUl", [IsLoad, IsStreamingCompatible], MemEltTyInt32, "aarch64_sve_ld1">;
+def SVLD1UW_VNUM : MInst<"svld1uw_vnum_{d}", "dPYl", "lUl", [IsLoad, IsZExtReturn, IsStreamingCompatible], MemEltTyInt32, "aarch64_sve_ld1">;
// Load one vector (vector base)
def SVLD1_GATHER_BASES_U : MInst<"svld1_gather[_{2}base]_{d}", "dPu", "ilUiUlfd", [IsGatherLoad], MemEltTyDefault, "aarch64_sve_ld1_gather_scalar_offset">;
@@ -381,7 +137,7 @@ def SVLDFF1UH_VNUM : MInst<"svldff1uh_vnum_{d}", "dPXl", "ilUiUl", [IsL
def SVLDFF1SW_VNUM : MInst<"svldff1sw_vnum_{d}", "dPUl", "lUl", [IsLoad], MemEltTyInt32, "aarch64_sve_ldff1">;
def SVLDFF1UW_VNUM : MInst<"svldff1uw_vnum_{d}", "dPYl", "lUl", [IsLoad, IsZExtReturn], MemEltTyInt32, "aarch64_sve_ldff1">;
-let ArchGuard = "defined(__ARM_FEATURE_SVE_BF16)" in {
+let TargetGuard = "sve,bf16" in {
def SVLDFF1_BF : MInst<"svldff1[_{2}]", "dPc", "b", [IsLoad], MemEltTyDefault, "aarch64_sve_ldff1">;
def SVLDFF1_VNUM_BF : MInst<"svldff1_vnum[_{2}]", "dPcl", "b", [IsLoad], MemEltTyDefault, "aarch64_sve_ldff1">;
}
@@ -481,91 +237,123 @@ def SVLDNF1UH_VNUM : MInst<"svldnf1uh_vnum_{d}", "dPXl", "ilUiUl", [IsL
def SVLDNF1SW_VNUM : MInst<"svldnf1sw_vnum_{d}", "dPUl", "lUl", [IsLoad], MemEltTyInt32, "aarch64_sve_ldnf1">;
def SVLDNF1UW_VNUM : MInst<"svldnf1uw_vnum_{d}", "dPYl", "lUl", [IsLoad, IsZExtReturn], MemEltTyInt32, "aarch64_sve_ldnf1">;
-let ArchGuard = "defined(__ARM_FEATURE_SVE_BF16)" in {
+let TargetGuard = "sve,bf16" in {
def SVLDNF1_BF : MInst<"svldnf1[_{2}]", "dPc", "b", [IsLoad], MemEltTyDefault, "aarch64_sve_ldnf1">;
def SVLDNF1_VNUM_BF : MInst<"svldnf1_vnum[_{2}]", "dPcl", "b", [IsLoad], MemEltTyDefault, "aarch64_sve_ldnf1">;
}
// Load one vector, unextended load, non-temporal (scalar base)
-def SVLDNT1 : MInst<"svldnt1[_{2}]", "dPc", "csilUcUsUiUlhfd", [IsLoad], MemEltTyDefault, "aarch64_sve_ldnt1">;
+def SVLDNT1 : MInst<"svldnt1[_{2}]", "dPc", "csilUcUsUiUlhfd", [IsLoad, IsStreamingCompatible], MemEltTyDefault, "aarch64_sve_ldnt1">;
// Load one vector, unextended load, non-temporal (scalar base, VL displacement)
-def SVLDNT1_VNUM : MInst<"svldnt1_vnum[_{2}]", "dPcl", "csilUcUsUiUlhfd", [IsLoad], MemEltTyDefault, "aarch64_sve_ldnt1">;
+def SVLDNT1_VNUM : MInst<"svldnt1_vnum[_{2}]", "dPcl", "csilUcUsUiUlhfd", [IsLoad, IsStreamingCompatible], MemEltTyDefault, "aarch64_sve_ldnt1">;
-let ArchGuard = "defined(__ARM_FEATURE_SVE_BF16)" in {
- def SVLDNT1_BF : MInst<"svldnt1[_{2}]", "dPc", "b", [IsLoad], MemEltTyDefault, "aarch64_sve_ldnt1">;
- def SVLDNT1_VNUM_BF : MInst<"svldnt1_vnum[_{2}]", "dPcl", "b", [IsLoad], MemEltTyDefault, "aarch64_sve_ldnt1">;
+let TargetGuard = "sve,bf16" in {
+ def SVLDNT1_BF : MInst<"svldnt1[_{2}]", "dPc", "b", [IsLoad, IsStreamingCompatible], MemEltTyDefault, "aarch64_sve_ldnt1">;
+ def SVLDNT1_VNUM_BF : MInst<"svldnt1_vnum[_{2}]", "dPcl", "b", [IsLoad, IsStreamingCompatible], MemEltTyDefault, "aarch64_sve_ldnt1">;
}
// Load one quadword and replicate (scalar base)
-def SVLD1RQ : SInst<"svld1rq[_{2}]", "dPc", "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_ld1rq">;
+def SVLD1RQ : SInst<"svld1rq[_{2}]", "dPc", "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_ld1rq", [IsStreamingCompatible]>;
-let ArchGuard = "defined(__ARM_FEATURE_SVE_BF16)" in {
- def SVLD1RQ_BF : SInst<"svld1rq[_{2}]", "dPc", "b", MergeNone, "aarch64_sve_ld1rq">;
+let TargetGuard = "sve,bf16" in {
+ def SVLD1RQ_BF : SInst<"svld1rq[_{2}]", "dPc", "b", MergeNone, "aarch64_sve_ld1rq", [IsStreamingCompatible]>;
}
multiclass StructLoad<string name, string proto, string i> {
- def : SInst<name, proto, "csilUcUsUiUlhfd", MergeNone, i, [IsStructLoad]>;
- let ArchGuard = "defined(__ARM_FEATURE_SVE_BF16)" in {
- def: SInst<name, proto, "b", MergeNone, i, [IsStructLoad]>;
+ def : SInst<name, proto, "csilUcUsUiUlhfd", MergeNone, i, [IsStructLoad, IsStreamingCompatible]>;
+ let TargetGuard = "sve,bf16" in {
+ def: SInst<name, proto, "b", MergeNone, i, [IsStructLoad, IsStreamingCompatible]>;
}
}
// Load N-element structure into N vectors (scalar base)
-defm SVLD2 : StructLoad<"svld2[_{2}]", "2Pc", "aarch64_sve_ld2">;
-defm SVLD3 : StructLoad<"svld3[_{2}]", "3Pc", "aarch64_sve_ld3">;
-defm SVLD4 : StructLoad<"svld4[_{2}]", "4Pc", "aarch64_sve_ld4">;
+defm SVLD2 : StructLoad<"svld2[_{2}]", "2Pc", "aarch64_sve_ld2_sret">;
+defm SVLD3 : StructLoad<"svld3[_{2}]", "3Pc", "aarch64_sve_ld3_sret">;
+defm SVLD4 : StructLoad<"svld4[_{2}]", "4Pc", "aarch64_sve_ld4_sret">;
// Load N-element structure into N vectors (scalar base, VL displacement)
-defm SVLD2_VNUM : StructLoad<"svld2_vnum[_{2}]", "2Pcl", "aarch64_sve_ld2">;
-defm SVLD3_VNUM : StructLoad<"svld3_vnum[_{2}]", "3Pcl", "aarch64_sve_ld3">;
-defm SVLD4_VNUM : StructLoad<"svld4_vnum[_{2}]", "4Pcl", "aarch64_sve_ld4">;
+defm SVLD2_VNUM : StructLoad<"svld2_vnum[_{2}]", "2Pcl", "aarch64_sve_ld2_sret">;
+defm SVLD3_VNUM : StructLoad<"svld3_vnum[_{2}]", "3Pcl", "aarch64_sve_ld3_sret">;
+defm SVLD4_VNUM : StructLoad<"svld4_vnum[_{2}]", "4Pcl", "aarch64_sve_ld4_sret">;
// Load one octoword and replicate (scalar base)
-let ArchGuard = "defined(__ARM_FEATURE_SVE_MATMUL_FP64)" in {
+let TargetGuard = "sve,f64mm" in {
def SVLD1RO : SInst<"svld1ro[_{2}]", "dPc", "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_ld1ro">;
}
-let ArchGuard = "defined(__ARM_FEATURE_SVE_MATMUL_FP64) && defined(__ARM_FEATURE_SVE_BF16)" in {
+let TargetGuard = "sve,f64mm,bf16" in {
def SVLD1RO_BF16 : SInst<"svld1ro[_{2}]", "dPc", "b", MergeNone, "aarch64_sve_ld1ro">;
}
-let ArchGuard = "defined(__ARM_FEATURE_SVE_BF16)" in {
- def SVBFDOT : SInst<"svbfdot[_{0}]", "MMdd", "b", MergeNone, "aarch64_sve_bfdot", [IsOverloadNone]>;
- def SVBFMLALB : SInst<"svbfmlalb[_{0}]", "MMdd", "b", MergeNone, "aarch64_sve_bfmlalb", [IsOverloadNone]>;
- def SVBFMLALT : SInst<"svbfmlalt[_{0}]", "MMdd", "b", MergeNone, "aarch64_sve_bfmlalt", [IsOverloadNone]>;
- def SVBFMMLA : SInst<"svbfmmla[_{0}]", "MMdd", "b", MergeNone, "aarch64_sve_bfmmla", [IsOverloadNone]>;
- def SVBFDOT_N : SInst<"svbfdot[_n_{0}]", "MMda", "b", MergeNone, "aarch64_sve_bfdot", [IsOverloadNone]>;
- def SVBFMLAL_N : SInst<"svbfmlalb[_n_{0}]", "MMda", "b", MergeNone, "aarch64_sve_bfmlalb", [IsOverloadNone]>;
- def SVBFMLALT_N : SInst<"svbfmlalt[_n_{0}]", "MMda", "b", MergeNone, "aarch64_sve_bfmlalt", [IsOverloadNone]>;
- def SVBFDOT_LANE : SInst<"svbfdot_lane[_{0}]", "MMddn", "b", MergeNone, "aarch64_sve_bfdot_lane", [IsOverloadNone], [ImmCheck<3, ImmCheck0_3>]>;
- def SVBFMLALB_LANE : SInst<"svbfmlalb_lane[_{0}]", "MMddn", "b", MergeNone, "aarch64_sve_bfmlalb_lane", [IsOverloadNone], [ImmCheck<3, ImmCheck0_7>]>;
- def SVBFMLALT_LANE : SInst<"svbfmlalt_lane[_{0}]", "MMddn", "b", MergeNone, "aarch64_sve_bfmlalt_lane", [IsOverloadNone], [ImmCheck<3, ImmCheck0_7>]>;
+let TargetGuard = "sve,bf16" in {
+ def SVBFDOT : SInst<"svbfdot[_{0}]", "MMdd", "b", MergeNone, "aarch64_sve_bfdot", [IsOverloadNone, IsStreamingCompatible]>;
+ def SVBFMLALB : SInst<"svbfmlalb[_{0}]", "MMdd", "b", MergeNone, "aarch64_sve_bfmlalb", [IsOverloadNone, IsStreamingCompatible]>;
+ def SVBFMLALT : SInst<"svbfmlalt[_{0}]", "MMdd", "b", MergeNone, "aarch64_sve_bfmlalt", [IsOverloadNone, IsStreamingCompatible]>;
+ def SVBFMMLA : SInst<"svbfmmla[_{0}]", "MMdd", "b", MergeNone, "aarch64_sve_bfmmla", [IsOverloadNone, IsStreamingCompatible]>;
+ def SVBFDOT_N : SInst<"svbfdot[_n_{0}]", "MMda", "b", MergeNone, "aarch64_sve_bfdot", [IsOverloadNone, IsStreamingCompatible]>;
+ def SVBFMLAL_N : SInst<"svbfmlalb[_n_{0}]", "MMda", "b", MergeNone, "aarch64_sve_bfmlalb", [IsOverloadNone, IsStreamingCompatible]>;
+ def SVBFMLALT_N : SInst<"svbfmlalt[_n_{0}]", "MMda", "b", MergeNone, "aarch64_sve_bfmlalt", [IsOverloadNone, IsStreamingCompatible]>;
+ def SVBFDOT_LANE : SInst<"svbfdot_lane[_{0}]", "MMddi", "b", MergeNone, "aarch64_sve_bfdot_lane_v2", [IsOverloadNone, IsStreamingCompatible], [ImmCheck<3, ImmCheck0_3>]>;
+ def SVBFMLALB_LANE : SInst<"svbfmlalb_lane[_{0}]", "MMddi", "b", MergeNone, "aarch64_sve_bfmlalb_lane_v2", [IsOverloadNone, IsStreamingCompatible], [ImmCheck<3, ImmCheck0_7>]>;
+ def SVBFMLALT_LANE : SInst<"svbfmlalt_lane[_{0}]", "MMddi", "b", MergeNone, "aarch64_sve_bfmlalt_lane_v2", [IsOverloadNone, IsStreamingCompatible], [ImmCheck<3, ImmCheck0_7>]>;
+}
+
+let TargetGuard = "sve2p1" in {
+ // Contiguous zero-extending load to quadword (single vector).
+ def SVLD1UWQ : MInst<"svld1uwq[_{d}]", "dPc", "iUif", [IsLoad], MemEltTyInt32, "aarch64_sve_ld1uwq">;
+ def SVLD1UWQ_VNUM : MInst<"svld1uwq_vnum[_{d}]", "dPcl", "iUif", [IsLoad], MemEltTyInt32, "aarch64_sve_ld1uwq">;
+
+ def SVLD1UDQ : MInst<"svld1udq[_{d}]", "dPc", "lUld", [IsLoad], MemEltTyInt64, "aarch64_sve_ld1udq">;
+ def SVLD1UDQ_VNUM : MInst<"svld1udq_vnum[_{d}]", "dPcl", "lUld", [IsLoad], MemEltTyInt64, "aarch64_sve_ld1udq">;
+
+ // Load one vector (vector base + scalar offset)
+ def SVLD1Q_GATHER_U64BASE_OFFSET : MInst<"svld1q_gather[_{2}base]_offset_{d}", "dPgl", "cUcsUsiUilUlfhdb", [IsGatherLoad, IsByteIndexed], MemEltTyDefault, "aarch64_sve_ld1q_gather_scalar_offset">;
+ def SVLD1Q_GATHER_U64BASE : MInst<"svld1q_gather[_{2}base]_{d}", "dPg", "cUcsUsiUilUlfhdb", [IsGatherLoad, IsByteIndexed], MemEltTyDefault, "aarch64_sve_ld1q_gather_scalar_offset">;
+
+ // Load one vector (scalar base + vector offset)
+ def SVLD1Q_GATHER_U64OFFSET : MInst<"svld1q_gather_[{3}]offset[_{d}]", "dPcg", "cUcsUsiUilUlfhdb", [IsGatherLoad, IsByteIndexed], MemEltTyDefault, "aarch64_sve_ld1q_gather_vector_offset">;
+
+ // Load N-element structure into N vectors (scalar base)
+ defm SVLD2Q : StructLoad<"svld2q[_{2}]", "2Pc", "aarch64_sve_ld2q_sret">;
+ defm SVLD3Q : StructLoad<"svld3q[_{2}]", "3Pc", "aarch64_sve_ld3q_sret">;
+ defm SVLD4Q : StructLoad<"svld4q[_{2}]", "4Pc", "aarch64_sve_ld4q_sret">;
+
+ // Load N-element structure into N vectors (scalar base, VL displacement)
+ defm SVLD2Q_VNUM : StructLoad<"svld2q_vnum[_{2}]", "2Pcl", "aarch64_sve_ld2q_sret">;
+ defm SVLD3Q_VNUM : StructLoad<"svld3q_vnum[_{2}]", "3Pcl", "aarch64_sve_ld3q_sret">;
+ defm SVLD4Q_VNUM : StructLoad<"svld4q_vnum[_{2}]", "4Pcl", "aarch64_sve_ld4q_sret">;
+
+ // Load quadwords (scalar base + vector index)
+ def SVLD1Q_GATHER_INDICES_U : MInst<"svld1q_gather_[{3}]index[_{d}]", "dPcg", "sUsiUilUlbhfd", [IsGatherLoad], MemEltTyDefault, "aarch64_sve_ld1q_gather_index">;
+
+ // Load quadwords (vector base + scalar index)
+ def SVLD1Q_GATHER_INDEX_S : MInst<"svld1q_gather[_{2}base]_index_{d}", "dPgl", "sUsiUilUlbhfd", [IsGatherLoad], MemEltTyDefault, "aarch64_sve_ld1q_gather_scalar_offset">;
}
////////////////////////////////////////////////////////////////////////////////
// Stores
// Store one vector (scalar base)
-def SVST1 : MInst<"svst1[_{d}]", "vPpd", "csilUcUsUiUlhfd", [IsStore], MemEltTyDefault, "aarch64_sve_st1">;
-def SVST1B_S : MInst<"svst1b[_{d}]", "vPAd", "sil", [IsStore], MemEltTyInt8, "aarch64_sve_st1">;
-def SVST1B_U : MInst<"svst1b[_{d}]", "vPEd", "UsUiUl", [IsStore], MemEltTyInt8, "aarch64_sve_st1">;
-def SVST1H_S : MInst<"svst1h[_{d}]", "vPBd", "il", [IsStore], MemEltTyInt16, "aarch64_sve_st1">;
-def SVST1H_U : MInst<"svst1h[_{d}]", "vPFd", "UiUl", [IsStore], MemEltTyInt16, "aarch64_sve_st1">;
-def SVST1W_S : MInst<"svst1w[_{d}]", "vPCd", "l", [IsStore], MemEltTyInt32, "aarch64_sve_st1">;
-def SVST1W_U : MInst<"svst1w[_{d}]", "vPGd", "Ul", [IsStore], MemEltTyInt32, "aarch64_sve_st1">;
+def SVST1 : MInst<"svst1[_{d}]", "vPpd", "csilUcUsUiUlhfd", [IsStore, IsStreamingCompatible], MemEltTyDefault, "aarch64_sve_st1">;
+def SVST1B_S : MInst<"svst1b[_{d}]", "vPAd", "sil", [IsStore, IsStreamingCompatible], MemEltTyInt8, "aarch64_sve_st1">;
+def SVST1B_U : MInst<"svst1b[_{d}]", "vPEd", "UsUiUl", [IsStore, IsStreamingCompatible], MemEltTyInt8, "aarch64_sve_st1">;
+def SVST1H_S : MInst<"svst1h[_{d}]", "vPBd", "il", [IsStore, IsStreamingCompatible], MemEltTyInt16, "aarch64_sve_st1">;
+def SVST1H_U : MInst<"svst1h[_{d}]", "vPFd", "UiUl", [IsStore, IsStreamingCompatible], MemEltTyInt16, "aarch64_sve_st1">;
+def SVST1W_S : MInst<"svst1w[_{d}]", "vPCd", "l", [IsStore, IsStreamingCompatible], MemEltTyInt32, "aarch64_sve_st1">;
+def SVST1W_U : MInst<"svst1w[_{d}]", "vPGd", "Ul", [IsStore, IsStreamingCompatible], MemEltTyInt32, "aarch64_sve_st1">;
// Store one vector (scalar base, VL displacement)
-def SVST1_VNUM : MInst<"svst1_vnum[_{d}]", "vPpld", "csilUcUsUiUlhfd", [IsStore], MemEltTyDefault, "aarch64_sve_st1">;
-def SVST1B_VNUM_S : MInst<"svst1b_vnum[_{d}]", "vPAld", "sil", [IsStore], MemEltTyInt8, "aarch64_sve_st1">;
-def SVST1B_VNUM_U : MInst<"svst1b_vnum[_{d}]", "vPEld", "UsUiUl", [IsStore], MemEltTyInt8, "aarch64_sve_st1">;
-def SVST1H_VNUM_S : MInst<"svst1h_vnum[_{d}]", "vPBld", "il", [IsStore], MemEltTyInt16, "aarch64_sve_st1">;
-def SVST1H_VNUM_U : MInst<"svst1h_vnum[_{d}]", "vPFld", "UiUl", [IsStore], MemEltTyInt16, "aarch64_sve_st1">;
-def SVST1W_VNUM_S : MInst<"svst1w_vnum[_{d}]", "vPCld", "l", [IsStore], MemEltTyInt32, "aarch64_sve_st1">;
-def SVST1W_VNUM_U : MInst<"svst1w_vnum[_{d}]", "vPGld", "Ul", [IsStore], MemEltTyInt32, "aarch64_sve_st1">;
+def SVST1_VNUM : MInst<"svst1_vnum[_{d}]", "vPpld", "csilUcUsUiUlhfd", [IsStore, IsStreamingCompatible], MemEltTyDefault, "aarch64_sve_st1">;
+def SVST1B_VNUM_S : MInst<"svst1b_vnum[_{d}]", "vPAld", "sil", [IsStore, IsStreamingCompatible], MemEltTyInt8, "aarch64_sve_st1">;
+def SVST1B_VNUM_U : MInst<"svst1b_vnum[_{d}]", "vPEld", "UsUiUl", [IsStore, IsStreamingCompatible], MemEltTyInt8, "aarch64_sve_st1">;
+def SVST1H_VNUM_S : MInst<"svst1h_vnum[_{d}]", "vPBld", "il", [IsStore, IsStreamingCompatible], MemEltTyInt16, "aarch64_sve_st1">;
+def SVST1H_VNUM_U : MInst<"svst1h_vnum[_{d}]", "vPFld", "UiUl", [IsStore, IsStreamingCompatible], MemEltTyInt16, "aarch64_sve_st1">;
+def SVST1W_VNUM_S : MInst<"svst1w_vnum[_{d}]", "vPCld", "l", [IsStore, IsStreamingCompatible], MemEltTyInt32, "aarch64_sve_st1">;
+def SVST1W_VNUM_U : MInst<"svst1w_vnum[_{d}]", "vPGld", "Ul", [IsStore, IsStreamingCompatible], MemEltTyInt32, "aarch64_sve_st1">;
-let ArchGuard = "defined(__ARM_FEATURE_SVE_BF16)" in {
- def SVST1_BF : MInst<"svst1[_{d}]", "vPpd", "b", [IsStore], MemEltTyDefault, "aarch64_sve_st1">;
- def SVST1_VNUM_BF : MInst<"svst1_vnum[_{d}]", "vPpld", "b", [IsStore], MemEltTyDefault, "aarch64_sve_st1">;
+let TargetGuard = "sve,bf16" in {
+ def SVST1_BF : MInst<"svst1[_{d}]", "vPpd", "b", [IsStore, IsStreamingCompatible], MemEltTyDefault, "aarch64_sve_st1">;
+ def SVST1_VNUM_BF : MInst<"svst1_vnum[_{d}]", "vPpld", "b", [IsStore, IsStreamingCompatible], MemEltTyDefault, "aarch64_sve_st1">;
}
// Store one vector (vector base)
@@ -638,9 +426,9 @@ def SVST1H_SCATTER_INDEX_S : MInst<"svst1h_scatter[_{2}base]_index[_{d}]", "v
def SVST1W_SCATTER_INDEX_S : MInst<"svst1w_scatter[_{2}base]_index[_{d}]", "vPuld", "lUl", [IsScatterStore], MemEltTyInt32, "aarch64_sve_st1_scatter_scalar_offset">;
multiclass StructStore<string name, string proto, string i> {
- def : SInst<name, proto, "csilUcUsUiUlhfd", MergeNone, i, [IsStructStore]>;
- let ArchGuard = "defined(__ARM_FEATURE_SVE_BF16)" in {
- def: SInst<name, proto, "b", MergeNone, i, [IsStructStore]>;
+ def : SInst<name, proto, "csilUcUsUiUlhfd", MergeNone, i, [IsStructStore, IsStreamingCompatible]>;
+ let TargetGuard = "sve,bf16" in {
+ def: SInst<name, proto, "b", MergeNone, i, [IsStructStore, IsStreamingCompatible]>;
}
}
// Store N vectors into N-element structure (scalar base)
@@ -654,30 +442,62 @@ defm SVST3_VNUM : StructStore<"svst3_vnum[_{d}]", "vPpl3", "aarch64_sve_st3">;
defm SVST4_VNUM : StructStore<"svst4_vnum[_{d}]", "vPpl4", "aarch64_sve_st4">;
// Store one vector, with no truncation, non-temporal (scalar base)
-def SVSTNT1 : MInst<"svstnt1[_{d}]", "vPpd", "csilUcUsUiUlhfd", [IsStore], MemEltTyDefault, "aarch64_sve_stnt1">;
+def SVSTNT1 : MInst<"svstnt1[_{d}]", "vPpd", "csilUcUsUiUlhfd", [IsStore, IsStreamingCompatible], MemEltTyDefault, "aarch64_sve_stnt1">;
// Store one vector, with no truncation, non-temporal (scalar base, VL displacement)
-def SVSTNT1_VNUM : MInst<"svstnt1_vnum[_{d}]", "vPpld", "csilUcUsUiUlhfd", [IsStore], MemEltTyDefault, "aarch64_sve_stnt1">;
+def SVSTNT1_VNUM : MInst<"svstnt1_vnum[_{d}]", "vPpld", "csilUcUsUiUlhfd", [IsStore, IsStreamingCompatible], MemEltTyDefault, "aarch64_sve_stnt1">;
-let ArchGuard = "defined(__ARM_FEATURE_SVE_BF16)" in {
- def SVSTNT1_BF : MInst<"svstnt1[_{d}]", "vPpd", "b", [IsStore], MemEltTyDefault, "aarch64_sve_stnt1">;
- def SVSTNT1_VNUM_BF : MInst<"svstnt1_vnum[_{d}]", "vPpld", "b", [IsStore], MemEltTyDefault, "aarch64_sve_stnt1">;
+let TargetGuard = "sve,bf16" in {
+ def SVSTNT1_BF : MInst<"svstnt1[_{d}]", "vPpd", "b", [IsStore, IsStreamingCompatible], MemEltTyDefault, "aarch64_sve_stnt1">;
+ def SVSTNT1_VNUM_BF : MInst<"svstnt1_vnum[_{d}]", "vPpld", "b", [IsStore, IsStreamingCompatible], MemEltTyDefault, "aarch64_sve_stnt1">;
+}
+
+let TargetGuard = "sve2p1" in {
+ // Contiguous truncating store from quadword (single vector).
+ def SVST1UWQ : MInst<"svst1wq[_{d}]", "vPcd", "iUif", [IsStore], MemEltTyInt32, "aarch64_sve_st1wq">;
+ def SVST1UWQ_VNUM : MInst<"svst1wq_vnum[_{d}]", "vPcld", "iUif", [IsStore], MemEltTyInt32, "aarch64_sve_st1wq">;
+
+ def SVST1UDQ : MInst<"svst1dq[_{d}]", "vPcd", "lUld", [IsStore], MemEltTyInt64, "aarch64_sve_st1dq">;
+ def SVST1UDQ_VNUM : MInst<"svst1dq_vnum[_{d}]", "vPcld", "lUld", [IsStore], MemEltTyInt64, "aarch64_sve_st1dq">;
+
+ // Store one vector (vector base + scalar offset)
+ def SVST1Q_SCATTER_U64BASE_OFFSET : MInst<"svst1q_scatter[_{2}base]_offset[_{d}]", "vPgld", "cUcsUsiUilUlfhdb", [IsScatterStore, IsByteIndexed], MemEltTyDefault, "aarch64_sve_st1q_scatter_scalar_offset">;
+ def SVST1Q_SCATTER_U64BASE : MInst<"svst1q_scatter[_{2}base][_{d}]", "vPgd", "cUcsUsiUilUlfhdb", [IsScatterStore, IsByteIndexed], MemEltTyDefault, "aarch64_sve_st1q_scatter_scalar_offset">;
+
+ // Store one vector (scalar base + vector offset)
+ def SVST1Q_SCATTER_U64OFFSET : MInst<"svst1q_scatter_[{3}]offset[_{d}]", "vPpgd", "cUcsUsiUilUlfhdb", [IsScatterStore, IsByteIndexed], MemEltTyDefault, "aarch64_sve_st1q_scatter_vector_offset">;
+
+ // Store N vectors into N-element structure (scalar base)
+ defm SVST2Q : StructStore<"svst2q[_{d}]", "vPc2", "aarch64_sve_st2q">;
+ defm SVST3Q : StructStore<"svst3q[_{d}]", "vPc3", "aarch64_sve_st3q">;
+ defm SVST4Q : StructStore<"svst4q[_{d}]", "vPc4", "aarch64_sve_st4q">;
+
+ // Store N vectors into N-element structure (scalar base, VL displacement)
+ defm SVST2Q_VNUM : StructStore<"svst2q_vnum[_{d}]", "vPcl2", "aarch64_sve_st2q">;
+ defm SVST3Q_VNUM : StructStore<"svst3q_vnum[_{d}]", "vPcl3", "aarch64_sve_st3q">;
+ defm SVST4Q_VNUM : StructStore<"svst4q_vnum[_{d}]", "vPcl4", "aarch64_sve_st4q">;
+
+ // Scatter store quadwords (scalar base + vector index)
+ def SVST1Q_SCATTER_INDICES_U : MInst<"svst1q_scatter_[{3}]index[_{d}]", "vPpgd", "sUsiUilUlbhfd", [IsScatterStore], MemEltTyDefault, "aarch64_sve_st1q_scatter_index">;
+
+ // Scatter store quadwords (vector base + scalar index)
+ def SVST1Q_SCATTER_INDEX_S : MInst<"svst1q_scatter[_{2}base]_index[_{d}]", "vPgld", "sUsiUilUlbhfd", [IsScatterStore], MemEltTyDefault, "aarch64_sve_st1q_scatter_scalar_offset">;
}
////////////////////////////////////////////////////////////////////////////////
// Prefetches
// Prefetch (Scalar base)
-def SVPRFB : MInst<"svprfb", "vPQJ", "c", [IsPrefetch], MemEltTyInt8, "aarch64_sve_prf">;
-def SVPRFH : MInst<"svprfh", "vPQJ", "s", [IsPrefetch], MemEltTyInt16, "aarch64_sve_prf">;
-def SVPRFW : MInst<"svprfw", "vPQJ", "i", [IsPrefetch], MemEltTyInt32, "aarch64_sve_prf">;
-def SVPRFD : MInst<"svprfd", "vPQJ", "l", [IsPrefetch], MemEltTyInt64, "aarch64_sve_prf">;
+def SVPRFB : MInst<"svprfb", "vPQJ", "c", [IsPrefetch, IsStreamingCompatible], MemEltTyInt8, "aarch64_sve_prf">;
+def SVPRFH : MInst<"svprfh", "vPQJ", "s", [IsPrefetch, IsStreamingCompatible], MemEltTyInt16, "aarch64_sve_prf">;
+def SVPRFW : MInst<"svprfw", "vPQJ", "i", [IsPrefetch, IsStreamingCompatible], MemEltTyInt32, "aarch64_sve_prf">;
+def SVPRFD : MInst<"svprfd", "vPQJ", "l", [IsPrefetch, IsStreamingCompatible], MemEltTyInt64, "aarch64_sve_prf">;
// Prefetch (Scalar base, VL displacement)
-def SVPRFB_VNUM : MInst<"svprfb_vnum", "vPQlJ", "c", [IsPrefetch], MemEltTyInt8, "aarch64_sve_prf">;
-def SVPRFH_VNUM : MInst<"svprfh_vnum", "vPQlJ", "s", [IsPrefetch], MemEltTyInt16, "aarch64_sve_prf">;
-def SVPRFW_VNUM : MInst<"svprfw_vnum", "vPQlJ", "i", [IsPrefetch], MemEltTyInt32, "aarch64_sve_prf">;
-def SVPRFD_VNUM : MInst<"svprfd_vnum", "vPQlJ", "l", [IsPrefetch], MemEltTyInt64, "aarch64_sve_prf">;
+def SVPRFB_VNUM : MInst<"svprfb_vnum", "vPQlJ", "c", [IsPrefetch, IsStreamingCompatible], MemEltTyInt8, "aarch64_sve_prf">;
+def SVPRFH_VNUM : MInst<"svprfh_vnum", "vPQlJ", "s", [IsPrefetch, IsStreamingCompatible], MemEltTyInt16, "aarch64_sve_prf">;
+def SVPRFW_VNUM : MInst<"svprfw_vnum", "vPQlJ", "i", [IsPrefetch, IsStreamingCompatible], MemEltTyInt32, "aarch64_sve_prf">;
+def SVPRFD_VNUM : MInst<"svprfd_vnum", "vPQlJ", "l", [IsPrefetch, IsStreamingCompatible], MemEltTyInt64, "aarch64_sve_prf">;
// Prefetch (Vector bases)
def SVPRFB_GATHER_BASES : MInst<"svprfb_gather[_{2}base]", "vPdJ", "UiUl", [IsGatherPrefetch], MemEltTyInt8, "aarch64_sve_prfb_gather_scalar_offset">;
@@ -723,18 +543,18 @@ def SVADRD : SInst<"svadrd[_{0}base]_[{2}]index", "uud", "ilUiUl", MergeNone, "
////////////////////////////////////////////////////////////////////////////////
// Scalar to vector
-def SVDUPQ_8 : SInst<"svdupq[_n]_{d}", "dssssssssssssssss", "cUc", MergeNone>;
-def SVDUPQ_16 : SInst<"svdupq[_n]_{d}", "dssssssss", "sUsh", MergeNone>;
-let ArchGuard = "defined(__ARM_FEATURE_SVE_BF16)" in {
- def SVDUPQ_BF16 : SInst<"svdupq[_n]_{d}", "dssssssss", "b", MergeNone>;
+def SVDUPQ_8 : SInst<"svdupq[_n]_{d}", "dssssssssssssssss", "cUc", MergeNone, "", [IsStreamingCompatible]>;
+def SVDUPQ_16 : SInst<"svdupq[_n]_{d}", "dssssssss", "sUsh", MergeNone, "", [IsStreamingCompatible]>;
+let TargetGuard = "sve,bf16" in {
+ def SVDUPQ_BF16 : SInst<"svdupq[_n]_{d}", "dssssssss", "b", MergeNone, "", [IsStreamingCompatible]>;
}
-def SVDUPQ_32 : SInst<"svdupq[_n]_{d}", "dssss", "iUif", MergeNone>;
-def SVDUPQ_64 : SInst<"svdupq[_n]_{d}", "dss", "lUld", MergeNone>;
+def SVDUPQ_32 : SInst<"svdupq[_n]_{d}", "dssss", "iUif", MergeNone, "", [IsStreamingCompatible]>;
+def SVDUPQ_64 : SInst<"svdupq[_n]_{d}", "dss", "lUld", MergeNone, "", [IsStreamingCompatible]>;
multiclass svdup_base<string n, string p, MergeType mt, string i> {
- def NAME : SInst<n, p, "csilUcUsUiUlhfd", mt, i>;
- let ArchGuard = "defined(__ARM_FEATURE_SVE_BF16)" in {
- def _BF16: SInst<n, p, "b", mt, i>;
+ def NAME : SInst<n, p, "csilUcUsUiUlhfd", mt, i, [IsStreamingCompatible]>;
+ let TargetGuard = "sve,bf16" in {
+ def _BF16: SInst<n, p, "b", mt, i, [IsStreamingCompatible]>;
}
}
@@ -743,14 +563,14 @@ defm SVDUP_M : svdup_base<"svdup[_n]_{d}", "ddPs", MergeOp1, "aarch64_sve_du
defm SVDUP_X : svdup_base<"svdup[_n]_{d}", "dPs", MergeAnyExp, "aarch64_sve_dup">;
defm SVDUP_Z : svdup_base<"svdup[_n]_{d}", "dPs", MergeZeroExp, "aarch64_sve_dup">;
-def SVINDEX : SInst<"svindex_{d}", "dss", "csilUcUsUiUl", MergeNone, "aarch64_sve_index">;
+def SVINDEX : SInst<"svindex_{d}", "dss", "csilUcUsUiUl", MergeNone, "aarch64_sve_index", [IsStreamingCompatible]>;
// Integer arithmetic
-multiclass SInstZPZ<string name, string types, string intrinsic, list<FlagType> flags=[]> {
- def _M : SInst<name # "[_{d}]", "ddPd", types, MergeOp1, intrinsic, flags>;
- def _X : SInst<name # "[_{d}]", "dPd", types, MergeAnyExp, intrinsic, flags>;
- def _Z : SInst<name # "[_{d}]", "dPd", types, MergeZeroExp, intrinsic, flags>;
+multiclass SInstZPZ<string name, string types, string intrinsic> {
+ def _M : SInst<name # "[_{d}]", "ddPd", types, MergeOp1, intrinsic, [IsStreamingCompatible]>;
+ def _X : SInst<name # "[_{d}]", "dPd", types, MergeAnyExp, intrinsic, [IsStreamingCompatible]>;
+ def _Z : SInst<name # "[_{d}]", "dPd", types, MergeZeroExp, intrinsic, [IsStreamingCompatible]>;
}
defm SVABS : SInstZPZ<"svabs", "csil", "aarch64_sve_abs">;
@@ -758,76 +578,76 @@ defm SVNEG : SInstZPZ<"svneg", "csil", "aarch64_sve_neg">;
//------------------------------------------------------------------------------
-multiclass SInstZPZZ<string name, string types, string intrinsic, list<FlagType> flags=[]> {
- def _M : SInst<name # "[_{d}]", "dPdd", types, MergeOp1, intrinsic, flags>;
- def _X : SInst<name # "[_{d}]", "dPdd", types, MergeAny, intrinsic, flags>;
- def _Z : SInst<name # "[_{d}]", "dPdd", types, MergeZero, intrinsic, flags>;
-
- def _N_M : SInst<name # "[_n_{d}]", "dPda", types, MergeOp1, intrinsic, flags>;
- def _N_X : SInst<name # "[_n_{d}]", "dPda", types, MergeAny, intrinsic, flags>;
- def _N_Z : SInst<name # "[_n_{d}]", "dPda", types, MergeZero, intrinsic, flags>;
-}
-
-defm SVABD_S : SInstZPZZ<"svabd", "csil", "aarch64_sve_sabd">;
-defm SVABD_U : SInstZPZZ<"svabd", "UcUsUiUl", "aarch64_sve_uabd">;
-defm SVADD : SInstZPZZ<"svadd", "csilUcUsUiUl", "aarch64_sve_add">;
-defm SVDIV_S : SInstZPZZ<"svdiv", "il", "aarch64_sve_sdiv">;
-defm SVDIV_U : SInstZPZZ<"svdiv", "UiUl", "aarch64_sve_udiv">;
-defm SVDIVR_S : SInstZPZZ<"svdivr", "il", "aarch64_sve_sdivr">;
-defm SVDIVR_U : SInstZPZZ<"svdivr", "UiUl", "aarch64_sve_udivr">;
-defm SVMAX_S : SInstZPZZ<"svmax", "csil", "aarch64_sve_smax">;
-defm SVMAX_U : SInstZPZZ<"svmax", "UcUsUiUl", "aarch64_sve_umax">;
-defm SVMIN_S : SInstZPZZ<"svmin", "csil", "aarch64_sve_smin">;
-defm SVMIN_U : SInstZPZZ<"svmin", "UcUsUiUl", "aarch64_sve_umin">;
-defm SVMUL : SInstZPZZ<"svmul", "csilUcUsUiUl", "aarch64_sve_mul">;
-defm SVMULH_S : SInstZPZZ<"svmulh", "csil", "aarch64_sve_smulh">;
-defm SVMULH_U : SInstZPZZ<"svmulh", "UcUsUiUl", "aarch64_sve_umulh">;
-defm SVSUB : SInstZPZZ<"svsub", "csilUcUsUiUl", "aarch64_sve_sub">;
-defm SVSUBR : SInstZPZZ<"svsubr", "csilUcUsUiUl", "aarch64_sve_subr">;
+multiclass SInstZPZZ<string name, string types, string m_intrinsic, string x_intrinsic, list<FlagType> flags=[]> {
+ def _M : SInst<name # "[_{d}]", "dPdd", types, MergeOp1, m_intrinsic, !listconcat(flags, [IsStreamingCompatible])>;
+ def _X : SInst<name # "[_{d}]", "dPdd", types, MergeAny, x_intrinsic, !listconcat(flags, [IsStreamingCompatible])>;
+ def _Z : SInst<name # "[_{d}]", "dPdd", types, MergeZero, m_intrinsic, !listconcat(flags, [IsStreamingCompatible])>;
+
+ def _N_M : SInst<name # "[_n_{d}]", "dPda", types, MergeOp1, m_intrinsic, !listconcat(flags, [IsStreamingCompatible])>;
+ def _N_X : SInst<name # "[_n_{d}]", "dPda", types, MergeAny, x_intrinsic, !listconcat(flags, [IsStreamingCompatible])>;
+ def _N_Z : SInst<name # "[_n_{d}]", "dPda", types, MergeZero, m_intrinsic, !listconcat(flags, [IsStreamingCompatible])>;
+}
+
+defm SVABD_S : SInstZPZZ<"svabd", "csil", "aarch64_sve_sabd", "aarch64_sve_sabd_u">;
+defm SVABD_U : SInstZPZZ<"svabd", "UcUsUiUl", "aarch64_sve_uabd", "aarch64_sve_uabd_u">;
+defm SVADD : SInstZPZZ<"svadd", "csilUcUsUiUl", "aarch64_sve_add", "aarch64_sve_add_u">;
+defm SVDIV_S : SInstZPZZ<"svdiv", "il", "aarch64_sve_sdiv", "aarch64_sve_sdiv_u">;
+defm SVDIV_U : SInstZPZZ<"svdiv", "UiUl", "aarch64_sve_udiv", "aarch64_sve_udiv_u">;
+defm SVDIVR_S : SInstZPZZ<"svdivr", "il", "aarch64_sve_sdivr", "aarch64_sve_sdiv_u", [ReverseMergeAnyBinOp]>;
+defm SVDIVR_U : SInstZPZZ<"svdivr", "UiUl", "aarch64_sve_udivr", "aarch64_sve_udiv_u", [ReverseMergeAnyBinOp]>;
+defm SVMAX_S : SInstZPZZ<"svmax", "csil", "aarch64_sve_smax", "aarch64_sve_smax_u">;
+defm SVMAX_U : SInstZPZZ<"svmax", "UcUsUiUl", "aarch64_sve_umax", "aarch64_sve_umax_u">;
+defm SVMIN_S : SInstZPZZ<"svmin", "csil", "aarch64_sve_smin", "aarch64_sve_smin_u">;
+defm SVMIN_U : SInstZPZZ<"svmin", "UcUsUiUl", "aarch64_sve_umin", "aarch64_sve_umin_u">;
+defm SVMUL : SInstZPZZ<"svmul", "csilUcUsUiUl", "aarch64_sve_mul", "aarch64_sve_mul_u">;
+defm SVMULH_S : SInstZPZZ<"svmulh", "csil", "aarch64_sve_smulh", "aarch64_sve_smulh_u">;
+defm SVMULH_U : SInstZPZZ<"svmulh", "UcUsUiUl", "aarch64_sve_umulh", "aarch64_sve_umulh_u">;
+defm SVSUB : SInstZPZZ<"svsub", "csilUcUsUiUl", "aarch64_sve_sub", "aarch64_sve_sub_u">;
+defm SVSUBR : SInstZPZZ<"svsubr", "csilUcUsUiUl", "aarch64_sve_subr", "aarch64_sve_sub_u", [ReverseMergeAnyBinOp]>;
//------------------------------------------------------------------------------
-multiclass SInstZPZZZ<string name, string types, string intrinsic, list<FlagType> flags=[]> {
- def _M : SInst<name # "[_{d}]", "dPddd", types, MergeOp1, intrinsic, flags>;
- def _X : SInst<name # "[_{d}]", "dPddd", types, MergeAny, intrinsic, flags>;
- def _Z : SInst<name # "[_{d}]", "dPddd", types, MergeZero, intrinsic, flags>;
+multiclass SInstZPZZZ<string name, string types, string m_intrinsic, string x_intrinsic, list<FlagType> flags=[]> {
+ def _M : SInst<name # "[_{d}]", "dPddd", types, MergeOp1, m_intrinsic, flags>;
+ def _X : SInst<name # "[_{d}]", "dPddd", types, MergeAny, x_intrinsic, flags>;
+ def _Z : SInst<name # "[_{d}]", "dPddd", types, MergeZero, m_intrinsic, flags>;
- def _N_M : SInst<name # "[_n_{d}]", "dPdda", types, MergeOp1, intrinsic, flags>;
- def _N_X : SInst<name # "[_n_{d}]", "dPdda", types, MergeAny, intrinsic, flags>;
- def _N_Z : SInst<name # "[_n_{d}]", "dPdda", types, MergeZero, intrinsic, flags>;
+ def _N_M : SInst<name # "[_n_{d}]", "dPdda", types, MergeOp1, m_intrinsic, flags>;
+ def _N_X : SInst<name # "[_n_{d}]", "dPdda", types, MergeAny, x_intrinsic, flags>;
+ def _N_Z : SInst<name # "[_n_{d}]", "dPdda", types, MergeZero, m_intrinsic, flags>;
}
-defm SVMAD : SInstZPZZZ<"svmad", "csilUcUsUiUl", "aarch64_sve_mad">;
-defm SVMLA : SInstZPZZZ<"svmla", "csilUcUsUiUl", "aarch64_sve_mla">;
-defm SVMLS : SInstZPZZZ<"svmls", "csilUcUsUiUl", "aarch64_sve_mls">;
-defm SVMSB : SInstZPZZZ<"svmsb", "csilUcUsUiUl", "aarch64_sve_msb">;
+defm SVMAD : SInstZPZZZ<"svmad", "csilUcUsUiUl", "aarch64_sve_mad", "aarch64_sve_mla_u", [ReverseMergeAnyAccOp, IsStreamingCompatible]>;
+defm SVMLA : SInstZPZZZ<"svmla", "csilUcUsUiUl", "aarch64_sve_mla", "aarch64_sve_mla_u", [IsStreamingCompatible]>;
+defm SVMLS : SInstZPZZZ<"svmls", "csilUcUsUiUl", "aarch64_sve_mls", "aarch64_sve_mls_u", [IsStreamingCompatible]>;
+defm SVMSB : SInstZPZZZ<"svmsb", "csilUcUsUiUl", "aarch64_sve_msb", "aarch64_sve_mls_u", [ReverseMergeAnyAccOp, IsStreamingCompatible]>;
//------------------------------------------------------------------------------
-def SVDOT_S : SInst<"svdot[_{0}]", "ddqq", "il", MergeNone, "aarch64_sve_sdot">;
-def SVDOT_U : SInst<"svdot[_{0}]", "ddqq", "UiUl", MergeNone, "aarch64_sve_udot">;
-def SVQADD_S : SInst<"svqadd[_{d}]", "ddd", "csil", MergeNone, "aarch64_sve_sqadd_x">;
-def SVQADD_U : SInst<"svqadd[_{d}]", "ddd", "UcUsUiUl", MergeNone, "aarch64_sve_uqadd_x">;
-def SVQSUB_S : SInst<"svqsub[_{d}]", "ddd", "csil", MergeNone, "aarch64_sve_sqsub_x">;
-def SVQSUB_U : SInst<"svqsub[_{d}]", "ddd", "UcUsUiUl", MergeNone, "aarch64_sve_uqsub_x">;
+def SVDOT_S : SInst<"svdot[_{0}]", "ddqq", "il", MergeNone, "aarch64_sve_sdot", [IsStreamingCompatible]>;
+def SVDOT_U : SInst<"svdot[_{0}]", "ddqq", "UiUl", MergeNone, "aarch64_sve_udot", [IsStreamingCompatible]>;
+def SVQADD_S : SInst<"svqadd[_{d}]", "ddd", "csil", MergeNone, "aarch64_sve_sqadd_x", [IsStreamingCompatible]>;
+def SVQADD_U : SInst<"svqadd[_{d}]", "ddd", "UcUsUiUl", MergeNone, "aarch64_sve_uqadd_x", [IsStreamingCompatible]>;
+def SVQSUB_S : SInst<"svqsub[_{d}]", "ddd", "csil", MergeNone, "aarch64_sve_sqsub_x", [IsStreamingCompatible]>;
+def SVQSUB_U : SInst<"svqsub[_{d}]", "ddd", "UcUsUiUl", MergeNone, "aarch64_sve_uqsub_x", [IsStreamingCompatible]>;
-def SVDOT_N_S : SInst<"svdot[_n_{0}]", "ddqr", "il", MergeNone, "aarch64_sve_sdot">;
-def SVDOT_N_U : SInst<"svdot[_n_{0}]", "ddqr", "UiUl", MergeNone, "aarch64_sve_udot">;
-def SVQADD_N_S : SInst<"svqadd[_n_{d}]", "dda", "csil", MergeNone, "aarch64_sve_sqadd_x">;
-def SVQADD_N_U : SInst<"svqadd[_n_{d}]", "dda", "UcUsUiUl", MergeNone, "aarch64_sve_uqadd_x">;
-def SVQSUB_N_S : SInst<"svqsub[_n_{d}]", "dda", "csil", MergeNone, "aarch64_sve_sqsub_x">;
-def SVQSUB_N_U : SInst<"svqsub[_n_{d}]", "dda", "UcUsUiUl", MergeNone, "aarch64_sve_uqsub_x">;
+def SVDOT_N_S : SInst<"svdot[_n_{0}]", "ddqr", "il", MergeNone, "aarch64_sve_sdot", [IsStreamingCompatible]>;
+def SVDOT_N_U : SInst<"svdot[_n_{0}]", "ddqr", "UiUl", MergeNone, "aarch64_sve_udot", [IsStreamingCompatible]>;
+def SVQADD_N_S : SInst<"svqadd[_n_{d}]", "dda", "csil", MergeNone, "aarch64_sve_sqadd_x", [IsStreamingCompatible]>;
+def SVQADD_N_U : SInst<"svqadd[_n_{d}]", "dda", "UcUsUiUl", MergeNone, "aarch64_sve_uqadd_x", [IsStreamingCompatible]>;
+def SVQSUB_N_S : SInst<"svqsub[_n_{d}]", "dda", "csil", MergeNone, "aarch64_sve_sqsub_x", [IsStreamingCompatible]>;
+def SVQSUB_N_U : SInst<"svqsub[_n_{d}]", "dda", "UcUsUiUl", MergeNone, "aarch64_sve_uqsub_x", [IsStreamingCompatible]>;
-def SVDOT_LANE_S : SInst<"svdot_lane[_{d}]", "ddqqi", "il", MergeNone, "aarch64_sve_sdot_lane", [], [ImmCheck<3, ImmCheckLaneIndexDot, 2>]>;
-def SVDOT_LANE_U : SInst<"svdot_lane[_{d}]", "ddqqi", "UiUl", MergeNone, "aarch64_sve_udot_lane", [], [ImmCheck<3, ImmCheckLaneIndexDot, 2>]>;
+def SVDOT_LANE_S : SInst<"svdot_lane[_{d}]", "ddqqi", "il", MergeNone, "aarch64_sve_sdot_lane", [IsStreamingCompatible], [ImmCheck<3, ImmCheckLaneIndexDot, 2>]>;
+def SVDOT_LANE_U : SInst<"svdot_lane[_{d}]", "ddqqi", "UiUl", MergeNone, "aarch64_sve_udot_lane", [IsStreamingCompatible], [ImmCheck<3, ImmCheckLaneIndexDot, 2>]>;
////////////////////////////////////////////////////////////////////////////////
// Logical operations
-defm SVAND : SInstZPZZ<"svand", "csilUcUsUiUl", "aarch64_sve_and">;
-defm SVBIC : SInstZPZZ<"svbic", "csilUcUsUiUl", "aarch64_sve_bic">;
-defm SVEOR : SInstZPZZ<"sveor", "csilUcUsUiUl", "aarch64_sve_eor">;
-defm SVORR : SInstZPZZ<"svorr", "csilUcUsUiUl", "aarch64_sve_orr">;
+defm SVAND : SInstZPZZ<"svand", "csilUcUsUiUl", "aarch64_sve_and", "aarch64_sve_and_u">;
+defm SVBIC : SInstZPZZ<"svbic", "csilUcUsUiUl", "aarch64_sve_bic", "aarch64_sve_bic_u">;
+defm SVEOR : SInstZPZZ<"sveor", "csilUcUsUiUl", "aarch64_sve_eor", "aarch64_sve_eor_u">;
+defm SVORR : SInstZPZZ<"svorr", "csilUcUsUiUl", "aarch64_sve_orr", "aarch64_sve_orr_u">;
defm SVCNOT : SInstZPZ<"svcnot", "csilUcUsUiUl", "aarch64_sve_cnot">;
defm SVNOT : SInstZPZ<"svnot", "csilUcUsUiUl", "aarch64_sve_not">;
@@ -836,107 +656,107 @@ defm SVNOT : SInstZPZ<"svnot", "csilUcUsUiUl", "aarch64_sve_not">;
// Shifts
multiclass SInst_SHIFT<string name, string intrinsic, string ts, string wide_ts> {
- def _M : SInst<name # "[_{d}]", "dPdu", ts, MergeOp1, intrinsic>;
- def _X : SInst<name # "[_{d}]", "dPdu", ts, MergeAny, intrinsic>;
- def _Z : SInst<name # "[_{d}]", "dPdu", ts, MergeZero, intrinsic>;
+ def _M : SInst<name # "[_{d}]", "dPdu", ts, MergeOp1, intrinsic, [IsStreamingCompatible]>;
+ def _X : SInst<name # "[_{d}]", "dPdu", ts, MergeAny, intrinsic # _u, [IsStreamingCompatible]>;
+ def _Z : SInst<name # "[_{d}]", "dPdu", ts, MergeZero, intrinsic, [IsStreamingCompatible]>;
- def _N_M : SInst<name # "[_n_{d}]", "dPdL", ts, MergeOp1, intrinsic>;
- def _N_X : SInst<name # "[_n_{d}]", "dPdL", ts, MergeAny, intrinsic>;
- def _N_Z : SInst<name # "[_n_{d}]", "dPdL", ts, MergeZero, intrinsic>;
+ def _N_M : SInst<name # "[_n_{d}]", "dPdL", ts, MergeOp1, intrinsic, [IsStreamingCompatible]>;
+ def _N_X : SInst<name # "[_n_{d}]", "dPdL", ts, MergeAny, intrinsic # _u, [IsStreamingCompatible]>;
+ def _N_Z : SInst<name # "[_n_{d}]", "dPdL", ts, MergeZero, intrinsic, [IsStreamingCompatible]>;
- def _WIDE_M : SInst<name # _wide # "[_{d}]", "dPdg", wide_ts, MergeOp1, intrinsic # _wide>;
- def _WIDE_X : SInst<name # _wide # "[_{d}]", "dPdg", wide_ts, MergeAny, intrinsic # _wide>;
- def _WIDE_Z : SInst<name # _wide # "[_{d}]", "dPdg", wide_ts, MergeZero, intrinsic # _wide>;
+ def _WIDE_M : SInst<name # _wide # "[_{d}]", "dPdg", wide_ts, MergeOp1, intrinsic # _wide, [IsStreamingCompatible]>;
+ def _WIDE_X : SInst<name # _wide # "[_{d}]", "dPdg", wide_ts, MergeAny, intrinsic # _wide, [IsStreamingCompatible]>;
+ def _WIDE_Z : SInst<name # _wide # "[_{d}]", "dPdg", wide_ts, MergeZero, intrinsic # _wide, [IsStreamingCompatible]>;
- def _WIDE_N_M : SInst<name # _wide # "[_n_{d}]", "dPdf", wide_ts, MergeOp1, intrinsic # _wide>;
- def _WIDE_N_X : SInst<name # _wide # "[_n_{d}]", "dPdf", wide_ts, MergeAny, intrinsic # _wide>;
- def _WIDE_N_Z : SInst<name # _wide # "[_n_{d}]", "dPdf", wide_ts, MergeZero, intrinsic # _wide>;
+ def _WIDE_N_M : SInst<name # _wide # "[_n_{d}]", "dPdf", wide_ts, MergeOp1, intrinsic # _wide, [IsStreamingCompatible]>;
+ def _WIDE_N_X : SInst<name # _wide # "[_n_{d}]", "dPdf", wide_ts, MergeAny, intrinsic # _wide, [IsStreamingCompatible]>;
+ def _WIDE_N_Z : SInst<name # _wide # "[_n_{d}]", "dPdf", wide_ts, MergeZero, intrinsic # _wide, [IsStreamingCompatible]>;
}
defm SVASR : SInst_SHIFT<"svasr", "aarch64_sve_asr", "csil", "csi">;
defm SVLSL : SInst_SHIFT<"svlsl", "aarch64_sve_lsl", "csilUcUsUiUl", "csiUcUsUi">;
defm SVLSR : SInst_SHIFT<"svlsr", "aarch64_sve_lsr", "UcUsUiUl", "UcUsUi">;
-def SVASRD_M : SInst<"svasrd[_n_{d}]", "dPdi", "csil", MergeOp1, "aarch64_sve_asrd", [], [ImmCheck<2, ImmCheckShiftRight, 1>]>;
-def SVASRD_X : SInst<"svasrd[_n_{d}]", "dPdi", "csil", MergeAny, "aarch64_sve_asrd", [], [ImmCheck<2, ImmCheckShiftRight, 1>]>;
-def SVASRD_Z : SInst<"svasrd[_n_{d}]", "dPdi", "csil", MergeZero, "aarch64_sve_asrd", [], [ImmCheck<2, ImmCheckShiftRight, 1>]>;
+def SVASRD_M : SInst<"svasrd[_n_{d}]", "dPdi", "csil", MergeOp1, "aarch64_sve_asrd", [IsStreamingCompatible], [ImmCheck<2, ImmCheckShiftRight, 1>]>;
+def SVASRD_X : SInst<"svasrd[_n_{d}]", "dPdi", "csil", MergeAny, "aarch64_sve_asrd", [IsStreamingCompatible], [ImmCheck<2, ImmCheckShiftRight, 1>]>;
+def SVASRD_Z : SInst<"svasrd[_n_{d}]", "dPdi", "csil", MergeZero, "aarch64_sve_asrd", [IsStreamingCompatible], [ImmCheck<2, ImmCheckShiftRight, 1>]>;
-def SVINSR : SInst<"svinsr[_n_{d}]", "dds", "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_insr">;
-let ArchGuard = "defined(__ARM_FEATURE_SVE_BF16)" in {
- def SVINSR_BF16 : SInst<"svinsr[_n_{d}]", "dds", "b", MergeNone, "aarch64_sve_insr">;
+def SVINSR : SInst<"svinsr[_n_{d}]", "dds", "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_insr", [IsStreamingCompatible]>;
+let TargetGuard = "sve,bf16" in {
+ def SVINSR_BF16 : SInst<"svinsr[_n_{d}]", "dds", "b", MergeNone, "aarch64_sve_insr", [IsStreamingCompatible]>;
}
////////////////////////////////////////////////////////////////////////////////
// Integer reductions
-def SVADDV_S : SInst<"svaddv[_{d}]", "lPd", "csil", MergeNone, "aarch64_sve_saddv">;
-def SVADDV_U : SInst<"svaddv[_{d}]", "nPd", "UcUsUiUl", MergeNone, "aarch64_sve_uaddv">;
-def SVANDV : SInst<"svandv[_{d}]", "sPd", "csilUcUsUiUl", MergeNone, "aarch64_sve_andv">;
-def SVEORV : SInst<"sveorv[_{d}]", "sPd", "csilUcUsUiUl", MergeNone, "aarch64_sve_eorv">;
-def SVMAXV_S : SInst<"svmaxv[_{d}]", "sPd", "csil", MergeNone, "aarch64_sve_smaxv">;
-def SVMAXV_U : SInst<"svmaxv[_{d}]", "sPd", "UcUsUiUl", MergeNone, "aarch64_sve_umaxv">;
-def SVMINV_S : SInst<"svminv[_{d}]", "sPd", "csil", MergeNone, "aarch64_sve_sminv">;
-def SVMINV_U : SInst<"svminv[_{d}]", "sPd", "UcUsUiUl", MergeNone, "aarch64_sve_uminv">;
-def SVORV : SInst<"svorv[_{d}]", "sPd", "csilUcUsUiUl", MergeNone, "aarch64_sve_orv">;
+def SVADDV_S : SInst<"svaddv[_{d}]", "lPd", "csil", MergeNone, "aarch64_sve_saddv", [IsStreamingCompatible]>;
+def SVADDV_U : SInst<"svaddv[_{d}]", "nPd", "UcUsUiUl", MergeNone, "aarch64_sve_uaddv", [IsStreamingCompatible]>;
+def SVANDV : SInst<"svandv[_{d}]", "sPd", "csilUcUsUiUl", MergeNone, "aarch64_sve_andv", [IsStreamingCompatible]>;
+def SVEORV : SInst<"sveorv[_{d}]", "sPd", "csilUcUsUiUl", MergeNone, "aarch64_sve_eorv", [IsStreamingCompatible]>;
+def SVMAXV_S : SInst<"svmaxv[_{d}]", "sPd", "csil", MergeNone, "aarch64_sve_smaxv", [IsStreamingCompatible]>;
+def SVMAXV_U : SInst<"svmaxv[_{d}]", "sPd", "UcUsUiUl", MergeNone, "aarch64_sve_umaxv", [IsStreamingCompatible]>;
+def SVMINV_S : SInst<"svminv[_{d}]", "sPd", "csil", MergeNone, "aarch64_sve_sminv", [IsStreamingCompatible]>;
+def SVMINV_U : SInst<"svminv[_{d}]", "sPd", "UcUsUiUl", MergeNone, "aarch64_sve_uminv", [IsStreamingCompatible]>;
+def SVORV : SInst<"svorv[_{d}]", "sPd", "csilUcUsUiUl", MergeNone, "aarch64_sve_orv", [IsStreamingCompatible]>;
////////////////////////////////////////////////////////////////////////////////
// Integer comparisons
-def SVCMPEQ : SInst<"svcmpeq[_{d}]", "PPdd", "csilUcUsUiUl", MergeNone, "aarch64_sve_cmpeq">;
-def SVCMPNE : SInst<"svcmpne[_{d}]", "PPdd", "csilUcUsUiUl", MergeNone, "aarch64_sve_cmpne">;
-def SVCMPGE : SInst<"svcmpge[_{d}]", "PPdd", "csil", MergeNone, "aarch64_sve_cmpge">;
-def SVCMPGT : SInst<"svcmpgt[_{d}]", "PPdd", "csil", MergeNone, "aarch64_sve_cmpgt">;
-def SVCMPLE : SInst<"svcmple[_{d}]", "PPdd", "csil", MergeNone, "aarch64_sve_cmpge", [ReverseCompare]>;
-def SVCMPLT : SInst<"svcmplt[_{d}]", "PPdd", "csil", MergeNone, "aarch64_sve_cmpgt", [ReverseCompare]>;
-def SVCMPHI : SInst<"svcmpgt[_{d}]", "PPdd", "UcUsUiUl", MergeNone, "aarch64_sve_cmphi">;
-def SVCMPHS : SInst<"svcmpge[_{d}]", "PPdd", "UcUsUiUl", MergeNone, "aarch64_sve_cmphs">;
-def SVCMPLO : SInst<"svcmplt[_{d}]", "PPdd", "UcUsUiUl", MergeNone, "aarch64_sve_cmphi", [ReverseCompare]>;
-def SVCMPLS : SInst<"svcmple[_{d}]", "PPdd", "UcUsUiUl", MergeNone, "aarch64_sve_cmphs", [ReverseCompare]>;
-
-def SVCMPEQ_N : SInst<"svcmpeq[_n_{d}]", "PPda", "csilUcUsUiUl", MergeNone, "aarch64_sve_cmpeq">;
-def SVCMPNE_N : SInst<"svcmpne[_n_{d}]", "PPda", "csilUcUsUiUl", MergeNone, "aarch64_sve_cmpne">;
-def SVCMPGE_N : SInst<"svcmpge[_n_{d}]", "PPda", "csil", MergeNone, "aarch64_sve_cmpge">;
-def SVCMPGT_N : SInst<"svcmpgt[_n_{d}]", "PPda", "csil", MergeNone, "aarch64_sve_cmpgt">;
-def SVCMPLE_N : SInst<"svcmple[_n_{d}]", "PPda", "csil", MergeNone, "aarch64_sve_cmpge", [ReverseCompare]>;
-def SVCMPLT_N : SInst<"svcmplt[_n_{d}]", "PPda", "csil", MergeNone, "aarch64_sve_cmpgt", [ReverseCompare]>;
-def SVCMPHS_N : SInst<"svcmpge[_n_{d}]", "PPda", "UcUsUiUl", MergeNone, "aarch64_sve_cmphs">;
-def SVCMPHI_N : SInst<"svcmpgt[_n_{d}]", "PPda", "UcUsUiUl", MergeNone, "aarch64_sve_cmphi">;
-def SVCMPLS_N : SInst<"svcmple[_n_{d}]", "PPda", "UcUsUiUl", MergeNone, "aarch64_sve_cmphs", [ReverseCompare]>;
-def SVCMPLO_N : SInst<"svcmplt[_n_{d}]", "PPda", "UcUsUiUl", MergeNone, "aarch64_sve_cmphi", [ReverseCompare]>;
-
-def SVCMPEQ_WIDE : SInst<"svcmpeq_wide[_{d}]", "PPdw", "csi", MergeNone, "aarch64_sve_cmpeq_wide">;
-def SVCMPNE_WIDE : SInst<"svcmpne_wide[_{d}]", "PPdw", "csi", MergeNone, "aarch64_sve_cmpne_wide">;
-def SVCMPGE_WIDE : SInst<"svcmpge_wide[_{d}]", "PPdw", "csi", MergeNone, "aarch64_sve_cmpge_wide">;
-def SVCMPGT_WIDE : SInst<"svcmpgt_wide[_{d}]", "PPdw", "csi", MergeNone, "aarch64_sve_cmpgt_wide">;
-def SVCMPLE_WIDE : SInst<"svcmple_wide[_{d}]", "PPdw", "csi", MergeNone, "aarch64_sve_cmple_wide">;
-def SVCMPLT_WIDE : SInst<"svcmplt_wide[_{d}]", "PPdw", "csi", MergeNone, "aarch64_sve_cmplt_wide">;
-def SVCMPHI_WIDE : SInst<"svcmpgt_wide[_{d}]", "PPdw", "UcUsUi", MergeNone, "aarch64_sve_cmphi_wide">;
-def SVCMPHS_WIDE : SInst<"svcmpge_wide[_{d}]", "PPdw", "UcUsUi", MergeNone, "aarch64_sve_cmphs_wide">;
-def SVCMPLO_WIDE : SInst<"svcmplt_wide[_{d}]", "PPdw", "UcUsUi", MergeNone, "aarch64_sve_cmplo_wide">;
-def SVCMPLS_WIDE : SInst<"svcmple_wide[_{d}]", "PPdw", "UcUsUi", MergeNone, "aarch64_sve_cmpls_wide">;
-
-def SVCMPEQ_WIDE_N : SInst<"svcmpeq_wide[_n_{d}]", "PPdj", "csi", MergeNone, "aarch64_sve_cmpeq_wide">;
-def SVCMPNE_WIDE_N : SInst<"svcmpne_wide[_n_{d}]", "PPdj", "csi", MergeNone, "aarch64_sve_cmpne_wide">;
-def SVCMPGE_WIDE_N : SInst<"svcmpge_wide[_n_{d}]", "PPdj", "csi", MergeNone, "aarch64_sve_cmpge_wide">;
-def SVCMPGT_WIDE_N : SInst<"svcmpgt_wide[_n_{d}]", "PPdj", "csi", MergeNone, "aarch64_sve_cmpgt_wide">;
-def SVCMPLE_WIDE_N : SInst<"svcmple_wide[_n_{d}]", "PPdj", "csi", MergeNone, "aarch64_sve_cmple_wide">;
-def SVCMPLT_WIDE_N : SInst<"svcmplt_wide[_n_{d}]", "PPdj", "csi", MergeNone, "aarch64_sve_cmplt_wide">;
-def SVCMPHS_WIDE_N : SInst<"svcmpge_wide[_n_{d}]", "PPdj", "UcUsUi", MergeNone, "aarch64_sve_cmphs_wide">;
-def SVCMPHI_WIDE_N : SInst<"svcmpgt_wide[_n_{d}]", "PPdj", "UcUsUi", MergeNone, "aarch64_sve_cmphi_wide">;
-def SVCMPLO_WIDE_N : SInst<"svcmplt_wide[_n_{d}]", "PPdj", "UcUsUi", MergeNone, "aarch64_sve_cmplo_wide">;
-def SVCMPLS_WIDE_N : SInst<"svcmple_wide[_n_{d}]", "PPdj", "UcUsUi", MergeNone, "aarch64_sve_cmpls_wide">;
+def SVCMPEQ : SInst<"svcmpeq[_{d}]", "PPdd", "csilUcUsUiUl", MergeNone, "aarch64_sve_cmpeq", [IsStreamingCompatible]>;
+def SVCMPNE : SInst<"svcmpne[_{d}]", "PPdd", "csilUcUsUiUl", MergeNone, "aarch64_sve_cmpne", [IsStreamingCompatible]>;
+def SVCMPGE : SInst<"svcmpge[_{d}]", "PPdd", "csil", MergeNone, "aarch64_sve_cmpge", [IsStreamingCompatible]>;
+def SVCMPGT : SInst<"svcmpgt[_{d}]", "PPdd", "csil", MergeNone, "aarch64_sve_cmpgt", [IsStreamingCompatible]>;
+def SVCMPLE : SInst<"svcmple[_{d}]", "PPdd", "csil", MergeNone, "aarch64_sve_cmpge", [ReverseCompare, IsStreamingCompatible]>;
+def SVCMPLT : SInst<"svcmplt[_{d}]", "PPdd", "csil", MergeNone, "aarch64_sve_cmpgt", [ReverseCompare, IsStreamingCompatible]>;
+def SVCMPHI : SInst<"svcmpgt[_{d}]", "PPdd", "UcUsUiUl", MergeNone, "aarch64_sve_cmphi", [IsStreamingCompatible]>;
+def SVCMPHS : SInst<"svcmpge[_{d}]", "PPdd", "UcUsUiUl", MergeNone, "aarch64_sve_cmphs", [IsStreamingCompatible]>;
+def SVCMPLO : SInst<"svcmplt[_{d}]", "PPdd", "UcUsUiUl", MergeNone, "aarch64_sve_cmphi", [ReverseCompare, IsStreamingCompatible]>;
+def SVCMPLS : SInst<"svcmple[_{d}]", "PPdd", "UcUsUiUl", MergeNone, "aarch64_sve_cmphs", [ReverseCompare, IsStreamingCompatible]>;
+
+def SVCMPEQ_N : SInst<"svcmpeq[_n_{d}]", "PPda", "csilUcUsUiUl", MergeNone, "aarch64_sve_cmpeq", [IsStreamingCompatible]>;
+def SVCMPNE_N : SInst<"svcmpne[_n_{d}]", "PPda", "csilUcUsUiUl", MergeNone, "aarch64_sve_cmpne", [IsStreamingCompatible]>;
+def SVCMPGE_N : SInst<"svcmpge[_n_{d}]", "PPda", "csil", MergeNone, "aarch64_sve_cmpge", [IsStreamingCompatible]>;
+def SVCMPGT_N : SInst<"svcmpgt[_n_{d}]", "PPda", "csil", MergeNone, "aarch64_sve_cmpgt", [IsStreamingCompatible]>;
+def SVCMPLE_N : SInst<"svcmple[_n_{d}]", "PPda", "csil", MergeNone, "aarch64_sve_cmpge", [ReverseCompare, IsStreamingCompatible]>;
+def SVCMPLT_N : SInst<"svcmplt[_n_{d}]", "PPda", "csil", MergeNone, "aarch64_sve_cmpgt", [ReverseCompare, IsStreamingCompatible]>;
+def SVCMPHS_N : SInst<"svcmpge[_n_{d}]", "PPda", "UcUsUiUl", MergeNone, "aarch64_sve_cmphs", [IsStreamingCompatible]>;
+def SVCMPHI_N : SInst<"svcmpgt[_n_{d}]", "PPda", "UcUsUiUl", MergeNone, "aarch64_sve_cmphi", [IsStreamingCompatible]>;
+def SVCMPLS_N : SInst<"svcmple[_n_{d}]", "PPda", "UcUsUiUl", MergeNone, "aarch64_sve_cmphs", [ReverseCompare, IsStreamingCompatible]>;
+def SVCMPLO_N : SInst<"svcmplt[_n_{d}]", "PPda", "UcUsUiUl", MergeNone, "aarch64_sve_cmphi", [ReverseCompare, IsStreamingCompatible]>;
+
+def SVCMPEQ_WIDE : SInst<"svcmpeq_wide[_{d}]", "PPdw", "csi", MergeNone, "aarch64_sve_cmpeq_wide", [IsStreamingCompatible]>;
+def SVCMPNE_WIDE : SInst<"svcmpne_wide[_{d}]", "PPdw", "csi", MergeNone, "aarch64_sve_cmpne_wide", [IsStreamingCompatible]>;
+def SVCMPGE_WIDE : SInst<"svcmpge_wide[_{d}]", "PPdw", "csi", MergeNone, "aarch64_sve_cmpge_wide", [IsStreamingCompatible]>;
+def SVCMPGT_WIDE : SInst<"svcmpgt_wide[_{d}]", "PPdw", "csi", MergeNone, "aarch64_sve_cmpgt_wide", [IsStreamingCompatible]>;
+def SVCMPLE_WIDE : SInst<"svcmple_wide[_{d}]", "PPdw", "csi", MergeNone, "aarch64_sve_cmple_wide", [IsStreamingCompatible]>;
+def SVCMPLT_WIDE : SInst<"svcmplt_wide[_{d}]", "PPdw", "csi", MergeNone, "aarch64_sve_cmplt_wide", [IsStreamingCompatible]>;
+def SVCMPHI_WIDE : SInst<"svcmpgt_wide[_{d}]", "PPdw", "UcUsUi", MergeNone, "aarch64_sve_cmphi_wide", [IsStreamingCompatible]>;
+def SVCMPHS_WIDE : SInst<"svcmpge_wide[_{d}]", "PPdw", "UcUsUi", MergeNone, "aarch64_sve_cmphs_wide", [IsStreamingCompatible]>;
+def SVCMPLO_WIDE : SInst<"svcmplt_wide[_{d}]", "PPdw", "UcUsUi", MergeNone, "aarch64_sve_cmplo_wide", [IsStreamingCompatible]>;
+def SVCMPLS_WIDE : SInst<"svcmple_wide[_{d}]", "PPdw", "UcUsUi", MergeNone, "aarch64_sve_cmpls_wide", [IsStreamingCompatible]>;
+
+def SVCMPEQ_WIDE_N : SInst<"svcmpeq_wide[_n_{d}]", "PPdj", "csi", MergeNone, "aarch64_sve_cmpeq_wide", [IsStreamingCompatible]>;
+def SVCMPNE_WIDE_N : SInst<"svcmpne_wide[_n_{d}]", "PPdj", "csi", MergeNone, "aarch64_sve_cmpne_wide", [IsStreamingCompatible]>;
+def SVCMPGE_WIDE_N : SInst<"svcmpge_wide[_n_{d}]", "PPdj", "csi", MergeNone, "aarch64_sve_cmpge_wide", [IsStreamingCompatible]>;
+def SVCMPGT_WIDE_N : SInst<"svcmpgt_wide[_n_{d}]", "PPdj", "csi", MergeNone, "aarch64_sve_cmpgt_wide", [IsStreamingCompatible]>;
+def SVCMPLE_WIDE_N : SInst<"svcmple_wide[_n_{d}]", "PPdj", "csi", MergeNone, "aarch64_sve_cmple_wide", [IsStreamingCompatible]>;
+def SVCMPLT_WIDE_N : SInst<"svcmplt_wide[_n_{d}]", "PPdj", "csi", MergeNone, "aarch64_sve_cmplt_wide", [IsStreamingCompatible]>;
+def SVCMPHS_WIDE_N : SInst<"svcmpge_wide[_n_{d}]", "PPdj", "UcUsUi", MergeNone, "aarch64_sve_cmphs_wide", [IsStreamingCompatible]>;
+def SVCMPHI_WIDE_N : SInst<"svcmpgt_wide[_n_{d}]", "PPdj", "UcUsUi", MergeNone, "aarch64_sve_cmphi_wide", [IsStreamingCompatible]>;
+def SVCMPLO_WIDE_N : SInst<"svcmplt_wide[_n_{d}]", "PPdj", "UcUsUi", MergeNone, "aarch64_sve_cmplo_wide", [IsStreamingCompatible]>;
+def SVCMPLS_WIDE_N : SInst<"svcmple_wide[_n_{d}]", "PPdj", "UcUsUi", MergeNone, "aarch64_sve_cmpls_wide", [IsStreamingCompatible]>;
////////////////////////////////////////////////////////////////////////////////
// While comparisons
-def SVWHILELE_S32 : SInst<"svwhilele_{d}[_{1}]", "Pkk", "PcPsPiPl", MergeNone, "aarch64_sve_whilele", [IsOverloadWhile]>;
-def SVWHILELE_S64 : SInst<"svwhilele_{d}[_{1}]", "Pll", "PcPsPiPl", MergeNone, "aarch64_sve_whilele", [IsOverloadWhile]>;
-def SVWHILELO_U32 : SInst<"svwhilelt_{d}[_{1}]", "Pmm", "PUcPUsPUiPUl", MergeNone, "aarch64_sve_whilelo", [IsOverloadWhile]>;
-def SVWHILELO_U64 : SInst<"svwhilelt_{d}[_{1}]", "Pnn", "PUcPUsPUiPUl", MergeNone, "aarch64_sve_whilelo", [IsOverloadWhile]>;
-def SVWHILELS_U32 : SInst<"svwhilele_{d}[_{1}]", "Pmm", "PUcPUsPUiPUl", MergeNone, "aarch64_sve_whilels", [IsOverloadWhile]>;
-def SVWHILELS_U64 : SInst<"svwhilele_{d}[_{1}]", "Pnn", "PUcPUsPUiPUl", MergeNone, "aarch64_sve_whilels", [IsOverloadWhile]>;
-def SVWHILELT_S32 : SInst<"svwhilelt_{d}[_{1}]", "Pkk", "PcPsPiPl", MergeNone, "aarch64_sve_whilelt", [IsOverloadWhile]>;
-def SVWHILELT_S64 : SInst<"svwhilelt_{d}[_{1}]", "Pll", "PcPsPiPl", MergeNone, "aarch64_sve_whilelt", [IsOverloadWhile]>;
+def SVWHILELE_S32 : SInst<"svwhilele_{d}[_{1}]", "Pkk", "PcPsPiPl", MergeNone, "aarch64_sve_whilele", [IsOverloadWhileOrMultiVecCvt, IsStreamingCompatible]>;
+def SVWHILELE_S64 : SInst<"svwhilele_{d}[_{1}]", "Pll", "PcPsPiPl", MergeNone, "aarch64_sve_whilele", [IsOverloadWhileOrMultiVecCvt, IsStreamingCompatible]>;
+def SVWHILELO_U32 : SInst<"svwhilelt_{d}[_{1}]", "Pmm", "PUcPUsPUiPUl", MergeNone, "aarch64_sve_whilelo", [IsOverloadWhileOrMultiVecCvt, IsStreamingCompatible]>;
+def SVWHILELO_U64 : SInst<"svwhilelt_{d}[_{1}]", "Pnn", "PUcPUsPUiPUl", MergeNone, "aarch64_sve_whilelo", [IsOverloadWhileOrMultiVecCvt, IsStreamingCompatible]>;
+def SVWHILELS_U32 : SInst<"svwhilele_{d}[_{1}]", "Pmm", "PUcPUsPUiPUl", MergeNone, "aarch64_sve_whilels", [IsOverloadWhileOrMultiVecCvt, IsStreamingCompatible]>;
+def SVWHILELS_U64 : SInst<"svwhilele_{d}[_{1}]", "Pnn", "PUcPUsPUiPUl", MergeNone, "aarch64_sve_whilels", [IsOverloadWhileOrMultiVecCvt, IsStreamingCompatible]>;
+def SVWHILELT_S32 : SInst<"svwhilelt_{d}[_{1}]", "Pkk", "PcPsPiPl", MergeNone, "aarch64_sve_whilelt", [IsOverloadWhileOrMultiVecCvt, IsStreamingCompatible]>;
+def SVWHILELT_S64 : SInst<"svwhilelt_{d}[_{1}]", "Pll", "PcPsPiPl", MergeNone, "aarch64_sve_whilelt", [IsOverloadWhileOrMultiVecCvt, IsStreamingCompatible]>;
////////////////////////////////////////////////////////////////////////////////
// Counting bit
@@ -947,12 +767,12 @@ multiclass SInstCLS<string name, string types, string intrinsic, list<FlagType>
def _Z : SInst<name # "[_{d}]", "uPd", types, MergeZeroExp, intrinsic, flags>;
}
-defm SVCLS : SInstCLS<"svcls", "csil", "aarch64_sve_cls">;
-defm SVCLZ : SInstCLS<"svclz", "csilUcUsUiUl", "aarch64_sve_clz">;
-defm SVCNT : SInstCLS<"svcnt", "csilUcUsUiUlhfd", "aarch64_sve_cnt">;
+defm SVCLS : SInstCLS<"svcls", "csil", "aarch64_sve_cls", [IsStreamingCompatible]>;
+defm SVCLZ : SInstCLS<"svclz", "csilUcUsUiUl", "aarch64_sve_clz", [IsStreamingCompatible]>;
+defm SVCNT : SInstCLS<"svcnt", "csilUcUsUiUlhfd", "aarch64_sve_cnt", [IsStreamingCompatible]>;
-let ArchGuard = "defined(__ARM_FEATURE_SVE_BF16)" in {
- defm SVCNT_BF16 : SInstCLS<"svcnt", "b", "aarch64_sve_cnt">;
+let TargetGuard = "sve,bf16" in {
+ defm SVCNT_BF16 : SInstCLS<"svcnt", "b", "aarch64_sve_cnt", [IsStreamingCompatible]>;
}
////////////////////////////////////////////////////////////////////////////////
@@ -979,18 +799,18 @@ defm SVREVW : SInstZPZ<"svrevw", "lUl", "aarch64_sve_revw">;
defm SVABS_F : SInstZPZ<"svabs", "hfd", "aarch64_sve_fabs">;
defm SVNEG_F : SInstZPZ<"svneg", "hfd", "aarch64_sve_fneg">;
-defm SVABD_F : SInstZPZZ<"svabd", "hfd", "aarch64_sve_fabd">;
-defm SVADD_F : SInstZPZZ<"svadd", "hfd", "aarch64_sve_fadd">;
-defm SVDIV_F : SInstZPZZ<"svdiv", "hfd", "aarch64_sve_fdiv">;
-defm SVDIVR_F : SInstZPZZ<"svdivr", "hfd", "aarch64_sve_fdivr">;
-defm SVMAX_F : SInstZPZZ<"svmax", "hfd", "aarch64_sve_fmax">;
-defm SVMAXNM : SInstZPZZ<"svmaxnm","hfd", "aarch64_sve_fmaxnm">;
-defm SVMIN_F : SInstZPZZ<"svmin", "hfd", "aarch64_sve_fmin">;
-defm SVMINNM : SInstZPZZ<"svminnm","hfd", "aarch64_sve_fminnm">;
-defm SVMUL_F : SInstZPZZ<"svmul", "hfd", "aarch64_sve_fmul">;
-defm SVMULX : SInstZPZZ<"svmulx", "hfd", "aarch64_sve_fmulx">;
-defm SVSUB_F : SInstZPZZ<"svsub", "hfd", "aarch64_sve_fsub">;
-defm SVSUBR_F : SInstZPZZ<"svsubr", "hfd", "aarch64_sve_fsubr">;
+defm SVABD_F : SInstZPZZ<"svabd", "hfd", "aarch64_sve_fabd", "aarch64_sve_fabd_u">;
+defm SVADD_F : SInstZPZZ<"svadd", "hfd", "aarch64_sve_fadd", "aarch64_sve_fadd_u">;
+defm SVDIV_F : SInstZPZZ<"svdiv", "hfd", "aarch64_sve_fdiv", "aarch64_sve_fdiv_u">;
+defm SVDIVR_F : SInstZPZZ<"svdivr", "hfd", "aarch64_sve_fdivr", "aarch64_sve_fdiv_u", [ReverseMergeAnyBinOp]>;
+defm SVMAX_F : SInstZPZZ<"svmax", "hfd", "aarch64_sve_fmax", "aarch64_sve_fmax_u">;
+defm SVMAXNM : SInstZPZZ<"svmaxnm","hfd", "aarch64_sve_fmaxnm", "aarch64_sve_fmaxnm_u">;
+defm SVMIN_F : SInstZPZZ<"svmin", "hfd", "aarch64_sve_fmin", "aarch64_sve_fmin_u">;
+defm SVMINNM : SInstZPZZ<"svminnm","hfd", "aarch64_sve_fminnm", "aarch64_sve_fminnm_u">;
+defm SVMUL_F : SInstZPZZ<"svmul", "hfd", "aarch64_sve_fmul", "aarch64_sve_fmul_u">;
+defm SVMULX : SInstZPZZ<"svmulx", "hfd", "aarch64_sve_fmulx", "aarch64_sve_fmulx_u">;
+defm SVSUB_F : SInstZPZZ<"svsub", "hfd", "aarch64_sve_fsub", "aarch64_sve_fsub_u">;
+defm SVSUBR_F : SInstZPZZ<"svsubr", "hfd", "aarch64_sve_fsubr", "aarch64_sve_fsub_u", [ReverseMergeAnyBinOp]>;
defm SVRECPX : SInstZPZ<"svrecpx", "hfd", "aarch64_sve_frecpx">;
defm SVRINTA : SInstZPZ<"svrinta", "hfd", "aarch64_sve_frinta">;
@@ -1007,79 +827,79 @@ def SVTMAD : SInst<"svtmad[_{d}]", "dddi", "hfd", MergeNone, "aarch64_sve_ftma
def SVTSMUL : SInst<"svtsmul[_{d}]", "ddu", "hfd", MergeNone, "aarch64_sve_ftsmul_x">;
def SVTSSEL : SInst<"svtssel[_{d}]", "ddu", "hfd", MergeNone, "aarch64_sve_ftssel_x">;
-def SVSCALE_M : SInst<"svscale[_{d}]", "dPdx", "hfd", MergeOp1, "aarch64_sve_fscale">;
-def SVSCALE_X : SInst<"svscale[_{d}]", "dPdx", "hfd", MergeAny, "aarch64_sve_fscale">;
-def SVSCALE_Z : SInst<"svscale[_{d}]", "dPdx", "hfd", MergeZero, "aarch64_sve_fscale">;
-
-def SVSCALE_N_M : SInst<"svscale[_n_{d}]", "dPdK", "hfd", MergeOp1, "aarch64_sve_fscale">;
-def SVSCALE_N_X : SInst<"svscale[_n_{d}]", "dPdK", "hfd", MergeAny, "aarch64_sve_fscale">;
-def SVSCALE_N_Z : SInst<"svscale[_n_{d}]", "dPdK", "hfd", MergeZero, "aarch64_sve_fscale">;
-
-defm SVMAD_F : SInstZPZZZ<"svmad", "hfd", "aarch64_sve_fmad">;
-defm SVMLA_F : SInstZPZZZ<"svmla", "hfd", "aarch64_sve_fmla">;
-defm SVMLS_F : SInstZPZZZ<"svmls", "hfd", "aarch64_sve_fmls">;
-defm SVMSB_F : SInstZPZZZ<"svmsb", "hfd", "aarch64_sve_fmsb">;
-defm SVNMAD_F : SInstZPZZZ<"svnmad", "hfd", "aarch64_sve_fnmad">;
-defm SVNMLA_F : SInstZPZZZ<"svnmla", "hfd", "aarch64_sve_fnmla">;
-defm SVNMLS_F : SInstZPZZZ<"svnmls", "hfd", "aarch64_sve_fnmls">;
-defm SVNMSB_F : SInstZPZZZ<"svnmsb", "hfd", "aarch64_sve_fnmsb">;
-
-def SVCADD_M : SInst<"svcadd[_{d}]", "dPddi", "hfd", MergeOp1, "aarch64_sve_fcadd", [], [ImmCheck<3, ImmCheckComplexRot90_270>]>;
-def SVCADD_X : SInst<"svcadd[_{d}]", "dPddi", "hfd", MergeAny, "aarch64_sve_fcadd", [], [ImmCheck<3, ImmCheckComplexRot90_270>]>;
-def SVCADD_Z : SInst<"svcadd[_{d}]", "dPddi", "hfd", MergeZero, "aarch64_sve_fcadd", [], [ImmCheck<3, ImmCheckComplexRot90_270>]>;
-def SVCMLA_M : SInst<"svcmla[_{d}]", "dPdddi", "hfd", MergeOp1, "aarch64_sve_fcmla", [], [ImmCheck<4, ImmCheckComplexRotAll90>]>;
-def SVCMLA_X : SInst<"svcmla[_{d}]", "dPdddi", "hfd", MergeAny, "aarch64_sve_fcmla", [], [ImmCheck<4, ImmCheckComplexRotAll90>]>;
-def SVCMLA_Z : SInst<"svcmla[_{d}]", "dPdddi", "hfd", MergeZero, "aarch64_sve_fcmla", [], [ImmCheck<4, ImmCheckComplexRotAll90>]>;
-
-def SVCMLA_LANE : SInst<"svcmla_lane[_{d}]", "ddddii", "hf", MergeNone, "aarch64_sve_fcmla_lane", [], [ImmCheck<3, ImmCheckLaneIndexCompRotate, 2>,
+def SVSCALE_M : SInst<"svscale[_{d}]", "dPdx", "hfd", MergeOp1, "aarch64_sve_fscale", [IsStreamingCompatible]>;
+def SVSCALE_X : SInst<"svscale[_{d}]", "dPdx", "hfd", MergeAny, "aarch64_sve_fscale", [IsStreamingCompatible]>;
+def SVSCALE_Z : SInst<"svscale[_{d}]", "dPdx", "hfd", MergeZero, "aarch64_sve_fscale", [IsStreamingCompatible]>;
+
+def SVSCALE_N_M : SInst<"svscale[_n_{d}]", "dPdK", "hfd", MergeOp1, "aarch64_sve_fscale", [IsStreamingCompatible]>;
+def SVSCALE_N_X : SInst<"svscale[_n_{d}]", "dPdK", "hfd", MergeAny, "aarch64_sve_fscale", [IsStreamingCompatible]>;
+def SVSCALE_N_Z : SInst<"svscale[_n_{d}]", "dPdK", "hfd", MergeZero, "aarch64_sve_fscale", [IsStreamingCompatible]>;
+
+defm SVMAD_F : SInstZPZZZ<"svmad", "hfd", "aarch64_sve_fmad", "aarch64_sve_fmla_u", [IsStreamingCompatible, ReverseMergeAnyAccOp]>;
+defm SVMLA_F : SInstZPZZZ<"svmla", "hfd", "aarch64_sve_fmla", "aarch64_sve_fmla_u", [IsStreamingCompatible]>;
+defm SVMLS_F : SInstZPZZZ<"svmls", "hfd", "aarch64_sve_fmls", "aarch64_sve_fmls_u", [IsStreamingCompatible]>;
+defm SVMSB_F : SInstZPZZZ<"svmsb", "hfd", "aarch64_sve_fmsb", "aarch64_sve_fmls_u", [IsStreamingCompatible, ReverseMergeAnyAccOp]>;
+defm SVNMAD_F : SInstZPZZZ<"svnmad", "hfd", "aarch64_sve_fnmad", "aarch64_sve_fnmla_u", [IsStreamingCompatible, ReverseMergeAnyAccOp]>;
+defm SVNMLA_F : SInstZPZZZ<"svnmla", "hfd", "aarch64_sve_fnmla", "aarch64_sve_fnmla_u", [IsStreamingCompatible]>;
+defm SVNMLS_F : SInstZPZZZ<"svnmls", "hfd", "aarch64_sve_fnmls", "aarch64_sve_fnmls_u", [IsStreamingCompatible]>;
+defm SVNMSB_F : SInstZPZZZ<"svnmsb", "hfd", "aarch64_sve_fnmsb", "aarch64_sve_fnmls_u", [IsStreamingCompatible, ReverseMergeAnyAccOp]>;
+
+def SVCADD_M : SInst<"svcadd[_{d}]", "dPddi", "hfd", MergeOp1, "aarch64_sve_fcadd", [IsStreamingCompatible], [ImmCheck<3, ImmCheckComplexRot90_270>]>;
+def SVCADD_X : SInst<"svcadd[_{d}]", "dPddi", "hfd", MergeAny, "aarch64_sve_fcadd", [IsStreamingCompatible], [ImmCheck<3, ImmCheckComplexRot90_270>]>;
+def SVCADD_Z : SInst<"svcadd[_{d}]", "dPddi", "hfd", MergeZero, "aarch64_sve_fcadd", [IsStreamingCompatible], [ImmCheck<3, ImmCheckComplexRot90_270>]>;
+def SVCMLA_M : SInst<"svcmla[_{d}]", "dPdddi", "hfd", MergeOp1, "aarch64_sve_fcmla", [IsStreamingCompatible], [ImmCheck<4, ImmCheckComplexRotAll90>]>;
+def SVCMLA_X : SInst<"svcmla[_{d}]", "dPdddi", "hfd", MergeAny, "aarch64_sve_fcmla", [IsStreamingCompatible], [ImmCheck<4, ImmCheckComplexRotAll90>]>;
+def SVCMLA_Z : SInst<"svcmla[_{d}]", "dPdddi", "hfd", MergeZero, "aarch64_sve_fcmla", [IsStreamingCompatible], [ImmCheck<4, ImmCheckComplexRotAll90>]>;
+
+def SVCMLA_LANE : SInst<"svcmla_lane[_{d}]", "ddddii", "hf", MergeNone, "aarch64_sve_fcmla_lane", [IsStreamingCompatible], [ImmCheck<3, ImmCheckLaneIndexCompRotate, 2>,
ImmCheck<4, ImmCheckComplexRotAll90>]>;
-def SVMLA_LANE : SInst<"svmla_lane[_{d}]", "ddddi", "hfd", MergeNone, "aarch64_sve_fmla_lane", [], [ImmCheck<3, ImmCheckLaneIndex, 2>]>;
-def SVMLS_LANE : SInst<"svmls_lane[_{d}]", "ddddi", "hfd", MergeNone, "aarch64_sve_fmls_lane", [], [ImmCheck<3, ImmCheckLaneIndex, 2>]>;
-def SVMUL_LANE : SInst<"svmul_lane[_{d}]", "dddi", "hfd", MergeNone, "aarch64_sve_fmul_lane", [], [ImmCheck<2, ImmCheckLaneIndex, 1>]>;
+def SVMLA_LANE : SInst<"svmla_lane[_{d}]", "ddddi", "hfd", MergeNone, "aarch64_sve_fmla_lane", [IsStreamingCompatible], [ImmCheck<3, ImmCheckLaneIndex, 2>]>;
+def SVMLS_LANE : SInst<"svmls_lane[_{d}]", "ddddi", "hfd", MergeNone, "aarch64_sve_fmls_lane", [IsStreamingCompatible], [ImmCheck<3, ImmCheckLaneIndex, 2>]>;
+def SVMUL_LANE : SInst<"svmul_lane[_{d}]", "dddi", "hfd", MergeNone, "aarch64_sve_fmul_lane", [IsStreamingCompatible], [ImmCheck<2, ImmCheckLaneIndex, 1>]>;
-def SVRECPE : SInst<"svrecpe[_{d}]", "dd", "hfd", MergeNone, "aarch64_sve_frecpe_x">;
-def SVRECPS : SInst<"svrecps[_{d}]", "ddd", "hfd", MergeNone, "aarch64_sve_frecps_x">;
-def SVRSQRTE : SInst<"svrsqrte[_{d}]", "dd", "hfd", MergeNone, "aarch64_sve_frsqrte_x">;
-def SVRSQRTS : SInst<"svrsqrts[_{d}]", "ddd", "hfd", MergeNone, "aarch64_sve_frsqrts_x">;
+def SVRECPE : SInst<"svrecpe[_{d}]", "dd", "hfd", MergeNone, "aarch64_sve_frecpe_x", [IsStreamingCompatible]>;
+def SVRECPS : SInst<"svrecps[_{d}]", "ddd", "hfd", MergeNone, "aarch64_sve_frecps_x", [IsStreamingCompatible]>;
+def SVRSQRTE : SInst<"svrsqrte[_{d}]", "dd", "hfd", MergeNone, "aarch64_sve_frsqrte_x", [IsStreamingCompatible]>;
+def SVRSQRTS : SInst<"svrsqrts[_{d}]", "ddd", "hfd", MergeNone, "aarch64_sve_frsqrts_x", [IsStreamingCompatible]>;
////////////////////////////////////////////////////////////////////////////////
// Floating-point reductions
-def SVFADDA : SInst<"svadda[_{d}]", "sPsd", "hfd", MergeNone, "aarch64_sve_fadda">;
-def SVFADDV : SInst<"svaddv[_{d}]", "sPd", "hfd", MergeNone, "aarch64_sve_faddv">;
-def SVFMAXV : SInst<"svmaxv[_{d}]", "sPd", "hfd", MergeNone, "aarch64_sve_fmaxv">;
-def SVFMAXNMV : SInst<"svmaxnmv[_{d}]", "sPd", "hfd", MergeNone, "aarch64_sve_fmaxnmv">;
-def SVFMINV : SInst<"svminv[_{d}]", "sPd", "hfd", MergeNone, "aarch64_sve_fminv">;
-def SVFMINNMV : SInst<"svminnmv[_{d}]", "sPd", "hfd", MergeNone, "aarch64_sve_fminnmv">;
+def SVFADDA : SInst<"svadda[_{d}]", "sPsd", "hfd", MergeNone, "aarch64_sve_fadda", [IsStreamingCompatible]>;
+def SVFADDV : SInst<"svaddv[_{d}]", "sPd", "hfd", MergeNone, "aarch64_sve_faddv", [IsStreamingCompatible]>;
+def SVFMAXV : SInst<"svmaxv[_{d}]", "sPd", "hfd", MergeNone, "aarch64_sve_fmaxv", [IsStreamingCompatible]>;
+def SVFMAXNMV : SInst<"svmaxnmv[_{d}]", "sPd", "hfd", MergeNone, "aarch64_sve_fmaxnmv", [IsStreamingCompatible]>;
+def SVFMINV : SInst<"svminv[_{d}]", "sPd", "hfd", MergeNone, "aarch64_sve_fminv", [IsStreamingCompatible]>;
+def SVFMINNMV : SInst<"svminnmv[_{d}]", "sPd", "hfd", MergeNone, "aarch64_sve_fminnmv", [IsStreamingCompatible]>;
////////////////////////////////////////////////////////////////////////////////
// Floating-point comparisons
-def SVACGE : SInst<"svacge[_{d}]", "PPdd", "hfd", MergeNone, "aarch64_sve_facge">;
-def SVACGT : SInst<"svacgt[_{d}]", "PPdd", "hfd", MergeNone, "aarch64_sve_facgt">;
-def SVACLE : SInst<"svacle[_{d}]", "PPdd", "hfd", MergeNone, "aarch64_sve_facge", [ReverseCompare]>;
-def SVACLT : SInst<"svaclt[_{d}]", "PPdd", "hfd", MergeNone, "aarch64_sve_facgt", [ReverseCompare]>;
-def SVCMPUO : SInst<"svcmpuo[_{d}]", "PPdd", "hfd", MergeNone, "aarch64_sve_fcmpuo">;
-
-def SVACGE_N : SInst<"svacge[_n_{d}]", "PPda", "hfd", MergeNone, "aarch64_sve_facge">;
-def SVACGT_N : SInst<"svacgt[_n_{d}]", "PPda", "hfd", MergeNone, "aarch64_sve_facgt">;
-def SVACLE_N : SInst<"svacle[_n_{d}]", "PPda", "hfd", MergeNone, "aarch64_sve_facge", [ReverseCompare]>;
-def SVACLT_N : SInst<"svaclt[_n_{d}]", "PPda", "hfd", MergeNone, "aarch64_sve_facgt", [ReverseCompare]>;
-def SVCMPUO_N : SInst<"svcmpuo[_n_{d}]", "PPda", "hfd", MergeNone, "aarch64_sve_fcmpuo">;
-
-def SVCMPEQ_F : SInst<"svcmpeq[_{d}]", "PPdd", "hfd", MergeNone, "aarch64_sve_fcmpeq">;
-def SVCMPNE_F : SInst<"svcmpne[_{d}]", "PPdd", "hfd", MergeNone, "aarch64_sve_fcmpne">;
-def SVCMPGE_F : SInst<"svcmpge[_{d}]", "PPdd", "hfd", MergeNone, "aarch64_sve_fcmpge">;
-def SVCMPGT_F : SInst<"svcmpgt[_{d}]", "PPdd", "hfd", MergeNone, "aarch64_sve_fcmpgt">;
-def SVCMPLE_F : SInst<"svcmple[_{d}]", "PPdd", "hfd", MergeNone, "aarch64_sve_fcmpge", [ReverseCompare]>;
-def SVCMPLT_F : SInst<"svcmplt[_{d}]", "PPdd", "hfd", MergeNone, "aarch64_sve_fcmpgt", [ReverseCompare]>;
-
-def SVCMPEQ_F_N : SInst<"svcmpeq[_n_{d}]", "PPda", "hfd", MergeNone, "aarch64_sve_fcmpeq">;
-def SVCMPNE_F_N : SInst<"svcmpne[_n_{d}]", "PPda", "hfd", MergeNone, "aarch64_sve_fcmpne">;
-def SVCMPGE_F_N : SInst<"svcmpge[_n_{d}]", "PPda", "hfd", MergeNone, "aarch64_sve_fcmpge">;
-def SVCMPGT_F_N : SInst<"svcmpgt[_n_{d}]", "PPda", "hfd", MergeNone, "aarch64_sve_fcmpgt">;
-def SVCMPLE_F_N : SInst<"svcmple[_n_{d}]", "PPda", "hfd", MergeNone, "aarch64_sve_fcmpge", [ReverseCompare]>;
-def SVCMPLT_F_N : SInst<"svcmplt[_n_{d}]", "PPda", "hfd", MergeNone, "aarch64_sve_fcmpgt", [ReverseCompare]>;
+def SVACGE : SInst<"svacge[_{d}]", "PPdd", "hfd", MergeNone, "aarch64_sve_facge", [IsStreamingCompatible]>;
+def SVACGT : SInst<"svacgt[_{d}]", "PPdd", "hfd", MergeNone, "aarch64_sve_facgt", [IsStreamingCompatible]>;
+def SVACLE : SInst<"svacle[_{d}]", "PPdd", "hfd", MergeNone, "aarch64_sve_facge", [ReverseCompare, IsStreamingCompatible]>;
+def SVACLT : SInst<"svaclt[_{d}]", "PPdd", "hfd", MergeNone, "aarch64_sve_facgt", [ReverseCompare, IsStreamingCompatible]>;
+def SVCMPUO : SInst<"svcmpuo[_{d}]", "PPdd", "hfd", MergeNone, "aarch64_sve_fcmpuo", [IsStreamingCompatible]>;
+
+def SVACGE_N : SInst<"svacge[_n_{d}]", "PPda", "hfd", MergeNone, "aarch64_sve_facge", [IsStreamingCompatible]>;
+def SVACGT_N : SInst<"svacgt[_n_{d}]", "PPda", "hfd", MergeNone, "aarch64_sve_facgt", [IsStreamingCompatible]>;
+def SVACLE_N : SInst<"svacle[_n_{d}]", "PPda", "hfd", MergeNone, "aarch64_sve_facge", [ReverseCompare, IsStreamingCompatible]>;
+def SVACLT_N : SInst<"svaclt[_n_{d}]", "PPda", "hfd", MergeNone, "aarch64_sve_facgt", [ReverseCompare, IsStreamingCompatible]>;
+def SVCMPUO_N : SInst<"svcmpuo[_n_{d}]", "PPda", "hfd", MergeNone, "aarch64_sve_fcmpuo", [IsStreamingCompatible]>;
+
+def SVCMPEQ_F : SInst<"svcmpeq[_{d}]", "PPdd", "hfd", MergeNone, "aarch64_sve_fcmpeq", [IsStreamingCompatible]>;
+def SVCMPNE_F : SInst<"svcmpne[_{d}]", "PPdd", "hfd", MergeNone, "aarch64_sve_fcmpne", [IsStreamingCompatible]>;
+def SVCMPGE_F : SInst<"svcmpge[_{d}]", "PPdd", "hfd", MergeNone, "aarch64_sve_fcmpge", [IsStreamingCompatible]>;
+def SVCMPGT_F : SInst<"svcmpgt[_{d}]", "PPdd", "hfd", MergeNone, "aarch64_sve_fcmpgt", [IsStreamingCompatible]>;
+def SVCMPLE_F : SInst<"svcmple[_{d}]", "PPdd", "hfd", MergeNone, "aarch64_sve_fcmpge", [ReverseCompare, IsStreamingCompatible]>;
+def SVCMPLT_F : SInst<"svcmplt[_{d}]", "PPdd", "hfd", MergeNone, "aarch64_sve_fcmpgt", [ReverseCompare, IsStreamingCompatible]>;
+
+def SVCMPEQ_F_N : SInst<"svcmpeq[_n_{d}]", "PPda", "hfd", MergeNone, "aarch64_sve_fcmpeq", [IsStreamingCompatible]>;
+def SVCMPNE_F_N : SInst<"svcmpne[_n_{d}]", "PPda", "hfd", MergeNone, "aarch64_sve_fcmpne", [IsStreamingCompatible]>;
+def SVCMPGE_F_N : SInst<"svcmpge[_n_{d}]", "PPda", "hfd", MergeNone, "aarch64_sve_fcmpge", [IsStreamingCompatible]>;
+def SVCMPGT_F_N : SInst<"svcmpgt[_n_{d}]", "PPda", "hfd", MergeNone, "aarch64_sve_fcmpgt", [IsStreamingCompatible]>;
+def SVCMPLE_F_N : SInst<"svcmple[_n_{d}]", "PPda", "hfd", MergeNone, "aarch64_sve_fcmpge", [ReverseCompare, IsStreamingCompatible]>;
+def SVCMPLT_F_N : SInst<"svcmplt[_n_{d}]", "PPda", "hfd", MergeNone, "aarch64_sve_fcmpgt", [ReverseCompare, IsStreamingCompatible]>;
////////////////////////////////////////////////////////////////////////////////
// Floating-point conversions
@@ -1087,16 +907,16 @@ def SVCMPLT_F_N : SInst<"svcmplt[_n_{d}]", "PPda", "hfd", MergeNone, "aarch64_sv
multiclass SInstCvtMXZ<
string name, string m_types, string xz_types, string types,
string intrinsic, list<FlagType> flags = [IsOverloadNone]> {
- def _M : SInst<name, m_types, types, MergeOp1, intrinsic, flags>;
- def _X : SInst<name, xz_types, types, MergeAnyExp, intrinsic, flags>;
- def _Z : SInst<name, xz_types, types, MergeZeroExp, intrinsic, flags>;
+ def _M : SInst<name, m_types, types, MergeOp1, intrinsic, !listconcat(flags, [IsStreamingCompatible])>;
+ def _X : SInst<name, xz_types, types, MergeAnyExp, intrinsic, !listconcat(flags, [IsStreamingCompatible])>;
+ def _Z : SInst<name, xz_types, types, MergeZeroExp, intrinsic, !listconcat(flags, [IsStreamingCompatible])>;
}
multiclass SInstCvtMX<string name, string m_types, string xz_types,
string types, string intrinsic,
list<FlagType> flags = [IsOverloadNone]> {
- def _M : SInst<name, m_types, types, MergeOp1, intrinsic, flags>;
- def _X : SInst<name, xz_types, types, MergeAnyExp, intrinsic, flags>;
+ def _M : SInst<name, m_types, types, MergeOp1, intrinsic, !listconcat(flags, [IsStreamingCompatible])>;
+ def _X : SInst<name, xz_types, types, MergeAnyExp, intrinsic, !listconcat(flags, [IsStreamingCompatible])>;
}
// svcvt_s##_f16
@@ -1108,9 +928,9 @@ defm SVFCVTZS_S64_F16 : SInstCvtMXZ<"svcvt_s64[_f16]", "ddPO", "dPO", "l", "aar
defm SVFCVTZS_S32_F32 : SInstCvtMXZ<"svcvt_s32[_f32]", "ddPM", "dPM", "i", "aarch64_sve_fcvtzs", [IsOverloadCvt]>;
defm SVFCVTZS_S64_F32 : SInstCvtMXZ<"svcvt_s64[_f32]", "ddPM", "dPM", "l", "aarch64_sve_fcvtzs_i64f32">;
-let ArchGuard = "defined(__ARM_FEATURE_SVE_BF16)" in {
+let TargetGuard = "sve,bf16" in {
defm SVCVT_BF16_F32 : SInstCvtMXZ<"svcvt_bf16[_f32]", "ddPM", "dPM", "b", "aarch64_sve_fcvt_bf16f32">;
- def SVCVTNT_BF16_F32 : SInst<"svcvtnt_bf16[_f32]", "ddPM", "b", MergeOp1, "aarch64_sve_fcvtnt_bf16f32", [IsOverloadNone]>;
+ def SVCVTNT_BF16_F32 : SInst<"svcvtnt_bf16[_f32]", "ddPM", "b", MergeOp1, "aarch64_sve_fcvtnt_bf16f32", [IsOverloadNone, IsStreamingCompatible]>;
}
// svcvt_s##_f64
@@ -1168,17 +988,17 @@ defm SVFCVT_F32_F64 : SInstCvtMXZ<"svcvt_f32[_f64]", "MMPd", "MPd", "d", "aarc
defm SVFCVT_F64_F16 : SInstCvtMXZ<"svcvt_f64[_f16]", "ddPO", "dPO", "d", "aarch64_sve_fcvt_f64f16">;
defm SVFCVT_F64_F32 : SInstCvtMXZ<"svcvt_f64[_f32]", "ddPM", "dPM", "d", "aarch64_sve_fcvt_f64f32">;
-let ArchGuard = "defined(__ARM_FEATURE_SVE2)" in {
+let TargetGuard = "sve2" in {
defm SVCVTLT_F32 : SInstCvtMX<"svcvtlt_f32[_f16]", "ddPh", "dPh", "f", "aarch64_sve_fcvtlt_f32f16">;
defm SVCVTLT_F64 : SInstCvtMX<"svcvtlt_f64[_f32]", "ddPh", "dPh", "d", "aarch64_sve_fcvtlt_f64f32">;
defm SVCVTX_F32 : SInstCvtMXZ<"svcvtx_f32[_f64]", "MMPd", "MPd", "d", "aarch64_sve_fcvtx_f32f64">;
-def SVCVTNT_F32 : SInst<"svcvtnt_f16[_f32]", "hhPd", "f", MergeOp1, "aarch64_sve_fcvtnt_f16f32", [IsOverloadNone]>;
-def SVCVTNT_F64 : SInst<"svcvtnt_f32[_f64]", "hhPd", "d", MergeOp1, "aarch64_sve_fcvtnt_f32f64", [IsOverloadNone]>;
+def SVCVTNT_F32 : SInst<"svcvtnt_f16[_f32]", "hhPd", "f", MergeOp1, "aarch64_sve_fcvtnt_f16f32", [IsOverloadNone, IsStreamingCompatible]>;
+def SVCVTNT_F64 : SInst<"svcvtnt_f32[_f64]", "hhPd", "d", MergeOp1, "aarch64_sve_fcvtnt_f32f64", [IsOverloadNone, IsStreamingCompatible]>;
// SVCVTNT_X : Implemented as macro by SveEmitter.cpp
-def SVCVTXNT_F32 : SInst<"svcvtxnt_f32[_f64]", "MMPd", "d", MergeOp1, "aarch64_sve_fcvtxnt_f32f64", [IsOverloadNone]>;
+def SVCVTXNT_F32 : SInst<"svcvtxnt_f32[_f64]", "MMPd", "d", MergeOp1, "aarch64_sve_fcvtxnt_f32f64", [IsOverloadNone, IsStreamingCompatible]>;
// SVCVTXNT_X_F32 : Implemented as macro by SveEmitter.cpp
}
@@ -1187,9 +1007,9 @@ def SVCVTXNT_F32 : SInst<"svcvtxnt_f32[_f64]", "MMPd", "d", MergeOp1, "aarch6
// Permutations and selection
multiclass SVEPerm<string name, string proto, string i> {
- def : SInst<name, proto, "csilUcUsUiUlhfd", MergeNone, i>;
- let ArchGuard = "defined(__ARM_FEATURE_SVE_BF16)" in {
- def: SInst<name, proto, "b", MergeNone, i>;
+ def : SInst<name, proto, "csilUcUsUiUlhfd", MergeNone, i, [IsStreamingCompatible]>;
+ let TargetGuard = "sve,bf16" in {
+ def: SInst<name, proto, "b", MergeNone, i, [IsStreamingCompatible]>;
}
}
@@ -1203,135 +1023,156 @@ def SVCOMPACT : SInst<"svcompact[_{d}]", "dPd", "ilUiUlfd", MergeNo
// splat of any possible lane. It is upto LLVM to pick a more efficient
// instruction such as DUP (indexed) if the lane index fits the range of the
// instruction's immediate.
-def SVDUP_LANE : SInst<"svdup_lane[_{d}]", "ddL", "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_tbl">;
-let ArchGuard = "defined(__ARM_FEATURE_SVE_BF16)" in {
+def SVDUP_LANE : SInst<"svdup_lane[_{d}]", "ddL", "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_tbl", [IsStreamingCompatible]>;
+let TargetGuard = "sve,bf16" in {
def SVDUP_LANE_BF16 :
- SInst<"svdup_lane[_{d}]", "ddL", "b", MergeNone, "aarch64_sve_tbl">;
+ SInst<"svdup_lane[_{d}]", "ddL", "b", MergeNone, "aarch64_sve_tbl", [IsStreamingCompatible]>;
}
-def SVDUPQ_LANE : SInst<"svdupq_lane[_{d}]", "ddn", "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_dupq_lane">;
-let ArchGuard = "defined(__ARM_FEATURE_SVE_BF16)" in {
- def SVDUPQ_LANE_BF16 : SInst<"svdupq_lane[_{d}]", "ddn", "b", MergeNone, "aarch64_sve_dupq_lane">;
+def SVDUPQ_LANE : SInst<"svdupq_lane[_{d}]", "ddn", "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_dupq_lane", [IsStreamingCompatible]>;
+let TargetGuard = "sve,bf16" in {
+ def SVDUPQ_LANE_BF16 : SInst<"svdupq_lane[_{d}]", "ddn", "b", MergeNone, "aarch64_sve_dupq_lane", [IsStreamingCompatible]>;
}
-def SVEXT : SInst<"svext[_{d}]", "dddi", "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_ext", [], [ImmCheck<2, ImmCheckExtract, 1>]>;
+def SVEXT : SInst<"svext[_{d}]", "dddi", "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_ext", [IsStreamingCompatible], [ImmCheck<2, ImmCheckExtract, 1>]>;
defm SVLASTA : SVEPerm<"svlasta[_{d}]", "sPd", "aarch64_sve_lasta">;
defm SVLASTB : SVEPerm<"svlastb[_{d}]", "sPd", "aarch64_sve_lastb">;
-def SVREV : SInst<"svrev[_{d}]", "dd", "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_rev">;
-def SVSEL : SInst<"svsel[_{d}]", "dPdd", "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_sel">;
-def SVSPLICE : SInst<"svsplice[_{d}]", "dPdd", "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_splice">;
-def SVTBL : SInst<"svtbl[_{d}]", "ddu", "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_tbl">;
-
-let ArchGuard = "defined(__ARM_FEATURE_SVE_BF16)" in {
- def SVTBL_BF16 : SInst<"svtbl[_{d}]", "ddu", "b", MergeNone, "aarch64_sve_tbl">;
-}
-
-def SVTRN1 : SInst<"svtrn1[_{d}]", "ddd", "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_trn1">;
-def SVTRN2 : SInst<"svtrn2[_{d}]", "ddd", "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_trn2">;
-def SVUNPKHI_S : SInst<"svunpkhi[_{d}]", "dh", "sil", MergeNone, "aarch64_sve_sunpkhi">;
-def SVUNPKHI_U : SInst<"svunpkhi[_{d}]", "dh", "UsUiUl", MergeNone, "aarch64_sve_uunpkhi">;
-def SVUNPKLO_S : SInst<"svunpklo[_{d}]", "dh", "sil", MergeNone, "aarch64_sve_sunpklo">;
-def SVUNPKLO_U : SInst<"svunpklo[_{d}]", "dh", "UsUiUl", MergeNone, "aarch64_sve_uunpklo">;
-def SVUZP1 : SInst<"svuzp1[_{d}]", "ddd", "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_uzp1">;
-def SVUZP2 : SInst<"svuzp2[_{d}]", "ddd", "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_uzp2">;
-def SVZIP1 : SInst<"svzip1[_{d}]", "ddd", "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_zip1">;
-def SVZIP2 : SInst<"svzip2[_{d}]", "ddd", "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_zip2">;
-
-let ArchGuard = "defined(__ARM_FEATURE_SVE_BF16)" in {
-def SVEXT_BF16 : SInst<"svext[_{d}]", "dddi", "b", MergeNone, "aarch64_sve_ext", [], [ImmCheck<2, ImmCheckExtract, 1>]>;
-def SVREV_BF16 : SInst<"svrev[_{d}]", "dd", "b", MergeNone, "aarch64_sve_rev">;
-def SVSEL_BF16 : SInst<"svsel[_{d}]", "dPdd", "b", MergeNone, "aarch64_sve_sel">;
-def SVSPLICE_BF16 : SInst<"svsplice[_{d}]", "dPdd", "b", MergeNone, "aarch64_sve_splice">;
-def SVTRN1_BF16 : SInst<"svtrn1[_{d}]", "ddd", "b", MergeNone, "aarch64_sve_trn1">;
-def SVTRN2_BF16 : SInst<"svtrn2[_{d}]", "ddd", "b", MergeNone, "aarch64_sve_trn2">;
-def SVUZP1_BF16 : SInst<"svuzp1[_{d}]", "ddd", "b", MergeNone, "aarch64_sve_uzp1">;
-def SVUZP2_BF16 : SInst<"svuzp2[_{d}]", "ddd", "b", MergeNone, "aarch64_sve_uzp2">;
-def SVZIP1_BF16 : SInst<"svzip1[_{d}]", "ddd", "b", MergeNone, "aarch64_sve_zip1">;
-def SVZIP2_BF16 : SInst<"svzip2[_{d}]", "ddd", "b", MergeNone, "aarch64_sve_zip2">;
-}
-
-def SVREV_B : SInst<"svrev_{d}", "PP", "PcPsPiPl", MergeNone, "aarch64_sve_rev">;
-def SVSEL_B : SInst<"svsel[_b]", "PPPP", "Pc", MergeNone, "aarch64_sve_sel">;
-def SVTRN1_B : SInst<"svtrn1_{d}", "PPP", "PcPsPiPl", MergeNone, "aarch64_sve_trn1">;
-def SVTRN2_B : SInst<"svtrn2_{d}", "PPP", "PcPsPiPl", MergeNone, "aarch64_sve_trn2">;
-def SVPUNPKHI : SInst<"svunpkhi[_b]", "PP", "Pc", MergeNone, "aarch64_sve_punpkhi">;
-def SVPUNPKLO : SInst<"svunpklo[_b]", "PP", "Pc", MergeNone, "aarch64_sve_punpklo">;
-def SVUZP1_B : SInst<"svuzp1_{d}", "PPP", "PcPsPiPl", MergeNone, "aarch64_sve_uzp1">;
-def SVUZP2_B : SInst<"svuzp2_{d}", "PPP", "PcPsPiPl", MergeNone, "aarch64_sve_uzp2">;
-def SVZIP1_B : SInst<"svzip1_{d}", "PPP", "PcPsPiPl", MergeNone, "aarch64_sve_zip1">;
-def SVZIP2_B : SInst<"svzip2_{d}", "PPP", "PcPsPiPl", MergeNone, "aarch64_sve_zip2">;
+def SVREV : SInst<"svrev[_{d}]", "dd", "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_rev", [IsStreamingCompatible]>;
+def SVSEL : SInst<"svsel[_{d}]", "dPdd", "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_sel", [IsStreamingCompatible]>;
+def SVSPLICE : SInst<"svsplice[_{d}]", "dPdd", "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_splice", [IsStreamingCompatible]>;
+def SVTBL : SInst<"svtbl[_{d}]", "ddu", "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_tbl", [IsStreamingCompatible]>;
+
+let TargetGuard = "sve,bf16" in {
+ def SVTBL_BF16 : SInst<"svtbl[_{d}]", "ddu", "b", MergeNone, "aarch64_sve_tbl", [IsStreamingCompatible]>;
+}
+
+def SVTRN1 : SInst<"svtrn1[_{d}]", "ddd", "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_trn1", [IsStreamingCompatible]>;
+def SVTRN2 : SInst<"svtrn2[_{d}]", "ddd", "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_trn2", [IsStreamingCompatible]>;
+def SVUNPKHI_S : SInst<"svunpkhi[_{d}]", "dh", "sil", MergeNone, "aarch64_sve_sunpkhi", [IsStreamingCompatible]>;
+def SVUNPKHI_U : SInst<"svunpkhi[_{d}]", "dh", "UsUiUl", MergeNone, "aarch64_sve_uunpkhi", [IsStreamingCompatible]>;
+def SVUNPKLO_S : SInst<"svunpklo[_{d}]", "dh", "sil", MergeNone, "aarch64_sve_sunpklo", [IsStreamingCompatible]>;
+def SVUNPKLO_U : SInst<"svunpklo[_{d}]", "dh", "UsUiUl", MergeNone, "aarch64_sve_uunpklo", [IsStreamingCompatible]>;
+def SVUZP1 : SInst<"svuzp1[_{d}]", "ddd", "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_uzp1", [IsStreamingCompatible]>;
+def SVUZP2 : SInst<"svuzp2[_{d}]", "ddd", "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_uzp2", [IsStreamingCompatible]>;
+def SVZIP1 : SInst<"svzip1[_{d}]", "ddd", "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_zip1", [IsStreamingCompatible]>;
+def SVZIP2 : SInst<"svzip2[_{d}]", "ddd", "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_zip2", [IsStreamingCompatible]>;
+
+let TargetGuard = "sve,bf16" in {
+def SVEXT_BF16 : SInst<"svext[_{d}]", "dddi", "b", MergeNone, "aarch64_sve_ext", [IsStreamingCompatible], [ImmCheck<2, ImmCheckExtract, 1>]>;
+def SVREV_BF16 : SInst<"svrev[_{d}]", "dd", "b", MergeNone, "aarch64_sve_rev", [IsStreamingCompatible]>;
+def SVSEL_BF16 : SInst<"svsel[_{d}]", "dPdd", "b", MergeNone, "aarch64_sve_sel", [IsStreamingCompatible]>;
+def SVSPLICE_BF16 : SInst<"svsplice[_{d}]", "dPdd", "b", MergeNone, "aarch64_sve_splice", [IsStreamingCompatible]>;
+def SVTRN1_BF16 : SInst<"svtrn1[_{d}]", "ddd", "b", MergeNone, "aarch64_sve_trn1", [IsStreamingCompatible]>;
+def SVTRN2_BF16 : SInst<"svtrn2[_{d}]", "ddd", "b", MergeNone, "aarch64_sve_trn2", [IsStreamingCompatible]>;
+def SVUZP1_BF16 : SInst<"svuzp1[_{d}]", "ddd", "b", MergeNone, "aarch64_sve_uzp1", [IsStreamingCompatible]>;
+def SVUZP2_BF16 : SInst<"svuzp2[_{d}]", "ddd", "b", MergeNone, "aarch64_sve_uzp2", [IsStreamingCompatible]>;
+def SVZIP1_BF16 : SInst<"svzip1[_{d}]", "ddd", "b", MergeNone, "aarch64_sve_zip1", [IsStreamingCompatible]>;
+def SVZIP2_BF16 : SInst<"svzip2[_{d}]", "ddd", "b", MergeNone, "aarch64_sve_zip2", [IsStreamingCompatible]>;
+}
+
+def SVREV_B8 : SInst<"svrev_b8", "PP", "Pc", MergeNone, "aarch64_sve_rev", [IsStreamingCompatible]>;
+def SVREV_B16 : SInst<"svrev_b16", "PP", "Pc", MergeNone, "aarch64_sve_rev_b16", [IsOverloadNone, IsStreamingCompatible]>;
+def SVREV_B32 : SInst<"svrev_b32", "PP", "Pc", MergeNone, "aarch64_sve_rev_b32", [IsOverloadNone, IsStreamingCompatible]>;
+def SVREV_B64 : SInst<"svrev_b64", "PP", "Pc", MergeNone, "aarch64_sve_rev_b64", [IsOverloadNone, IsStreamingCompatible]>;
+def SVSEL_B : SInst<"svsel[_b]", "PPPP", "Pc", MergeNone, "aarch64_sve_sel", [IsStreamingCompatible]>;
+def SVTRN1_B8 : SInst<"svtrn1_b8", "PPP", "Pc", MergeNone, "aarch64_sve_trn1", [IsStreamingCompatible]>;
+def SVTRN1_B16 : SInst<"svtrn1_b16", "PPP", "Pc", MergeNone, "aarch64_sve_trn1_b16", [IsOverloadNone, IsStreamingCompatible]>;
+def SVTRN1_B32 : SInst<"svtrn1_b32", "PPP", "Pc", MergeNone, "aarch64_sve_trn1_b32", [IsOverloadNone, IsStreamingCompatible]>;
+def SVTRN1_B64 : SInst<"svtrn1_b64", "PPP", "Pc", MergeNone, "aarch64_sve_trn1_b64", [IsOverloadNone, IsStreamingCompatible]>;
+def SVTRN2_B8 : SInst<"svtrn2_b8", "PPP", "Pc", MergeNone, "aarch64_sve_trn2", [IsStreamingCompatible]>;
+def SVTRN2_B16 : SInst<"svtrn2_b16", "PPP", "Pc", MergeNone, "aarch64_sve_trn2_b16", [IsOverloadNone, IsStreamingCompatible]>;
+def SVTRN2_B32 : SInst<"svtrn2_b32", "PPP", "Pc", MergeNone, "aarch64_sve_trn2_b32", [IsOverloadNone, IsStreamingCompatible]>;
+def SVTRN2_B64 : SInst<"svtrn2_b64", "PPP", "Pc", MergeNone, "aarch64_sve_trn2_b64", [IsOverloadNone, IsStreamingCompatible]>;
+def SVPUNPKHI : SInst<"svunpkhi[_b]", "PP", "Pc", MergeNone, "aarch64_sve_punpkhi", [IsStreamingCompatible]>;
+def SVPUNPKLO : SInst<"svunpklo[_b]", "PP", "Pc", MergeNone, "aarch64_sve_punpklo", [IsStreamingCompatible]>;
+def SVUZP1_B8 : SInst<"svuzp1_b8", "PPP", "Pc", MergeNone, "aarch64_sve_uzp1", [IsStreamingCompatible]>;
+def SVUZP1_B16 : SInst<"svuzp1_b16", "PPP", "Pc", MergeNone, "aarch64_sve_uzp1_b16", [IsOverloadNone, IsStreamingCompatible]>;
+def SVUZP1_B32 : SInst<"svuzp1_b32", "PPP", "Pc", MergeNone, "aarch64_sve_uzp1_b32", [IsOverloadNone, IsStreamingCompatible]>;
+def SVUZP1_B64 : SInst<"svuzp1_b64", "PPP", "Pc", MergeNone, "aarch64_sve_uzp1_b64", [IsOverloadNone, IsStreamingCompatible]>;
+def SVUZP2_B8 : SInst<"svuzp2_b8", "PPP", "Pc", MergeNone, "aarch64_sve_uzp2", [IsStreamingCompatible]>;
+def SVUZP2_B16 : SInst<"svuzp2_b16", "PPP", "Pc", MergeNone, "aarch64_sve_uzp2_b16", [IsOverloadNone, IsStreamingCompatible]>;
+def SVUZP2_B32 : SInst<"svuzp2_b32", "PPP", "Pc", MergeNone, "aarch64_sve_uzp2_b32", [IsOverloadNone, IsStreamingCompatible]>;
+def SVUZP2_B64 : SInst<"svuzp2_b64", "PPP", "Pc", MergeNone, "aarch64_sve_uzp2_b64", [IsOverloadNone, IsStreamingCompatible]>;
+def SVZIP1_B8 : SInst<"svzip1_b8", "PPP", "Pc", MergeNone, "aarch64_sve_zip1", [IsStreamingCompatible]>;
+def SVZIP1_B16 : SInst<"svzip1_b16", "PPP", "Pc", MergeNone, "aarch64_sve_zip1_b16", [IsOverloadNone, IsStreamingCompatible]>;
+def SVZIP1_B32 : SInst<"svzip1_b32", "PPP", "Pc", MergeNone, "aarch64_sve_zip1_b32", [IsOverloadNone, IsStreamingCompatible]>;
+def SVZIP1_B64 : SInst<"svzip1_b64", "PPP", "Pc", MergeNone, "aarch64_sve_zip1_b64", [IsOverloadNone, IsStreamingCompatible]>;
+def SVZIP2_B : SInst<"svzip2_b8", "PPP", "Pc", MergeNone, "aarch64_sve_zip2", [IsStreamingCompatible]>;
+def SVZIP2_B16 : SInst<"svzip2_b16", "PPP", "Pc", MergeNone, "aarch64_sve_zip2_b16", [IsOverloadNone, IsStreamingCompatible]>;
+def SVZIP2_B32 : SInst<"svzip2_b32", "PPP", "Pc", MergeNone, "aarch64_sve_zip2_b32", [IsOverloadNone, IsStreamingCompatible]>;
+def SVZIP2_B64 : SInst<"svzip2_b64", "PPP", "Pc", MergeNone, "aarch64_sve_zip2_b64", [IsOverloadNone, IsStreamingCompatible]>;
////////////////////////////////////////////////////////////////////////////////
// Predicate creation
-def SVPFALSE : SInst<"svpfalse[_b]", "P", "", MergeNone, "", [IsOverloadNone]>;
+def SVPFALSE : SInst<"svpfalse[_b]", "Pv", "", MergeNone, "", [IsOverloadNone, IsStreamingCompatible]>;
-def SVPTRUE_PAT : SInst<"svptrue_pat_{d}", "PI", "PcPsPiPl", MergeNone, "aarch64_sve_ptrue">;
-def SVPTRUE : SInst<"svptrue_{d}", "P", "PcPsPiPl", MergeNone, "aarch64_sve_ptrue", [IsAppendSVALL]>;
+def SVPTRUE_PAT : SInst<"svptrue_pat_{d}", "PI", "PcPsPiPl", MergeNone, "aarch64_sve_ptrue", [IsStreamingCompatible]>;
+def SVPTRUE : SInst<"svptrue_{d}", "Pv", "PcPsPiPl", MergeNone, "aarch64_sve_ptrue", [IsAppendSVALL, IsStreamingCompatible]>;
-def SVDUPQ_B8 : SInst<"svdupq[_n]_{d}", "Pssssssssssssssss", "Pc", MergeNone>;
-def SVDUPQ_B16 : SInst<"svdupq[_n]_{d}", "Pssssssss", "Ps", MergeNone>;
-def SVDUPQ_B32 : SInst<"svdupq[_n]_{d}", "Pssss", "Pi", MergeNone>;
-def SVDUPQ_B64 : SInst<"svdupq[_n]_{d}", "Pss", "Pl", MergeNone>;
-def SVDUP_N_B : SInst<"svdup[_n]_{d}", "Ps", "PcPsPiPl", MergeNone>;
+def SVDUPQ_B8 : SInst<"svdupq[_n]_{d}", "Pssssssssssssssss", "Pc", MergeNone, "", [IsStreamingCompatible]>;
+def SVDUPQ_B16 : SInst<"svdupq[_n]_{d}", "Pssssssss", "Ps", MergeNone, "", [IsStreamingCompatible]>;
+def SVDUPQ_B32 : SInst<"svdupq[_n]_{d}", "Pssss", "Pi", MergeNone, "", [IsStreamingCompatible]>;
+def SVDUPQ_B64 : SInst<"svdupq[_n]_{d}", "Pss", "Pl", MergeNone, "", [IsStreamingCompatible]>;
+def SVDUP_N_B : SInst<"svdup[_n]_{d}", "Ps", "PcPsPiPl", MergeNone, "", [IsStreamingCompatible]>;
////////////////////////////////////////////////////////////////////////////////
// Predicate operations
-def SVAND_B_Z : SInst<"svand[_b]_z", "PPPP", "Pc", MergeNone, "aarch64_sve_and_z">;
-def SVBIC_B_Z : SInst<"svbic[_b]_z", "PPPP", "Pc", MergeNone, "aarch64_sve_bic_z">;
-def SVEOR_B_Z : SInst<"sveor[_b]_z", "PPPP", "Pc", MergeNone, "aarch64_sve_eor_z">;
-def SVMOV_B_Z : SInst<"svmov[_b]_z", "PPP", "Pc", MergeNone>; // Uses custom expansion
-def SVNAND_B_Z : SInst<"svnand[_b]_z", "PPPP", "Pc", MergeNone, "aarch64_sve_nand_z">;
-def SVNOR_B_Z : SInst<"svnor[_b]_z", "PPPP", "Pc", MergeNone, "aarch64_sve_nor_z">;
-def SVNOT_B_Z : SInst<"svnot[_b]_z", "PPP", "Pc", MergeNone>; // Uses custom expansion
-def SVORN_B_Z : SInst<"svorn[_b]_z", "PPPP", "Pc", MergeNone, "aarch64_sve_orn_z">;
-def SVORR_B_Z : SInst<"svorr[_b]_z", "PPPP", "Pc", MergeNone, "aarch64_sve_orr_z">;
-
-def SVBRKA : SInst<"svbrka[_b]_m", "PPPP", "Pc", MergeNone, "aarch64_sve_brka">;
-def SVBRKA_Z : SInst<"svbrka[_b]_z", "PPP", "Pc", MergeNone, "aarch64_sve_brka_z">;
-def SVBRKB : SInst<"svbrkb[_b]_m", "PPPP", "Pc", MergeNone, "aarch64_sve_brkb">;
-def SVBRKB_Z : SInst<"svbrkb[_b]_z", "PPP", "Pc", MergeNone, "aarch64_sve_brkb_z">;
-def SVBRKN_Z : SInst<"svbrkn[_b]_z", "PPPP", "Pc", MergeNone, "aarch64_sve_brkn_z">;
-def SVBRKPA_Z : SInst<"svbrkpa[_b]_z", "PPPP", "Pc", MergeNone, "aarch64_sve_brkpa_z">;
-def SVBRKPB_Z : SInst<"svbrkpb[_b]_z", "PPPP", "Pc", MergeNone, "aarch64_sve_brkpb_z">;
-
-def SVPFIRST : SInst<"svpfirst[_b]", "PPP", "Pc", MergeNone, "aarch64_sve_pfirst">;
-def SVPNEXT : SInst<"svpnext_{d}", "PPP", "PcPsPiPl", MergeNone, "aarch64_sve_pnext">;
+def SVAND_B_Z : SInst<"svand[_b]_z", "PPPP", "Pc", MergeNone, "aarch64_sve_and_z", [IsStreamingCompatible]>;
+def SVBIC_B_Z : SInst<"svbic[_b]_z", "PPPP", "Pc", MergeNone, "aarch64_sve_bic_z", [IsStreamingCompatible]>;
+def SVEOR_B_Z : SInst<"sveor[_b]_z", "PPPP", "Pc", MergeNone, "aarch64_sve_eor_z", [IsStreamingCompatible]>;
+def SVMOV_B_Z : SInst<"svmov[_b]_z", "PPP", "Pc", MergeNone, "", [IsStreamingCompatible]>; // Uses custom expansion
+def SVNAND_B_Z : SInst<"svnand[_b]_z", "PPPP", "Pc", MergeNone, "aarch64_sve_nand_z", [IsStreamingCompatible]>;
+def SVNOR_B_Z : SInst<"svnor[_b]_z", "PPPP", "Pc", MergeNone, "aarch64_sve_nor_z", [IsStreamingCompatible]>;
+def SVNOT_B_Z : SInst<"svnot[_b]_z", "PPP", "Pc", MergeNone, "", [IsStreamingCompatible]>; // Uses custom expansion
+def SVORN_B_Z : SInst<"svorn[_b]_z", "PPPP", "Pc", MergeNone, "aarch64_sve_orn_z", [IsStreamingCompatible]>;
+def SVORR_B_Z : SInst<"svorr[_b]_z", "PPPP", "Pc", MergeNone, "aarch64_sve_orr_z", [IsStreamingCompatible]>;
+
+def SVBRKA : SInst<"svbrka[_b]_m", "PPPP", "Pc", MergeNone, "aarch64_sve_brka", [IsStreamingCompatible]>;
+def SVBRKA_Z : SInst<"svbrka[_b]_z", "PPP", "Pc", MergeNone, "aarch64_sve_brka_z", [IsStreamingCompatible]>;
+def SVBRKB : SInst<"svbrkb[_b]_m", "PPPP", "Pc", MergeNone, "aarch64_sve_brkb", [IsStreamingCompatible]>;
+def SVBRKB_Z : SInst<"svbrkb[_b]_z", "PPP", "Pc", MergeNone, "aarch64_sve_brkb_z", [IsStreamingCompatible]>;
+def SVBRKN_Z : SInst<"svbrkn[_b]_z", "PPPP", "Pc", MergeNone, "aarch64_sve_brkn_z", [IsStreamingCompatible]>;
+def SVBRKPA_Z : SInst<"svbrkpa[_b]_z", "PPPP", "Pc", MergeNone, "aarch64_sve_brkpa_z", [IsStreamingCompatible]>;
+def SVBRKPB_Z : SInst<"svbrkpb[_b]_z", "PPPP", "Pc", MergeNone, "aarch64_sve_brkpb_z", [IsStreamingCompatible]>;
+
+def SVPFIRST : SInst<"svpfirst[_b]", "PPP", "Pc", MergeNone, "aarch64_sve_pfirst", [IsStreamingCompatible]>;
+def SVPNEXT : SInst<"svpnext_{d}", "PPP", "PcPsPiPl", MergeNone, "aarch64_sve_pnext", [IsStreamingCompatible]>;
////////////////////////////////////////////////////////////////////////////////
// Testing predicates
-def SVPTEST_ANY : SInst<"svptest_any", "sPP", "Pc", MergeNone, "aarch64_sve_ptest_any">;
-def SVPTEST_FIRST : SInst<"svptest_first", "sPP", "Pc", MergeNone, "aarch64_sve_ptest_first">;
-def SVPTEST_LAST : SInst<"svptest_last", "sPP", "Pc", MergeNone, "aarch64_sve_ptest_last">;
+def SVPTEST_ANY : SInst<"svptest_any", "sPP", "Pc", MergeNone, "aarch64_sve_ptest_any", [IsStreamingCompatible]>;
+def SVPTEST_FIRST : SInst<"svptest_first", "sPP", "Pc", MergeNone, "aarch64_sve_ptest_first", [IsStreamingCompatible]>;
+def SVPTEST_LAST : SInst<"svptest_last", "sPP", "Pc", MergeNone, "aarch64_sve_ptest_last", [IsStreamingCompatible]>;
////////////////////////////////////////////////////////////////////////////////
// FFR manipulation
-def SVRDFFR : SInst<"svrdffr", "P", "Pc", MergeNone, "", [IsOverloadNone]>;
+def SVRDFFR : SInst<"svrdffr", "Pv", "Pc", MergeNone, "", [IsOverloadNone]>;
def SVRDFFR_Z : SInst<"svrdffr_z", "PP", "Pc", MergeNone, "", [IsOverloadNone]>;
-def SVSETFFR : SInst<"svsetffr", "v", "", MergeNone, "", [IsOverloadNone]>;
+def SVSETFFR : SInst<"svsetffr", "vv", "", MergeNone, "", [IsOverloadNone]>;
def SVWRFFR : SInst<"svwrffr", "vP", "Pc", MergeNone, "", [IsOverloadNone]>;
////////////////////////////////////////////////////////////////////////////////
// Counting elements
-def SVCNTB_PAT : SInst<"svcntb_pat", "nI", "", MergeNone, "aarch64_sve_cntb", [IsOverloadNone]>;
-def SVCNTH_PAT : SInst<"svcnth_pat", "nI", "", MergeNone, "aarch64_sve_cnth", [IsOverloadNone]>;
-def SVCNTW_PAT : SInst<"svcntw_pat", "nI", "", MergeNone, "aarch64_sve_cntw", [IsOverloadNone]>;
-def SVCNTD_PAT : SInst<"svcntd_pat", "nI", "", MergeNone, "aarch64_sve_cntd", [IsOverloadNone]>;
+def SVCNTB_PAT : SInst<"svcntb_pat", "nI", "", MergeNone, "aarch64_sve_cntb", [IsOverloadNone, IsStreamingCompatible]>;
+def SVCNTH_PAT : SInst<"svcnth_pat", "nI", "", MergeNone, "aarch64_sve_cnth", [IsOverloadNone, IsStreamingCompatible]>;
+def SVCNTW_PAT : SInst<"svcntw_pat", "nI", "", MergeNone, "aarch64_sve_cntw", [IsOverloadNone, IsStreamingCompatible]>;
+def SVCNTD_PAT : SInst<"svcntd_pat", "nI", "", MergeNone, "aarch64_sve_cntd", [IsOverloadNone, IsStreamingCompatible]>;
-def SVCNTB : SInst<"svcntb", "n", "", MergeNone, "aarch64_sve_cntb", [IsAppendSVALL, IsOverloadNone]>;
-def SVCNTH : SInst<"svcnth", "n", "", MergeNone, "aarch64_sve_cnth", [IsAppendSVALL, IsOverloadNone]>;
-def SVCNTW : SInst<"svcntw", "n", "", MergeNone, "aarch64_sve_cntw", [IsAppendSVALL, IsOverloadNone]>;
-def SVCNTD : SInst<"svcntd", "n", "", MergeNone, "aarch64_sve_cntd", [IsAppendSVALL, IsOverloadNone]>;
+def SVCNTB : SInst<"svcntb", "nv", "", MergeNone, "aarch64_sve_cntb", [IsAppendSVALL, IsOverloadNone, IsStreamingCompatible]>;
+def SVCNTH : SInst<"svcnth", "nv", "", MergeNone, "aarch64_sve_cnth", [IsAppendSVALL, IsOverloadNone, IsStreamingCompatible]>;
+def SVCNTW : SInst<"svcntw", "nv", "", MergeNone, "aarch64_sve_cntw", [IsAppendSVALL, IsOverloadNone, IsStreamingCompatible]>;
+def SVCNTD : SInst<"svcntd", "nv", "", MergeNone, "aarch64_sve_cntd", [IsAppendSVALL, IsOverloadNone, IsStreamingCompatible]>;
-def SVCNTP : SInst<"svcntp_{d}", "nPP", "PcPsPiPl", MergeNone, "aarch64_sve_cntp">;
-def SVLEN : SInst<"svlen[_{d}]", "nd", "csilUcUsUiUlhfd", MergeNone>;
+def SVCNTP : SInst<"svcntp_{d}", "nPP", "PcPsPiPl", MergeNone, "aarch64_sve_cntp", [IsStreamingCompatible]>;
+def SVLEN : SInst<"svlen[_{d}]", "nd", "csilUcUsUiUlhfd", MergeNone, "", [IsStreamingCompatible]>;
-let ArchGuard = "defined(__ARM_FEATURE_SVE_BF16)" in {
-def SVLEN_BF16 : SInst<"svlen[_{d}]", "nd", "b", MergeNone>;
+let TargetGuard = "sve,bf16" in {
+def SVLEN_BF16 : SInst<"svlen[_{d}]", "nd", "b", MergeNone, "", [IsStreamingCompatible]>;
}
////////////////////////////////////////////////////////////////////////////////
@@ -1348,20 +1189,20 @@ def UnsignedWord : sat_type<"U", "Ui">;
def UnsignedDoubleWord : sat_type<"U", "Ul">;
multiclass SInst_SAT1<string name, string intrinsic, sat_type type> {
- def _N32 : SInst<name # "_pat[_n_{d}]", "ssIi", type.U # "i", MergeNone, intrinsic # "_n32", [IsOverloadNone], [ImmCheck<2, ImmCheck1_16>]>;
- def _N64 : SInst<name # "_pat[_n_{d}]", "ssIi", type.U # "l", MergeNone, intrinsic # "_n64", [IsOverloadNone], [ImmCheck<2, ImmCheck1_16>]>;
- def _N32_ALL : SInst<name # "[_n_{d}]", "ssi", type.U # "i", MergeNone, intrinsic # "_n32", [IsOverloadNone, IsInsertOp1SVALL], [ImmCheck<1, ImmCheck1_16>]>;
- def _N64_ALL : SInst<name # "[_n_{d}]", "ssi", type.U # "l", MergeNone, intrinsic # "_n64", [IsOverloadNone, IsInsertOp1SVALL], [ImmCheck<1, ImmCheck1_16>]>;
+ def _N32 : SInst<name # "_pat[_n_{d}]", "ssIi", type.U # "i", MergeNone, intrinsic # "_n32", [IsOverloadNone, IsStreamingCompatible], [ImmCheck<2, ImmCheck1_16>]>;
+ def _N64 : SInst<name # "_pat[_n_{d}]", "ssIi", type.U # "l", MergeNone, intrinsic # "_n64", [IsOverloadNone, IsStreamingCompatible], [ImmCheck<2, ImmCheck1_16>]>;
+ def _N32_ALL : SInst<name # "[_n_{d}]", "ssi", type.U # "i", MergeNone, intrinsic # "_n32", [IsOverloadNone, IsInsertOp1SVALL, IsStreamingCompatible], [ImmCheck<1, ImmCheck1_16>]>;
+ def _N64_ALL : SInst<name # "[_n_{d}]", "ssi", type.U # "l", MergeNone, intrinsic # "_n64", [IsOverloadNone, IsInsertOp1SVALL, IsStreamingCompatible], [ImmCheck<1, ImmCheck1_16>]>;
}
multiclass SInst_SAT2<string name, string intrinsic, sat_type type> {
- def "" : SInst<name # "_pat[_{d}]", "ddIi", type.T, MergeNone, intrinsic, [], [ImmCheck<2, ImmCheck1_16>]>;
- def _ALL : SInst<name # "[_{d}]", "ddi", type.T, MergeNone, intrinsic, [IsInsertOp1SVALL], [ImmCheck<1, ImmCheck1_16>]>;
+ def "" : SInst<name # "_pat[_{d}]", "ddIi", type.T, MergeNone, intrinsic, [IsStreamingCompatible], [ImmCheck<2, ImmCheck1_16>]>;
+ def _ALL : SInst<name # "[_{d}]", "ddi", type.T, MergeNone, intrinsic, [IsInsertOp1SVALL, IsStreamingCompatible], [ImmCheck<1, ImmCheck1_16>]>;
- def _N32 : SInst<name # "_pat[_n_{d}]", "ssIi", type.U # "i", MergeNone, intrinsic # "_n32", [IsOverloadNone], [ImmCheck<2, ImmCheck1_16>]>;
- def _N64 : SInst<name # "_pat[_n_{d}]", "ssIi", type.U # "l", MergeNone, intrinsic # "_n64", [IsOverloadNone], [ImmCheck<2, ImmCheck1_16>]>;
- def _N32_ALL : SInst<name # "[_n_{d}]", "ssi", type.U # "i", MergeNone, intrinsic # "_n32", [IsOverloadNone, IsInsertOp1SVALL], [ImmCheck<1, ImmCheck1_16>]>;
- def _N64_ALL : SInst<name # "[_n_{d}]", "ssi", type.U # "l", MergeNone, intrinsic # "_n64", [IsOverloadNone, IsInsertOp1SVALL], [ImmCheck<1, ImmCheck1_16>]>;
+ def _N32 : SInst<name # "_pat[_n_{d}]", "ssIi", type.U # "i", MergeNone, intrinsic # "_n32", [IsOverloadNone, IsStreamingCompatible], [ImmCheck<2, ImmCheck1_16>]>;
+ def _N64 : SInst<name # "_pat[_n_{d}]", "ssIi", type.U # "l", MergeNone, intrinsic # "_n64", [IsOverloadNone, IsStreamingCompatible], [ImmCheck<2, ImmCheck1_16>]>;
+ def _N32_ALL : SInst<name # "[_n_{d}]", "ssi", type.U # "i", MergeNone, intrinsic # "_n32", [IsOverloadNone, IsInsertOp1SVALL, IsStreamingCompatible], [ImmCheck<1, ImmCheck1_16>]>;
+ def _N64_ALL : SInst<name # "[_n_{d}]", "ssi", type.U # "l", MergeNone, intrinsic # "_n64", [IsOverloadNone, IsInsertOp1SVALL, IsStreamingCompatible], [ImmCheck<1, ImmCheck1_16>]>;
}
defm SVQDECB_S : SInst_SAT1<"svqdecb", "aarch64_sve_sqdecb", SignedByte>;
@@ -1382,131 +1223,160 @@ defm SVQINCW_U : SInst_SAT2<"svqincw", "aarch64_sve_uqincw", UnsignedWord>;
defm SVQINCD_S : SInst_SAT2<"svqincd", "aarch64_sve_sqincd", SignedDoubleWord>;
defm SVQINCD_U : SInst_SAT2<"svqincd", "aarch64_sve_uqincd", UnsignedDoubleWord>;
-def SVQDECP_S : SInst<"svqdecp[_{d}]", "ddP", "sil", MergeNone, "aarch64_sve_sqdecp">;
-def SVQDECP_U : SInst<"svqdecp[_{d}]", "ddP", "UsUiUl", MergeNone, "aarch64_sve_uqdecp">;
-def SVQINCP_S : SInst<"svqincp[_{d}]", "ddP", "sil", MergeNone, "aarch64_sve_sqincp">;
-def SVQINCP_U : SInst<"svqincp[_{d}]", "ddP", "UsUiUl", MergeNone, "aarch64_sve_uqincp">;
-
-def SVQDECP_N_S32 : SInst<"svqdecp[_n_s32]_{d}", "kkP", "PcPsPiPl", MergeNone, "aarch64_sve_sqdecp_n32">;
-def SVQDECP_N_S64 : SInst<"svqdecp[_n_s64]_{d}", "llP", "PcPsPiPl", MergeNone, "aarch64_sve_sqdecp_n64">;
-def SVQDECP_N_U32 : SInst<"svqdecp[_n_u32]_{d}", "mmP", "PcPsPiPl", MergeNone, "aarch64_sve_uqdecp_n32">;
-def SVQDECP_N_U64 : SInst<"svqdecp[_n_u64]_{d}", "nnP", "PcPsPiPl", MergeNone, "aarch64_sve_uqdecp_n64">;
-def SVQINCP_N_S32 : SInst<"svqincp[_n_s32]_{d}", "kkP", "PcPsPiPl", MergeNone, "aarch64_sve_sqincp_n32">;
-def SVQINCP_N_S64 : SInst<"svqincp[_n_s64]_{d}", "llP", "PcPsPiPl", MergeNone, "aarch64_sve_sqincp_n64">;
-def SVQINCP_N_U32 : SInst<"svqincp[_n_u32]_{d}", "mmP", "PcPsPiPl", MergeNone, "aarch64_sve_uqincp_n32">;
-def SVQINCP_N_U64 : SInst<"svqincp[_n_u64]_{d}", "nnP", "PcPsPiPl", MergeNone, "aarch64_sve_uqincp_n64">;
-
-let ArchGuard = "defined(__ARM_FEATURE_SVE_MATMUL_INT8)" in {
+def SVQDECP_S : SInst<"svqdecp[_{d}]", "ddP", "sil", MergeNone, "aarch64_sve_sqdecp", [IsStreamingCompatible]>;
+def SVQDECP_U : SInst<"svqdecp[_{d}]", "ddP", "UsUiUl", MergeNone, "aarch64_sve_uqdecp", [IsStreamingCompatible]>;
+def SVQINCP_S : SInst<"svqincp[_{d}]", "ddP", "sil", MergeNone, "aarch64_sve_sqincp", [IsStreamingCompatible]>;
+def SVQINCP_U : SInst<"svqincp[_{d}]", "ddP", "UsUiUl", MergeNone, "aarch64_sve_uqincp", [IsStreamingCompatible]>;
+
+def SVQDECP_N_S32 : SInst<"svqdecp[_n_s32]_{d}", "kkP", "PcPsPiPl", MergeNone, "aarch64_sve_sqdecp_n32", [IsStreamingCompatible]>;
+def SVQDECP_N_S64 : SInst<"svqdecp[_n_s64]_{d}", "llP", "PcPsPiPl", MergeNone, "aarch64_sve_sqdecp_n64", [IsStreamingCompatible]>;
+def SVQDECP_N_U32 : SInst<"svqdecp[_n_u32]_{d}", "mmP", "PcPsPiPl", MergeNone, "aarch64_sve_uqdecp_n32", [IsStreamingCompatible]>;
+def SVQDECP_N_U64 : SInst<"svqdecp[_n_u64]_{d}", "nnP", "PcPsPiPl", MergeNone, "aarch64_sve_uqdecp_n64", [IsStreamingCompatible]>;
+def SVQINCP_N_S32 : SInst<"svqincp[_n_s32]_{d}", "kkP", "PcPsPiPl", MergeNone, "aarch64_sve_sqincp_n32", [IsStreamingCompatible]>;
+def SVQINCP_N_S64 : SInst<"svqincp[_n_s64]_{d}", "llP", "PcPsPiPl", MergeNone, "aarch64_sve_sqincp_n64", [IsStreamingCompatible]>;
+def SVQINCP_N_U32 : SInst<"svqincp[_n_u32]_{d}", "mmP", "PcPsPiPl", MergeNone, "aarch64_sve_uqincp_n32", [IsStreamingCompatible]>;
+def SVQINCP_N_U64 : SInst<"svqincp[_n_u64]_{d}", "nnP", "PcPsPiPl", MergeNone, "aarch64_sve_uqincp_n64", [IsStreamingCompatible]>;
+
+let TargetGuard = "sve,i8mm" in {
def SVMLLA_S32 : SInst<"svmmla[_s32]", "ddqq","i", MergeNone, "aarch64_sve_smmla">;
def SVMLLA_U32 : SInst<"svmmla[_u32]", "ddqq","Ui", MergeNone, "aarch64_sve_ummla">;
def SVUSMLLA_S32 : SInst<"svusmmla[_s32]", "ddbq","i", MergeNone, "aarch64_sve_usmmla">;
-def SVUSDOT_S : SInst<"svusdot[_s32]", "ddbq", "i", MergeNone, "aarch64_sve_usdot">;
-def SVUSDOT_N_S : SInst<"svusdot[_n_s32]", "ddbr", "i", MergeNone, "aarch64_sve_usdot">;
-def SVSUDOT_S : SInst<"svsudot[_s32]", "ddqb", "i", MergeNone, "aarch64_sve_usdot", [ReverseUSDOT]>;
-def SVSUDOT_N_S : SInst<"svsudot[_n_s32]", "ddq@", "i", MergeNone, "aarch64_sve_usdot", [ReverseUSDOT]>;
+def SVUSDOT_S : SInst<"svusdot[_s32]", "ddbq", "i", MergeNone, "aarch64_sve_usdot", [IsStreamingCompatible]>;
+def SVUSDOT_N_S : SInst<"svusdot[_n_s32]", "ddbr", "i", MergeNone, "aarch64_sve_usdot", [IsStreamingCompatible]>;
+def SVSUDOT_S : SInst<"svsudot[_s32]", "ddqb", "i", MergeNone, "aarch64_sve_usdot", [ReverseUSDOT, IsStreamingCompatible]>;
+def SVSUDOT_N_S : SInst<"svsudot[_n_s32]", "ddq@", "i", MergeNone, "aarch64_sve_usdot", [ReverseUSDOT, IsStreamingCompatible]>;
-def SVUSDOT_LANE_S : SInst<"svusdot_lane[_s32]", "ddbqi", "i", MergeNone, "aarch64_sve_usdot_lane", [], [ImmCheck<3, ImmCheckLaneIndexDot, 2>]>;
-def SVSUDOT_LANE_S : SInst<"svsudot_lane[_s32]", "ddqbi", "i", MergeNone, "aarch64_sve_sudot_lane", [], [ImmCheck<3, ImmCheckLaneIndexDot, 2>]>;
+def SVUSDOT_LANE_S : SInst<"svusdot_lane[_s32]", "ddbqi", "i", MergeNone, "aarch64_sve_usdot_lane", [IsStreamingCompatible], [ImmCheck<3, ImmCheckLaneIndexDot, 2>]>;
+def SVSUDOT_LANE_S : SInst<"svsudot_lane[_s32]", "ddqbi", "i", MergeNone, "aarch64_sve_sudot_lane", [IsStreamingCompatible], [ImmCheck<3, ImmCheckLaneIndexDot, 2>]>;
}
-let ArchGuard = "defined(__ARM_FEATURE_SVE_MATMUL_FP32)" in {
+let TargetGuard = "sve,f32mm" in {
def SVMLLA_F32 : SInst<"svmmla[_f32]", "dddd","f", MergeNone, "aarch64_sve_fmmla">;
}
-let ArchGuard = "defined(__ARM_FEATURE_SVE_MATMUL_FP64)" in {
+let TargetGuard = "sve,f64mm" in {
def SVMLLA_F64 : SInst<"svmmla[_f64]", "dddd","d", MergeNone, "aarch64_sve_fmmla">;
-def SVTRN1Q : SInst<"svtrn1q[_{d}]", "ddd", "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_trn1q">;
-def SVTRN2Q : SInst<"svtrn2q[_{d}]", "ddd", "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_trn2q">;
-def SVUZP1Q : SInst<"svuzp1q[_{d}]", "ddd", "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_uzp1q">;
-def SVUZP2Q : SInst<"svuzp2q[_{d}]", "ddd", "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_uzp2q">;
-def SVZIP1Q : SInst<"svzip1q[_{d}]", "ddd", "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_zip1q">;
-def SVZIP2Q : SInst<"svzip2q[_{d}]", "ddd", "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_zip2q">;
+def SVTRN1Q : SInst<"svtrn1q[_{d}]", "ddd", "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_trn1q", [IsStreamingCompatible]>;
+def SVTRN2Q : SInst<"svtrn2q[_{d}]", "ddd", "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_trn2q", [IsStreamingCompatible]>;
+def SVUZP1Q : SInst<"svuzp1q[_{d}]", "ddd", "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_uzp1q", [IsStreamingCompatible]>;
+def SVUZP2Q : SInst<"svuzp2q[_{d}]", "ddd", "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_uzp2q", [IsStreamingCompatible]>;
+def SVZIP1Q : SInst<"svzip1q[_{d}]", "ddd", "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_zip1q", [IsStreamingCompatible]>;
+def SVZIP2Q : SInst<"svzip2q[_{d}]", "ddd", "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_zip2q", [IsStreamingCompatible]>;
}
-let ArchGuard = "defined(__ARM_FEATURE_SVE_MATMUL_FP64) && defined(__ARM_FEATURE_SVE_BF16)" in {
+let TargetGuard = "sve,bf16,f64mm" in {
def SVTRN1Q_BF16 : SInst<"svtrn1q[_{d}]", "ddd", "b", MergeNone, "aarch64_sve_trn1q">;
def SVTRN2Q_BF16 : SInst<"svtrn2q[_{d}]", "ddd", "b", MergeNone, "aarch64_sve_trn2q">;
-def SVUZP1Q_BF16 : SInst<"svuzp1q[_{d}]", "ddd", "b", MergeNone, "aarch64_sve_uzp1q">;
-def SVUZP2Q_BF16 : SInst<"svuzp2q[_{d}]", "ddd", "b", MergeNone, "aarch64_sve_uzp2q">;
-def SVZIP1Q_BF16 : SInst<"svzip1q[_{d}]", "ddd", "b", MergeNone, "aarch64_sve_zip1q">;
-def SVZIP2Q_BF16 : SInst<"svzip2q[_{d}]", "ddd", "b", MergeNone, "aarch64_sve_zip2q">;
+def SVUZP1Q_BF16 : SInst<"svuzp1q[_{d}]", "ddd", "b", MergeNone, "aarch64_sve_uzp1q", [IsStreamingCompatible]>;
+def SVUZP2Q_BF16 : SInst<"svuzp2q[_{d}]", "ddd", "b", MergeNone, "aarch64_sve_uzp2q", [IsStreamingCompatible]>;
+def SVZIP1Q_BF16 : SInst<"svzip1q[_{d}]", "ddd", "b", MergeNone, "aarch64_sve_zip1q", [IsStreamingCompatible]>;
+def SVZIP2Q_BF16 : SInst<"svzip2q[_{d}]", "ddd", "b", MergeNone, "aarch64_sve_zip2q", [IsStreamingCompatible]>;
}
////////////////////////////////////////////////////////////////////////////////
// Vector creation
-def SVUNDEF_1 : SInst<"svundef_{d}", "d", "csilUcUsUiUlhfd", MergeNone, "", [IsUndef]>;
-def SVUNDEF_2 : SInst<"svundef2_{d}", "2", "csilUcUsUiUlhfd", MergeNone, "", [IsUndef]>;
-def SVUNDEF_3 : SInst<"svundef3_{d}", "3", "csilUcUsUiUlhfd", MergeNone, "", [IsUndef]>;
-def SVUNDEF_4 : SInst<"svundef4_{d}", "4", "csilUcUsUiUlhfd", MergeNone, "", [IsUndef]>;
+def SVUNDEF_1 : SInst<"svundef_{d}", "dv", "csilUcUsUiUlhfd", MergeNone, "", [IsUndef, IsStreamingCompatible]>;
+def SVUNDEF_2 : SInst<"svundef2_{d}", "2v", "csilUcUsUiUlhfd", MergeNone, "", [IsUndef, IsStreamingCompatible]>;
+def SVUNDEF_3 : SInst<"svundef3_{d}", "3v", "csilUcUsUiUlhfd", MergeNone, "", [IsUndef, IsStreamingCompatible]>;
+def SVUNDEF_4 : SInst<"svundef4_{d}", "4v", "csilUcUsUiUlhfd", MergeNone, "", [IsUndef, IsStreamingCompatible]>;
-def SVCREATE_2 : SInst<"svcreate2[_{d}]", "2dd", "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_tuple_create2", [IsTupleCreate]>;
-def SVCREATE_3 : SInst<"svcreate3[_{d}]", "3ddd", "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_tuple_create3", [IsTupleCreate]>;
-def SVCREATE_4 : SInst<"svcreate4[_{d}]", "4dddd", "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_tuple_create4", [IsTupleCreate]>;
+def SVCREATE_2 : SInst<"svcreate2[_{d}]", "2dd", "csilUcUsUiUlhfd", MergeNone, "", [IsTupleCreate, IsStreamingCompatible]>;
+def SVCREATE_3 : SInst<"svcreate3[_{d}]", "3ddd", "csilUcUsUiUlhfd", MergeNone, "", [IsTupleCreate, IsStreamingCompatible]>;
+def SVCREATE_4 : SInst<"svcreate4[_{d}]", "4dddd", "csilUcUsUiUlhfd", MergeNone, "", [IsTupleCreate, IsStreamingCompatible]>;
-let ArchGuard = "defined(__ARM_FEATURE_SVE_BF16)" in {
-def SVUNDEF_1_BF16 : SInst<"svundef_{d}", "d", "b", MergeNone, "", [IsUndef]>;
-def SVUNDEF_2_BF16 : SInst<"svundef2_{d}", "2", "b", MergeNone, "", [IsUndef]>;
-def SVUNDEF_3_BF16 : SInst<"svundef3_{d}", "3", "b", MergeNone, "", [IsUndef]>;
-def SVUNDEF_4_BF16 : SInst<"svundef4_{d}", "4", "b", MergeNone, "", [IsUndef]>;
+let TargetGuard = "sve,bf16" in {
+def SVUNDEF_1_BF16 : SInst<"svundef_{d}", "dv", "b", MergeNone, "", [IsUndef, IsStreamingCompatible]>;
+def SVUNDEF_2_BF16 : SInst<"svundef2_{d}", "2v", "b", MergeNone, "", [IsUndef, IsStreamingCompatible]>;
+def SVUNDEF_3_BF16 : SInst<"svundef3_{d}", "3v", "b", MergeNone, "", [IsUndef, IsStreamingCompatible]>;
+def SVUNDEF_4_BF16 : SInst<"svundef4_{d}", "4v", "b", MergeNone, "", [IsUndef, IsStreamingCompatible]>;
+
+def SVCREATE_2_BF16 : SInst<"svcreate2[_{d}]", "2dd", "b", MergeNone, "", [IsTupleCreate, IsStreamingCompatible]>;
+def SVCREATE_3_BF16 : SInst<"svcreate3[_{d}]", "3ddd", "b", MergeNone, "", [IsTupleCreate, IsStreamingCompatible]>;
+def SVCREATE_4_BF16 : SInst<"svcreate4[_{d}]", "4dddd", "b", MergeNone, "", [IsTupleCreate, IsStreamingCompatible]>;
+}
-def SVCREATE_2_BF16 : SInst<"svcreate2[_{d}]", "2dd", "b", MergeNone, "aarch64_sve_tuple_create2", [IsTupleCreate]>;
-def SVCREATE_3_BF16 : SInst<"svcreate3[_{d}]", "3ddd", "b", MergeNone, "aarch64_sve_tuple_create3", [IsTupleCreate]>;
-def SVCREATE_4_BF16 : SInst<"svcreate4[_{d}]", "4dddd", "b", MergeNone, "aarch64_sve_tuple_create4", [IsTupleCreate]>;
+let TargetGuard = "sve2p1|sme2" in {
+ def SVCREATE_2_B : SInst<"svcreate2[_b]", "2dd", "Pc", MergeNone, "", [IsTupleCreate, IsStreamingCompatible]>;
+ def SVCREATE_4_B : SInst<"svcreate4[_b]", "4dddd", "Pc", MergeNone, "", [IsTupleCreate, IsStreamingCompatible]>;
}
////////////////////////////////////////////////////////////////////////////////
// Vector insertion and extraction
-def SVGET_2 : SInst<"svget2[_{d}]", "d2i", "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_tuple_get", [IsTupleGet], [ImmCheck<1, ImmCheck0_1>]>;
-def SVGET_3 : SInst<"svget3[_{d}]", "d3i", "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_tuple_get", [IsTupleGet], [ImmCheck<1, ImmCheck0_2>]>;
-def SVGET_4 : SInst<"svget4[_{d}]", "d4i", "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_tuple_get", [IsTupleGet], [ImmCheck<1, ImmCheck0_3>]>;
+def SVGET_2 : SInst<"svget2[_{d}]", "d2i", "csilUcUsUiUlhfd", MergeNone, "", [IsTupleGet, IsStreamingCompatible], [ImmCheck<1, ImmCheck0_1>]>;
+def SVGET_3 : SInst<"svget3[_{d}]", "d3i", "csilUcUsUiUlhfd", MergeNone, "", [IsTupleGet, IsStreamingCompatible], [ImmCheck<1, ImmCheck0_2>]>;
+def SVGET_4 : SInst<"svget4[_{d}]", "d4i", "csilUcUsUiUlhfd", MergeNone, "", [IsTupleGet, IsStreamingCompatible], [ImmCheck<1, ImmCheck0_3>]>;
-def SVSET_2 : SInst<"svset2[_{d}]", "22id", "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_tuple_set", [IsTupleSet], [ImmCheck<1, ImmCheck0_1>]>;
-def SVSET_3 : SInst<"svset3[_{d}]", "33id", "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_tuple_set", [IsTupleSet], [ImmCheck<1, ImmCheck0_2>]>;
-def SVSET_4 : SInst<"svset4[_{d}]", "44id", "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_tuple_set", [IsTupleSet], [ImmCheck<1, ImmCheck0_3>]>;
+def SVSET_2 : SInst<"svset2[_{d}]", "22id", "csilUcUsUiUlhfd", MergeNone, "", [IsTupleSet, IsStreamingCompatible], [ImmCheck<1, ImmCheck0_1>]>;
+def SVSET_3 : SInst<"svset3[_{d}]", "33id", "csilUcUsUiUlhfd", MergeNone, "", [IsTupleSet, IsStreamingCompatible], [ImmCheck<1, ImmCheck0_2>]>;
+def SVSET_4 : SInst<"svset4[_{d}]", "44id", "csilUcUsUiUlhfd", MergeNone, "", [IsTupleSet, IsStreamingCompatible], [ImmCheck<1, ImmCheck0_3>]>;
-let ArchGuard = "defined(__ARM_FEATURE_SVE_BF16)" in {
-def SVGET_2_BF16 : SInst<"svget2[_{d}]", "d2i", "b", MergeNone, "aarch64_sve_tuple_get", [IsTupleGet], [ImmCheck<1, ImmCheck0_1>]>;
-def SVGET_3_BF16 : SInst<"svget3[_{d}]", "d3i", "b", MergeNone, "aarch64_sve_tuple_get", [IsTupleGet], [ImmCheck<1, ImmCheck0_2>]>;
-def SVGET_4_BF16 : SInst<"svget4[_{d}]", "d4i", "b", MergeNone, "aarch64_sve_tuple_get", [IsTupleGet], [ImmCheck<1, ImmCheck0_3>]>;
+let TargetGuard = "sve,bf16" in {
+def SVGET_2_BF16 : SInst<"svget2[_{d}]", "d2i", "b", MergeNone, "", [IsTupleGet, IsStreamingCompatible], [ImmCheck<1, ImmCheck0_1>]>;
+def SVGET_3_BF16 : SInst<"svget3[_{d}]", "d3i", "b", MergeNone, "", [IsTupleGet, IsStreamingCompatible], [ImmCheck<1, ImmCheck0_2>]>;
+def SVGET_4_BF16 : SInst<"svget4[_{d}]", "d4i", "b", MergeNone, "", [IsTupleGet, IsStreamingCompatible], [ImmCheck<1, ImmCheck0_3>]>;
-def SVSET_2_BF16 : SInst<"svset2[_{d}]", "22id", "b", MergeNone, "aarch64_sve_tuple_set", [IsTupleSet], [ImmCheck<1, ImmCheck0_1>]>;
-def SVSET_3_BF16 : SInst<"svset3[_{d}]", "33id", "b", MergeNone, "aarch64_sve_tuple_set", [IsTupleSet], [ImmCheck<1, ImmCheck0_2>]>;
-def SVSET_4_BF16 : SInst<"svset4[_{d}]", "44id", "b", MergeNone, "aarch64_sve_tuple_set", [IsTupleSet], [ImmCheck<1, ImmCheck0_3>]>;
+def SVSET_2_BF16 : SInst<"svset2[_{d}]", "22id", "b", MergeNone, "", [IsTupleSet, IsStreamingCompatible], [ImmCheck<1, ImmCheck0_1>]>;
+def SVSET_3_BF16 : SInst<"svset3[_{d}]", "33id", "b", MergeNone, "", [IsTupleSet, IsStreamingCompatible], [ImmCheck<1, ImmCheck0_2>]>;
+def SVSET_4_BF16 : SInst<"svset4[_{d}]", "44id", "b", MergeNone, "", [IsTupleSet, IsStreamingCompatible], [ImmCheck<1, ImmCheck0_3>]>;
}
+let TargetGuard = "sve2p1|sme2" in {
+ def SVGET_2_B : SInst<"svget2[_b]", "d2i", "Pc", MergeNone, "", [IsTupleGet, IsStreamingCompatible], [ImmCheck<1, ImmCheck0_1>]>;
+ def SVGET_4_B : SInst<"svget4[_b]", "d4i", "Pc", MergeNone, "", [IsTupleGet, IsStreamingCompatible], [ImmCheck<1, ImmCheck0_3>]>;
+
+ def SVSET_2_B : SInst<"svset2[_b]", "22id", "Pc", MergeNone, "", [IsTupleSet, IsStreamingCompatible], [ImmCheck<1, ImmCheck0_1>]>;
+ def SVSET_4_B : SInst<"svset4[_b]", "44id", "Pc", MergeNone, "", [IsTupleSet, IsStreamingCompatible], [ImmCheck<1, ImmCheck0_3>]>;
+}
+
+let TargetGuard = "sve2p1|sme2" in {
+ def SVUNDEF_2_B: Inst<"svundef2_b", "2", "Pc", MergeNone, "", [IsUndef, IsStreamingCompatible], []>;
+ def SVUNDEF_4_B: Inst<"svundef4_b", "4", "Pc", MergeNone, "", [IsUndef, IsStreamingCompatible], []>;
+}
////////////////////////////////////////////////////////////////////////////////
// SVE2 WhileGE/GT
-let ArchGuard = "defined(__ARM_FEATURE_SVE2)" in {
-def SVWHILEGE_S32 : SInst<"svwhilege_{d}[_{1}]", "Pkk", "PcPsPiPl", MergeNone, "aarch64_sve_whilege", [IsOverloadWhile]>;
-def SVWHILEGE_S64 : SInst<"svwhilege_{d}[_{1}]", "Pll", "PcPsPiPl", MergeNone, "aarch64_sve_whilege", [IsOverloadWhile]>;
-def SVWHILEGT_S32 : SInst<"svwhilegt_{d}[_{1}]", "Pkk", "PcPsPiPl", MergeNone, "aarch64_sve_whilegt", [IsOverloadWhile]>;
-def SVWHILEGT_S64 : SInst<"svwhilegt_{d}[_{1}]", "Pll", "PcPsPiPl", MergeNone, "aarch64_sve_whilegt", [IsOverloadWhile]>;
-def SVWHILEHI_U32 : SInst<"svwhilegt_{d}[_{1}]", "Pmm", "PUcPUsPUiPUl", MergeNone, "aarch64_sve_whilehi", [IsOverloadWhile]>;
-def SVWHILEHI_U64 : SInst<"svwhilegt_{d}[_{1}]", "Pnn", "PUcPUsPUiPUl", MergeNone, "aarch64_sve_whilehi", [IsOverloadWhile]>;
-def SVWHILEHS_U32 : SInst<"svwhilege_{d}[_{1}]", "Pmm", "PUcPUsPUiPUl", MergeNone, "aarch64_sve_whilehs", [IsOverloadWhile]>;
-def SVWHILEHS_U64 : SInst<"svwhilege_{d}[_{1}]", "Pnn", "PUcPUsPUiPUl", MergeNone, "aarch64_sve_whilehs", [IsOverloadWhile]>;
+let TargetGuard = "sve2" in {
+def SVWHILEGE_S32 : SInst<"svwhilege_{d}[_{1}]", "Pkk", "PcPsPiPl", MergeNone, "aarch64_sve_whilege", [IsOverloadWhileOrMultiVecCvt, IsStreamingCompatible]>;
+def SVWHILEGE_S64 : SInst<"svwhilege_{d}[_{1}]", "Pll", "PcPsPiPl", MergeNone, "aarch64_sve_whilege", [IsOverloadWhileOrMultiVecCvt, IsStreamingCompatible]>;
+def SVWHILEGT_S32 : SInst<"svwhilegt_{d}[_{1}]", "Pkk", "PcPsPiPl", MergeNone, "aarch64_sve_whilegt", [IsOverloadWhileOrMultiVecCvt, IsStreamingCompatible]>;
+def SVWHILEGT_S64 : SInst<"svwhilegt_{d}[_{1}]", "Pll", "PcPsPiPl", MergeNone, "aarch64_sve_whilegt", [IsOverloadWhileOrMultiVecCvt, IsStreamingCompatible]>;
+def SVWHILEHI_U32 : SInst<"svwhilegt_{d}[_{1}]", "Pmm", "PUcPUsPUiPUl", MergeNone, "aarch64_sve_whilehi", [IsOverloadWhileOrMultiVecCvt, IsStreamingCompatible]>;
+def SVWHILEHI_U64 : SInst<"svwhilegt_{d}[_{1}]", "Pnn", "PUcPUsPUiPUl", MergeNone, "aarch64_sve_whilehi", [IsOverloadWhileOrMultiVecCvt, IsStreamingCompatible]>;
+def SVWHILEHS_U32 : SInst<"svwhilege_{d}[_{1}]", "Pmm", "PUcPUsPUiPUl", MergeNone, "aarch64_sve_whilehs", [IsOverloadWhileOrMultiVecCvt, IsStreamingCompatible]>;
+def SVWHILEHS_U64 : SInst<"svwhilege_{d}[_{1}]", "Pnn", "PUcPUsPUiPUl", MergeNone, "aarch64_sve_whilehs", [IsOverloadWhileOrMultiVecCvt, IsStreamingCompatible]>;
+}
+
+let TargetGuard = "sve2p1|sme2" in {
+ def SVWHILEGE_S64_X2 : SInst<"svwhilege_{d}[_{1}]_x2", "2ll", "PcPsPiPl", MergeNone, "aarch64_sve_whilege_x2", [IsStreamingOrSVE2p1]>;
+ def SVWHILEGT_S64_X2 : SInst<"svwhilegt_{d}[_{1}]_x2", "2ll", "PcPsPiPl", MergeNone, "aarch64_sve_whilegt_x2", [IsStreamingOrSVE2p1]>;
+ def SVWHILEHI_U64_X2 : SInst<"svwhilegt_{d}[_{1}]_x2", "2nn", "PcPsPiPl", MergeNone, "aarch64_sve_whilehi_x2", [IsStreamingOrSVE2p1]>;
+ def SVWHILEHS_U64_X2 : SInst<"svwhilege_{d}[_{1}]_x2", "2nn", "PcPsPiPl", MergeNone, "aarch64_sve_whilehs_x2", [IsStreamingOrSVE2p1]>;
+ def SVWHILELE_S64_X2 : SInst<"svwhilele_{d}[_{1}]_x2", "2ll", "PcPsPiPl", MergeNone, "aarch64_sve_whilele_x2", [IsStreamingOrSVE2p1]>;
+ def SVWHILELT_S64_X2 : SInst<"svwhilelt_{d}[_{1}]_x2", "2ll", "PcPsPiPl", MergeNone, "aarch64_sve_whilelt_x2", [IsStreamingOrSVE2p1]>;
+ def SVWHILELO_U64_X2 : SInst<"svwhilelt_{d}[_{1}]_x2", "2nn", "PcPsPiPl", MergeNone, "aarch64_sve_whilelo_x2", [IsStreamingOrSVE2p1]>;
+ def SVWHILELS_U64_X2 : SInst<"svwhilele_{d}[_{1}]_x2", "2nn", "PcPsPiPl", MergeNone, "aarch64_sve_whilels_x2", [IsStreamingOrSVE2p1]>;
+
}
////////////////////////////////////////////////////////////////////////////////
// SVE2 - Uniform DSP operations
-let ArchGuard = "defined(__ARM_FEATURE_SVE2)" in {
-defm SVQADD_S : SInstZPZZ<"svqadd", "csli", "aarch64_sve_sqadd">;
-defm SVQADD_U : SInstZPZZ<"svqadd", "UcUsUiUl", "aarch64_sve_uqadd">;
-defm SVHADD_S : SInstZPZZ<"svhadd", "csli", "aarch64_sve_shadd">;
-defm SVHADD_U : SInstZPZZ<"svhadd", "UcUsUiUl", "aarch64_sve_uhadd">;
-defm SVRHADD_S : SInstZPZZ<"svrhadd", "csli", "aarch64_sve_srhadd">;
-defm SVRHADD_U : SInstZPZZ<"svrhadd", "UcUsUiUl", "aarch64_sve_urhadd">;
-
-defm SVQSUB_S : SInstZPZZ<"svqsub", "csli", "aarch64_sve_sqsub">;
-defm SVQSUB_U : SInstZPZZ<"svqsub", "UcUsUiUl", "aarch64_sve_uqsub">;
-defm SVQSUBR_S : SInstZPZZ<"svqsubr", "csli", "aarch64_sve_sqsubr">;
-defm SVQSUBR_U : SInstZPZZ<"svqsubr", "UcUsUiUl", "aarch64_sve_uqsubr">;
-defm SVHSUB_S : SInstZPZZ<"svhsub", "csli", "aarch64_sve_shsub">;
-defm SVHSUB_U : SInstZPZZ<"svhsub", "UcUsUiUl", "aarch64_sve_uhsub">;
-defm SVHSUBR_S : SInstZPZZ<"svhsubr", "csli", "aarch64_sve_shsubr">;
-defm SVHSUBR_U : SInstZPZZ<"svhsubr", "UcUsUiUl", "aarch64_sve_uhsubr">;
+let TargetGuard = "sve2" in {
+defm SVQADD_S : SInstZPZZ<"svqadd", "csli", "aarch64_sve_sqadd", "aarch64_sve_sqadd">;
+defm SVQADD_U : SInstZPZZ<"svqadd", "UcUsUiUl", "aarch64_sve_uqadd", "aarch64_sve_uqadd">;
+defm SVHADD_S : SInstZPZZ<"svhadd", "csli", "aarch64_sve_shadd", "aarch64_sve_shadd">;
+defm SVHADD_U : SInstZPZZ<"svhadd", "UcUsUiUl", "aarch64_sve_uhadd", "aarch64_sve_uhadd">;
+defm SVRHADD_S : SInstZPZZ<"svrhadd", "csli", "aarch64_sve_srhadd", "aarch64_sve_srhadd">;
+defm SVRHADD_U : SInstZPZZ<"svrhadd", "UcUsUiUl", "aarch64_sve_urhadd", "aarch64_sve_urhadd">;
+
+defm SVQSUB_S : SInstZPZZ<"svqsub", "csli", "aarch64_sve_sqsub", "aarch64_sve_sqsub_u">;
+defm SVQSUB_U : SInstZPZZ<"svqsub", "UcUsUiUl", "aarch64_sve_uqsub", "aarch64_sve_uqsub_u">;
+defm SVQSUBR_S : SInstZPZZ<"svqsubr", "csli", "aarch64_sve_sqsubr", "aarch64_sve_sqsub_u", [ReverseMergeAnyBinOp]>;
+defm SVQSUBR_U : SInstZPZZ<"svqsubr", "UcUsUiUl", "aarch64_sve_uqsubr", "aarch64_sve_uqsub_u", [ReverseMergeAnyBinOp]>;
+defm SVHSUB_S : SInstZPZZ<"svhsub", "csli", "aarch64_sve_shsub", "aarch64_sve_shsub">;
+defm SVHSUB_U : SInstZPZZ<"svhsub", "UcUsUiUl", "aarch64_sve_uhsub", "aarch64_sve_uhsub">;
+defm SVHSUBR_S : SInstZPZZ<"svhsubr", "csli", "aarch64_sve_shsubr", "aarch64_sve_shsubr">;
+defm SVHSUBR_U : SInstZPZZ<"svhsubr", "UcUsUiUl", "aarch64_sve_uhsubr", "aarch64_sve_uhsubr">;
defm SVQABS : SInstZPZ<"svqabs", "csil", "aarch64_sve_sqabs">;
defm SVQNEG : SInstZPZ<"svqneg", "csil", "aarch64_sve_sqneg">;
@@ -1526,50 +1396,50 @@ multiclass SInstZPZxZ<string name, string types, string pat_v, string pat_n, str
def _N_Z : SInst<name # "[_n_{d}]", pat_n, types, MergeZero, intrinsic, flags>;
}
-let ArchGuard = "defined(__ARM_FEATURE_SVE2)" in {
-defm SVQRSHL_S : SInstZPZxZ<"svqrshl", "csil", "dPdx", "dPdK", "aarch64_sve_sqrshl">;
-defm SVQRSHL_U : SInstZPZxZ<"svqrshl", "UcUsUiUl", "dPdx", "dPdK", "aarch64_sve_uqrshl">;
-defm SVQSHL_S : SInstZPZxZ<"svqshl", "csil", "dPdx", "dPdK", "aarch64_sve_sqshl">;
-defm SVQSHL_U : SInstZPZxZ<"svqshl", "UcUsUiUl", "dPdx", "dPdK", "aarch64_sve_uqshl">;
-defm SVRSHL_S : SInstZPZxZ<"svrshl", "csil", "dPdx", "dPdK", "aarch64_sve_srshl">;
-defm SVRSHL_U : SInstZPZxZ<"svrshl", "UcUsUiUl", "dPdx", "dPdK", "aarch64_sve_urshl">;
-defm SVSQADD : SInstZPZxZ<"svsqadd", "UcUsUiUl", "dPdx", "dPdK", "aarch64_sve_usqadd">;
-defm SVUQADD : SInstZPZxZ<"svuqadd", "csil", "dPdu", "dPdL", "aarch64_sve_suqadd">;
-
-def SVABA_S : SInst<"svaba[_{d}]", "dddd", "csil" , MergeNone, "aarch64_sve_saba">;
-def SVABA_U : SInst<"svaba[_{d}]", "dddd", "UcUsUiUl", MergeNone, "aarch64_sve_uaba">;
-def SVQDMULH : SInst<"svqdmulh[_{d}]", "ddd", "csil", MergeNone, "aarch64_sve_sqdmulh">;
-def SVQRDMULH : SInst<"svqrdmulh[_{d}]", "ddd", "csil", MergeNone, "aarch64_sve_sqrdmulh">;
-def SVQRDMLAH : SInst<"svqrdmlah[_{d}]", "dddd", "csil", MergeNone, "aarch64_sve_sqrdmlah">;
-def SVQRDMLSH : SInst<"svqrdmlsh[_{d}]", "dddd", "csil", MergeNone, "aarch64_sve_sqrdmlsh">;
-
-def SVABA_S_N : SInst<"svaba[_n_{d}]", "ddda", "csil", MergeNone, "aarch64_sve_saba">;
-def SVABA_U_N : SInst<"svaba[_n_{d}]", "ddda", "UcUsUiUl", MergeNone, "aarch64_sve_uaba">;
-def SVQDMULH_N : SInst<"svqdmulh[_n_{d}]", "dda", "csil", MergeNone, "aarch64_sve_sqdmulh">;
-def SVQRDMULH_N : SInst<"svqrdmulh[_n_{d}]", "dda", "csil", MergeNone, "aarch64_sve_sqrdmulh">;
-def SVQRDMLAH_N : SInst<"svqrdmlah[_n_{d}]", "ddda", "csil", MergeNone, "aarch64_sve_sqrdmlah">;
-def SVQRDMLSH_N : SInst<"svqrdmlsh[_n_{d}]", "ddda", "csil", MergeNone, "aarch64_sve_sqrdmlsh">;
-
-def SVQDMULH_LANE : SInst<"svqdmulh_lane[_{d}]", "dddi", "sil", MergeNone, "aarch64_sve_sqdmulh_lane", [], [ImmCheck<2, ImmCheckLaneIndex, 1>]>;
-def SVQRDMULH_LANE : SInst<"svqrdmulh_lane[_{d}]", "dddi", "sil", MergeNone, "aarch64_sve_sqrdmulh_lane", [], [ImmCheck<2, ImmCheckLaneIndex, 1>]>;
-def SVQRDMLAH_LANE : SInst<"svqrdmlah_lane[_{d}]", "ddddi", "sil", MergeNone, "aarch64_sve_sqrdmlah_lane", [], [ImmCheck<3, ImmCheckLaneIndex, 2>]>;
-def SVQRDMLSH_LANE : SInst<"svqrdmlsh_lane[_{d}]", "ddddi", "sil", MergeNone, "aarch64_sve_sqrdmlsh_lane", [], [ImmCheck<3, ImmCheckLaneIndex, 2>]>;
-
-def SVQSHLU_M : SInst<"svqshlu[_n_{d}]", "uPdi", "csil", MergeOp1, "aarch64_sve_sqshlu", [], [ImmCheck<2, ImmCheckShiftLeft, 1>]>;
-def SVQSHLU_X : SInst<"svqshlu[_n_{d}]", "uPdi", "csil", MergeAny, "aarch64_sve_sqshlu", [], [ImmCheck<2, ImmCheckShiftLeft, 1>]>;
-def SVQSHLU_Z : SInst<"svqshlu[_n_{d}]", "uPdi", "csil", MergeZero, "aarch64_sve_sqshlu", [], [ImmCheck<2, ImmCheckShiftLeft, 1>]>;
-def SVRSHR_M_S : SInst<"svrshr[_n_{d}]", "dPdi", "csil", MergeOp1, "aarch64_sve_srshr", [], [ImmCheck<2, ImmCheckShiftRight, 1>]>;
-def SVRSHR_M_U : SInst<"svrshr[_n_{d}]", "dPdi", "UcUsUiUl", MergeOp1, "aarch64_sve_urshr", [], [ImmCheck<2, ImmCheckShiftRight, 1>]>;
-def SVRSHR_X_S : SInst<"svrshr[_n_{d}]", "dPdi", "csil", MergeAny, "aarch64_sve_srshr", [], [ImmCheck<2, ImmCheckShiftRight, 1>]>;
-def SVRSHR_X_U : SInst<"svrshr[_n_{d}]", "dPdi", "UcUsUiUl", MergeAny, "aarch64_sve_urshr", [], [ImmCheck<2, ImmCheckShiftRight, 1>]>;
-def SVRSHR_Z_S : SInst<"svrshr[_n_{d}]", "dPdi", "csil", MergeZero, "aarch64_sve_srshr", [], [ImmCheck<2, ImmCheckShiftRight, 1>]>;
-def SVRSHR_Z_U : SInst<"svrshr[_n_{d}]", "dPdi", "UcUsUiUl", MergeZero, "aarch64_sve_urshr", [], [ImmCheck<2, ImmCheckShiftRight, 1>]>;
-def SVRSRA_S : SInst<"svrsra[_n_{d}]", "dddi", "csil", MergeNone, "aarch64_sve_srsra", [], [ImmCheck<2, ImmCheckShiftRight, 1>]>;
-def SVRSRA_U : SInst<"svrsra[_n_{d}]", "dddi", "UcUsUiUl", MergeNone, "aarch64_sve_ursra", [], [ImmCheck<2, ImmCheckShiftRight, 1>]>;
-def SVSLI : SInst<"svsli[_n_{d}]", "dddi", "csilUcUsUiUl", MergeNone, "aarch64_sve_sli", [], [ImmCheck<2, ImmCheckShiftLeft, 1>]>;
-def SVSRA_S : SInst<"svsra[_n_{d}]", "dddi", "csil", MergeNone, "aarch64_sve_ssra", [], [ImmCheck<2, ImmCheckShiftRight, 1>]>;
-def SVSRA_U : SInst<"svsra[_n_{d}]", "dddi", "UcUsUiUl", MergeNone, "aarch64_sve_usra", [], [ImmCheck<2, ImmCheckShiftRight, 1>]>;
-def SVSRI : SInst<"svsri[_n_{d}]", "dddi", "csilUcUsUiUl", MergeNone, "aarch64_sve_sri", [], [ImmCheck<2, ImmCheckShiftRight, 1>]>;
+let TargetGuard = "sve2" in {
+defm SVQRSHL_S : SInstZPZxZ<"svqrshl", "csil", "dPdx", "dPdK", "aarch64_sve_sqrshl", [IsStreamingCompatible]>;
+defm SVQRSHL_U : SInstZPZxZ<"svqrshl", "UcUsUiUl", "dPdx", "dPdK", "aarch64_sve_uqrshl", [IsStreamingCompatible]>;
+defm SVQSHL_S : SInstZPZxZ<"svqshl", "csil", "dPdx", "dPdK", "aarch64_sve_sqshl", [IsStreamingCompatible]>;
+defm SVQSHL_U : SInstZPZxZ<"svqshl", "UcUsUiUl", "dPdx", "dPdK", "aarch64_sve_uqshl", [IsStreamingCompatible]>;
+defm SVRSHL_S : SInstZPZxZ<"svrshl", "csil", "dPdx", "dPdK", "aarch64_sve_srshl", [IsStreamingCompatible]>;
+defm SVRSHL_U : SInstZPZxZ<"svrshl", "UcUsUiUl", "dPdx", "dPdK", "aarch64_sve_urshl", [IsStreamingCompatible]>;
+defm SVSQADD : SInstZPZxZ<"svsqadd", "UcUsUiUl", "dPdx", "dPdK", "aarch64_sve_usqadd", [IsStreamingCompatible]>;
+defm SVUQADD : SInstZPZxZ<"svuqadd", "csil", "dPdu", "dPdL", "aarch64_sve_suqadd", [IsStreamingCompatible]>;
+
+def SVABA_S : SInst<"svaba[_{d}]", "dddd", "csil" , MergeNone, "aarch64_sve_saba", [IsStreamingCompatible]>;
+def SVABA_U : SInst<"svaba[_{d}]", "dddd", "UcUsUiUl", MergeNone, "aarch64_sve_uaba", [IsStreamingCompatible]>;
+def SVQDMULH : SInst<"svqdmulh[_{d}]", "ddd", "csil", MergeNone, "aarch64_sve_sqdmulh", [IsStreamingCompatible]>;
+def SVQRDMULH : SInst<"svqrdmulh[_{d}]", "ddd", "csil", MergeNone, "aarch64_sve_sqrdmulh", [IsStreamingCompatible]>;
+def SVQRDMLAH : SInst<"svqrdmlah[_{d}]", "dddd", "csil", MergeNone, "aarch64_sve_sqrdmlah", [IsStreamingCompatible]>;
+def SVQRDMLSH : SInst<"svqrdmlsh[_{d}]", "dddd", "csil", MergeNone, "aarch64_sve_sqrdmlsh", [IsStreamingCompatible]>;
+
+def SVABA_S_N : SInst<"svaba[_n_{d}]", "ddda", "csil", MergeNone, "aarch64_sve_saba", [IsStreamingCompatible]>;
+def SVABA_U_N : SInst<"svaba[_n_{d}]", "ddda", "UcUsUiUl", MergeNone, "aarch64_sve_uaba", [IsStreamingCompatible]>;
+def SVQDMULH_N : SInst<"svqdmulh[_n_{d}]", "dda", "csil", MergeNone, "aarch64_sve_sqdmulh", [IsStreamingCompatible]>;
+def SVQRDMULH_N : SInst<"svqrdmulh[_n_{d}]", "dda", "csil", MergeNone, "aarch64_sve_sqrdmulh", [IsStreamingCompatible]>;
+def SVQRDMLAH_N : SInst<"svqrdmlah[_n_{d}]", "ddda", "csil", MergeNone, "aarch64_sve_sqrdmlah", [IsStreamingCompatible]>;
+def SVQRDMLSH_N : SInst<"svqrdmlsh[_n_{d}]", "ddda", "csil", MergeNone, "aarch64_sve_sqrdmlsh", [IsStreamingCompatible]>;
+
+def SVQDMULH_LANE : SInst<"svqdmulh_lane[_{d}]", "dddi", "sil", MergeNone, "aarch64_sve_sqdmulh_lane", [IsStreamingCompatible], [ImmCheck<2, ImmCheckLaneIndex, 1>]>;
+def SVQRDMULH_LANE : SInst<"svqrdmulh_lane[_{d}]", "dddi", "sil", MergeNone, "aarch64_sve_sqrdmulh_lane", [IsStreamingCompatible], [ImmCheck<2, ImmCheckLaneIndex, 1>]>;
+def SVQRDMLAH_LANE : SInst<"svqrdmlah_lane[_{d}]", "ddddi", "sil", MergeNone, "aarch64_sve_sqrdmlah_lane", [IsStreamingCompatible], [ImmCheck<3, ImmCheckLaneIndex, 2>]>;
+def SVQRDMLSH_LANE : SInst<"svqrdmlsh_lane[_{d}]", "ddddi", "sil", MergeNone, "aarch64_sve_sqrdmlsh_lane", [IsStreamingCompatible], [ImmCheck<3, ImmCheckLaneIndex, 2>]>;
+
+def SVQSHLU_M : SInst<"svqshlu[_n_{d}]", "uPdi", "csil", MergeOp1, "aarch64_sve_sqshlu", [IsStreamingCompatible], [ImmCheck<2, ImmCheckShiftLeft, 1>]>;
+def SVQSHLU_X : SInst<"svqshlu[_n_{d}]", "uPdi", "csil", MergeAny, "aarch64_sve_sqshlu", [IsStreamingCompatible], [ImmCheck<2, ImmCheckShiftLeft, 1>]>;
+def SVQSHLU_Z : SInst<"svqshlu[_n_{d}]", "uPdi", "csil", MergeZero, "aarch64_sve_sqshlu", [IsStreamingCompatible], [ImmCheck<2, ImmCheckShiftLeft, 1>]>;
+def SVRSHR_M_S : SInst<"svrshr[_n_{d}]", "dPdi", "csil", MergeOp1, "aarch64_sve_srshr", [IsStreamingCompatible], [ImmCheck<2, ImmCheckShiftRight, 1>]>;
+def SVRSHR_M_U : SInst<"svrshr[_n_{d}]", "dPdi", "UcUsUiUl", MergeOp1, "aarch64_sve_urshr", [IsStreamingCompatible], [ImmCheck<2, ImmCheckShiftRight, 1>]>;
+def SVRSHR_X_S : SInst<"svrshr[_n_{d}]", "dPdi", "csil", MergeAny, "aarch64_sve_srshr", [IsStreamingCompatible], [ImmCheck<2, ImmCheckShiftRight, 1>]>;
+def SVRSHR_X_U : SInst<"svrshr[_n_{d}]", "dPdi", "UcUsUiUl", MergeAny, "aarch64_sve_urshr", [IsStreamingCompatible], [ImmCheck<2, ImmCheckShiftRight, 1>]>;
+def SVRSHR_Z_S : SInst<"svrshr[_n_{d}]", "dPdi", "csil", MergeZero, "aarch64_sve_srshr", [IsStreamingCompatible], [ImmCheck<2, ImmCheckShiftRight, 1>]>;
+def SVRSHR_Z_U : SInst<"svrshr[_n_{d}]", "dPdi", "UcUsUiUl", MergeZero, "aarch64_sve_urshr", [IsStreamingCompatible], [ImmCheck<2, ImmCheckShiftRight, 1>]>;
+def SVRSRA_S : SInst<"svrsra[_n_{d}]", "dddi", "csil", MergeNone, "aarch64_sve_srsra", [IsStreamingCompatible], [ImmCheck<2, ImmCheckShiftRight, 1>]>;
+def SVRSRA_U : SInst<"svrsra[_n_{d}]", "dddi", "UcUsUiUl", MergeNone, "aarch64_sve_ursra", [IsStreamingCompatible], [ImmCheck<2, ImmCheckShiftRight, 1>]>;
+def SVSLI : SInst<"svsli[_n_{d}]", "dddi", "csilUcUsUiUl", MergeNone, "aarch64_sve_sli", [IsStreamingCompatible], [ImmCheck<2, ImmCheckShiftLeft, 1>]>;
+def SVSRA_S : SInst<"svsra[_n_{d}]", "dddi", "csil", MergeNone, "aarch64_sve_ssra", [IsStreamingCompatible], [ImmCheck<2, ImmCheckShiftRight, 1>]>;
+def SVSRA_U : SInst<"svsra[_n_{d}]", "dddi", "UcUsUiUl", MergeNone, "aarch64_sve_usra", [IsStreamingCompatible], [ImmCheck<2, ImmCheckShiftRight, 1>]>;
+def SVSRI : SInst<"svsri[_n_{d}]", "dddi", "csilUcUsUiUl", MergeNone, "aarch64_sve_sri", [IsStreamingCompatible], [ImmCheck<2, ImmCheckShiftRight, 1>]>;
}
////////////////////////////////////////////////////////////////////////////////
@@ -1580,87 +1450,87 @@ multiclass SInstPairwise<string name, string types, string intrinsic, list<FlagT
def _X : SInst<name # "[_{d}]", "dPdd", types, MergeAny, intrinsic, flags>;
}
-let ArchGuard = "defined(__ARM_FEATURE_SVE2)" in {
-defm SVADDP : SInstPairwise<"svaddp", "csliUcUsUiUl", "aarch64_sve_addp">;
-defm SVADDP_F : SInstPairwise<"svaddp", "hfd", "aarch64_sve_faddp">;
-defm SVMAXNMP : SInstPairwise<"svmaxnmp", "hfd", "aarch64_sve_fmaxnmp">;
-defm SVMAXP_F : SInstPairwise<"svmaxp", "hfd", "aarch64_sve_fmaxp">;
-defm SVMAXP_S : SInstPairwise<"svmaxp", "csli", "aarch64_sve_smaxp">;
-defm SVMAXP_U : SInstPairwise<"svmaxp", "UcUsUiUl", "aarch64_sve_umaxp">;
-defm SVMINNMP : SInstPairwise<"svminnmp", "hfd", "aarch64_sve_fminnmp">;
-defm SVMINP_F : SInstPairwise<"svminp", "hfd", "aarch64_sve_fminp">;
-defm SVMINP_S : SInstPairwise<"svminp", "csli", "aarch64_sve_sminp">;
-defm SVMINP_U : SInstPairwise<"svminp", "UcUsUiUl", "aarch64_sve_uminp">;
+let TargetGuard = "sve2" in {
+defm SVADDP : SInstPairwise<"svaddp", "csliUcUsUiUl", "aarch64_sve_addp", [IsStreamingCompatible]>;
+defm SVADDP_F : SInstPairwise<"svaddp", "hfd", "aarch64_sve_faddp", [IsStreamingCompatible]>;
+defm SVMAXNMP : SInstPairwise<"svmaxnmp", "hfd", "aarch64_sve_fmaxnmp", [IsStreamingCompatible]>;
+defm SVMAXP_F : SInstPairwise<"svmaxp", "hfd", "aarch64_sve_fmaxp", [IsStreamingCompatible]>;
+defm SVMAXP_S : SInstPairwise<"svmaxp", "csli", "aarch64_sve_smaxp", [IsStreamingCompatible]>;
+defm SVMAXP_U : SInstPairwise<"svmaxp", "UcUsUiUl", "aarch64_sve_umaxp", [IsStreamingCompatible]>;
+defm SVMINNMP : SInstPairwise<"svminnmp", "hfd", "aarch64_sve_fminnmp", [IsStreamingCompatible]>;
+defm SVMINP_F : SInstPairwise<"svminp", "hfd", "aarch64_sve_fminp", [IsStreamingCompatible]>;
+defm SVMINP_S : SInstPairwise<"svminp", "csli", "aarch64_sve_sminp", [IsStreamingCompatible]>;
+defm SVMINP_U : SInstPairwise<"svminp", "UcUsUiUl", "aarch64_sve_uminp", [IsStreamingCompatible]>;
}
////////////////////////////////////////////////////////////////////////////////
// SVE2 - Widening pairwise arithmetic
-let ArchGuard = "defined(__ARM_FEATURE_SVE2)" in {
-def SVADALP_S_M : SInst<"svadalp[_{d}]", "dPdh", "sil", MergeOp1, "aarch64_sve_sadalp">;
-def SVADALP_S_X : SInst<"svadalp[_{d}]", "dPdh", "sil", MergeAny, "aarch64_sve_sadalp">;
-def SVADALP_S_Z : SInst<"svadalp[_{d}]", "dPdh", "sil", MergeZero, "aarch64_sve_sadalp">;
+let TargetGuard = "sve2" in {
+def SVADALP_S_M : SInst<"svadalp[_{d}]", "dPdh", "sil", MergeOp1, "aarch64_sve_sadalp", [IsStreamingCompatible]>;
+def SVADALP_S_X : SInst<"svadalp[_{d}]", "dPdh", "sil", MergeAny, "aarch64_sve_sadalp", [IsStreamingCompatible]>;
+def SVADALP_S_Z : SInst<"svadalp[_{d}]", "dPdh", "sil", MergeZero, "aarch64_sve_sadalp", [IsStreamingCompatible]>;
-def SVADALP_U_M : SInst<"svadalp[_{d}]", "dPdh", "UsUiUl", MergeOp1, "aarch64_sve_uadalp">;
-def SVADALP_U_X : SInst<"svadalp[_{d}]", "dPdh", "UsUiUl", MergeAny, "aarch64_sve_uadalp">;
-def SVADALP_U_Z : SInst<"svadalp[_{d}]", "dPdh", "UsUiUl", MergeZero, "aarch64_sve_uadalp">;
+def SVADALP_U_M : SInst<"svadalp[_{d}]", "dPdh", "UsUiUl", MergeOp1, "aarch64_sve_uadalp", [IsStreamingCompatible]>;
+def SVADALP_U_X : SInst<"svadalp[_{d}]", "dPdh", "UsUiUl", MergeAny, "aarch64_sve_uadalp", [IsStreamingCompatible]>;
+def SVADALP_U_Z : SInst<"svadalp[_{d}]", "dPdh", "UsUiUl", MergeZero, "aarch64_sve_uadalp", [IsStreamingCompatible]>;
}
////////////////////////////////////////////////////////////////////////////////
// SVE2 - Bitwise ternary logical instructions
//
-let ArchGuard = "defined(__ARM_FEATURE_SVE2)" in {
-def SVBCAX : SInst<"svbcax[_{d}]", "dddd", "csilUcUsUiUl", MergeNone, "aarch64_sve_bcax">;
-def SVBSL : SInst<"svbsl[_{d}]", "dddd", "csilUcUsUiUl", MergeNone, "aarch64_sve_bsl">;
-def SVBSL1N : SInst<"svbsl1n[_{d}]", "dddd", "csilUcUsUiUl", MergeNone, "aarch64_sve_bsl1n">;
-def SVBSL2N : SInst<"svbsl2n[_{d}]", "dddd", "csilUcUsUiUl", MergeNone, "aarch64_sve_bsl2n">;
-def SVEOR3 : SInst<"sveor3[_{d}]", "dddd", "csilUcUsUiUl", MergeNone, "aarch64_sve_eor3">;
-def SVNBSL : SInst<"svnbsl[_{d}]", "dddd", "csilUcUsUiUl", MergeNone, "aarch64_sve_nbsl">;
+let TargetGuard = "sve2" in {
+def SVBCAX : SInst<"svbcax[_{d}]", "dddd", "csilUcUsUiUl", MergeNone, "aarch64_sve_bcax", [IsStreamingCompatible]>;
+def SVBSL : SInst<"svbsl[_{d}]", "dddd", "csilUcUsUiUl", MergeNone, "aarch64_sve_bsl", [IsStreamingCompatible]>;
+def SVBSL1N : SInst<"svbsl1n[_{d}]", "dddd", "csilUcUsUiUl", MergeNone, "aarch64_sve_bsl1n", [IsStreamingCompatible]>;
+def SVBSL2N : SInst<"svbsl2n[_{d}]", "dddd", "csilUcUsUiUl", MergeNone, "aarch64_sve_bsl2n", [IsStreamingCompatible]>;
+def SVEOR3 : SInst<"sveor3[_{d}]", "dddd", "csilUcUsUiUl", MergeNone, "aarch64_sve_eor3", [IsStreamingCompatible]>;
+def SVNBSL : SInst<"svnbsl[_{d}]", "dddd", "csilUcUsUiUl", MergeNone, "aarch64_sve_nbsl", [IsStreamingCompatible]>;
-def SVBCAX_N : SInst<"svbcax[_n_{d}]", "ddda", "csilUcUsUiUl", MergeNone, "aarch64_sve_bcax">;
-def SVBSL_N : SInst<"svbsl[_n_{d}]", "ddda", "csilUcUsUiUl", MergeNone, "aarch64_sve_bsl">;
-def SVBSL1N_N : SInst<"svbsl1n[_n_{d}]", "ddda", "csilUcUsUiUl", MergeNone, "aarch64_sve_bsl1n">;
-def SVBSL2N_N : SInst<"svbsl2n[_n_{d}]", "ddda", "csilUcUsUiUl", MergeNone, "aarch64_sve_bsl2n">;
-def SVEOR3_N : SInst<"sveor3[_n_{d}]", "ddda", "csilUcUsUiUl", MergeNone, "aarch64_sve_eor3">;
-def SVNBSL_N : SInst<"svnbsl[_n_{d}]", "ddda", "csilUcUsUiUl", MergeNone, "aarch64_sve_nbsl">;
-def SVXAR_N : SInst<"svxar[_n_{d}]", "dddi", "csilUcUsUiUl", MergeNone, "aarch64_sve_xar", [], [ImmCheck<2, ImmCheckShiftRight, 1>]>;
+def SVBCAX_N : SInst<"svbcax[_n_{d}]", "ddda", "csilUcUsUiUl", MergeNone, "aarch64_sve_bcax", [IsStreamingCompatible]>;
+def SVBSL_N : SInst<"svbsl[_n_{d}]", "ddda", "csilUcUsUiUl", MergeNone, "aarch64_sve_bsl", [IsStreamingCompatible]>;
+def SVBSL1N_N : SInst<"svbsl1n[_n_{d}]", "ddda", "csilUcUsUiUl", MergeNone, "aarch64_sve_bsl1n", [IsStreamingCompatible]>;
+def SVBSL2N_N : SInst<"svbsl2n[_n_{d}]", "ddda", "csilUcUsUiUl", MergeNone, "aarch64_sve_bsl2n", [IsStreamingCompatible]>;
+def SVEOR3_N : SInst<"sveor3[_n_{d}]", "ddda", "csilUcUsUiUl", MergeNone, "aarch64_sve_eor3", [IsStreamingCompatible]>;
+def SVNBSL_N : SInst<"svnbsl[_n_{d}]", "ddda", "csilUcUsUiUl", MergeNone, "aarch64_sve_nbsl", [IsStreamingCompatible]>;
+def SVXAR_N : SInst<"svxar[_n_{d}]", "dddi", "csilUcUsUiUl", MergeNone, "aarch64_sve_xar", [IsStreamingCompatible], [ImmCheck<2, ImmCheckShiftRight, 1>]>;
}
////////////////////////////////////////////////////////////////////////////////
// SVE2 - Large integer arithmetic
-let ArchGuard = "defined(__ARM_FEATURE_SVE2)" in {
-def SVADCLB : SInst<"svadclb[_{d}]", "dddd", "UiUl", MergeNone, "aarch64_sve_adclb">;
-def SVADCLT : SInst<"svadclt[_{d}]", "dddd", "UiUl", MergeNone, "aarch64_sve_adclt">;
-def SVSBCLB : SInst<"svsbclb[_{d}]", "dddd", "UiUl", MergeNone, "aarch64_sve_sbclb">;
-def SVSBCLT : SInst<"svsbclt[_{d}]", "dddd", "UiUl", MergeNone, "aarch64_sve_sbclt">;
+let TargetGuard = "sve2" in {
+def SVADCLB : SInst<"svadclb[_{d}]", "dddd", "UiUl", MergeNone, "aarch64_sve_adclb", [IsStreamingCompatible]>;
+def SVADCLT : SInst<"svadclt[_{d}]", "dddd", "UiUl", MergeNone, "aarch64_sve_adclt", [IsStreamingCompatible]>;
+def SVSBCLB : SInst<"svsbclb[_{d}]", "dddd", "UiUl", MergeNone, "aarch64_sve_sbclb", [IsStreamingCompatible]>;
+def SVSBCLT : SInst<"svsbclt[_{d}]", "dddd", "UiUl", MergeNone, "aarch64_sve_sbclt", [IsStreamingCompatible]>;
-def SVADCLB_N : SInst<"svadclb[_n_{d}]", "ddda", "UiUl", MergeNone, "aarch64_sve_adclb">;
-def SVADCLT_N : SInst<"svadclt[_n_{d}]", "ddda", "UiUl", MergeNone, "aarch64_sve_adclt">;
-def SVSBCLB_N : SInst<"svsbclb[_n_{d}]", "ddda", "UiUl", MergeNone, "aarch64_sve_sbclb">;
-def SVSBCLT_N : SInst<"svsbclt[_n_{d}]", "ddda", "UiUl", MergeNone, "aarch64_sve_sbclt">;
+def SVADCLB_N : SInst<"svadclb[_n_{d}]", "ddda", "UiUl", MergeNone, "aarch64_sve_adclb", [IsStreamingCompatible]>;
+def SVADCLT_N : SInst<"svadclt[_n_{d}]", "ddda", "UiUl", MergeNone, "aarch64_sve_adclt", [IsStreamingCompatible]>;
+def SVSBCLB_N : SInst<"svsbclb[_n_{d}]", "ddda", "UiUl", MergeNone, "aarch64_sve_sbclb", [IsStreamingCompatible]>;
+def SVSBCLT_N : SInst<"svsbclt[_n_{d}]", "ddda", "UiUl", MergeNone, "aarch64_sve_sbclt", [IsStreamingCompatible]>;
}
////////////////////////////////////////////////////////////////////////////////
// SVE2 - Multiplication by indexed elements
-let ArchGuard = "defined(__ARM_FEATURE_SVE2)" in {
-def SVMLA_LANE_2 : SInst<"svmla_lane[_{d}]", "ddddi", "silUsUiUl", MergeNone, "aarch64_sve_mla_lane", [], [ImmCheck<3, ImmCheckLaneIndex, 2>]>;
-def SVMLS_LANE_2 : SInst<"svmls_lane[_{d}]", "ddddi", "silUsUiUl", MergeNone, "aarch64_sve_mls_lane", [], [ImmCheck<3, ImmCheckLaneIndex, 2>]>;
-def SVMUL_LANE_2 : SInst<"svmul_lane[_{d}]", "dddi", "silUsUiUl", MergeNone, "aarch64_sve_mul_lane", [], [ImmCheck<2, ImmCheckLaneIndex, 1>]>;
+let TargetGuard = "sve2" in {
+def SVMLA_LANE_2 : SInst<"svmla_lane[_{d}]", "ddddi", "silUsUiUl", MergeNone, "aarch64_sve_mla_lane", [IsStreamingCompatible], [ImmCheck<3, ImmCheckLaneIndex, 2>]>;
+def SVMLS_LANE_2 : SInst<"svmls_lane[_{d}]", "ddddi", "silUsUiUl", MergeNone, "aarch64_sve_mls_lane", [IsStreamingCompatible], [ImmCheck<3, ImmCheckLaneIndex, 2>]>;
+def SVMUL_LANE_2 : SInst<"svmul_lane[_{d}]", "dddi", "silUsUiUl", MergeNone, "aarch64_sve_mul_lane", [IsStreamingCompatible], [ImmCheck<2, ImmCheckLaneIndex, 1>]>;
}
////////////////////////////////////////////////////////////////////////////////
// SVE2 - Uniform complex integer arithmetic
-let ArchGuard = "defined(__ARM_FEATURE_SVE2)" in {
-def SVCADD : SInst<"svcadd[_{d}]", "dddi", "csilUcUsUiUl", MergeNone, "aarch64_sve_cadd_x", [], [ImmCheck<2, ImmCheckComplexRot90_270>]>;
-def SVSQCADD : SInst<"svqcadd[_{d}]", "dddi", "csil", MergeNone, "aarch64_sve_sqcadd_x", [], [ImmCheck<2, ImmCheckComplexRot90_270>]>;
-def SVCMLA : SInst<"svcmla[_{d}]", "ddddi", "csilUcUsUiUl", MergeNone, "aarch64_sve_cmla_x", [], [ImmCheck<3, ImmCheckComplexRotAll90>]>;
-def SVCMLA_LANE_X : SInst<"svcmla_lane[_{d}]", "ddddii", "siUsUi", MergeNone, "aarch64_sve_cmla_lane_x", [], [ImmCheck<3, ImmCheckLaneIndexCompRotate, 2>,
+let TargetGuard = "sve2" in {
+def SVCADD : SInst<"svcadd[_{d}]", "dddi", "csilUcUsUiUl", MergeNone, "aarch64_sve_cadd_x", [IsStreamingCompatible], [ImmCheck<2, ImmCheckComplexRot90_270>]>;
+def SVSQCADD : SInst<"svqcadd[_{d}]", "dddi", "csil", MergeNone, "aarch64_sve_sqcadd_x", [IsStreamingCompatible], [ImmCheck<2, ImmCheckComplexRot90_270>]>;
+def SVCMLA : SInst<"svcmla[_{d}]", "ddddi", "csilUcUsUiUl", MergeNone, "aarch64_sve_cmla_x", [IsStreamingCompatible], [ImmCheck<3, ImmCheckComplexRotAll90>]>;
+def SVCMLA_LANE_X : SInst<"svcmla_lane[_{d}]", "ddddii", "siUsUi", MergeNone, "aarch64_sve_cmla_lane_x", [IsStreamingCompatible], [ImmCheck<3, ImmCheckLaneIndexCompRotate, 2>,
ImmCheck<4, ImmCheckComplexRotAll90>]>;
-def SVSQRDCMLAH_X : SInst<"svqrdcmlah[_{d}]", "ddddi", "csil", MergeNone, "aarch64_sve_sqrdcmlah_x", [], [ImmCheck<3, ImmCheckComplexRotAll90>]>;
-def SVSQRDCMLAH_LANE_X : SInst<"svqrdcmlah_lane[_{d}]", "ddddii", "si", MergeNone, "aarch64_sve_sqrdcmlah_lane_x", [], [ImmCheck<3, ImmCheckLaneIndexCompRotate, 2>,
+def SVSQRDCMLAH_X : SInst<"svqrdcmlah[_{d}]", "ddddi", "csil", MergeNone, "aarch64_sve_sqrdcmlah_x", [IsStreamingCompatible], [ImmCheck<3, ImmCheckComplexRotAll90>]>;
+def SVSQRDCMLAH_LANE_X : SInst<"svqrdcmlah_lane[_{d}]", "ddddii", "si", MergeNone, "aarch64_sve_sqrdcmlah_lane_x", [IsStreamingCompatible], [ImmCheck<3, ImmCheckLaneIndexCompRotate, 2>,
ImmCheck<4, ImmCheckComplexRotAll90>]>;
}
@@ -1668,21 +1538,21 @@ def SVSQRDCMLAH_LANE_X : SInst<"svqrdcmlah_lane[_{d}]", "ddddii", "si",
// SVE2 - Widening DSP operations
multiclass SInstWideDSPAcc<string name, string types, string intrinsic> {
- def : SInst<name # "[_{d}]", "ddhh", types, MergeNone, intrinsic>;
- def _N : SInst<name # "[_n_{d}]", "ddhR", types, MergeNone, intrinsic>;
+ def : SInst<name # "[_{d}]", "ddhh", types, MergeNone, intrinsic, [IsStreamingCompatible]>;
+ def _N : SInst<name # "[_n_{d}]", "ddhR", types, MergeNone, intrinsic, [IsStreamingCompatible]>;
}
multiclass SInstWideDSPLong<string name, string types, string intrinsic> {
- def : SInst<name # "[_{d}]", "dhh", types, MergeNone, intrinsic>;
- def _N : SInst<name # "[_n_{d}]", "dhR", types, MergeNone, intrinsic>;
+ def : SInst<name # "[_{d}]", "dhh", types, MergeNone, intrinsic, [IsStreamingCompatible]>;
+ def _N : SInst<name # "[_n_{d}]", "dhR", types, MergeNone, intrinsic, [IsStreamingCompatible]>;
}
multiclass SInstWideDSPWide<string name, string types, string intrinsic> {
- def : SInst<name # "[_{d}]", "ddh", types, MergeNone, intrinsic>;
- def _N : SInst<name # "[_n_{d}]", "ddR", types, MergeNone, intrinsic>;
+ def : SInst<name # "[_{d}]", "ddh", types, MergeNone, intrinsic, [IsStreamingCompatible]>;
+ def _N : SInst<name # "[_n_{d}]", "ddR", types, MergeNone, intrinsic, [IsStreamingCompatible]>;
}
-let ArchGuard = "defined(__ARM_FEATURE_SVE2)" in {
+let TargetGuard = "sve2" in {
defm SVABALB_S : SInstWideDSPAcc<"svabalb", "sil", "aarch64_sve_sabalb">;
defm SVABALB_U : SInstWideDSPAcc<"svabalb", "UsUiUl", "aarch64_sve_uabalb">;
defm SVABALT_S : SInstWideDSPAcc<"svabalt", "sil", "aarch64_sve_sabalt">;
@@ -1728,93 +1598,93 @@ defm SVSUBWB_U : SInstWideDSPWide<"svsubwb", "UsUiUl", "aarch64_sve_usubwb">;
defm SVSUBWT_S : SInstWideDSPWide<"svsubwt", "sil", "aarch64_sve_ssubwt">;
defm SVSUBWT_U : SInstWideDSPWide<"svsubwt", "UsUiUl", "aarch64_sve_usubwt">;
-def SVSHLLB_S_N : SInst<"svshllb[_n_{d}]", "dhi", "sil", MergeNone, "aarch64_sve_sshllb", [], [ImmCheck<1, ImmCheckShiftLeft, 0>]>;
-def SVSHLLB_U_N : SInst<"svshllb[_n_{d}]", "dhi", "UsUiUl", MergeNone, "aarch64_sve_ushllb", [], [ImmCheck<1, ImmCheckShiftLeft, 0>]>;
-def SVSHLLT_S_N : SInst<"svshllt[_n_{d}]", "dhi", "sil", MergeNone, "aarch64_sve_sshllt", [], [ImmCheck<1, ImmCheckShiftLeft, 0>]>;
-def SVSHLLT_U_N : SInst<"svshllt[_n_{d}]", "dhi", "UsUiUl", MergeNone, "aarch64_sve_ushllt", [], [ImmCheck<1, ImmCheckShiftLeft, 0>]>;
-
-def SVMOVLB_S_N : SInst<"svmovlb[_{d}]", "dh", "sil", MergeNone>;
-def SVMOVLB_U_N : SInst<"svmovlb[_{d}]", "dh", "UsUiUl", MergeNone>;
-def SVMOVLT_S_N : SInst<"svmovlt[_{d}]", "dh", "sil", MergeNone>;
-def SVMOVLT_U_N : SInst<"svmovlt[_{d}]", "dh", "UsUiUl", MergeNone>;
-
-def SVMLALB_S_LANE : SInst<"svmlalb_lane[_{d}]", "ddhhi", "il", MergeNone, "aarch64_sve_smlalb_lane", [], [ImmCheck<3, ImmCheckLaneIndex, 2>]>;
-def SVMLALB_U_LANE : SInst<"svmlalb_lane[_{d}]", "ddhhi", "UiUl", MergeNone, "aarch64_sve_umlalb_lane", [], [ImmCheck<3, ImmCheckLaneIndex, 2>]>;
-def SVMLALT_S_LANE : SInst<"svmlalt_lane[_{d}]", "ddhhi", "il", MergeNone, "aarch64_sve_smlalt_lane", [], [ImmCheck<3, ImmCheckLaneIndex, 2>]>;
-def SVMLALT_U_LANE : SInst<"svmlalt_lane[_{d}]", "ddhhi", "UiUl", MergeNone, "aarch64_sve_umlalt_lane", [], [ImmCheck<3, ImmCheckLaneIndex, 2>]>;
-def SVMLSLB_S_LANE : SInst<"svmlslb_lane[_{d}]", "ddhhi", "il", MergeNone, "aarch64_sve_smlslb_lane", [], [ImmCheck<3, ImmCheckLaneIndex, 2>]>;
-def SVMLSLB_U_LANE : SInst<"svmlslb_lane[_{d}]", "ddhhi", "UiUl", MergeNone, "aarch64_sve_umlslb_lane", [], [ImmCheck<3, ImmCheckLaneIndex, 2>]>;
-def SVMLSLT_S_LANE : SInst<"svmlslt_lane[_{d}]", "ddhhi", "il", MergeNone, "aarch64_sve_smlslt_lane", [], [ImmCheck<3, ImmCheckLaneIndex, 2>]>;
-def SVMLSLT_U_LANE : SInst<"svmlslt_lane[_{d}]", "ddhhi", "UiUl", MergeNone, "aarch64_sve_umlslt_lane", [], [ImmCheck<3, ImmCheckLaneIndex, 2>]>;
-def SVMULLB_S_LANE : SInst<"svmullb_lane[_{d}]", "dhhi", "il", MergeNone, "aarch64_sve_smullb_lane", [], [ImmCheck<2, ImmCheckLaneIndex, 1>]>;
-def SVMULLB_U_LANE : SInst<"svmullb_lane[_{d}]", "dhhi", "UiUl", MergeNone, "aarch64_sve_umullb_lane", [], [ImmCheck<2, ImmCheckLaneIndex, 1>]>;
-def SVMULLT_S_LANE : SInst<"svmullt_lane[_{d}]", "dhhi", "il", MergeNone, "aarch64_sve_smullt_lane", [], [ImmCheck<2, ImmCheckLaneIndex, 1>]>;
-def SVMULLT_U_LANE : SInst<"svmullt_lane[_{d}]", "dhhi", "UiUl", MergeNone, "aarch64_sve_umullt_lane", [], [ImmCheck<2, ImmCheckLaneIndex, 1>]>;
-def SVQDMLALB_LANE : SInst<"svqdmlalb_lane[_{d}]", "ddhhi", "il", MergeNone, "aarch64_sve_sqdmlalb_lane", [], [ImmCheck<3, ImmCheckLaneIndex, 2>]>;
-def SVQDMLALT_LANE : SInst<"svqdmlalt_lane[_{d}]", "ddhhi", "il", MergeNone, "aarch64_sve_sqdmlalt_lane", [], [ImmCheck<3, ImmCheckLaneIndex, 2>]>;
-def SVQDMLSLB_LANE : SInst<"svqdmlslb_lane[_{d}]", "ddhhi", "il", MergeNone, "aarch64_sve_sqdmlslb_lane", [], [ImmCheck<3, ImmCheckLaneIndex, 2>]>;
-def SVQDMLSLT_LANE : SInst<"svqdmlslt_lane[_{d}]", "ddhhi", "il", MergeNone, "aarch64_sve_sqdmlslt_lane", [], [ImmCheck<3, ImmCheckLaneIndex, 2>]>;
-def SVQDMULLB_LANE : SInst<"svqdmullb_lane[_{d}]", "dhhi", "il", MergeNone, "aarch64_sve_sqdmullb_lane", [], [ImmCheck<2, ImmCheckLaneIndex, 1>]>;
-def SVQDMULLT_LANE : SInst<"svqdmullt_lane[_{d}]", "dhhi", "il", MergeNone, "aarch64_sve_sqdmullt_lane", [], [ImmCheck<2, ImmCheckLaneIndex, 1>]>;
+def SVSHLLB_S_N : SInst<"svshllb[_n_{d}]", "dhi", "sil", MergeNone, "aarch64_sve_sshllb", [IsStreamingCompatible], [ImmCheck<1, ImmCheckShiftLeft, 0>]>;
+def SVSHLLB_U_N : SInst<"svshllb[_n_{d}]", "dhi", "UsUiUl", MergeNone, "aarch64_sve_ushllb", [IsStreamingCompatible], [ImmCheck<1, ImmCheckShiftLeft, 0>]>;
+def SVSHLLT_S_N : SInst<"svshllt[_n_{d}]", "dhi", "sil", MergeNone, "aarch64_sve_sshllt", [IsStreamingCompatible], [ImmCheck<1, ImmCheckShiftLeft, 0>]>;
+def SVSHLLT_U_N : SInst<"svshllt[_n_{d}]", "dhi", "UsUiUl", MergeNone, "aarch64_sve_ushllt", [IsStreamingCompatible], [ImmCheck<1, ImmCheckShiftLeft, 0>]>;
+
+def SVMOVLB_S_N : SInst<"svmovlb[_{d}]", "dh", "sil", MergeNone, "", [IsStreamingCompatible]>;
+def SVMOVLB_U_N : SInst<"svmovlb[_{d}]", "dh", "UsUiUl", MergeNone, "", [IsStreamingCompatible]>;
+def SVMOVLT_S_N : SInst<"svmovlt[_{d}]", "dh", "sil", MergeNone, "", [IsStreamingCompatible]>;
+def SVMOVLT_U_N : SInst<"svmovlt[_{d}]", "dh", "UsUiUl", MergeNone, "", [IsStreamingCompatible]>;
+
+def SVMLALB_S_LANE : SInst<"svmlalb_lane[_{d}]", "ddhhi", "il", MergeNone, "aarch64_sve_smlalb_lane", [IsStreamingCompatible], [ImmCheck<3, ImmCheckLaneIndex, 2>]>;
+def SVMLALB_U_LANE : SInst<"svmlalb_lane[_{d}]", "ddhhi", "UiUl", MergeNone, "aarch64_sve_umlalb_lane", [IsStreamingCompatible], [ImmCheck<3, ImmCheckLaneIndex, 2>]>;
+def SVMLALT_S_LANE : SInst<"svmlalt_lane[_{d}]", "ddhhi", "il", MergeNone, "aarch64_sve_smlalt_lane", [IsStreamingCompatible], [ImmCheck<3, ImmCheckLaneIndex, 2>]>;
+def SVMLALT_U_LANE : SInst<"svmlalt_lane[_{d}]", "ddhhi", "UiUl", MergeNone, "aarch64_sve_umlalt_lane", [IsStreamingCompatible], [ImmCheck<3, ImmCheckLaneIndex, 2>]>;
+def SVMLSLB_S_LANE : SInst<"svmlslb_lane[_{d}]", "ddhhi", "il", MergeNone, "aarch64_sve_smlslb_lane", [IsStreamingCompatible], [ImmCheck<3, ImmCheckLaneIndex, 2>]>;
+def SVMLSLB_U_LANE : SInst<"svmlslb_lane[_{d}]", "ddhhi", "UiUl", MergeNone, "aarch64_sve_umlslb_lane", [IsStreamingCompatible], [ImmCheck<3, ImmCheckLaneIndex, 2>]>;
+def SVMLSLT_S_LANE : SInst<"svmlslt_lane[_{d}]", "ddhhi", "il", MergeNone, "aarch64_sve_smlslt_lane", [IsStreamingCompatible], [ImmCheck<3, ImmCheckLaneIndex, 2>]>;
+def SVMLSLT_U_LANE : SInst<"svmlslt_lane[_{d}]", "ddhhi", "UiUl", MergeNone, "aarch64_sve_umlslt_lane", [IsStreamingCompatible], [ImmCheck<3, ImmCheckLaneIndex, 2>]>;
+def SVMULLB_S_LANE : SInst<"svmullb_lane[_{d}]", "dhhi", "il", MergeNone, "aarch64_sve_smullb_lane", [IsStreamingCompatible], [ImmCheck<2, ImmCheckLaneIndex, 1>]>;
+def SVMULLB_U_LANE : SInst<"svmullb_lane[_{d}]", "dhhi", "UiUl", MergeNone, "aarch64_sve_umullb_lane", [IsStreamingCompatible], [ImmCheck<2, ImmCheckLaneIndex, 1>]>;
+def SVMULLT_S_LANE : SInst<"svmullt_lane[_{d}]", "dhhi", "il", MergeNone, "aarch64_sve_smullt_lane", [IsStreamingCompatible], [ImmCheck<2, ImmCheckLaneIndex, 1>]>;
+def SVMULLT_U_LANE : SInst<"svmullt_lane[_{d}]", "dhhi", "UiUl", MergeNone, "aarch64_sve_umullt_lane", [IsStreamingCompatible], [ImmCheck<2, ImmCheckLaneIndex, 1>]>;
+def SVQDMLALB_LANE : SInst<"svqdmlalb_lane[_{d}]", "ddhhi", "il", MergeNone, "aarch64_sve_sqdmlalb_lane", [IsStreamingCompatible], [ImmCheck<3, ImmCheckLaneIndex, 2>]>;
+def SVQDMLALT_LANE : SInst<"svqdmlalt_lane[_{d}]", "ddhhi", "il", MergeNone, "aarch64_sve_sqdmlalt_lane", [IsStreamingCompatible], [ImmCheck<3, ImmCheckLaneIndex, 2>]>;
+def SVQDMLSLB_LANE : SInst<"svqdmlslb_lane[_{d}]", "ddhhi", "il", MergeNone, "aarch64_sve_sqdmlslb_lane", [IsStreamingCompatible], [ImmCheck<3, ImmCheckLaneIndex, 2>]>;
+def SVQDMLSLT_LANE : SInst<"svqdmlslt_lane[_{d}]", "ddhhi", "il", MergeNone, "aarch64_sve_sqdmlslt_lane", [IsStreamingCompatible], [ImmCheck<3, ImmCheckLaneIndex, 2>]>;
+def SVQDMULLB_LANE : SInst<"svqdmullb_lane[_{d}]", "dhhi", "il", MergeNone, "aarch64_sve_sqdmullb_lane", [IsStreamingCompatible], [ImmCheck<2, ImmCheckLaneIndex, 1>]>;
+def SVQDMULLT_LANE : SInst<"svqdmullt_lane[_{d}]", "dhhi", "il", MergeNone, "aarch64_sve_sqdmullt_lane", [IsStreamingCompatible], [ImmCheck<2, ImmCheckLaneIndex, 1>]>;
}
////////////////////////////////////////////////////////////////////////////////
// SVE2 - Narrowing DSP operations
-let ArchGuard = "defined(__ARM_FEATURE_SVE2)" in {
-def SVADDHNB : SInst<"svaddhnb[_{d}]", "hdd", "silUsUiUl", MergeNone, "aarch64_sve_addhnb">;
-def SVADDHNT : SInst<"svaddhnt[_{d}]", "hhdd", "silUsUiUl", MergeNone, "aarch64_sve_addhnt">;
-def SVRADDHNB : SInst<"svraddhnb[_{d}]", "hdd", "silUsUiUl", MergeNone, "aarch64_sve_raddhnb">;
-def SVRADDHNT : SInst<"svraddhnt[_{d}]", "hhdd", "silUsUiUl", MergeNone, "aarch64_sve_raddhnt">;
-def SVRSUBHNB : SInst<"svrsubhnb[_{d}]", "hdd", "silUsUiUl", MergeNone, "aarch64_sve_rsubhnb">;
-def SVRSUBHNT : SInst<"svrsubhnt[_{d}]", "hhdd", "silUsUiUl", MergeNone, "aarch64_sve_rsubhnt">;
-def SVSUBHNB : SInst<"svsubhnb[_{d}]", "hdd", "silUsUiUl", MergeNone, "aarch64_sve_subhnb">;
-def SVSUBHNT : SInst<"svsubhnt[_{d}]", "hhdd", "silUsUiUl", MergeNone, "aarch64_sve_subhnt">;
-
-def SVADDHNB_N : SInst<"svaddhnb[_n_{d}]", "hda", "silUsUiUl", MergeNone, "aarch64_sve_addhnb">;
-def SVADDHNT_N : SInst<"svaddhnt[_n_{d}]", "hhda", "silUsUiUl", MergeNone, "aarch64_sve_addhnt">;
-def SVRADDHNB_N : SInst<"svraddhnb[_n_{d}]", "hda", "silUsUiUl", MergeNone, "aarch64_sve_raddhnb">;
-def SVRADDHNT_N : SInst<"svraddhnt[_n_{d}]", "hhda", "silUsUiUl", MergeNone, "aarch64_sve_raddhnt">;
-def SVRSUBHNB_N : SInst<"svrsubhnb[_n_{d}]", "hda", "silUsUiUl", MergeNone, "aarch64_sve_rsubhnb">;
-def SVRSUBHNT_N : SInst<"svrsubhnt[_n_{d}]", "hhda", "silUsUiUl", MergeNone, "aarch64_sve_rsubhnt">;
-def SVSUBHNB_N : SInst<"svsubhnb[_n_{d}]", "hda", "silUsUiUl", MergeNone, "aarch64_sve_subhnb">;
-def SVSUBHNT_N : SInst<"svsubhnt[_n_{d}]", "hhda", "silUsUiUl", MergeNone, "aarch64_sve_subhnt">;
-
-def SVSHRNB : SInst<"svshrnb[_n_{d}]", "hdi", "silUsUiUl", MergeNone, "aarch64_sve_shrnb", [], [ImmCheck<1, ImmCheckShiftRightNarrow, 0>]>;
-def SVRSHRNB : SInst<"svrshrnb[_n_{d}]", "hdi", "silUsUiUl", MergeNone, "aarch64_sve_rshrnb", [], [ImmCheck<1, ImmCheckShiftRightNarrow, 0>]>;
-def SVQSHRUNB : SInst<"svqshrunb[_n_{d}]", "edi", "sil", MergeNone, "aarch64_sve_sqshrunb", [], [ImmCheck<1, ImmCheckShiftRightNarrow, 0>]>;
-def SVQRSHRUNB : SInst<"svqrshrunb[_n_{d}]", "edi", "sil", MergeNone, "aarch64_sve_sqrshrunb", [], [ImmCheck<1, ImmCheckShiftRightNarrow, 0>]>;
-def SVQSHRNB_S : SInst<"svqshrnb[_n_{d}]", "hdi", "sil", MergeNone, "aarch64_sve_sqshrnb", [], [ImmCheck<1, ImmCheckShiftRightNarrow, 0>]>;
-def SVQSHRNB_U : SInst<"svqshrnb[_n_{d}]", "hdi", "UsUiUl", MergeNone, "aarch64_sve_uqshrnb", [], [ImmCheck<1, ImmCheckShiftRightNarrow, 0>]>;
-def SVQRSHRNB_S : SInst<"svqrshrnb[_n_{d}]", "hdi", "sil", MergeNone, "aarch64_sve_sqrshrnb", [], [ImmCheck<1, ImmCheckShiftRightNarrow, 0>]>;
-def SVQRSHRNB_U : SInst<"svqrshrnb[_n_{d}]", "hdi", "UsUiUl", MergeNone, "aarch64_sve_uqrshrnb", [], [ImmCheck<1, ImmCheckShiftRightNarrow, 0>]>;
-
-def SVSHRNT : SInst<"svshrnt[_n_{d}]", "hhdi", "silUsUiUl", MergeNone, "aarch64_sve_shrnt", [], [ImmCheck<2, ImmCheckShiftRightNarrow, 1>]>;
-def SVRSHRNT : SInst<"svrshrnt[_n_{d}]", "hhdi", "silUsUiUl", MergeNone, "aarch64_sve_rshrnt", [], [ImmCheck<2, ImmCheckShiftRightNarrow, 1>]>;
-def SVQSHRUNT : SInst<"svqshrunt[_n_{d}]", "eedi", "sil", MergeNone, "aarch64_sve_sqshrunt", [], [ImmCheck<2, ImmCheckShiftRightNarrow, 1>]>;
-def SVQRSHRUNT : SInst<"svqrshrunt[_n_{d}]", "eedi", "sil", MergeNone, "aarch64_sve_sqrshrunt", [], [ImmCheck<2, ImmCheckShiftRightNarrow, 1>]>;
-def SVQSHRNT_S : SInst<"svqshrnt[_n_{d}]", "hhdi", "sil", MergeNone, "aarch64_sve_sqshrnt", [], [ImmCheck<2, ImmCheckShiftRightNarrow, 1>]>;
-def SVQSHRNT_U : SInst<"svqshrnt[_n_{d}]", "hhdi", "UsUiUl", MergeNone, "aarch64_sve_uqshrnt", [], [ImmCheck<2, ImmCheckShiftRightNarrow, 1>]>;
-def SVQRSHRNT_S : SInst<"svqrshrnt[_n_{d}]", "hhdi", "sil", MergeNone, "aarch64_sve_sqrshrnt", [], [ImmCheck<2, ImmCheckShiftRightNarrow, 1>]>;
-def SVQRSHRNT_U : SInst<"svqrshrnt[_n_{d}]", "hhdi", "UsUiUl", MergeNone, "aarch64_sve_uqrshrnt", [], [ImmCheck<2, ImmCheckShiftRightNarrow, 1>]>;
+let TargetGuard = "sve2" in {
+def SVADDHNB : SInst<"svaddhnb[_{d}]", "hdd", "silUsUiUl", MergeNone, "aarch64_sve_addhnb", [IsStreamingCompatible]>;
+def SVADDHNT : SInst<"svaddhnt[_{d}]", "hhdd", "silUsUiUl", MergeNone, "aarch64_sve_addhnt", [IsStreamingCompatible]>;
+def SVRADDHNB : SInst<"svraddhnb[_{d}]", "hdd", "silUsUiUl", MergeNone, "aarch64_sve_raddhnb", [IsStreamingCompatible]>;
+def SVRADDHNT : SInst<"svraddhnt[_{d}]", "hhdd", "silUsUiUl", MergeNone, "aarch64_sve_raddhnt", [IsStreamingCompatible]>;
+def SVRSUBHNB : SInst<"svrsubhnb[_{d}]", "hdd", "silUsUiUl", MergeNone, "aarch64_sve_rsubhnb", [IsStreamingCompatible]>;
+def SVRSUBHNT : SInst<"svrsubhnt[_{d}]", "hhdd", "silUsUiUl", MergeNone, "aarch64_sve_rsubhnt", [IsStreamingCompatible]>;
+def SVSUBHNB : SInst<"svsubhnb[_{d}]", "hdd", "silUsUiUl", MergeNone, "aarch64_sve_subhnb", [IsStreamingCompatible]>;
+def SVSUBHNT : SInst<"svsubhnt[_{d}]", "hhdd", "silUsUiUl", MergeNone, "aarch64_sve_subhnt", [IsStreamingCompatible]>;
+
+def SVADDHNB_N : SInst<"svaddhnb[_n_{d}]", "hda", "silUsUiUl", MergeNone, "aarch64_sve_addhnb", [IsStreamingCompatible]>;
+def SVADDHNT_N : SInst<"svaddhnt[_n_{d}]", "hhda", "silUsUiUl", MergeNone, "aarch64_sve_addhnt", [IsStreamingCompatible]>;
+def SVRADDHNB_N : SInst<"svraddhnb[_n_{d}]", "hda", "silUsUiUl", MergeNone, "aarch64_sve_raddhnb", [IsStreamingCompatible]>;
+def SVRADDHNT_N : SInst<"svraddhnt[_n_{d}]", "hhda", "silUsUiUl", MergeNone, "aarch64_sve_raddhnt", [IsStreamingCompatible]>;
+def SVRSUBHNB_N : SInst<"svrsubhnb[_n_{d}]", "hda", "silUsUiUl", MergeNone, "aarch64_sve_rsubhnb", [IsStreamingCompatible]>;
+def SVRSUBHNT_N : SInst<"svrsubhnt[_n_{d}]", "hhda", "silUsUiUl", MergeNone, "aarch64_sve_rsubhnt", [IsStreamingCompatible]>;
+def SVSUBHNB_N : SInst<"svsubhnb[_n_{d}]", "hda", "silUsUiUl", MergeNone, "aarch64_sve_subhnb", [IsStreamingCompatible]>;
+def SVSUBHNT_N : SInst<"svsubhnt[_n_{d}]", "hhda", "silUsUiUl", MergeNone, "aarch64_sve_subhnt", [IsStreamingCompatible]>;
+
+def SVSHRNB : SInst<"svshrnb[_n_{d}]", "hdi", "silUsUiUl", MergeNone, "aarch64_sve_shrnb", [IsStreamingCompatible], [ImmCheck<1, ImmCheckShiftRightNarrow, 0>]>;
+def SVRSHRNB : SInst<"svrshrnb[_n_{d}]", "hdi", "silUsUiUl", MergeNone, "aarch64_sve_rshrnb", [IsStreamingCompatible], [ImmCheck<1, ImmCheckShiftRightNarrow, 0>]>;
+def SVQSHRUNB : SInst<"svqshrunb[_n_{d}]", "edi", "sil", MergeNone, "aarch64_sve_sqshrunb", [IsStreamingCompatible], [ImmCheck<1, ImmCheckShiftRightNarrow, 0>]>;
+def SVQRSHRUNB : SInst<"svqrshrunb[_n_{d}]", "edi", "sil", MergeNone, "aarch64_sve_sqrshrunb", [IsStreamingCompatible], [ImmCheck<1, ImmCheckShiftRightNarrow, 0>]>;
+def SVQSHRNB_S : SInst<"svqshrnb[_n_{d}]", "hdi", "sil", MergeNone, "aarch64_sve_sqshrnb", [IsStreamingCompatible], [ImmCheck<1, ImmCheckShiftRightNarrow, 0>]>;
+def SVQSHRNB_U : SInst<"svqshrnb[_n_{d}]", "hdi", "UsUiUl", MergeNone, "aarch64_sve_uqshrnb", [IsStreamingCompatible], [ImmCheck<1, ImmCheckShiftRightNarrow, 0>]>;
+def SVQRSHRNB_S : SInst<"svqrshrnb[_n_{d}]", "hdi", "sil", MergeNone, "aarch64_sve_sqrshrnb", [IsStreamingCompatible], [ImmCheck<1, ImmCheckShiftRightNarrow, 0>]>;
+def SVQRSHRNB_U : SInst<"svqrshrnb[_n_{d}]", "hdi", "UsUiUl", MergeNone, "aarch64_sve_uqrshrnb", [IsStreamingCompatible], [ImmCheck<1, ImmCheckShiftRightNarrow, 0>]>;
+
+def SVSHRNT : SInst<"svshrnt[_n_{d}]", "hhdi", "silUsUiUl", MergeNone, "aarch64_sve_shrnt", [IsStreamingCompatible], [ImmCheck<2, ImmCheckShiftRightNarrow, 1>]>;
+def SVRSHRNT : SInst<"svrshrnt[_n_{d}]", "hhdi", "silUsUiUl", MergeNone, "aarch64_sve_rshrnt", [IsStreamingCompatible], [ImmCheck<2, ImmCheckShiftRightNarrow, 1>]>;
+def SVQSHRUNT : SInst<"svqshrunt[_n_{d}]", "eedi", "sil", MergeNone, "aarch64_sve_sqshrunt", [IsStreamingCompatible], [ImmCheck<2, ImmCheckShiftRightNarrow, 1>]>;
+def SVQRSHRUNT : SInst<"svqrshrunt[_n_{d}]", "eedi", "sil", MergeNone, "aarch64_sve_sqrshrunt", [IsStreamingCompatible], [ImmCheck<2, ImmCheckShiftRightNarrow, 1>]>;
+def SVQSHRNT_S : SInst<"svqshrnt[_n_{d}]", "hhdi", "sil", MergeNone, "aarch64_sve_sqshrnt", [IsStreamingCompatible], [ImmCheck<2, ImmCheckShiftRightNarrow, 1>]>;
+def SVQSHRNT_U : SInst<"svqshrnt[_n_{d}]", "hhdi", "UsUiUl", MergeNone, "aarch64_sve_uqshrnt", [IsStreamingCompatible], [ImmCheck<2, ImmCheckShiftRightNarrow, 1>]>;
+def SVQRSHRNT_S : SInst<"svqrshrnt[_n_{d}]", "hhdi", "sil", MergeNone, "aarch64_sve_sqrshrnt", [IsStreamingCompatible], [ImmCheck<2, ImmCheckShiftRightNarrow, 1>]>;
+def SVQRSHRNT_U : SInst<"svqrshrnt[_n_{d}]", "hhdi", "UsUiUl", MergeNone, "aarch64_sve_uqrshrnt", [IsStreamingCompatible], [ImmCheck<2, ImmCheckShiftRightNarrow, 1>]>;
}
////////////////////////////////////////////////////////////////////////////////
// SVE2 - Unary narrowing operations
-let ArchGuard = "defined(__ARM_FEATURE_SVE2)" in {
-def SVQXTNB_S : SInst<"svqxtnb[_{d}]", "hd", "sil", MergeNone, "aarch64_sve_sqxtnb">;
-def SVQXTNB_U : SInst<"svqxtnb[_{d}]", "hd", "UsUiUl", MergeNone, "aarch64_sve_uqxtnb">;
-def SVQXTUNB_S : SInst<"svqxtunb[_{d}]", "ed", "sil", MergeNone, "aarch64_sve_sqxtunb">;
+let TargetGuard = "sve2" in {
+def SVQXTNB_S : SInst<"svqxtnb[_{d}]", "hd", "sil", MergeNone, "aarch64_sve_sqxtnb", [IsStreamingCompatible]>;
+def SVQXTNB_U : SInst<"svqxtnb[_{d}]", "hd", "UsUiUl", MergeNone, "aarch64_sve_uqxtnb", [IsStreamingCompatible]>;
+def SVQXTUNB_S : SInst<"svqxtunb[_{d}]", "ed", "sil", MergeNone, "aarch64_sve_sqxtunb", [IsStreamingCompatible]>;
-def SVQXTNT_S : SInst<"svqxtnt[_{d}]", "hhd", "sil", MergeNone, "aarch64_sve_sqxtnt">;
-def SVQXTNT_U : SInst<"svqxtnt[_{d}]", "hhd", "UsUiUl", MergeNone, "aarch64_sve_uqxtnt">;
-def SVQXTUNT_S : SInst<"svqxtunt[_{d}]", "eed", "sil", MergeNone, "aarch64_sve_sqxtunt">;
+def SVQXTNT_S : SInst<"svqxtnt[_{d}]", "hhd", "sil", MergeNone, "aarch64_sve_sqxtnt", [IsStreamingCompatible]>;
+def SVQXTNT_U : SInst<"svqxtnt[_{d}]", "hhd", "UsUiUl", MergeNone, "aarch64_sve_uqxtnt", [IsStreamingCompatible]>;
+def SVQXTUNT_S : SInst<"svqxtunt[_{d}]", "eed", "sil", MergeNone, "aarch64_sve_sqxtunt", [IsStreamingCompatible]>;
}
////////////////////////////////////////////////////////////////////////////////
// SVE2 - Widening complex integer arithmetic
-let ArchGuard = "defined(__ARM_FEATURE_SVE2)" in {
+let TargetGuard = "sve2" in {
defm SVADDLBT : SInstWideDSPLong<"svaddlbt", "sil", "aarch64_sve_saddlbt">;
defm SVSUBLBT : SInstWideDSPLong<"svsublbt", "sil", "aarch64_sve_ssublbt">;
defm SVSUBLTB : SInstWideDSPLong<"svsubltb", "sil", "aarch64_sve_ssubltb">;
@@ -1825,7 +1695,7 @@ defm SVQDMLSLBT : SInstWideDSPAcc<"svqdmlslbt", "sil", "aarch64_sve_sqdmlslbt">;
////////////////////////////////////////////////////////////////////////////////
// SVE2 - Non-temporal gather/scatter
-let ArchGuard = "defined(__ARM_FEATURE_SVE2)" in {
+let TargetGuard = "sve2" in {
// Non-temporal gather load one vector (vector base)
def SVLDNT1_GATHER_BASES_U : MInst<"svldnt1_gather[_{2}base]_{0}", "dPu", "ilUiUlfd", [IsGatherLoad], MemEltTyDefault, "aarch64_sve_ldnt1_gather_scalar_offset">;
def SVLDNT1SB_GATHER_BASES_U : MInst<"svldnt1sb_gather[_{2}base]_{0}", "dPu", "ilUiUl", [IsGatherLoad], MemEltTyInt8, "aarch64_sve_ldnt1_gather_scalar_offset">;
@@ -1948,63 +1818,63 @@ def SVSTNT1W_SCATTER_INDEX_S : MInst<"svstnt1w_scatter[_{2}base]_index[_{d}]", "
////////////////////////////////////////////////////////////////////////////////
// SVE2 - Polynomial arithmetic
-let ArchGuard = "defined(__ARM_FEATURE_SVE2)" in {
-def SVEORBT : SInst<"sveorbt[_{d}]", "dddd", "csilUcUsUiUl", MergeNone, "aarch64_sve_eorbt">;
-def SVEORBT_N : SInst<"sveorbt[_n_{d}]", "ddda", "csilUcUsUiUl", MergeNone, "aarch64_sve_eorbt">;
-def SVEORTB : SInst<"sveortb[_{d}]", "dddd", "csilUcUsUiUl", MergeNone, "aarch64_sve_eortb">;
-def SVEORTB_N : SInst<"sveortb[_n_{d}]", "ddda", "csilUcUsUiUl", MergeNone, "aarch64_sve_eortb">;
-def SVPMUL : SInst<"svpmul[_{d}]", "ddd", "Uc", MergeNone, "aarch64_sve_pmul">;
-def SVPMUL_N : SInst<"svpmul[_n_{d}]", "dda", "Uc", MergeNone, "aarch64_sve_pmul">;
-def SVPMULLB : SInst<"svpmullb[_{d}]", "dhh", "UsUl", MergeNone>;
-def SVPMULLB_N : SInst<"svpmullb[_n_{d}]", "dhR", "UsUl", MergeNone>;
-def SVPMULLB_PAIR : SInst<"svpmullb_pair[_{d}]", "ddd", "UcUi", MergeNone, "aarch64_sve_pmullb_pair">;
-def SVPMULLB_PAIR_N : SInst<"svpmullb_pair[_n_{d}]", "dda", "UcUi", MergeNone, "aarch64_sve_pmullb_pair">;
-def SVPMULLT : SInst<"svpmullt[_{d}]", "dhh", "UsUl", MergeNone>;
-def SVPMULLT_N : SInst<"svpmullt[_n_{d}]", "dhR", "UsUl", MergeNone>;
-def SVPMULLT_PAIR : SInst<"svpmullt_pair[_{d}]", "ddd", "UcUi", MergeNone, "aarch64_sve_pmullt_pair">;
-def SVPMULLT_PAIR_N : SInst<"svpmullt_pair[_n_{d}]", "dda", "UcUi", MergeNone, "aarch64_sve_pmullt_pair">;
+let TargetGuard = "sve2" in {
+def SVEORBT : SInst<"sveorbt[_{d}]", "dddd", "csilUcUsUiUl", MergeNone, "aarch64_sve_eorbt", [IsStreamingCompatible]>;
+def SVEORBT_N : SInst<"sveorbt[_n_{d}]", "ddda", "csilUcUsUiUl", MergeNone, "aarch64_sve_eorbt", [IsStreamingCompatible]>;
+def SVEORTB : SInst<"sveortb[_{d}]", "dddd", "csilUcUsUiUl", MergeNone, "aarch64_sve_eortb", [IsStreamingCompatible]>;
+def SVEORTB_N : SInst<"sveortb[_n_{d}]", "ddda", "csilUcUsUiUl", MergeNone, "aarch64_sve_eortb", [IsStreamingCompatible]>;
+def SVPMUL : SInst<"svpmul[_{d}]", "ddd", "Uc", MergeNone, "aarch64_sve_pmul", [IsStreamingCompatible]>;
+def SVPMUL_N : SInst<"svpmul[_n_{d}]", "dda", "Uc", MergeNone, "aarch64_sve_pmul", [IsStreamingCompatible]>;
+def SVPMULLB : SInst<"svpmullb[_{d}]", "dhh", "UsUl", MergeNone, "", [IsStreamingCompatible]>;
+def SVPMULLB_N : SInst<"svpmullb[_n_{d}]", "dhR", "UsUl", MergeNone, "", [IsStreamingCompatible]>;
+def SVPMULLB_PAIR : SInst<"svpmullb_pair[_{d}]", "ddd", "UcUi", MergeNone, "aarch64_sve_pmullb_pair", [IsStreamingCompatible]>;
+def SVPMULLB_PAIR_N : SInst<"svpmullb_pair[_n_{d}]", "dda", "UcUi", MergeNone, "aarch64_sve_pmullb_pair", [IsStreamingCompatible]>;
+def SVPMULLT : SInst<"svpmullt[_{d}]", "dhh", "UsUl", MergeNone, "", [IsStreamingCompatible]>;
+def SVPMULLT_N : SInst<"svpmullt[_n_{d}]", "dhR", "UsUl", MergeNone, "", [IsStreamingCompatible]>;
+def SVPMULLT_PAIR : SInst<"svpmullt_pair[_{d}]", "ddd", "UcUi", MergeNone, "aarch64_sve_pmullt_pair", [IsStreamingCompatible]>;
+def SVPMULLT_PAIR_N : SInst<"svpmullt_pair[_n_{d}]", "dda", "UcUi", MergeNone, "aarch64_sve_pmullt_pair", [IsStreamingCompatible]>;
}
////////////////////////////////////////////////////////////////////////////////
// SVE2 - Complex integer dot product
-let ArchGuard = "defined(__ARM_FEATURE_SVE2)" in {
-def SVCDOT : SInst<"svcdot[_{d}]", "ddqqi", "il", MergeNone, "aarch64_sve_cdot", [], [ImmCheck<3, ImmCheckComplexRotAll90>]>;
-def SVCDOT_LANE : SInst<"svcdot_lane[_{d}]", "ddqqii", "il", MergeNone, "aarch64_sve_cdot_lane", [], [ImmCheck<4, ImmCheckComplexRotAll90>,
+let TargetGuard = "sve2" in {
+def SVCDOT : SInst<"svcdot[_{d}]", "ddqqi", "il", MergeNone, "aarch64_sve_cdot", [IsStreamingCompatible], [ImmCheck<3, ImmCheckComplexRotAll90>]>;
+def SVCDOT_LANE : SInst<"svcdot_lane[_{d}]", "ddqqii", "il", MergeNone, "aarch64_sve_cdot_lane", [IsStreamingCompatible], [ImmCheck<4, ImmCheckComplexRotAll90>,
ImmCheck<3, ImmCheckLaneIndexDot, 2>]>;
}
////////////////////////////////////////////////////////////////////////////////
// SVE2 - Floating-point widening multiply-accumulate
-let ArchGuard = "defined(__ARM_FEATURE_SVE2)" in {
-def SVMLALB_F : SInst<"svmlalb[_{d}]", "ddhh", "f", MergeNone, "aarch64_sve_fmlalb">;
-def SVMLALB_F_N : SInst<"svmlalb[_n_{d}]", "ddhR", "f", MergeNone, "aarch64_sve_fmlalb">;
-def SVMLALB_F_LANE : SInst<"svmlalb_lane[_{d}]", "ddhhi", "f", MergeNone, "aarch64_sve_fmlalb_lane", [], [ImmCheck<3, ImmCheckLaneIndex, 2>]>;
-def SVMLALT_F : SInst<"svmlalt[_{d}]", "ddhh", "f", MergeNone, "aarch64_sve_fmlalt">;
-def SVMLALT_F_N : SInst<"svmlalt[_n_{d}]", "ddhR", "f", MergeNone, "aarch64_sve_fmlalt">;
-def SVMLALT_F_LANE : SInst<"svmlalt_lane[_{d}]", "ddhhi", "f", MergeNone, "aarch64_sve_fmlalt_lane", [], [ImmCheck<3, ImmCheckLaneIndex, 2>]>;
-def SVMLSLB_F : SInst<"svmlslb[_{d}]", "ddhh", "f", MergeNone, "aarch64_sve_fmlslb">;
-def SVMLSLB_F_N : SInst<"svmlslb[_n_{d}]", "ddhR", "f", MergeNone, "aarch64_sve_fmlslb">;
-def SVMLSLB_F_LANE : SInst<"svmlslb_lane[_{d}]", "ddhhi", "f", MergeNone, "aarch64_sve_fmlslb_lane", [], [ImmCheck<3, ImmCheckLaneIndex, 2>]>;
-def SVMLSLT_F : SInst<"svmlslt[_{d}]", "ddhh", "f", MergeNone, "aarch64_sve_fmlslt">;
-def SVMLSLT_F_N : SInst<"svmlslt[_n_{d}]", "ddhR", "f", MergeNone, "aarch64_sve_fmlslt">;
-def SVMLSLT_F_LANE : SInst<"svmlslt_lane[_{d}]", "ddhhi", "f", MergeNone, "aarch64_sve_fmlslt_lane", [], [ImmCheck<3, ImmCheckLaneIndex, 2>]>;
+let TargetGuard = "sve2" in {
+def SVMLALB_F : SInst<"svmlalb[_{d}]", "ddhh", "f", MergeNone, "aarch64_sve_fmlalb", [IsStreamingCompatible]>;
+def SVMLALB_F_N : SInst<"svmlalb[_n_{d}]", "ddhR", "f", MergeNone, "aarch64_sve_fmlalb", [IsStreamingCompatible]>;
+def SVMLALB_F_LANE : SInst<"svmlalb_lane[_{d}]", "ddhhi", "f", MergeNone, "aarch64_sve_fmlalb_lane", [IsStreamingCompatible], [ImmCheck<3, ImmCheckLaneIndex, 2>]>;
+def SVMLALT_F : SInst<"svmlalt[_{d}]", "ddhh", "f", MergeNone, "aarch64_sve_fmlalt", [IsStreamingCompatible]>;
+def SVMLALT_F_N : SInst<"svmlalt[_n_{d}]", "ddhR", "f", MergeNone, "aarch64_sve_fmlalt", [IsStreamingCompatible]>;
+def SVMLALT_F_LANE : SInst<"svmlalt_lane[_{d}]", "ddhhi", "f", MergeNone, "aarch64_sve_fmlalt_lane", [IsStreamingCompatible], [ImmCheck<3, ImmCheckLaneIndex, 2>]>;
+def SVMLSLB_F : SInst<"svmlslb[_{d}]", "ddhh", "f", MergeNone, "aarch64_sve_fmlslb", [IsStreamingCompatible]>;
+def SVMLSLB_F_N : SInst<"svmlslb[_n_{d}]", "ddhR", "f", MergeNone, "aarch64_sve_fmlslb", [IsStreamingCompatible]>;
+def SVMLSLB_F_LANE : SInst<"svmlslb_lane[_{d}]", "ddhhi", "f", MergeNone, "aarch64_sve_fmlslb_lane", [IsStreamingCompatible], [ImmCheck<3, ImmCheckLaneIndex, 2>]>;
+def SVMLSLT_F : SInst<"svmlslt[_{d}]", "ddhh", "f", MergeNone, "aarch64_sve_fmlslt", [IsStreamingCompatible]>;
+def SVMLSLT_F_N : SInst<"svmlslt[_n_{d}]", "ddhR", "f", MergeNone, "aarch64_sve_fmlslt", [IsStreamingCompatible]>;
+def SVMLSLT_F_LANE : SInst<"svmlslt_lane[_{d}]", "ddhhi", "f", MergeNone, "aarch64_sve_fmlslt_lane", [IsStreamingCompatible], [ImmCheck<3, ImmCheckLaneIndex, 2>]>;
}
////////////////////////////////////////////////////////////////////////////////
// SVE2 - Floating-point integer binary logarithm
-let ArchGuard = "defined(__ARM_FEATURE_SVE2)" in {
-def SVLOGB_M : SInst<"svlogb[_{d}]", "xxPd", "hfd", MergeOp1, "aarch64_sve_flogb">;
-def SVLOGB_X : SInst<"svlogb[_{d}]", "xPd", "hfd", MergeAnyExp, "aarch64_sve_flogb">;
-def SVLOGB_Z : SInst<"svlogb[_{d}]", "xPd", "hfd", MergeZeroExp, "aarch64_sve_flogb">;
+let TargetGuard = "sve2" in {
+def SVLOGB_M : SInst<"svlogb[_{d}]", "xxPd", "hfd", MergeOp1, "aarch64_sve_flogb", [IsStreamingCompatible]>;
+def SVLOGB_X : SInst<"svlogb[_{d}]", "xPd", "hfd", MergeAnyExp, "aarch64_sve_flogb", [IsStreamingCompatible]>;
+def SVLOGB_Z : SInst<"svlogb[_{d}]", "xPd", "hfd", MergeZeroExp, "aarch64_sve_flogb", [IsStreamingCompatible]>;
}
////////////////////////////////////////////////////////////////////////////////
// SVE2 - Vector Histogram count
-let ArchGuard = "defined(__ARM_FEATURE_SVE2)" in {
+let TargetGuard = "sve2" in {
def SVHISTCNT : SInst<"svhistcnt[_{d}]_z", "uPdd", "ilUiUl", MergeNone, "aarch64_sve_histcnt">;
def SVHISTSEG : SInst<"svhistseg[_{d}]", "udd", "cUc", MergeNone, "aarch64_sve_histseg">;
}
@@ -2012,46 +1882,46 @@ def SVHISTSEG : SInst<"svhistseg[_{d}]", "udd", "cUc", MergeNone, "aarch6
////////////////////////////////////////////////////////////////////////////////
// SVE2 - Character match
-let ArchGuard = "defined(__ARM_FEATURE_SVE2)" in {
+let TargetGuard = "sve2" in {
def SVMATCH : SInst<"svmatch[_{d}]", "PPdd", "csUcUs", MergeNone, "aarch64_sve_match">;
def SVNMATCH : SInst<"svnmatch[_{d}]", "PPdd", "csUcUs", MergeNone, "aarch64_sve_nmatch">;
}
////////////////////////////////////////////////////////////////////////////////
// SVE2 - Contiguous conflict detection
-let ArchGuard = "defined(__ARM_FEATURE_SVE2)" in {
-def SVWHILERW_B : SInst<"svwhilerw[_{1}]", "Pcc", "cUc", MergeNone, "aarch64_sve_whilerw_b", [IsOverloadWhileRW]>;
-def SVWHILERW_H : SInst<"svwhilerw[_{1}]", "Pcc", "sUsh", MergeNone, "aarch64_sve_whilerw_h", [IsOverloadWhileRW]>;
-def SVWHILERW_S : SInst<"svwhilerw[_{1}]", "Pcc", "iUif", MergeNone, "aarch64_sve_whilerw_s", [IsOverloadWhileRW]>;
-def SVWHILERW_D : SInst<"svwhilerw[_{1}]", "Pcc", "lUld", MergeNone, "aarch64_sve_whilerw_d", [IsOverloadWhileRW]>;
+let TargetGuard = "sve2" in {
+def SVWHILERW_B : SInst<"svwhilerw[_{1}]", "Pcc", "cUc", MergeNone, "aarch64_sve_whilerw_b", [IsOverloadWhileRW, IsStreamingCompatible]>;
+def SVWHILERW_H : SInst<"svwhilerw[_{1}]", "Pcc", "sUsh", MergeNone, "aarch64_sve_whilerw_h", [IsOverloadWhileRW, IsStreamingCompatible]>;
+def SVWHILERW_S : SInst<"svwhilerw[_{1}]", "Pcc", "iUif", MergeNone, "aarch64_sve_whilerw_s", [IsOverloadWhileRW, IsStreamingCompatible]>;
+def SVWHILERW_D : SInst<"svwhilerw[_{1}]", "Pcc", "lUld", MergeNone, "aarch64_sve_whilerw_d", [IsOverloadWhileRW, IsStreamingCompatible]>;
-def SVWHILEWR_B : SInst<"svwhilewr[_{1}]", "Pcc", "cUc", MergeNone, "aarch64_sve_whilewr_b", [IsOverloadWhileRW]>;
-def SVWHILEWR_H : SInst<"svwhilewr[_{1}]", "Pcc", "sUsh", MergeNone, "aarch64_sve_whilewr_h", [IsOverloadWhileRW]>;
-def SVWHILEWR_S : SInst<"svwhilewr[_{1}]", "Pcc", "iUif", MergeNone, "aarch64_sve_whilewr_s", [IsOverloadWhileRW]>;
-def SVWHILEWR_D : SInst<"svwhilewr[_{1}]", "Pcc", "lUld", MergeNone, "aarch64_sve_whilewr_d", [IsOverloadWhileRW]>;
+def SVWHILEWR_B : SInst<"svwhilewr[_{1}]", "Pcc", "cUc", MergeNone, "aarch64_sve_whilewr_b", [IsOverloadWhileRW, IsStreamingCompatible]>;
+def SVWHILEWR_H : SInst<"svwhilewr[_{1}]", "Pcc", "sUsh", MergeNone, "aarch64_sve_whilewr_h", [IsOverloadWhileRW, IsStreamingCompatible]>;
+def SVWHILEWR_S : SInst<"svwhilewr[_{1}]", "Pcc", "iUif", MergeNone, "aarch64_sve_whilewr_s", [IsOverloadWhileRW, IsStreamingCompatible]>;
+def SVWHILEWR_D : SInst<"svwhilewr[_{1}]", "Pcc", "lUld", MergeNone, "aarch64_sve_whilewr_d", [IsOverloadWhileRW, IsStreamingCompatible]>;
}
-let ArchGuard = "defined(__ARM_FEATURE_SVE2) && defined(__ARM_FEATURE_BF16_SCALAR_ARITHMETIC)" in {
-def SVWHILERW_H_BF16 : SInst<"svwhilerw[_{1}]", "Pcc", "b", MergeNone, "aarch64_sve_whilerw_h", [IsOverloadWhileRW]>;
-def SVWHILEWR_H_BF16 : SInst<"svwhilewr[_{1}]", "Pcc", "b", MergeNone, "aarch64_sve_whilewr_h", [IsOverloadWhileRW]>;
+let TargetGuard = "sve2,bf16" in {
+def SVWHILERW_H_BF16 : SInst<"svwhilerw[_{1}]", "Pcc", "b", MergeNone, "aarch64_sve_whilerw_h", [IsOverloadWhileRW, IsStreamingCompatible]>;
+def SVWHILEWR_H_BF16 : SInst<"svwhilewr[_{1}]", "Pcc", "b", MergeNone, "aarch64_sve_whilewr_h", [IsOverloadWhileRW, IsStreamingCompatible]>;
}
////////////////////////////////////////////////////////////////////////////////
// SVE2 - Extended table lookup/permute
-let ArchGuard = "defined(__ARM_FEATURE_SVE2)" in {
-def SVTBL2 : SInst<"svtbl2[_{d}]", "d2u", "csilUcUsUiUlhfd", MergeNone>;
-def SVTBX : SInst<"svtbx[_{d}]", "dddu", "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_tbx">;
+let TargetGuard = "sve2" in {
+def SVTBL2 : SInst<"svtbl2[_{d}]", "d2u", "csilUcUsUiUlhfd", MergeNone, "", [IsStreamingCompatible]>;
+def SVTBX : SInst<"svtbx[_{d}]", "dddu", "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_tbx", [IsStreamingCompatible]>;
}
-let ArchGuard = "defined(__ARM_FEATURE_SVE2) && defined(__ARM_FEATURE_SVE_BF16)" in {
-def SVTBL2_BF16 : SInst<"svtbl2[_{d}]", "d2u", "b", MergeNone>;
-def SVTBX_BF16 : SInst<"svtbx[_{d}]", "dddu", "b", MergeNone, "aarch64_sve_tbx">;
+let TargetGuard = "sve2,bf16" in {
+def SVTBL2_BF16 : SInst<"svtbl2[_{d}]", "d2u", "b", MergeNone, "", [IsStreamingCompatible]>;
+def SVTBX_BF16 : SInst<"svtbx[_{d}]", "dddu", "b", MergeNone, "aarch64_sve_tbx", [IsStreamingCompatible]>;
}
////////////////////////////////////////////////////////////////////////////////
// SVE2 - Optional
-let ArchGuard = "defined(__ARM_FEATURE_SVE2_AES)" in {
+let TargetGuard = "sve2-aes" in {
def SVAESD : SInst<"svaesd[_{d}]", "ddd", "Uc", MergeNone, "aarch64_sve_aesd", [IsOverloadNone]>;
def SVAESIMC : SInst<"svaesimc[_{d}]", "dd", "Uc", MergeNone, "aarch64_sve_aesimc", [IsOverloadNone]>;
def SVAESE : SInst<"svaese[_{d}]", "ddd", "Uc", MergeNone, "aarch64_sve_aese", [IsOverloadNone]>;
@@ -2064,16 +1934,16 @@ def SVPMULLT_PAIR_U64 : SInst<"svpmullt_pair[_{d}]", "ddd", "Ul", MergeNone,
def SVPMULLT_PAIR_N_U64 : SInst<"svpmullt_pair[_n_{d}]", "dda", "Ul", MergeNone, "aarch64_sve_pmullt_pair">;
}
-let ArchGuard = "defined(__ARM_FEATURE_SVE2_SHA3)" in {
+let TargetGuard = "sve2-sha3" in {
def SVRAX1 : SInst<"svrax1[_{d}]", "ddd", "lUl", MergeNone, "aarch64_sve_rax1", [IsOverloadNone]>;
}
-let ArchGuard = "defined(__ARM_FEATURE_SVE2_SM4)" in {
+let TargetGuard = "sve2-sm4" in {
def SVSM4E : SInst<"svsm4e[_{d}]", "ddd", "Ui", MergeNone, "aarch64_sve_sm4e", [IsOverloadNone]>;
def SVSM4EKEY : SInst<"svsm4ekey[_{d}]", "ddd", "Ui", MergeNone, "aarch64_sve_sm4ekey", [IsOverloadNone]>;
}
-let ArchGuard = "defined (__ARM_FEATURE_SVE2_BITPERM)" in {
+let TargetGuard = "sve2-bitperm" in {
def SVBDEP : SInst<"svbdep[_{d}]", "ddd", "UcUsUiUl", MergeNone, "aarch64_sve_bdep_x">;
def SVBDEP_N : SInst<"svbdep[_n_{d}]", "dda", "UcUsUiUl", MergeNone, "aarch64_sve_bdep_x">;
def SVBEXT : SInst<"svbext[_{d}]", "ddd", "UcUsUiUl", MergeNone, "aarch64_sve_bext_x">;
@@ -2081,3 +1951,386 @@ def SVBEXT_N : SInst<"svbext[_n_{d}]", "dda", "UcUsUiUl", MergeNone, "aarch64_sv
def SVBGRP : SInst<"svbgrp[_{d}]", "ddd", "UcUsUiUl", MergeNone, "aarch64_sve_bgrp_x">;
def SVBGRP_N : SInst<"svbgrp[_n_{d}]", "dda", "UcUsUiUl", MergeNone, "aarch64_sve_bgrp_x">;
}
+
+let TargetGuard = "sve2p1|sme" in {
+def SVPSEL_B : SInst<"svpsel_lane_b8", "PPPm", "Pc", MergeNone, "", [IsStreamingOrSVE2p1], []>;
+def SVPSEL_H : SInst<"svpsel_lane_b16", "PPPm", "Ps", MergeNone, "", [IsStreamingOrSVE2p1], []>;
+def SVPSEL_S : SInst<"svpsel_lane_b32", "PPPm", "Pi", MergeNone, "", [IsStreamingOrSVE2p1], []>;
+def SVPSEL_D : SInst<"svpsel_lane_b64", "PPPm", "Pl", MergeNone, "", [IsStreamingOrSVE2p1], []>;
+}
+
+// Standalone sve2.1 builtins
+let TargetGuard = "sve2p1" in {
+def SVORQV : SInst<"svorqv[_{d}]", "{Pd", "csilUcUsUiUl", MergeNone, "aarch64_sve_orqv", [IsReductionQV]>;
+def SVEORQV : SInst<"sveorqv[_{d}]", "{Pd", "csilUcUsUiUl", MergeNone, "aarch64_sve_eorqv", [IsReductionQV]>;
+def SVADDQV : SInst<"svaddqv[_{d}]", "{Pd", "hfdcsilUcUsUiUl", MergeNone, "aarch64_sve_addqv", [IsReductionQV]>;
+def SVANDQV : SInst<"svandqv[_{d}]", "{Pd", "csilUcUsUiUl", MergeNone, "aarch64_sve_andqv", [IsReductionQV]>;
+def SVSMAXQV : SInst<"svmaxqv[_{d}]", "{Pd", "csil", MergeNone, "aarch64_sve_smaxqv", [IsReductionQV]>;
+def SVUMAXQV : SInst<"svmaxqv[_{d}]", "{Pd", "UcUsUiUl", MergeNone, "aarch64_sve_umaxqv", [IsReductionQV]>;
+def SVSMINQV : SInst<"svminqv[_{d}]", "{Pd", "csil", MergeNone, "aarch64_sve_sminqv", [IsReductionQV]>;
+def SVUMINQV : SInst<"svminqv[_{d}]", "{Pd", "UcUsUiUl", MergeNone, "aarch64_sve_uminqv", [IsReductionQV]>;
+
+def SVFMAXNMQV: SInst<"svmaxnmqv[_{d}]", "{Pd", "hfd", MergeNone, "aarch64_sve_fmaxnmqv", [IsReductionQV]>;
+def SVFMINNMQV: SInst<"svminnmqv[_{d}]", "{Pd", "hfd", MergeNone, "aarch64_sve_fminnmqv", [IsReductionQV]>;
+def SVFMAXQV: SInst<"svmaxqv[_{d}]", "{Pd", "hfd", MergeNone, "aarch64_sve_fmaxqv", [IsReductionQV]>;
+def SVFMINQV: SInst<"svminqv[_{d}]", "{Pd", "hfd", MergeNone, "aarch64_sve_fminqv", [IsReductionQV]>;
+}
+
+let TargetGuard = "sve2p1|sme2" in {
+def SVPEXT_SINGLE : SInst<"svpext_lane_{d}", "P}i", "QcQsQiQl", MergeNone, "aarch64_sve_pext", [IsStreamingOrSVE2p1], [ImmCheck<1, ImmCheck0_3>]>;
+def SVPEXT_X2 : SInst<"svpext_lane_{d}_x2", "2.P}i", "QcQsQiQl", MergeNone, "aarch64_sve_pext_x2", [IsStreamingOrSVE2p1], [ImmCheck<1, ImmCheck0_1>]>;
+
+def SVPSEL_COUNT_ALIAS_B : SInst<"svpsel_lane_c8", "}}Pm", "Pc", MergeNone, "", [IsStreamingOrSVE2p1], []>;
+def SVPSEL_COUNT_ALIAS_H : SInst<"svpsel_lane_c16", "}}Pm", "Ps", MergeNone, "", [IsStreamingOrSVE2p1], []>;
+def SVPSEL_COUNT_ALIAS_S : SInst<"svpsel_lane_c32", "}}Pm", "Pi", MergeNone, "", [IsStreamingOrSVE2p1], []>;
+def SVPSEL_COUNT_ALIAS_D : SInst<"svpsel_lane_c64", "}}Pm", "Pl", MergeNone, "", [IsStreamingOrSVE2p1], []>;
+
+def SVWHILEGE_COUNT : SInst<"svwhilege_{d}[_{1}]", "}lli", "QcQsQiQl", MergeNone, "aarch64_sve_whilege_{d}", [IsOverloadNone, IsStreamingOrSVE2p1], [ImmCheck<2, ImmCheck2_4_Mul2>]>;
+def SVWHILEGT_COUNT : SInst<"svwhilegt_{d}[_{1}]", "}lli", "QcQsQiQl", MergeNone, "aarch64_sve_whilegt_{d}", [IsOverloadNone, IsStreamingOrSVE2p1], [ImmCheck<2, ImmCheck2_4_Mul2>]>;
+def SVWHILELE_COUNT : SInst<"svwhilele_{d}[_{1}]", "}lli", "QcQsQiQl", MergeNone, "aarch64_sve_whilele_{d}", [IsOverloadNone, IsStreamingOrSVE2p1], [ImmCheck<2, ImmCheck2_4_Mul2>]>;
+def SVWHILELT_COUNT : SInst<"svwhilelt_{d}[_{1}]", "}lli", "QcQsQiQl", MergeNone, "aarch64_sve_whilelt_{d}", [IsOverloadNone, IsStreamingOrSVE2p1], [ImmCheck<2, ImmCheck2_4_Mul2>]>;
+def SVWHILELO_COUNT : SInst<"svwhilelt_{d}[_{1}]", "}nni", "QcQsQiQl", MergeNone, "aarch64_sve_whilelo_{d}", [IsOverloadNone, IsStreamingOrSVE2p1], [ImmCheck<2, ImmCheck2_4_Mul2>]>;
+def SVWHILELS_COUNT : SInst<"svwhilele_{d}[_{1}]", "}nni", "QcQsQiQl", MergeNone, "aarch64_sve_whilels_{d}", [IsOverloadNone, IsStreamingOrSVE2p1], [ImmCheck<2, ImmCheck2_4_Mul2>]>;
+def SVWHILEHI_COUNT : SInst<"svwhilegt_{d}[_{1}]", "}nni", "QcQsQiQl", MergeNone, "aarch64_sve_whilehi_{d}", [IsOverloadNone, IsStreamingOrSVE2p1], [ImmCheck<2, ImmCheck2_4_Mul2>]>;
+def SVWHILEHS_COUNT : SInst<"svwhilege_{d}[_{1}]", "}nni", "QcQsQiQl", MergeNone, "aarch64_sve_whilehs_{d}", [IsOverloadNone, IsStreamingOrSVE2p1], [ImmCheck<2, ImmCheck2_4_Mul2>]>;
+}
+
+multiclass MultiVecLoad<string i> {
+ def SV # NAME # B_X2 : MInst<"sv" # i # "[_{2}]_x2", "2}c", "cUc", [IsStructLoad, IsStreamingOrSVE2p1], MemEltTyDefault, "aarch64_sve_" # i # "_pn_x2">;
+ def SV # NAME # H_X2 : MInst<"sv" # i # "[_{2}]_x2", "2}c", "sUshb", [IsStructLoad, IsStreamingOrSVE2p1], MemEltTyDefault, "aarch64_sve_" # i # "_pn_x2">;
+ def SV # NAME # W_X2 : MInst<"sv" # i # "[_{2}]_x2", "2}c", "iUif", [IsStructLoad, IsStreamingOrSVE2p1], MemEltTyDefault, "aarch64_sve_" # i # "_pn_x2">;
+ def SV # NAME # D_X2 : MInst<"sv" # i # "[_{2}]_x2", "2}c", "lUld", [IsStructLoad, IsStreamingOrSVE2p1], MemEltTyDefault, "aarch64_sve_" # i # "_pn_x2">;
+ def SV # NAME # B_X4 : MInst<"sv" # i # "[_{2}]_x4", "4}c", "cUc", [IsStructLoad, IsStreamingOrSVE2p1], MemEltTyDefault, "aarch64_sve_" # i # "_pn_x4">;
+ def SV # NAME # H_X4 : MInst<"sv" # i # "[_{2}]_x4", "4}c", "sUshb", [IsStructLoad, IsStreamingOrSVE2p1], MemEltTyDefault, "aarch64_sve_" # i # "_pn_x4">;
+ def SV # NAME # W_X4 : MInst<"sv" # i # "[_{2}]_x4", "4}c", "iUif", [IsStructLoad, IsStreamingOrSVE2p1], MemEltTyDefault, "aarch64_sve_" # i # "_pn_x4">;
+ def SV # NAME # D_X4 : MInst<"sv" # i # "[_{2}]_x4", "4}c", "lUld", [IsStructLoad, IsStreamingOrSVE2p1], MemEltTyDefault, "aarch64_sve_" # i # "_pn_x4">;
+
+ def SV # NAME # B_VNUM_X2 : MInst<"sv" # i # "_vnum" # "[_{2}]_x2", "2}cl", "cUc", [IsStructLoad, IsStreamingOrSVE2p1], MemEltTyDefault, "aarch64_sve_" # i # "_pn_x2">;
+ def SV # NAME # H_VNUM_X2 : MInst<"sv" # i # "_vnum" # "[_{2}]_x2", "2}cl", "sUshb", [IsStructLoad, IsStreamingOrSVE2p1], MemEltTyDefault, "aarch64_sve_" # i # "_pn_x2">;
+ def SV # NAME # W_VNUM_X2 : MInst<"sv" # i # "_vnum" # "[_{2}]_x2", "2}cl", "iUif", [IsStructLoad, IsStreamingOrSVE2p1], MemEltTyDefault, "aarch64_sve_" # i # "_pn_x2">;
+ def SV # NAME # D_VNUM_X2 : MInst<"sv" # i # "_vnum" # "[_{2}]_x2", "2}cl", "lUld", [IsStructLoad, IsStreamingOrSVE2p1], MemEltTyDefault, "aarch64_sve_" # i # "_pn_x2">;
+ def SV # NAME # B_VNUM_X4 : MInst<"sv" # i # "_vnum" # "[_{2}]_x4", "4}cl", "cUc", [IsStructLoad, IsStreamingOrSVE2p1], MemEltTyDefault, "aarch64_sve_" # i # "_pn_x4">;
+ def SV # NAME # H_VNUM_X4 : MInst<"sv" # i # "_vnum" # "[_{2}]_x4", "4}cl", "sUshb", [IsStructLoad, IsStreamingOrSVE2p1], MemEltTyDefault, "aarch64_sve_" # i # "_pn_x4">;
+ def SV # NAME # W_VNUM_X4 : MInst<"sv" # i # "_vnum" # "[_{2}]_x4", "4}cl", "iUif", [IsStructLoad, IsStreamingOrSVE2p1], MemEltTyDefault, "aarch64_sve_" # i # "_pn_x4">;
+ def SV # NAME # D_VNUM_X4 : MInst<"sv" # i # "_vnum" # "[_{2}]_x4", "4}cl", "lUld", [IsStructLoad, IsStreamingOrSVE2p1], MemEltTyDefault, "aarch64_sve_" # i # "_pn_x4">;
+}
+
+let TargetGuard = "sve2p1|sme2" in {
+ defm LD1 : MultiVecLoad<"ld1">;
+ defm LDNT1 : MultiVecLoad<"ldnt1">;
+}
+
+multiclass MultiVecStore<string i> {
+ def SV # NAME # B_X2 : MInst<"sv" # i # "[_{2}_x2]", "v}p2", "cUc", [IsStructStore, IsStreamingOrSVE2p1], MemEltTyDefault, "aarch64_sve_" # i # "_pn_x2">;
+ def SV # NAME # H_X2 : MInst<"sv" # i # "[_{2}_x2]", "v}p2", "sUshb", [IsStructStore, IsStreamingOrSVE2p1], MemEltTyDefault, "aarch64_sve_" # i # "_pn_x2">;
+ def SV # NAME # W_X2 : MInst<"sv" # i # "[_{2}_x2]", "v}p2", "iUif", [IsStructStore, IsStreamingOrSVE2p1], MemEltTyDefault, "aarch64_sve_" # i # "_pn_x2">;
+ def SV # NAME # D_X2 : MInst<"sv" # i # "[_{2}_x2]", "v}p2", "lUld", [IsStructStore, IsStreamingOrSVE2p1], MemEltTyDefault, "aarch64_sve_" # i # "_pn_x2">;
+ def SV # NAME # B_X4 : MInst<"sv" # i # "[_{2}_x4]", "v}p4", "cUc", [IsStructStore, IsStreamingOrSVE2p1], MemEltTyDefault, "aarch64_sve_" # i # "_pn_x4">;
+ def SV # NAME # H_X4 : MInst<"sv" # i # "[_{2}_x4]", "v}p4", "sUshb", [IsStructStore, IsStreamingOrSVE2p1], MemEltTyDefault, "aarch64_sve_" # i # "_pn_x4">;
+ def SV # NAME # W_X4 : MInst<"sv" # i # "[_{2}_x4]", "v}p4", "iUif", [IsStructStore, IsStreamingOrSVE2p1], MemEltTyDefault, "aarch64_sve_" # i # "_pn_x4">;
+ def SV # NAME # D_X4 : MInst<"sv" # i # "[_{2}_x4]", "v}p4", "lUld", [IsStructStore, IsStreamingOrSVE2p1], MemEltTyDefault, "aarch64_sve_" # i # "_pn_x4">;
+
+ def SV # NAME # B_VNUM_X2 : MInst<"sv" # i # "_vnum" # "[_{2}_x2]", "v}pl2", "cUc", [IsStructStore, IsStreamingOrSVE2p1], MemEltTyDefault, "aarch64_sve_" # i # "_pn_x2">;
+ def SV # NAME # H_VNUM_X2 : MInst<"sv" # i # "_vnum" # "[_{2}_x2]", "v}pl2", "sUshb", [IsStructStore, IsStreamingOrSVE2p1], MemEltTyDefault, "aarch64_sve_" # i # "_pn_x2">;
+ def SV # NAME # W_VNUM_X2 : MInst<"sv" # i # "_vnum" # "[_{2}_x2]", "v}pl2", "iUif", [IsStructStore, IsStreamingOrSVE2p1], MemEltTyDefault, "aarch64_sve_" # i # "_pn_x2">;
+ def SV # NAME # D_VNUM_X2 : MInst<"sv" # i # "_vnum" # "[_{2}_x2]", "v}pl2", "lUld", [IsStructStore, IsStreamingOrSVE2p1], MemEltTyDefault, "aarch64_sve_" # i # "_pn_x2">;
+ def SV # NAME # B_VNUM_X4 : MInst<"sv" # i # "_vnum" # "[_{2}_x4]", "v}pl4", "cUc", [IsStructStore, IsStreamingOrSVE2p1], MemEltTyDefault, "aarch64_sve_" # i # "_pn_x4">;
+ def SV # NAME # H_VNUM_X4 : MInst<"sv" # i # "_vnum" # "[_{2}_x4]", "v}pl4", "sUshb", [IsStructStore, IsStreamingOrSVE2p1], MemEltTyDefault, "aarch64_sve_" # i # "_pn_x4">;
+ def SV # NAME # W_VNUM_X4 : MInst<"sv" # i # "_vnum" # "[_{2}_x4]", "v}pl4", "iUif", [IsStructStore, IsStreamingOrSVE2p1], MemEltTyDefault, "aarch64_sve_" # i # "_pn_x4">;
+ def SV # NAME # D_VNUM_X4 : MInst<"sv" # i # "_vnum" # "[_{2}_x4]", "v}pl4", "lUld", [IsStructStore, IsStreamingOrSVE2p1], MemEltTyDefault, "aarch64_sve_" # i # "_pn_x4">;
+}
+
+let TargetGuard = "sve2p1|sme2" in {
+ defm ST1 : MultiVecStore<"st1">;
+ defm STNT1 : MultiVecStore<"stnt1">;
+}
+
+let TargetGuard = "sve2p1|sme2" in {
+def SVDOT_X2_S : SInst<"svdot[_{d}_{2}]", "ddhh", "i", MergeNone, "aarch64_sve_sdot_x2", [IsStreamingOrSVE2p1], []>;
+def SVDOT_X2_U : SInst<"svdot[_{d}_{2}]", "ddhh", "Ui", MergeNone, "aarch64_sve_udot_x2", [IsStreamingOrSVE2p1], []>;
+def SVDOT_X2_F : SInst<"svdot[_{d}_{2}]", "ddhh", "f", MergeNone, "aarch64_sve_fdot_x2", [IsStreamingOrSVE2p1], []>;
+def SVDOT_LANE_X2_S : SInst<"svdot_lane[_{d}_{2}]", "ddhhi", "i", MergeNone, "aarch64_sve_sdot_lane_x2", [IsStreamingOrSVE2p1], [ImmCheck<3, ImmCheck0_3>]>;
+def SVDOT_LANE_X2_U : SInst<"svdot_lane[_{d}_{2}]", "ddhhi", "Ui", MergeNone, "aarch64_sve_udot_lane_x2", [IsStreamingOrSVE2p1], [ImmCheck<3, ImmCheck0_3>]>;
+def SVDOT_LANE_X2_F : SInst<"svdot_lane[_{d}_{2}]", "ddhhi", "f", MergeNone, "aarch64_sve_fdot_lane_x2", [IsStreamingOrSVE2p1], [ImmCheck<3, ImmCheck0_3>]>;
+}
+
+let TargetGuard = "sve2p1|sme2" in {
+def SVSCLAMP : SInst<"svclamp[_{d}]", "dddd", "csil", MergeNone, "aarch64_sve_sclamp", [IsStreamingOrSVE2p1], []>;
+def SVUCLAMP : SInst<"svclamp[_{d}]", "dddd", "UcUsUiUl", MergeNone, "aarch64_sve_uclamp", [IsStreamingOrSVE2p1], []>;
+
+defm SVREVD : SInstZPZ<"svrevd", "csilUcUsUiUlbhfd", "aarch64_sve_revd">;
+}
+
+let TargetGuard = "sve2p1|sme2" in {
+ def SVPTRUE_COUNT : SInst<"svptrue_{d}", "}v", "QcQsQiQl", MergeNone, "aarch64_sve_ptrue_{d}", [IsOverloadNone, IsStreamingOrSVE2p1], []>;
+
+ def SVPFALSE_COUNT_ALIAS : SInst<"svpfalse_c", "}v", "", MergeNone, "", [IsOverloadNone, IsStreamingOrSVE2p1]>;
+
+ def SVFCLAMP : SInst<"svclamp[_{d}]", "dddd", "hfd", MergeNone, "aarch64_sve_fclamp", [IsStreamingOrSVE2p1], []>;
+ def SVCNTP_COUNT : SInst<"svcntp_{d}", "n}i", "QcQsQiQl", MergeNone, "aarch64_sve_cntp_{d}", [IsOverloadNone, IsStreamingOrSVE2p1], [ImmCheck<1, ImmCheck2_4_Mul2>]>;
+}
+
+let TargetGuard = "(sve2|sme2),b16b16" in {
+defm SVMUL_BF : SInstZPZZ<"svmul", "b", "aarch64_sve_fmul", "aarch64_sve_fmul_u", [IsStreamingCompatible]>;
+defm SVADD_BF : SInstZPZZ<"svadd", "b", "aarch64_sve_fadd", "aarch64_sve_fadd_u", [IsStreamingCompatible]>;
+defm SVSUB_BF : SInstZPZZ<"svsub", "b", "aarch64_sve_fsub", "aarch64_sve_fsub_u", [IsStreamingCompatible]>;
+defm SVMAXNM_BF : SInstZPZZ<"svmaxnm","b", "aarch64_sve_fmaxnm", "aarch64_sve_fmaxnm_u", [IsStreamingCompatible]>;
+defm SVMINNM_BF : SInstZPZZ<"svminnm","b", "aarch64_sve_fminnm", "aarch64_sve_fminnm_u", [IsStreamingCompatible]>;
+defm SVMAX_BF : SInstZPZZ<"svmax", "b", "aarch64_sve_fmax", "aarch64_sve_fmax_u", [IsStreamingCompatible]>;
+defm SVMIN_BF : SInstZPZZ<"svmin", "b", "aarch64_sve_fmin", "aarch64_sve_fmin_u", [IsStreamingCompatible]>;
+defm SVMLA_BF : SInstZPZZZ<"svmla", "b", "aarch64_sve_fmla", "aarch64_sve_fmla_u", [IsStreamingCompatible]>;
+defm SVMLS_BF : SInstZPZZZ<"svmls", "b", "aarch64_sve_fmls", "aarch64_sve_fmls_u", [IsStreamingCompatible]>;
+def SVMLA_LANE_BF : SInst<"svmla_lane[_{d}]", "ddddi", "b", MergeNone, "aarch64_sve_fmla_lane", [IsStreamingCompatible], [ImmCheck<3, ImmCheckLaneIndex, 2>]>;
+def SVMLS_LANE_BF : SInst<"svmls_lane[_{d}]", "ddddi", "b", MergeNone, "aarch64_sve_fmls_lane", [IsStreamingCompatible], [ImmCheck<3, ImmCheckLaneIndex, 2>]>;
+def SVMUL_LANE_BF : SInst<"svmul_lane[_{d}]", "dddi", "b", MergeNone, "aarch64_sve_fmul_lane", [IsStreamingCompatible], [ImmCheck<2, ImmCheckLaneIndex, 1>]>;
+def SVFCLAMP_BF : SInst<"svclamp[_{d}]", "dddd", "b", MergeNone, "aarch64_sve_fclamp", [IsStreamingCompatible], []>;
+}
+
+// SME2
+
+// SME intrinsics which operate only on vectors and do not require ZA should be added here,
+// as they could possibly become SVE instructions in the future.
+
+multiclass MinMaxIntr<string i, string zm, string mul, string t> {
+ def SVS # NAME : SInst<"sv" # i # "[" # zm # "_{d}_" # mul # "]", t, "csil", MergeNone, "aarch64_sve_s" # i # zm # "_" # mul, [IsStreaming], []>;
+ def SVU # NAME : SInst<"sv" # i # "[" # zm # "_{d}_" # mul # "]", t, "UcUsUiUl", MergeNone, "aarch64_sve_u" # i # zm # "_" # mul, [IsStreaming], []>;
+ def SVF # NAME : SInst<"sv" # i # "[" # zm # "_{d}_" # mul # "]", t, "hfd", MergeNone, "aarch64_sve_f" # i # zm # "_" # mul, [IsStreaming], []>;
+}
+
+let TargetGuard = "sme2" in {
+// == SMAX / UMAX / FMAX ==
+ defm MAX_SINGLE_X2 : MinMaxIntr<"max", "_single", "x2", "22d">;
+ defm MAX_MULTI_X2 : MinMaxIntr<"max", "", "x2", "222">;
+ defm MAX_SINGLE_X4 : MinMaxIntr<"max", "_single", "x4", "44d">;
+ defm MAX_MULTI_X4 : MinMaxIntr<"max", "", "x4", "444">;
+
+// == SMIN / UMIN / FMIN ==
+ defm MIN_SINGLE_X2 : MinMaxIntr<"min", "_single", "x2", "22d">;
+ defm MIN_MULTI_X2 : MinMaxIntr<"min", "", "x2", "222">;
+ defm MIN_SINGLE_X4 : MinMaxIntr<"min", "_single", "x4", "44d">;
+ defm MIN_MULTI_X4 : MinMaxIntr<"min", "", "x4", "444">;
+}
+
+multiclass SInstMinMaxByVector<string name> {
+ def NAME # _SINGLE_X2 : SInst<"sv" # name # "nm[_single_{d}_x2]", "22d", "hfd", MergeNone, "aarch64_sve_f" # name # "nm_single_x2", [IsStreaming], []>;
+ def NAME # _SINGLE_X4 : SInst<"sv" # name # "nm[_single_{d}_x4]", "44d", "hfd", MergeNone, "aarch64_sve_f" # name # "nm_single_x4", [IsStreaming], []>;
+
+ def NAME # _X2 : SInst<"sv" # name # "nm[_{d}_x2]", "222", "hfd", MergeNone, "aarch64_sve_f" # name # "nm_x2", [IsStreaming], []>;
+ def NAME # _X4 : SInst<"sv" # name # "nm[_{d}_x4]", "444", "hfd", MergeNone, "aarch64_sve_f" # name # "nm_x4", [IsStreaming], []>;
+}
+
+let TargetGuard = "sme2" in {
+// == FMINNM / FMAXNM ==
+ defm SVMINNM : SInstMinMaxByVector<"min">;
+ defm SVMAXNM : SInstMinMaxByVector<"max">;
+}
+
+let TargetGuard = "sme2" in {
+ // FRINTA / FRINTM / FRINTN / FRINTP
+ def SVRINTA_X2 : SInst<"svrinta[_{d}_x2]", "22", "f", MergeNone, "aarch64_sve_frinta_x2", [IsStreaming], []>;
+ def SVRINTA_X4 : SInst<"svrinta[_{d}_x4]", "44", "f", MergeNone, "aarch64_sve_frinta_x4", [IsStreaming], []>;
+
+ def SVRINTM_X2 : SInst<"svrintm[_{d}_x2]", "22", "f", MergeNone, "aarch64_sve_frintm_x2", [IsStreaming], []>;
+ def SVRINTM_X4 : SInst<"svrintm[_{d}_x4]", "44", "f", MergeNone, "aarch64_sve_frintm_x4", [IsStreaming], []>;
+
+ def SVRINTN_X2 : SInst<"svrintn[_{d}_x2]", "22", "f", MergeNone, "aarch64_sve_frintn_x2", [IsStreaming], []>;
+ def SVRINTN_X4 : SInst<"svrintn[_{d}_x4]", "44", "f", MergeNone, "aarch64_sve_frintn_x4", [IsStreaming], []>;
+
+ def SVRINTP_X2 : SInst<"svrintp[_{d}_x2]", "22", "f", MergeNone, "aarch64_sve_frintp_x2", [IsStreaming], []>;
+ def SVRINTP_X4 : SInst<"svrintp[_{d}_x4]", "44", "f", MergeNone, "aarch64_sve_frintp_x4", [IsStreaming], []>;
+}
+
+let TargetGuard = "sme2" in {
+ def SVSCLAMP_X2 : SInst<"svclamp[_single_{d}_x2]", "22dd", "csil", MergeNone, "aarch64_sve_sclamp_single_x2", [IsStreaming], []>;
+ def SVUCLAMP_X2 : SInst<"svclamp[_single_{d}_x2]", "22dd", "UcUsUiUl", MergeNone, "aarch64_sve_uclamp_single_x2", [IsStreaming], []>;
+ def SVFCLAMP_X2 : SInst<"svclamp[_single_{d}_x2]", "22dd", "hfd", MergeNone, "aarch64_sve_fclamp_single_x2", [IsStreaming], []>;
+
+ def SVSCLAMP_X4 : SInst<"svclamp[_single_{d}_x4]", "44dd", "csil", MergeNone, "aarch64_sve_sclamp_single_x4", [IsStreaming], []>;
+ def SVUCLAMP_X4 : SInst<"svclamp[_single_{d}_x4]", "44dd", "UcUsUiUl", MergeNone, "aarch64_sve_uclamp_single_x4", [IsStreaming], []>;
+ def SVFCLAMP_X4 : SInst<"svclamp[_single_{d}_x4]", "44dd", "hfd", MergeNone, "aarch64_sve_fclamp_single_x4", [IsStreaming], []>;
+}
+
+let TargetGuard = "sme2" in {
+// == ADD (vectors) ==
+ def SVADD_SINGLE_X2 : SInst<"svadd[_single_{d}_x2]", "22d", "cUcsUsiUilUl", MergeNone, "aarch64_sve_add_single_x2", [IsStreaming], []>;
+ def SVADD_SINGLE_X4 : SInst<"svadd[_single_{d}_x4]", "44d", "cUcsUsiUilUl", MergeNone, "aarch64_sve_add_single_x4", [IsStreaming], []>;
+
+ // 2-way and 4-way selects
+ def SVSEL_X2 : SInst<"svsel[_{d}_x2]", "2}22", "cUcsUsiUilUlbhfd", MergeNone, "aarch64_sve_sel_x2", [IsStreaming], []>;
+ def SVSEL_X4 : SInst<"svsel[_{d}_x4]", "4}44", "cUcsUsiUilUlbhfd", MergeNone, "aarch64_sve_sel_x4", [IsStreaming], []>;
+
+ // SRSHL / URSHL
+ def SVSRSHL_SINGLE_X2 : SInst<"svrshl[_single_{d}_x2]", "22d", "csil", MergeNone, "aarch64_sve_srshl_single_x2", [IsStreaming], []>;
+ def SVURSHL_SINGLE_X2 : SInst<"svrshl[_single_{d}_x2]", "22d", "UcUsUiUl", MergeNone, "aarch64_sve_urshl_single_x2", [IsStreaming], []>;
+ def SVSRSHL_SINGLE_X4 : SInst<"svrshl[_single_{d}_x4]", "44d", "csil", MergeNone, "aarch64_sve_srshl_single_x4", [IsStreaming], []>;
+ def SVURSHL_SINGLE_X4 : SInst<"svrshl[_single_{d}_x4]", "44d", "UcUsUiUl", MergeNone, "aarch64_sve_urshl_single_x4", [IsStreaming], []>;
+
+ def SVSRSHL_X2 : SInst<"svrshl[_{d}_x2]", "222", "csil", MergeNone, "aarch64_sve_srshl_x2", [IsStreaming], []>;
+ def SVURSHL_X2 : SInst<"svrshl[_{d}_x2]", "222", "UcUsUiUl", MergeNone, "aarch64_sve_urshl_x2", [IsStreaming], []>;
+ def SVSRSHL_X4 : SInst<"svrshl[_{d}_x4]", "444", "csil", MergeNone, "aarch64_sve_srshl_x4", [IsStreaming], []>;
+ def SVURSHL_X4 : SInst<"svrshl[_{d}_x4]", "444", "UcUsUiUl", MergeNone, "aarch64_sve_urshl_x4", [IsStreaming], []>;
+
+ def SVQRSHRN_X4 : SInst<"svqrshrn[_n]_{0}[_{d}_x4]", "q4i", "il", MergeNone, "aarch64_sve_sqrshrn_x4", [IsStreaming], [ImmCheck<1, ImmCheckShiftRight, 0>]>;
+ def SVUQRSHRN_X4 : SInst<"svqrshrn[_n]_{0}[_{d}_x4]", "b4i", "UiUl", MergeNone, "aarch64_sve_uqrshrn_x4", [IsStreaming], [ImmCheck<1, ImmCheckShiftRight, 0>]>;
+
+ // SQRSHR / UQRSHR
+ def SVQRSHR_X2 : SInst<"svqrshr[_n]_{0}[_{d}_x2]", "h2i", "i", MergeNone, "aarch64_sve_sqrshr_x2", [IsStreaming], [ImmCheck<1, ImmCheck1_16>]>;
+ def SVUQRSHR_X2 : SInst<"svqrshr[_n]_{0}[_{d}_x2]", "e2i", "Ui", MergeNone, "aarch64_sve_uqrshr_x2", [IsStreaming], [ImmCheck<1, ImmCheck1_16>]>;
+ def SVQRSHR_X4 : SInst<"svqrshr[_n]_{0}[_{d}_x4]", "q4i", "il", MergeNone, "aarch64_sve_sqrshr_x4", [IsStreaming], [ImmCheck<1, ImmCheckShiftRight, 0>]>;
+ def SVUQRSHR_X4 : SInst<"svqrshr[_n]_{0}[_{d}_x4]", "b4i", "UiUl", MergeNone, "aarch64_sve_uqrshr_x4", [IsStreaming], [ImmCheck<1, ImmCheckShiftRight, 0>]>;
+
+ // SQRSHRU
+ def SVSQRSHRU_X2 : SInst<"svqrshru[_n]_{0}[_{d}_x2]", "e2i", "i", MergeNone, "aarch64_sve_sqrshru_x2", [IsStreaming], [ImmCheck<1, ImmCheck1_16>]>;
+ def SVSQRSHRU_X4 : SInst<"svqrshru[_n]_{0}[_{d}_x4]", "b4i", "il", MergeNone, "aarch64_sve_sqrshru_x4", [IsStreaming], [ImmCheck<1, ImmCheckShiftRight, 0>]>;
+
+ def SVSQRSHRUN_X4 : SInst<"svqrshrun[_n]_{0}[_{d}_x4]", "b4i", "il", MergeNone, "aarch64_sve_sqrshrun_x4", [IsStreaming], [ImmCheck<1, ImmCheckShiftRight, 0>]>;
+
+ def REINTERPRET_SVBOOL_TO_SVCOUNT : Inst<"svreinterpret[_c]", "}P", "Pc", MergeNone, "", [IsStreamingCompatible], []>;
+ def REINTERPRET_SVCOUNT_TO_SVBOOL : Inst<"svreinterpret[_b]", "P}", "Pc", MergeNone, "", [IsStreamingCompatible], []>;
+
+ // SQDMULH
+ def SVSQDMULH_SINGLE_X2 : SInst<"svqdmulh[_single_{d}_x2]", "22d", "csil", MergeNone, "aarch64_sve_sqdmulh_single_vgx2", [IsStreaming], []>;
+ def SVSQDMULH_SINGLE_X4 : SInst<"svqdmulh[_single_{d}_x4]", "44d", "csil", MergeNone, "aarch64_sve_sqdmulh_single_vgx4", [IsStreaming], []>;
+ def SVSQDMULH_X2 : SInst<"svqdmulh[_{d}_x2]", "222", "csil", MergeNone, "aarch64_sve_sqdmulh_vgx2", [IsStreaming], []>;
+ def SVSQDMULH_X4 : SInst<"svqdmulh[_{d}_x4]", "444", "csil", MergeNone, "aarch64_sve_sqdmulh_vgx4", [IsStreaming], []>;
+}
+
+let TargetGuard = "sve2p1|sme2" in {
+ // SQRSHRN / UQRSHRN
+ def SVQRSHRN_X2 : SInst<"svqrshrn[_n]_{0}[_{d}_x2]", "h2i", "i", MergeNone, "aarch64_sve_sqrshrn_x2", [IsStreamingCompatible], [ImmCheck<1, ImmCheck1_16>]>;
+ def SVUQRSHRN_X2 : SInst<"svqrshrn[_n]_{0}[_{d}_x2]", "e2i", "Ui", MergeNone, "aarch64_sve_uqrshrn_x2", [IsStreamingCompatible], [ImmCheck<1, ImmCheck1_16>]>;
+
+ // SQRSHRUN
+ def SVSQRSHRUN_X2 : SInst<"svqrshrun[_n]_{0}[_{d}_x2]", "e2i", "i", MergeNone, "aarch64_sve_sqrshrun_x2", [IsStreamingCompatible], [ImmCheck<1, ImmCheck1_16>]>;
+}
+
+let TargetGuard = "sve2p1" in {
+ // ZIPQ1, ZIPQ2, UZPQ1, UZPQ2
+ def SVZIPQ1 : SInst<"svzipq1[_{d}]", "ddd", "cUcsUsiUilUlbhfd", MergeNone, "aarch64_sve_zipq1", [], []>;
+ def SVZIPQ2 : SInst<"svzipq2[_{d}]", "ddd", "cUcsUsiUilUlbhfd", MergeNone, "aarch64_sve_zipq2", [], []>;
+ def SVUZPQ1 : SInst<"svuzpq1[_{d}]", "ddd", "cUcsUsiUilUlbhfd", MergeNone, "aarch64_sve_uzpq1", [], []>;
+ def SVUZPQ2 : SInst<"svuzpq2[_{d}]", "ddd", "cUcsUsiUilUlbhfd", MergeNone, "aarch64_sve_uzpq2", [], []>;
+ // TBLQ, TBXQ
+ def SVTBLQ : SInst<"svtblq[_{d}]", "ddu", "cUcsUsiUilUlbhfd", MergeNone, "aarch64_sve_tblq">;
+ def SVTBXQ : SInst<"svtbxq[_{d}]", "dddu", "cUcsUsiUilUlbhfd", MergeNone, "aarch64_sve_tbxq">;
+ // EXTQ
+ def EXTQ : SInst<"svextq[_{d}]", "dddk", "cUcsUsiUilUlbhfd", MergeNone, "aarch64_sve_extq", [], [ImmCheck<2, ImmCheck0_15>]>;
+ // PMOV
+ // Move to Pred
+ multiclass PMOV_TO_PRED<string name, string types, string intrinsic, list<FlagType> flags=[], ImmCheckType immCh > {
+ def _LANE : Inst<name # "_lane[_{d}]", "Pdi", types, MergeNone, intrinsic, flags, [ImmCheck<1, immCh>]>;
+ def _LANE_ZERO : SInst<name # "[_{d}]", "Pd", types, MergeNone, intrinsic # "_zero", flags, []>;
+ }
+ defm SVPMOV_B_TO_PRED : PMOV_TO_PRED<"svpmov", "cUc", "aarch64_sve_pmov_to_pred_lane", [], ImmCheck0_0>;
+ defm SVPMOV_H_TO_PRED : PMOV_TO_PRED<"svpmov", "sUs", "aarch64_sve_pmov_to_pred_lane", [], ImmCheck0_1>;
+ defm SVPMOV_S_TO_PRED : PMOV_TO_PRED<"svpmov", "iUi", "aarch64_sve_pmov_to_pred_lane", [], ImmCheck0_3>;
+ defm SVPMOV_D_TO_PRED : PMOV_TO_PRED<"svpmov", "lUl", "aarch64_sve_pmov_to_pred_lane", [], ImmCheck0_7>;
+
+ // Move to Vector
+ multiclass PMOV_TO_VEC<string name, string types, string intrinsic, list<FlagType> flags=[], ImmCheckType immCh > {
+ def _M : SInst<name # "_lane[_{d}]", "ddPi", types, MergeOp1, intrinsic # "_merging", flags, [ImmCheck<2, immCh>]>;
+ def _Z : SInst<name # "_{d}_z", "dP", types, MergeNone, intrinsic # "_zeroing", flags, []>;
+ }
+ def SVPMOV_TO_VEC_LANE_B : SInst<"svpmov_{d}_z", "dP", "cUc", MergeNone, "aarch64_sve_pmov_to_vector_lane_zeroing", [], []>;
+ defm SVPMOV_TO_VEC_LANE_H : PMOV_TO_VEC<"svpmov", "sUs", "aarch64_sve_pmov_to_vector_lane", [], ImmCheck1_1>;
+ defm SVPMOV_TO_VEC_LANE_S : PMOV_TO_VEC<"svpmov", "iUi", "aarch64_sve_pmov_to_vector_lane", [], ImmCheck1_3>;
+ defm SVPMOV_TO_VEC_LANE_D : PMOV_TO_VEC<"svpmov", "lUl", "aarch64_sve_pmov_to_vector_lane" ,[], ImmCheck1_7>;
+}
+
+//
+// Multi-vector convert to/from floating-point.
+//
+let TargetGuard = "sme2" in {
+ def SVCVT_F16_X2 : SInst<"svcvt_f16[_f32_x2]", "e2", "f", MergeNone, "aarch64_sve_fcvt_x2", [IsStreaming],[]>;
+ def SVCVT_BF16_X2 : SInst<"svcvt_bf16[_f32_x2]", "$2", "f", MergeNone, "aarch64_sve_bfcvt_x2", [IsOverloadNone, IsStreaming],[]>;
+
+ def SVCVT_F32_U32_X2 : SInst<"svcvt_{d}[_u32_x2]", "2.d2.u", "f", MergeNone, "aarch64_sve_ucvtf_x2", [IsStreaming, IsOverloadWhileOrMultiVecCvt], []>;
+ def SVCVT_U32_F32_X2 : SInst<"svcvt_{d}[_f32_x2]", "2.d2.M", "Ui", MergeNone, "aarch64_sve_fcvtzu_x2", [IsStreaming, IsOverloadWhileOrMultiVecCvt], []>;
+ def SVCVT_F32_S32_X2 : SInst<"svcvt_{d}[_s32_x2]", "2.d2.x", "f", MergeNone, "aarch64_sve_scvtf_x2", [IsStreaming, IsOverloadWhileOrMultiVecCvt], []>;
+ def SVCVT_S32_F32_X2 : SInst<"svcvt_{d}[_f32_x2]", "2.d2.M", "i", MergeNone, "aarch64_sve_fcvtzs_x2", [IsStreaming, IsOverloadWhileOrMultiVecCvt], []>;
+
+ def SVCVT_F32_U32_X4 : SInst<"svcvt_{d}[_u32_x4]", "4.d4.u", "f", MergeNone, "aarch64_sve_ucvtf_x4", [IsStreaming, IsOverloadWhileOrMultiVecCvt], []>;
+ def SVCVT_U32_F32_X4 : SInst<"svcvt_{d}[_f32_x4]", "4.d4.M", "Ui", MergeNone, "aarch64_sve_fcvtzu_x4", [IsStreaming, IsOverloadWhileOrMultiVecCvt], []>;
+ def SVCVT_F32_S32_X4 : SInst<"svcvt_{d}[_s32_x4]", "4.d4.x", "f", MergeNone, "aarch64_sve_scvtf_x4", [IsStreaming, IsOverloadWhileOrMultiVecCvt], []>;
+ def SVCVT_S32_F32_X4 : SInst<"svcvt_{d}[_f32_x4]", "4.d4.M", "i", MergeNone, "aarch64_sve_fcvtzs_x4", [IsStreaming, IsOverloadWhileOrMultiVecCvt], []>;
+}
+
+//
+// Multi-vector floating-point convert from single-precision to interleaved half-precision/BFloat16
+//
+let TargetGuard = "sme2" in {
+ def SVCVTN_F16_X2 : SInst<"svcvtn_f16[_f32_x2]", "e2", "f", MergeNone, "aarch64_sve_fcvtn_x2", [IsStreaming],[]>;
+ def SVCVTN_BF16_X2 : SInst<"svcvtn_bf16[_f32_x2]", "$2", "f", MergeNone, "aarch64_sve_bfcvtn_x2", [IsOverloadNone, IsStreaming],[]>;
+}
+
+//
+// Multi-vector saturating extract narrow
+//
+let TargetGuard = "sme2" in {
+ def SVQCVT_S16_S32_X2 : SInst<"svqcvt_s16[_{d}_x2]", "h2.d", "i", MergeNone, "aarch64_sve_sqcvt_x2", [IsStreaming], []>;
+ def SVQCVT_U16_U32_X2 : SInst<"svqcvt_u16[_{d}_x2]", "e2.d", "Ui", MergeNone, "aarch64_sve_uqcvt_x2", [IsStreaming], []>;
+ def SVQCVT_U16_S32_X2 : SInst<"svqcvt_u16[_{d}_x2]", "e2.d", "i", MergeNone, "aarch64_sve_sqcvtu_x2", [IsStreaming], []>;
+
+ def SVQCVT_S8_S32_X4 : SInst<"svqcvt_s8[_{d}_x4]", "q4.d", "i", MergeNone, "aarch64_sve_sqcvt_x4", [IsStreaming], []>;
+ def SVQCVT_U8_U32_X4 : SInst<"svqcvt_u8[_{d}_x4]", "b4.d", "Ui", MergeNone, "aarch64_sve_uqcvt_x4", [IsStreaming], []>;
+ def SVQCVT_U8_S32_X4 : SInst<"svqcvt_u8[_{d}_x4]", "b4.d", "i", MergeNone, "aarch64_sve_sqcvtu_x4", [IsStreaming], []>;
+
+ def SVQCVT_S16_S64_X4 : SInst<"svqcvt_s16[_{d}_x4]", "q4.d", "l", MergeNone, "aarch64_sve_sqcvt_x4", [IsStreaming], []>;
+ def SVQCVT_U16_U64_X4 : SInst<"svqcvt_u16[_{d}_x4]", "b4.d", "Ul", MergeNone, "aarch64_sve_uqcvt_x4", [IsStreaming], []>;
+ def SVQCVT_U16_S64_X4 : SInst<"svqcvt_u16[_{d}_x4]", "b4.d", "l", MergeNone, "aarch64_sve_sqcvtu_x4", [IsStreaming], []>;
+}
+
+//
+// Multi-vector saturating extract narrow and interleave
+//
+let TargetGuard = "sme2|sve2p1" in {
+ def SVQCVTN_S16_S32_X2 : SInst<"svqcvtn_s16[_{d}_x2]", "h2.d", "i", MergeNone, "aarch64_sve_sqcvtn_x2", [IsStreamingCompatible], []>;
+ def SVQCVTN_U16_U32_X2 : SInst<"svqcvtn_u16[_{d}_x2]", "e2.d", "Ui", MergeNone, "aarch64_sve_uqcvtn_x2", [IsStreamingCompatible], []>;
+ def SVQCVTN_U16_S32_X2 : SInst<"svqcvtn_u16[_{d}_x2]", "e2.d", "i", MergeNone, "aarch64_sve_sqcvtun_x2", [IsStreamingCompatible], []>;
+}
+
+let TargetGuard = "sme2" in {
+ def SVQCVTN_S8_S32_X4 : SInst<"svqcvtn_s8[_{d}_x4]", "q4.d", "i", MergeNone, "aarch64_sve_sqcvtn_x4", [IsStreaming], []>;
+ def SVQCVTN_U8_U32_X4 : SInst<"svqcvtn_u8[_{d}_x4]", "b4.d", "Ui", MergeNone, "aarch64_sve_uqcvtn_x4", [IsStreaming], []>;
+ def SVQCVTN_U8_S32_X4 : SInst<"svqcvtn_u8[_{d}_x4]", "b4.d", "i", MergeNone, "aarch64_sve_sqcvtun_x4", [IsStreaming], []>;
+
+ def SVQCVTN_S16_S64_X4 : SInst<"svqcvtn_s16[_{d}_x4]", "q4.d", "l", MergeNone, "aarch64_sve_sqcvtn_x4", [IsStreaming], []>;
+ def SVQCVTN_U16_U64_X4 : SInst<"svqcvtn_u16[_{d}_x4]", "b4.d", "Ul", MergeNone, "aarch64_sve_uqcvtn_x4", [IsStreaming], []>;
+ def SVQCVTN_U16_S64_X4 : SInst<"svqcvtn_u16[_{d}_x4]", "b4.d", "l", MergeNone, "aarch64_sve_sqcvtun_x4", [IsStreaming], []>;
+}
+
+//
+// Multi-vector zip/unzip
+//
+
+let TargetGuard = "sme2" in {
+ def SVZIP_X2 : SInst<"svzip[_{d}_x2]", "22", "cUcsUsiUilUlbhfd", MergeNone, "aarch64_sve_zip_x2", [IsStreaming], []>;
+ def SVZIPQ_X2 : SInst<"svzipq[_{d}_x2]", "22", "cUcsUsiUilUlbhfd", MergeNone, "aarch64_sve_zipq_x2", [IsStreaming], []>;
+ def SVZIP_X4 : SInst<"svzip[_{d}_x4]", "44", "cUcsUsiUilUlbhfd", MergeNone, "aarch64_sve_zip_x4", [IsStreaming], []>;
+ def SVZIPQ_X4 : SInst<"svzipq[_{d}_x4]", "44", "cUcsUsiUilUlbhfd", MergeNone, "aarch64_sve_zipq_x4", [IsStreaming], []>;
+
+ def SVUZP_X2 : SInst<"svuzp[_{d}_x2]", "22", "cUcsUsiUilUlbhfd", MergeNone, "aarch64_sve_uzp_x2", [IsStreaming], []>;
+ def SVUZPQ_X2 : SInst<"svuzpq[_{d}_x2]", "22", "cUcsUsiUilUlbhfd", MergeNone, "aarch64_sve_uzpq_x2", [IsStreaming], []>;
+ def SVUZP_X4 : SInst<"svuzp[_{d}_x4]", "44", "cUcsUsiUilUlbhfd", MergeNone, "aarch64_sve_uzp_x4", [IsStreaming], []>;
+ def SVUZPQ_X4 : SInst<"svuzpq[_{d}_x4]", "44", "cUcsUsiUilUlbhfd", MergeNone, "aarch64_sve_uzpq_x4", [IsStreaming], []>;
+}
+
+//
+// Multi-vector unpack
+//
+
+let TargetGuard = "sme2" in {
+ def SVSUNPK_X2 : SInst<"svunpk_{d}[_{1}_x2]", "2h", "sil", MergeNone, "aarch64_sve_sunpk_x2", [IsStreaming], []>;
+ def SVUUNPK_X2 : SInst<"svunpk_{d}[_{1}_x2]", "2h", "UsUiUl", MergeNone, "aarch64_sve_uunpk_x2", [IsStreaming], []>;
+ def SVSUNPK_X4 : SInst<"svunpk_{d}[_{3}_x4]", "42.h", "sil", MergeNone, "aarch64_sve_sunpk_x4", [IsStreaming], []>;
+ def SVUUNPK_X4 : SInst<"svunpk_{d}[_{3}_x4]", "42.h", "UsUiUl", MergeNone, "aarch64_sve_uunpk_x4", [IsStreaming], []>;
+}
+
+let TargetGuard = "sve2p1|sme2" in {
+// == BFloat16 multiply-subtract ==
+ def SVBFMLSLB : SInst<"svbfmlslb[_{d}]", "dd$$", "f", MergeNone, "aarch64_sve_bfmlslb", [IsOverloadNone, IsStreamingOrSVE2p1], []>;
+ def SVBFMLSLT : SInst<"svbfmlslt[_{d}]", "dd$$", "f", MergeNone, "aarch64_sve_bfmlslt", [IsOverloadNone, IsStreamingOrSVE2p1], []>;
+
+ def SVBFMLSLB_LANE : SInst<"svbfmlslb_lane[_{d}]", "dd$$i", "f", MergeNone, "aarch64_sve_bfmlslb_lane", [IsOverloadNone, IsStreamingOrSVE2p1], [ImmCheck<3, ImmCheck0_7>]>;
+ def SVBFMLSLT_LANE : SInst<"svbfmlslt_lane[_{d}]", "dd$$i", "f", MergeNone, "aarch64_sve_bfmlslt_lane", [IsOverloadNone, IsStreamingOrSVE2p1], [ImmCheck<3, ImmCheck0_7>]>;
+}
diff --git a/contrib/llvm-project/clang/include/clang/Basic/arm_sve_sme_incl.td b/contrib/llvm-project/clang/include/clang/Basic/arm_sve_sme_incl.td
new file mode 100644
index 000000000000..9a6ea9898ef7
--- /dev/null
+++ b/contrib/llvm-project/clang/include/clang/Basic/arm_sve_sme_incl.td
@@ -0,0 +1,295 @@
+//===--- arm_sve_sme_incl.td - ARM SVE/SME compiler interface -------------===//
+//
+// 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 common properites of TableGen definitions use for both
+// SVE and SME intrinsics.
+//
+// https://developer.arm.com/architectures/system-architectures/software-standards/acle
+//
+//===----------------------------------------------------------------------===//
+
+//===----------------------------------------------------------------------===//
+// Instruction definitions
+//===----------------------------------------------------------------------===//
+// Every intrinsic subclasses "Inst". An intrinsic has a name, a prototype and
+// a sequence of typespecs.
+//
+// The name is the base name of the intrinsic, for example "svld1". This is
+// then mangled by the tblgen backend to add type information ("svld1_s16").
+//
+// A typespec is a sequence of uppercase characters (modifiers) followed by one
+// lowercase character. A typespec encodes a particular "base type" of the
+// intrinsic.
+//
+// An example typespec is "Us" - unsigned short - svuint16_t. The available
+// typespec codes are given below.
+//
+// The string given to an Inst class is a sequence of typespecs. The intrinsic
+// is instantiated for every typespec in the sequence. For example "sdUsUd".
+//
+// The prototype is a string that defines the return type of the intrinsic
+// and the type of each argument. The return type and every argument gets a
+// "modifier" that can change in some way the "base type" of the intrinsic.
+//
+// The modifier 'd' means "default" and does not modify the base type in any
+// way. The available modifiers are given below.
+//
+// Typespecs
+// ---------
+// c: char
+// s: short
+// i: int
+// l: long
+// q: int128_t
+// f: float
+// h: half-float
+// d: double
+// b: bfloat
+
+// Typespec modifiers
+// ------------------
+// P: boolean
+// U: unsigned
+// Q: svcount
+
+// Prototype modifiers
+// -------------------
+// prototype: return (arg, arg, ...)
+//
+// 2,3,4: array of vectors
+// .: indicator for multi-vector modifier that will follow (e.g. 2.x)
+// v: void
+// x: vector of signed integers
+// u: vector of unsigned integers
+// d: default
+// c: const pointer type
+// P: predicate type
+// s: scalar of element type
+// a: scalar of element type (splat to vector type)
+// R: scalar of 1/2 width element type (splat to vector type)
+// r: scalar of 1/4 width element type (splat to vector type)
+// @: unsigned scalar of 1/4 width element type (splat to vector type)
+// e: 1/2 width unsigned elements, 2x element count
+// b: 1/4 width unsigned elements, 4x element count
+// h: 1/2 width elements, 2x element count
+// q: 1/4 width elements, 4x element count
+// o: 4x width elements, 1/4 element count
+//
+// w: vector of element type promoted to 64bits, vector maintains
+// signedness of its element type.
+// f: element type promoted to uint64_t (splat to vector type)
+// j: element type promoted to 64bits (splat to vector type)
+// K: element type bitcast to a signed integer (splat to vector type)
+// L: element type bitcast to an unsigned integer (splat to vector type)
+//
+// i: constant uint64_t
+// k: int32_t
+// l: int64_t
+// m: uint32_t
+// n: uint64_t
+
+// [: svuint8_t
+// t: svint32_t
+// z: svuint32_t
+// g: svuint64_t
+// O: svfloat16_t
+// M: svfloat32_t
+// N: svfloat64_t
+// $: svbfloat16_t
+
+// J: Prefetch type (sv_prfop)
+
+// %: pointer to void
+
+// A: pointer to int8_t
+// B: pointer to int16_t
+// C: pointer to int32_t
+// D: pointer to int64_t
+
+// E: pointer to uint8_t
+// F: pointer to uint16_t
+// G: pointer to uint32_t
+// H: pointer to uint64_t
+
+// Q: const pointer to void
+
+// S: const pointer to int8_t
+// T: const pointer to int16_t
+// U: const pointer to int32_t
+// V: const pointer to int64_t
+//
+// W: const pointer to uint8_t
+// X: const pointer to uint16_t
+// Y: const pointer to uint32_t
+// Z: const pointer to uint64_t
+
+// Prototype modifiers added for SVE2p1
+// {: 128b vector
+// }: svcount_t
+
+class MergeType<int val, string suffix=""> {
+ int Value = val;
+ string Suffix = suffix;
+}
+def MergeNone : MergeType<0>;
+def MergeAny : MergeType<1, "_x">;
+def MergeOp1 : MergeType<2, "_m">;
+def MergeZero : MergeType<3, "_z">;
+def MergeAnyExp : MergeType<4, "_x">; // Use merged builtin with explicit
+def MergeZeroExp : MergeType<5, "_z">; // generation of its inactive argument.
+
+class EltType<int val> {
+ int Value = val;
+}
+def EltTyInvalid : EltType<0>;
+def EltTyInt8 : EltType<1>;
+def EltTyInt16 : EltType<2>;
+def EltTyInt32 : EltType<3>;
+def EltTyInt64 : EltType<4>;
+def EltTyInt128 : EltType<5>;
+def EltTyFloat16 : EltType<6>;
+def EltTyFloat32 : EltType<7>;
+def EltTyFloat64 : EltType<8>;
+def EltTyBool8 : EltType<9>;
+def EltTyBool16 : EltType<10>;
+def EltTyBool32 : EltType<11>;
+def EltTyBool64 : EltType<12>;
+def EltTyBFloat16 : EltType<13>;
+
+class MemEltType<int val> {
+ int Value = val;
+}
+def MemEltTyDefault : MemEltType<0>;
+def MemEltTyInt8 : MemEltType<1>;
+def MemEltTyInt16 : MemEltType<2>;
+def MemEltTyInt32 : MemEltType<3>;
+def MemEltTyInt64 : MemEltType<4>;
+
+class FlagType<int val> {
+ int Value = val;
+}
+
+// These must be kept in sync with the flags in utils/TableGen/SveEmitter.h
+// and include/clang/Basic/TargetBuiltins.h
+def NoFlags : FlagType<0x00000000>;
+def FirstEltType : FlagType<0x00000001>;
+// : :
+// : :
+def EltTypeMask : FlagType<0x0000000f>;
+def FirstMemEltType : FlagType<0x00000010>;
+// : :
+// : :
+def MemEltTypeMask : FlagType<0x00000070>;
+def FirstMergeTypeMask : FlagType<0x00000080>;
+// : :
+// : :
+def MergeTypeMask : FlagType<0x00000380>;
+def FirstSplatOperand : FlagType<0x00000400>;
+// : :
+// These flags are used to specify which scalar operand
+// needs to be duplicated/splatted into a vector.
+// : :
+def SplatOperandMask : FlagType<0x00001C00>;
+def IsLoad : FlagType<0x00002000>;
+def IsStore : FlagType<0x00004000>;
+def IsGatherLoad : FlagType<0x00008000>;
+def IsScatterStore : FlagType<0x00010000>;
+def IsStructLoad : FlagType<0x00020000>;
+def IsStructStore : FlagType<0x00040000>;
+def IsZExtReturn : FlagType<0x00080000>; // Return value is sign-extend by default
+def IsOverloadNone : FlagType<0x00100000>; // Intrinsic does not take any overloaded types.
+def IsOverloadWhileOrMultiVecCvt : FlagType<0x00200000>; // Use {default type, typeof(operand1)} as overloaded types.
+def IsOverloadWhileRW : FlagType<0x00400000>; // Use {pred(default type), typeof(operand0)} as overloaded types.
+def IsOverloadCvt : FlagType<0x00800000>; // Use {typeof(operand0), typeof(last operand)} as overloaded types.
+def OverloadKindMask : FlagType<0x00E00000>; // When the masked values are all '0', the default type is used as overload type.
+def IsByteIndexed : FlagType<0x01000000>;
+def IsAppendSVALL : FlagType<0x02000000>; // Appends SV_ALL as the last operand.
+def IsInsertOp1SVALL : FlagType<0x04000000>; // Inserts SV_ALL as the second operand.
+def IsPrefetch : FlagType<0x08000000>; // Contiguous prefetches.
+def IsGatherPrefetch : FlagType<0x10000000>;
+def ReverseCompare : FlagType<0x20000000>; // Compare operands must be swapped.
+def ReverseUSDOT : FlagType<0x40000000>; // Unsigned/signed operands must be swapped.
+def IsUndef : FlagType<0x80000000>; // Codegen `undef` of given type.
+def IsTupleCreate : FlagType<0x100000000>;
+def IsTupleGet : FlagType<0x200000000>;
+def IsTupleSet : FlagType<0x400000000>;
+def ReverseMergeAnyBinOp : FlagType<0x800000000>; // e.g. Implement SUBR_X using SUB_X.
+def ReverseMergeAnyAccOp : FlagType<0x1000000000>; // e.g. Implement MSB_X using MLS_X.
+def IsStreaming : FlagType<0x2000000000>;
+def IsStreamingCompatible : FlagType<0x4000000000>;
+def IsReadZA : FlagType<0x8000000000>;
+def IsWriteZA : FlagType<0x10000000000>;
+def IsReductionQV : FlagType<0x20000000000>;
+def IsStreamingOrSVE2p1 : FlagType<0x40000000000>; // Use for intrinsics that are common between sme/sme2 and sve2p1.
+def IsInZA : FlagType<0x80000000000>;
+def IsOutZA : FlagType<0x100000000000>;
+def IsInOutZA : FlagType<0x200000000000>;
+def IsInZT0 : FlagType<0x400000000000>;
+def IsOutZT0 : FlagType<0x800000000000>;
+def IsInOutZT0 : FlagType<0x1000000000000>;
+
+// These must be kept in sync with the flags in include/clang/Basic/TargetBuiltins.h
+class ImmCheckType<int val> {
+ int Value = val;
+}
+def ImmCheck0_31 : ImmCheckType<0>; // 0..31 (used for e.g. predicate patterns)
+def ImmCheck1_16 : ImmCheckType<1>; // 1..16
+def ImmCheckExtract : ImmCheckType<2>; // 0..(2048/sizeinbits(elt) - 1)
+def ImmCheckShiftRight : ImmCheckType<3>; // 1..sizeinbits(elt)
+def ImmCheckShiftRightNarrow : ImmCheckType<4>; // 1..sizeinbits(elt)/2
+def ImmCheckShiftLeft : ImmCheckType<5>; // 0..(sizeinbits(elt) - 1)
+def ImmCheck0_7 : ImmCheckType<6>; // 0..7
+def ImmCheckLaneIndex : ImmCheckType<7>; // 0..(128/(1*sizeinbits(elt)) - 1)
+def ImmCheckLaneIndexCompRotate : ImmCheckType<8>; // 0..(128/(2*sizeinbits(elt)) - 1)
+def ImmCheckLaneIndexDot : ImmCheckType<9>; // 0..(128/(4*sizeinbits(elt)) - 1)
+def ImmCheckComplexRot90_270 : ImmCheckType<10>; // [90,270]
+def ImmCheckComplexRotAll90 : ImmCheckType<11>; // [0, 90, 180,270]
+def ImmCheck0_13 : ImmCheckType<12>; // 0..13
+def ImmCheck0_1 : ImmCheckType<13>; // 0..1
+def ImmCheck0_2 : ImmCheckType<14>; // 0..2
+def ImmCheck0_3 : ImmCheckType<15>; // 0..3
+def ImmCheck0_0 : ImmCheckType<16>; // 0..0
+def ImmCheck0_15 : ImmCheckType<17>; // 0..15
+def ImmCheck0_255 : ImmCheckType<18>; // 0..255
+def ImmCheck2_4_Mul2 : ImmCheckType<19>; // 2, 4
+def ImmCheck1_1 : ImmCheckType<20>; // 1..1
+def ImmCheck1_3 : ImmCheckType<21>; // 1..3
+def ImmCheck1_7 : ImmCheckType<22>; // 1..7
+
+class ImmCheck<int arg, ImmCheckType kind, int eltSizeArg = -1> {
+ int Arg = arg;
+ int EltSizeArg = eltSizeArg;
+ ImmCheckType Kind = kind;
+}
+
+class Inst<string n, string p, string t, MergeType mt, string i,
+ list<FlagType> ft, list<ImmCheck> ch, MemEltType met = MemEltTyDefault> {
+ string Name = n;
+ string Prototype = p;
+ string Types = t;
+ string TargetGuard = "sve";
+ int Merge = mt.Value;
+ string MergeSuffix = mt.Suffix;
+ string LLVMIntrinsic = i;
+ list<FlagType> Flags = ft;
+ list<ImmCheck> ImmChecks = ch;
+ int MemEltType = met.Value;
+}
+
+// SInst: Instruction with signed/unsigned suffix (e.g., "s8", "u8")
+class SInst<string n, string p, string t, MergeType mt, string i = "",
+ list<FlagType> ft = [], list<ImmCheck> ch = []>
+ : Inst<n, p, t, mt, i, ft, ch, MemEltTyDefault> {
+}
+
+// MInst: Instructions which access memory
+class MInst<string n, string p, string t, list<FlagType> f,
+ MemEltType met = MemEltTyDefault, string i = "",
+ list<ImmCheck> ch = []>
+ : Inst<n, p, t, MergeNone, i, f, ch, met> {
+}
diff --git a/contrib/llvm-project/clang/include/clang/Basic/riscv_sifive_vector.td b/contrib/llvm-project/clang/include/clang/Basic/riscv_sifive_vector.td
new file mode 100644
index 000000000000..ef5114d6105e
--- /dev/null
+++ b/contrib/llvm-project/clang/include/clang/Basic/riscv_sifive_vector.td
@@ -0,0 +1,211 @@
+//==--- riscv_sifive_vector.td - RISC-V SiFive VCIX function list ---------===//
+//
+// 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 the builtins for RISC-V SiFive VCIX. See:
+//
+// https://sifive.cdn.prismic.io/sifive/c3829e36-8552-41f0-a841-79945784241b_vcix-spec-software.pdf
+//
+//===----------------------------------------------------------------------===//
+
+include "riscv_vector_common.td"
+
+//===----------------------------------------------------------------------===//
+// Instruction definitions
+//===----------------------------------------------------------------------===//
+
+class VCIXSuffix<string range> {
+ list<string> suffix = !cond(!eq(range, "c"): ["8mf8", "8mf4", "8mf2", "8m1", "8m2", "8m4", "8m8"],
+ !eq(range, "s"): ["16mf4", "16mf2", "16m1", "16m2", "16m4", "16m8"],
+ !eq(range, "i"): ["32mf2", "32m1", "32m2", "32m4", "32m8"],
+ !eq(range, "l"): ["64m1", "64m2", "64m4", "64m8"]);
+}
+
+class VCIXBuiltinSet<string name, string IR_name, string suffix,
+ string prototype, string type_range,
+ list<int> intrinsic_types>
+ : RVVBuiltin<suffix, prototype, type_range> {
+ let Name = name;
+ let OverloadedName = name;
+ let IRName = IR_name;
+ let HasMasked = false;
+ let IntrinsicTypes = intrinsic_types;
+}
+
+multiclass VCIXBuiltinSet<string name, string IR_name, string suffix,
+ string prototype, string type_range,
+ list<int> intrinsic_types> {
+ if !find(prototype, "0") then {
+ def : VCIXBuiltinSet<name, IR_name, suffix, prototype, type_range, intrinsic_types>;
+ }
+ def : VCIXBuiltinSet<name # "_se", IR_name # "_se", suffix, prototype, type_range, intrinsic_types>;
+}
+
+multiclass RVVVCIXBuiltinSet<list<string> range, string prototype,
+ list<int> intrinsic_types, bit UseGPR> {
+ foreach r = range in
+ let RequiredFeatures = !if(!and(UseGPR, !eq(r, "l")),
+ ["Xsfvcp", "RV64"], ["Xsfvcp"]) in
+ defm : VCIXBuiltinSet<NAME, NAME, "Uv", prototype, r, intrinsic_types>;
+}
+
+multiclass RVVVCIXBuiltinSetWVType<list<string> range, string prototype,
+ list<int> intrinsic_types, bit UseGPR> {
+ foreach r = range in
+ let RequiredFeatures = !if(!and(UseGPR, !eq(r, "l")),
+ ["Xsfvcp", "RV64"], ["Xsfvcp"]) in
+ // These intrinsics don't have any vector types in the output and inputs,
+ // but we still need to add vetvli for them. So we encode different
+ // VTYPE into the intrinsic names, and then will know which vsetvli is
+ // correct.
+ foreach s = VCIXSuffix<r>.suffix in
+ // Since we already encode the Vtype into the name, so just set
+ // Log2LMUL to zero. Otherwise the RISCVVEmitter will expand
+ // lots of redundant intrinsic but have same names.
+ let Log2LMUL = [0] in
+ def : VCIXBuiltinSet<NAME # "_u" # s, NAME # "_e" # s,
+ "", prototype, r, intrinsic_types>;
+}
+
+let SupportOverloading = false in {
+ defm sf_vc_x_se : RVVVCIXBuiltinSetWVType<["c", "s", "i", "l"], "0KzKzKzUe", [0, 3], UseGPR=1>;
+ defm sf_vc_i_se : RVVVCIXBuiltinSetWVType<["c", "s", "i", "l"], "0KzKzKzKz", [2, 3], UseGPR=0>;
+ defm sf_vc_xv : RVVVCIXBuiltinSet<["csi", "l"], "0KzKzUvUe", [0, 2, 3], UseGPR=1>;
+ defm sf_vc_iv : RVVVCIXBuiltinSet<["csi", "l"], "0KzKzUvKz", [0, 2, 3], UseGPR=0>;
+ defm sf_vc_vv : RVVVCIXBuiltinSet<["csi", "l"], "0KzKzUvUv", [0, 2, 3], UseGPR=0>;
+ defm sf_vc_fv : RVVVCIXBuiltinSet<["si", "l"], "0KzKzUvFe", [0, 2, 3], UseGPR=0>;
+ defm sf_vc_xvv : RVVVCIXBuiltinSet<["csi", "l"], "0KzUvUvUe", [0, 1, 2, 3], UseGPR=1>;
+ defm sf_vc_ivv : RVVVCIXBuiltinSet<["csi", "l"], "0KzUvUvKz", [0, 1, 2, 3], UseGPR=0>;
+ defm sf_vc_vvv : RVVVCIXBuiltinSet<["csi", "l"], "0KzUvUvUv", [0, 1, 2, 3], UseGPR=0>;
+ defm sf_vc_fvv : RVVVCIXBuiltinSet<["si", "l"], "0KzUvUvFe", [0, 1, 2, 3], UseGPR=0>;
+ defm sf_vc_v_x : RVVVCIXBuiltinSet<["csi", "l"], "UvKzKzUe", [-1, 1, 2], UseGPR=1>;
+ defm sf_vc_v_i : RVVVCIXBuiltinSet<["csi", "l"], "UvKzKzKz", [-1, 1, 2], UseGPR=0>;
+ defm sf_vc_v_xv : RVVVCIXBuiltinSet<["csi", "l"], "UvKzUvUe", [-1, 0, 1, 2], UseGPR=1>;
+ defm sf_vc_v_iv : RVVVCIXBuiltinSet<["csi", "l"], "UvKzUvKz", [-1, 0, 1, 2], UseGPR=0>;
+ defm sf_vc_v_vv : RVVVCIXBuiltinSet<["csi", "l"], "UvKzUvUv", [-1, 0, 1, 2], UseGPR=0>;
+ defm sf_vc_v_fv : RVVVCIXBuiltinSet<["si", "l"], "UvKzUvFe", [-1, 0, 1, 2], UseGPR=0>;
+ defm sf_vc_v_xvv : RVVVCIXBuiltinSet<["csi", "l"], "UvKzUvUvUe", [-1, 0, 1, 2, 3], UseGPR=1>;
+ defm sf_vc_v_ivv : RVVVCIXBuiltinSet<["csi", "l"], "UvKzUvUvKz", [-1, 0, 1, 2, 3], UseGPR=0>;
+ defm sf_vc_v_vvv : RVVVCIXBuiltinSet<["csi", "l"], "UvKzUvUvUv", [-1, 0, 1, 2, 3], UseGPR=0>;
+ defm sf_vc_v_fvv : RVVVCIXBuiltinSet<["si", "l"], "UvKzUvUvFe", [-1, 0, 1, 2, 3], UseGPR=0>;
+ let Log2LMUL = [-3, -2, -1, 0, 1, 2] in {
+ defm sf_vc_xvw : RVVVCIXBuiltinSet<["csi"], "0KzUwUvUe", [0, 1, 2, 3], UseGPR=1>;
+ defm sf_vc_ivw : RVVVCIXBuiltinSet<["csi"], "0KzUwUvKz", [0, 1, 2, 3], UseGPR=0>;
+ defm sf_vc_vvw : RVVVCIXBuiltinSet<["csi"], "0KzUwUvUv", [0, 1, 2, 3], UseGPR=0>;
+ defm sf_vc_fvw : RVVVCIXBuiltinSet<["si"], "0KzUwUvFe", [0, 1, 2, 3], UseGPR=0>;
+ defm sf_vc_v_xvw : RVVVCIXBuiltinSet<["csi"], "UwKzUwUvUe", [-1, 0, 1, 2, 3], UseGPR=1>;
+ defm sf_vc_v_ivw : RVVVCIXBuiltinSet<["csi"], "UwKzUwUvKz", [-1, 0, 1, 2, 3], UseGPR=0>;
+ defm sf_vc_v_vvw : RVVVCIXBuiltinSet<["csi"], "UwKzUwUvUv", [-1, 0, 1, 2, 3], UseGPR=0>;
+ defm sf_vc_v_fvw : RVVVCIXBuiltinSet<["si"], "UwKzUwUvFe", [-1, 0, 1, 2, 3], UseGPR=0>;
+ }
+}
+
+multiclass RVVVFWMACCBuiltinSet<list<list<string>> suffixes_prototypes> {
+ let OverloadedName = NAME,
+ Name = NAME,
+ HasMasked = false,
+ Log2LMUL = [-2, -1, 0, 1, 2] in
+ defm NAME : RVVOutOp1Op2BuiltinSet<NAME, "y", suffixes_prototypes>;
+}
+
+multiclass RVVVQMACCDODBuiltinSet<list<list<string>> suffixes_prototypes> {
+ let OverloadedName = NAME,
+ Name = NAME,
+ HasMasked = false,
+ Log2LMUL = [0, 1, 2, 3] in
+ defm NAME : RVVOutOp1Op2BuiltinSet<NAME, "i", suffixes_prototypes>;
+}
+
+multiclass RVVVQMACCQOQBuiltinSet<list<list<string>> suffixes_prototypes> {
+ let OverloadedName = NAME,
+ Name = NAME,
+ HasMasked = false,
+ Log2LMUL = [-1, 0, 1, 2] in
+ defm NAME : RVVOutOp1Op2BuiltinSet<NAME, "s", suffixes_prototypes>;
+}
+
+multiclass RVVVFNRCLIPBuiltinSet<string suffix, string prototype, string type_range> {
+ let Log2LMUL = [-3, -2, -1, 0, 1, 2],
+ Name = NAME,
+ IRName = NAME,
+ MaskedIRName = NAME # "_mask" in
+ def : RVVConvBuiltin<suffix, prototype, type_range, NAME>;
+}
+
+let UnMaskedPolicyScheme = HasPolicyOperand in
+ let RequiredFeatures = ["Xsfvqmaccdod"] in {
+ defm sf_vqmaccu_2x8x2 : RVVVQMACCDODBuiltinSet<[["", "v", "vv(FixedSEW:8)SUv(FixedSEW:8)Uv"]]>;
+ defm sf_vqmacc_2x8x2 : RVVVQMACCDODBuiltinSet<[["", "v", "vv(FixedSEW:8)Sv(FixedSEW:8)v"]]>;
+ defm sf_vqmaccus_2x8x2 : RVVVQMACCDODBuiltinSet<[["", "v", "vv(FixedSEW:8)SUv(FixedSEW:8)v"]]>;
+ defm sf_vqmaccsu_2x8x2 : RVVVQMACCDODBuiltinSet<[["", "v", "vv(FixedSEW:8)Sv(FixedSEW:8)Uv"]]>;
+ }
+
+let UnMaskedPolicyScheme = HasPolicyOperand in
+ let RequiredFeatures = ["Xsfvqmaccqoq"] in {
+ defm sf_vqmaccu_4x8x4 : RVVVQMACCQOQBuiltinSet<[["", "w", "ww(FixedSEW:8)SUv(FixedSEW:8)Uv"]]>;
+ defm sf_vqmacc_4x8x4 : RVVVQMACCQOQBuiltinSet<[["", "w", "ww(FixedSEW:8)Sv(FixedSEW:8)v"]]>;
+ defm sf_vqmaccus_4x8x4 : RVVVQMACCQOQBuiltinSet<[["", "w", "ww(FixedSEW:8)SUv(FixedSEW:8)v"]]>;
+ defm sf_vqmaccsu_4x8x4 : RVVVQMACCQOQBuiltinSet<[["", "w", "ww(FixedSEW:8)Sv(FixedSEW:8)Uv"]]>;
+ }
+
+let UnMaskedPolicyScheme = HasPolicyOperand in
+ let RequiredFeatures = ["Xsfvfwmaccqqq"] in
+ defm sf_vfwmacc_4x4x4 : RVVVFWMACCBuiltinSet<[["", "Fw", "FwFwSvv"]]>;
+
+let UnMaskedPolicyScheme = HasPassthruOperand, RequiredFeatures = ["Xsfvfnrclipxfqf"] in {
+let ManualCodegen = [{
+ {
+ // LLVM intrinsic
+ // Unmasked: (passthru, vector_in, scalar_in, frm, vl)
+ // Masked: (passthru, vector_in, scalar_in, mask, frm, vl, policy)
+
+ SmallVector<llvm::Value*, 7> Operands;
+ bool HasMaskedOff = !(
+ (IsMasked && (PolicyAttrs & RVV_VTA) && (PolicyAttrs & RVV_VMA)) ||
+ (!IsMasked && PolicyAttrs & RVV_VTA));
+ bool HasRoundModeOp = IsMasked ?
+ (HasMaskedOff ? Ops.size() == 6 : Ops.size() == 5) :
+ (HasMaskedOff ? Ops.size() == 5 : Ops.size() == 4);
+
+ unsigned Offset = IsMasked ?
+ (HasMaskedOff ? 2 : 1) : (HasMaskedOff ? 1 : 0);
+
+ if (!HasMaskedOff)
+ Operands.push_back(llvm::PoisonValue::get(ResultType));
+ else
+ Operands.push_back(Ops[IsMasked ? 1 : 0]);
+
+ Operands.push_back(Ops[Offset]); // op0
+ Operands.push_back(Ops[Offset + 1]); // op1
+
+ if (IsMasked)
+ Operands.push_back(Ops[0]); // mask
+
+ if (HasRoundModeOp) {
+ Operands.push_back(Ops[Offset + 2]); // frm
+ Operands.push_back(Ops[Offset + 3]); // vl
+ } else {
+ Operands.push_back(ConstantInt::get(Ops[Offset + 2]->getType(), 7)); // frm
+ Operands.push_back(Ops[Offset + 2]); // vl
+ }
+
+ if (IsMasked)
+ Operands.push_back(ConstantInt::get(Ops.back()->getType(), PolicyAttrs));
+
+ IntrinsicTypes = {ResultType, Ops[Offset]->getType(), Operands.back()->getType()};
+ llvm::Function *F = CGM.getIntrinsic(ID, IntrinsicTypes);
+ return Builder.CreateCall(F, Operands, "");
+ }
+}] in {
+ let HasFRMRoundModeOp = true in {
+ defm sf_vfnrclip_x_f_qf : RVVVFNRCLIPBuiltinSet<"v", "vFqfu", "c">;
+ defm sf_vfnrclip_xu_f_qf : RVVVFNRCLIPBuiltinSet<"Uv", "UvFqfu", "c">;
+ }
+ defm sf_vfnrclip_x_f_qf : RVVVFNRCLIPBuiltinSet<"v", "vFqf", "c">;
+ defm sf_vfnrclip_xu_f_qf : RVVVFNRCLIPBuiltinSet<"Uv", "UvFqf", "c">;
+}
+}
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 48c032dd1422..8bde08105250 100644
--- a/contrib/llvm-project/clang/include/clang/Basic/riscv_vector.td
+++ b/contrib/llvm-project/clang/include/clang/Basic/riscv_vector.td
@@ -12,539 +12,7 @@
//
//===----------------------------------------------------------------------===//
-//===----------------------------------------------------------------------===//
-// Instruction definitions
-//===----------------------------------------------------------------------===//
-// Each record of the class RVVBuiltin defines a collection of builtins (i.e.
-// "def vadd : RVVBuiltin" will be used to define things like "vadd_vv_i32m1",
-// "vadd_vv_i32m2", etc).
-//
-// The elements of this collection are defined by an instantiation process the
-// range of which is specified by the cross product of the LMUL attribute and
-// every element in the attribute TypeRange. By default builtins have LMUL = [1,
-// 2, 4, 8, 1/2, 1/4, 1/8] so the process is repeated 7 times. In tablegen we
-// use the Log2LMUL [0, 1, 2, 3, -1, -2, -3] to represent the LMUL.
-//
-// LMUL represents the fact that the types of values used by that builtin are
-// values generated by instructions that are executed under that LMUL. However,
-// this does not mean the builtin is necessarily lowered into an instruction
-// that executes under the specified LMUL. An example where this happens are
-// loads and stores of masks. A mask like `vbool8_t` can be generated, for
-// instance, by comparing two `__rvv_int8m1_t` (this is LMUL=1) or comparing two
-// `__rvv_int16m2_t` (this is LMUL=2). The actual load or store, however, will
-// be performed under LMUL=1 because mask registers are not grouped.
-//
-// TypeRange is a non-empty sequence of basic types:
-//
-// c: int8_t (i8)
-// s: int16_t (i16)
-// i: int32_t (i32)
-// l: int64_t (i64)
-// x: float16_t (half)
-// f: float32_t (float)
-// d: float64_t (double)
-//
-// This way, given an LMUL, a record with a TypeRange "sil" will cause the
-// definition of 3 builtins. Each type "t" in the TypeRange (in this example
-// they are int16_t, int32_t, int64_t) is used as a parameter that drives the
-// definition of that particular builtin (for the given LMUL).
-//
-// During the instantiation, types can be transformed or modified using type
-// transformers. Given a type "t" the following primitive type transformers can
-// be applied to it to yield another type.
-//
-// e: type of "t" as is (identity)
-// v: computes a vector type whose element type is "t" for the current LMUL
-// w: computes a vector type identical to what 'v' computes except for the
-// element type which is twice as wide as the element type of 'v'
-// q: computes a vector type identical to what 'v' computes except for the
-// element type which is four times as wide as the element type of 'v'
-// o: computes a vector type identical to what 'v' computes except for the
-// element type which is eight times as wide as the element type of 'v'
-// m: computes a vector type identical to what 'v' computes except for the
-// element type which is bool
-// 0: void type, ignores "t"
-// z: size_t, ignores "t"
-// t: ptrdiff_t, ignores "t"
-// u: unsigned long, ignores "t"
-// l: long, ignores "t"
-//
-// So for instance if t is "i", i.e. int, then "e" will yield int again. "v"
-// will yield an RVV vector type (assume LMUL=1), so __rvv_int32m1_t.
-// Accordingly "w" would yield __rvv_int64m2_t.
-//
-// A type transformer can be prefixed by other non-primitive type transformers.
-//
-// P: constructs a pointer to the current type
-// C: adds const to the type
-// K: requires the integer type to be a constant expression
-// U: given an integer type or vector type, computes its unsigned variant
-// I: given a vector type, compute the vector type with integer type
-// elements of the same width
-// F: given a vector type, compute the vector type with floating-point type
-// elements of the same width
-// S: given a vector type, computes its equivalent one for LMUL=1. This is a
-// no-op if the vector was already LMUL=1
-// (Log2EEW:Value): Log2EEW value could be 3/4/5/6 (8/16/32/64), given a
-// vector type (SEW and LMUL) and EEW (8/16/32/64), computes its
-// equivalent integer vector type with EEW and corresponding ELMUL (elmul =
-// (eew/sew) * lmul). For example, vector type is __rvv_float16m4
-// (SEW=16, LMUL=4) and Log2EEW is 3 (EEW=8), and then equivalent vector
-// type is __rvv_uint8m2_t (elmul=(8/16)*4 = 2). Ignore to define a new
-// builtins if its equivalent type has illegal lmul.
-// (FixedSEW:Value): Given a vector type (SEW and LMUL), and computes another
-// vector type which only changed SEW as given value. Ignore to define a new
-// builtin if its equivalent type has illegal lmul or the SEW does not changed.
-// (SFixedLog2LMUL:Value): Smaller Fixed Log2LMUL. Given a vector type (SEW
-// and LMUL), and computes another vector type which only changed LMUL as
-// given value. The new LMUL should be smaller than the old one. Ignore to
-// define a new builtin if its equivalent type has illegal lmul.
-// (LFixedLog2LMUL:Value): Larger Fixed Log2LMUL. Given a vector type (SEW
-// and LMUL), and computes another vector type which only changed LMUL as
-// given value. The new LMUL should be larger than the old one. Ignore to
-// define a new builtin if its equivalent type has illegal lmul.
-//
-// Following with the example above, if t is "i", then "Ue" will yield unsigned
-// int and "Fv" will yield __rvv_float32m1_t (again assuming LMUL=1), Fw would
-// yield __rvv_float64m2_t, etc.
-//
-// Each builtin is then defined by applying each type in TypeRange against the
-// sequence of type transformers described in Suffix and Prototype.
-//
-// The name of the builtin is defined by the Name attribute (which defaults to
-// the name of the class) appended (separated with an underscore) the Suffix
-// attribute. For instance with Name="foo", Suffix = "v" and TypeRange = "il",
-// the builtin generated will be __builtin_rvv_foo_i32m1 and
-// __builtin_rvv_foo_i64m1 (under LMUL=1). If Suffix contains more than one
-// type transformer (say "vv") each of the types is separated with an
-// underscore as in "__builtin_rvv_foo_i32m1_i32m1".
-//
-// The C/C++ prototype of the builtin is defined by the Prototype attribute.
-// Prototype is a non-empty sequence of type transformers, the first of which
-// is the return type of the builtin and the rest are the parameters of the
-// builtin, in order. For instance if Prototype is "wvv" and TypeRange is "si"
-// a first builtin will have type
-// __rvv_int32m2_t (__rvv_int16m1_t, __rvv_int16m1_t) and the second builtin
-// will have type __rvv_int64m2_t (__rvv_int32m1_t, __rvv_int32m1_t) (again
-// under LMUL=1).
-//
-// There are a number of attributes that are used to constraint the number and
-// shape of the builtins generated. Refer to the comments below for them.
-class RVVBuiltin<string suffix, string prototype, string type_range,
- string mangled_suffix = ""> {
- // Base name that will be prepended in __builtin_rvv_ and appended the
- // computed Suffix.
- string Name = NAME;
-
- // If not empty, each instantiated builtin will have this appended after an
- // underscore (_). It is instantiated like Prototype.
- string Suffix = suffix;
-
- // If empty, default MangledName is sub string of `Name` which end of first
- // '_'. For example, the default mangled name is `vadd` for Name `vadd_vv`.
- // It's used for describe some special naming cases.
- string MangledName = "";
-
- // If not empty, each MangledName will have this appended after an
- // underscore (_). It is instantiated like Prototype.
- string MangledSuffix = mangled_suffix;
-
- // The different variants of the builtin, parameterised with a type.
- string TypeRange = type_range;
-
- // We use each type described in TypeRange and LMUL with prototype to
- // instantiate a specific element of the set of builtins being defined.
- // Prototype attribute defines the C/C++ prototype of the builtin. It is a
- // non-empty sequence of type transformers, the first of which is the return
- // type of the builtin and the rest are the parameters of the builtin, in
- // order. For instance if Prototype is "wvv", TypeRange is "si" and LMUL=1, a
- // first builtin will have type
- // __rvv_int32m2_t (__rvv_int16m1_t, __rvv_int16m1_t), and the second builtin
- // will have type __rvv_int64m2_t (__rvv_int32m1_t, __rvv_int32m1_t).
- string Prototype = prototype;
-
- // This builtin has a masked form.
- bit HasMask = true;
-
- // If HasMask, this flag states that this builtin has a maskedoff operand. It
- // is always the first operand in builtin and IR intrinsic.
- bit HasMaskedOffOperand = true;
-
- // This builtin has a granted vector length parameter in the last position.
- bit HasVL = true;
-
- // This builtin supports non-masked function overloading api.
- // All masked operations support overloading api.
- bit HasNoMaskedOverloaded = true;
-
- // Reads or writes "memory" or has other side-effects.
- bit HasSideEffects = false;
-
- // This builtin is valid for the given Log2LMULs.
- list<int> Log2LMUL = [0, 1, 2, 3, -1, -2, -3];
-
- // Manual code in clang codegen riscv_vector_builtin_cg.inc
- code ManualCodegen = [{}];
- code ManualCodegenMask = [{}];
-
- // When emit the automatic clang codegen, it describes what types we have to use
- // to obtain the specific LLVM intrinsic. -1 means the return type, otherwise,
- // k >= 0 meaning the k-th operand (counting from zero) of the codegen'd
- // parameter of the unmasked version. k can't be the mask operand's position.
- list<int> IntrinsicTypes = [];
-
- // If these names are not empty, this is the ID of the LLVM intrinsic
- // we want to lower to.
- string IRName = NAME;
-
- // If HasMask, this is the ID of the LLVM intrinsic we want to lower to.
- string IRNameMask = NAME #"_mask";
-
- // If non empty, this is the code emitted in the header, otherwise
- // an automatic definition in header is emitted.
- string HeaderCode = "";
-
- // Sub extension of vector spec. Currently only support Zvamo or Zvlsseg.
- string RequiredExtension = "";
-
- // Number of fields for Zvlsseg.
- int NF = 1;
-}
-
-//===----------------------------------------------------------------------===//
-// Basic classes with automatic codegen.
-//===----------------------------------------------------------------------===//
-
-class RVVOutBuiltin<string suffix, string prototype, string type_range>
- : RVVBuiltin<suffix, prototype, type_range> {
- let IntrinsicTypes = [-1];
-}
-
-class RVVOp0Builtin<string suffix, string prototype, string type_range>
- : RVVBuiltin<suffix, prototype, type_range> {
- let IntrinsicTypes = [0];
-}
-
-class RVVOutOp1Builtin<string suffix, string prototype, string type_range>
- : RVVBuiltin<suffix, prototype, type_range> {
- let IntrinsicTypes = [-1, 1];
-}
-
-class RVVOutOp0Op1Builtin<string suffix, string prototype, string type_range>
- : RVVBuiltin<suffix, prototype, type_range> {
- let IntrinsicTypes = [-1, 0, 1];
-}
-
-multiclass RVVBuiltinSet<string intrinsic_name, string type_range,
- list<list<string>> suffixes_prototypes,
- list<int> intrinsic_types> {
- let IRName = intrinsic_name, IRNameMask = intrinsic_name # "_mask",
- IntrinsicTypes = intrinsic_types in {
- foreach s_p = suffixes_prototypes in {
- let Name = NAME # "_" # s_p[0] in {
- defvar suffix = s_p[1];
- defvar prototype = s_p[2];
- def : RVVBuiltin<suffix, prototype, type_range>;
- }
- }
- }
-}
-
-// IntrinsicTypes is output, op0, op1 [-1, 0, 1]
-multiclass RVVOutOp0Op1BuiltinSet<string intrinsic_name, string type_range,
- list<list<string>> suffixes_prototypes>
- : RVVBuiltinSet<intrinsic_name, type_range, suffixes_prototypes,
- [-1, 0, 1]>;
-
-multiclass RVVOutBuiltinSet<string intrinsic_name, string type_range,
- list<list<string>> suffixes_prototypes>
- : RVVBuiltinSet<intrinsic_name, type_range, suffixes_prototypes, [-1]>;
-
-multiclass RVVOp0BuiltinSet<string intrinsic_name, string type_range,
- list<list<string>> suffixes_prototypes>
- : RVVBuiltinSet<intrinsic_name, type_range, suffixes_prototypes, [0]>;
-
-// IntrinsicTypes is output, op1 [-1, 1]
-multiclass RVVOutOp1BuiltinSet<string intrinsic_name, string type_range,
- list<list<string>> suffixes_prototypes>
- : RVVBuiltinSet<intrinsic_name, type_range, suffixes_prototypes, [-1, 1]>;
-
-multiclass RVVOp0Op1BuiltinSet<string intrinsic_name, string type_range,
- list<list<string>> suffixes_prototypes>
- : RVVBuiltinSet<intrinsic_name, type_range, suffixes_prototypes, [0, 1]>;
-
-multiclass RVVOutOp1Op2BuiltinSet<string intrinsic_name, string type_range,
- list<list<string>> suffixes_prototypes>
- : RVVBuiltinSet<intrinsic_name, type_range, suffixes_prototypes, [-1, 1, 2]>;
-
-multiclass RVVSignedBinBuiltinSet
- : RVVOutOp1BuiltinSet<NAME, "csil",
- [["vv", "v", "vvv"],
- ["vx", "v", "vve"]]>;
-
-multiclass RVVUnsignedBinBuiltinSet
- : RVVOutOp1BuiltinSet<NAME, "csil",
- [["vv", "Uv", "UvUvUv"],
- ["vx", "Uv", "UvUvUe"]]>;
-
-multiclass RVVIntBinBuiltinSet
- : RVVSignedBinBuiltinSet,
- RVVUnsignedBinBuiltinSet;
-
-multiclass RVVSlideOneBuiltinSet
- : RVVOutOp1BuiltinSet<NAME, "csil",
- [["vx", "v", "vve"],
- ["vx", "Uv", "UvUve"]]>;
-
-multiclass RVVSignedShiftBuiltinSet
- : RVVOutOp1BuiltinSet<NAME, "csil",
- [["vv", "v", "vvUv"],
- ["vx", "v", "vvz"]]>;
-
-multiclass RVVUnsignedShiftBuiltinSet
- : RVVOutOp1BuiltinSet<NAME, "csil",
- [["vv", "Uv", "UvUvUv"],
- ["vx", "Uv", "UvUvz"]]>;
-
-multiclass RVVShiftBuiltinSet
- : RVVSignedShiftBuiltinSet,
- RVVUnsignedShiftBuiltinSet;
-
-let Log2LMUL = [-3, -2, -1, 0, 1, 2] in {
- multiclass RVVSignedNShiftBuiltinSet
- : RVVOutOp0Op1BuiltinSet<NAME, "csil",
- [["wv", "v", "vwUv"],
- ["wx", "v", "vwz"]]>;
- multiclass RVVUnsignedNShiftBuiltinSet
- : RVVOutOp0Op1BuiltinSet<NAME, "csil",
- [["wv", "Uv", "UvUwUv"],
- ["wx", "Uv", "UvUwz"]]>;
-}
-
-multiclass RVVCarryinBuiltinSet
- : RVVOutOp1BuiltinSet<NAME, "csil",
- [["vvm", "v", "vvvm"],
- ["vxm", "v", "vvem"],
- ["vvm", "Uv", "UvUvUvm"],
- ["vxm", "Uv", "UvUvUem"]]>;
-
-multiclass RVVCarryOutInBuiltinSet<string intrinsic_name>
- : RVVOp0Op1BuiltinSet<intrinsic_name, "csil",
- [["vvm", "vm", "mvvm"],
- ["vxm", "vm", "mvem"],
- ["vvm", "Uvm", "mUvUvm"],
- ["vxm", "Uvm", "mUvUem"]]>;
-
-multiclass RVVSignedMaskOutBuiltinSet
- : RVVOp0Op1BuiltinSet<NAME, "csil",
- [["vv", "vm", "mvv"],
- ["vx", "vm", "mve"]]>;
-
-multiclass RVVUnsignedMaskOutBuiltinSet
- : RVVOp0Op1BuiltinSet<NAME, "csil",
- [["vv", "Uvm", "mUvUv"],
- ["vx", "Uvm", "mUvUe"]]>;
-
-multiclass RVVIntMaskOutBuiltinSet
- : RVVSignedMaskOutBuiltinSet,
- RVVUnsignedMaskOutBuiltinSet;
-
-class RVVIntExt<string intrinsic_name, string suffix, string prototype,
- string type_range>
- : RVVBuiltin<suffix, prototype, type_range> {
- let IRName = intrinsic_name;
- let IRNameMask = intrinsic_name # "_mask";
- let MangledName = NAME;
- let IntrinsicTypes = [-1, 0];
-}
-
-let HasMaskedOffOperand = false in {
- multiclass RVVIntTerBuiltinSet {
- defm "" : RVVOutOp1BuiltinSet<NAME, "csil",
- [["vv", "v", "vvvv"],
- ["vx", "v", "vvev"],
- ["vv", "Uv", "UvUvUvUv"],
- ["vx", "Uv", "UvUvUeUv"]]>;
- }
- multiclass RVVFloatingTerBuiltinSet {
- defm "" : RVVOutOp1BuiltinSet<NAME, "xfd",
- [["vv", "v", "vvvv"],
- ["vf", "v", "vvev"]]>;
- }
-}
-
-let HasMaskedOffOperand = false, Log2LMUL = [-2, -1, 0, 1, 2] in {
- multiclass RVVFloatingWidenTerBuiltinSet {
- defm "" : RVVOutOp1Op2BuiltinSet<NAME, "xf",
- [["vv", "w", "wwvv"],
- ["vf", "w", "wwev"]]>;
- }
-}
-
-multiclass RVVFloatingBinBuiltinSet
- : RVVOutOp1BuiltinSet<NAME, "xfd",
- [["vv", "v", "vvv"],
- ["vf", "v", "vve"]]>;
-
-multiclass RVVFloatingBinVFBuiltinSet
- : RVVOutOp1BuiltinSet<NAME, "xfd",
- [["vf", "v", "vve"]]>;
-
-multiclass RVVFloatingMaskOutBuiltinSet
- : RVVOp0Op1BuiltinSet<NAME, "xfd",
- [["vv", "vm", "mvv"],
- ["vf", "vm", "mve"]]>;
-
-multiclass RVVFloatingMaskOutVFBuiltinSet
- : RVVOp0Op1BuiltinSet<NAME, "fd",
- [["vf", "vm", "mve"]]>;
-
-class RVVMaskBinBuiltin : RVVOutBuiltin<"m", "mmm", "c"> {
- let Name = NAME # "_mm";
- let HasMask = false;
-}
-
-class RVVMaskUnaryBuiltin : RVVOutBuiltin<"m", "mm", "c"> {
- let Name = NAME # "_m";
-}
-
-class RVVMaskNullaryBuiltin : RVVOutBuiltin<"m", "m", "c"> {
- let Name = NAME # "_m";
- let HasMask = false;
- let HasNoMaskedOverloaded = false;
-}
-
-class RVVMaskOp0Builtin<string prototype> : RVVOp0Builtin<"m", prototype, "c"> {
- let Name = NAME # "_m";
- let HasMaskedOffOperand = false;
-}
-
-let HasMaskedOffOperand = false in {
- multiclass RVVSlideBuiltinSet {
- defm "" : RVVOutBuiltinSet<NAME, "csilxfd",
- [["vx","v", "vvvz"]]>;
- defm "" : RVVOutBuiltinSet<NAME, "csil",
- [["vx","Uv", "UvUvUvz"]]>;
- }
-}
-
-class RVVFloatingUnaryBuiltin<string builtin_suffix, string ir_suffix,
- string prototype>
- : RVVOutBuiltin<ir_suffix, prototype, "xfd"> {
- let Name = NAME # "_" # builtin_suffix;
-}
-
-class RVVFloatingUnaryVVBuiltin : RVVFloatingUnaryBuiltin<"v", "v", "vv">;
-
-class RVVConvBuiltin<string suffix, string prototype, string type_range,
- string mangled_name>
- : RVVBuiltin<suffix, prototype, type_range> {
- let IntrinsicTypes = [-1, 0];
- let MangledName = mangled_name;
-}
-
-class RVVConvToSignedBuiltin<string mangled_name>
- : RVVConvBuiltin<"Iv", "Ivv", "xfd", mangled_name>;
-
-class RVVConvToUnsignedBuiltin<string mangled_name>
- : RVVConvBuiltin<"Uv", "Uvv", "xfd", mangled_name>;
-
-class RVVConvToWidenSignedBuiltin<string mangled_name>
- : RVVConvBuiltin<"Iw", "Iwv", "xf", mangled_name>;
-
-class RVVConvToWidenUnsignedBuiltin<string mangled_name>
- : RVVConvBuiltin<"Uw", "Uwv", "xf", mangled_name>;
-
-class RVVConvToNarrowingSignedBuiltin<string mangled_name>
- : RVVConvBuiltin<"Iv", "IvFw", "csi", mangled_name>;
-
-class RVVConvToNarrowingUnsignedBuiltin<string mangled_name>
- : RVVConvBuiltin<"Uv", "UvFw", "csi", mangled_name>;
-
-let HasMaskedOffOperand = false in {
- multiclass RVVSignedReductionBuiltin {
- defm "" : RVVOutOp1BuiltinSet<NAME, "csil",
- [["vs", "vSv", "SvSvvSv"]]>;
- }
- multiclass RVVUnsignedReductionBuiltin {
- defm "" : RVVOutOp1BuiltinSet<NAME, "csil",
- [["vs", "UvUSv", "USvUSvUvUSv"]]>;
- }
- multiclass RVVFloatingReductionBuiltin {
- defm "" : RVVOutOp1BuiltinSet<NAME, "xfd",
- [["vs", "vSv", "SvSvvSv"]]>;
- }
- multiclass RVVFloatingWidenReductionBuiltin {
- defm "" : RVVOutOp1BuiltinSet<NAME, "xf",
- [["vs", "vSw", "SwSwvSw"]]>;
- }
-}
-
-multiclass RVVIntReductionBuiltinSet
- : RVVSignedReductionBuiltin,
- RVVUnsignedReductionBuiltin;
-
-// For widen operation which has different mangling name.
-multiclass RVVWidenBuiltinSet<string intrinsic_name, string type_range,
- list<list<string>> suffixes_prototypes> {
- let Log2LMUL = [-3, -2, -1, 0, 1, 2],
- IRName = intrinsic_name, IRNameMask = intrinsic_name # "_mask" in {
- foreach s_p = suffixes_prototypes in {
- let Name = NAME # "_" # s_p[0],
- MangledName = NAME # "_" # s_p[0] in {
- defvar suffix = s_p[1];
- defvar prototype = s_p[2];
- def : RVVOutOp0Op1Builtin<suffix, prototype, type_range>;
- }
- }
- }
-}
-
-// For widen operation with widen operand which has different mangling name.
-multiclass RVVWidenWOp0BuiltinSet<string intrinsic_name, string type_range,
- list<list<string>> suffixes_prototypes> {
- let Log2LMUL = [-3, -2, -1, 0, 1, 2],
- IRName = intrinsic_name, IRNameMask = intrinsic_name # "_mask" in {
- foreach s_p = suffixes_prototypes in {
- let Name = NAME # "_" # s_p[0],
- MangledName = NAME # "_" # s_p[0] in {
- defvar suffix = s_p[1];
- defvar prototype = s_p[2];
- def : RVVOutOp1Builtin<suffix, prototype, type_range>;
- }
- }
- }
-}
-
-multiclass RVVSignedWidenBinBuiltinSet
- : RVVWidenBuiltinSet<NAME, "csi",
- [["vv", "w", "wvv"],
- ["vx", "w", "wve"]]>;
-
-multiclass RVVSignedWidenOp0BinBuiltinSet
- : RVVWidenWOp0BuiltinSet<NAME # "_w", "csi",
- [["wv", "w", "wwv"],
- ["wx", "w", "wwe"]]>;
-
-multiclass RVVUnsignedWidenBinBuiltinSet
- : RVVWidenBuiltinSet<NAME, "csi",
- [["vv", "Uw", "UwUvUv"],
- ["vx", "Uw", "UwUvUe"]]>;
-
-multiclass RVVUnsignedWidenOp0BinBuiltinSet
- : RVVWidenWOp0BuiltinSet<NAME # "_w", "csi",
- [["wv", "Uw", "UwUwUv"],
- ["wx", "Uw", "UwUwUe"]]>;
-
-multiclass RVVFloatingWidenBinBuiltinSet
- : RVVWidenBuiltinSet<NAME, "xf",
- [["vv", "w", "wvv"],
- ["vf", "w", "wve"]]>;
-
-multiclass RVVFloatingWidenOp0BinBuiltinSet
- : RVVWidenWOp0BuiltinSet<NAME # "_w", "xf",
- [["wv", "w", "wwv"],
- ["wf", "w", "wwe"]]>;
+include "riscv_vector_common.td"
defvar TypeList = ["c","s","i","l","x","f","d"];
defvar EEWList = [["8", "(Log2EEW:3)"],
@@ -556,30 +24,25 @@ class IsFloat<string type> {
bit val = !or(!eq(type, "x"), !eq(type, "f"), !eq(type, "d"));
}
-let HasNoMaskedOverloaded = false,
- ManualCodegen = [{
- IntrinsicTypes = {ResultType, Ops[1]->getType()};
- Ops[0] = Builder.CreateBitCast(Ops[0], ResultType->getPointerTo());
- }],
- ManualCodegenMask= [{
- // Move mask to right before vl.
- std::rotate(Ops.begin(), Ops.begin() + 1, Ops.end() - 1);
- IntrinsicTypes = {ResultType, Ops[3]->getType()};
- Ops[1] = Builder.CreateBitCast(Ops[1], ResultType->getPointerTo());
- }] in {
- class RVVVLEMaskBuiltin : RVVBuiltin<"m", "mPCUe", "c"> {
- let Name = "vle1_v";
- let IRName = "vle1";
- let HasMask = false;
+let SupportOverloading = false,
+ MaskedPolicyScheme = NonePolicy in {
+ class RVVVLEMaskBuiltin : RVVOutBuiltin<"m", "mPCUe", "c"> {
+ let Name = "vlm_v";
+ let IRName = "vlm";
+ let HasMasked = false;
}
+}
+
+let SupportOverloading = false,
+ UnMaskedPolicyScheme = HasPassthruOperand in {
multiclass RVVVLEBuiltin<list<string> types> {
let Name = NAME # "_v",
IRName = "vle",
- IRNameMask ="vle_mask" in {
+ MaskedIRName ="vle_mask" in {
foreach type = types in {
- def : RVVBuiltin<"v", "vPCe", type>;
+ def : RVVOutBuiltin<"v", "vPCe", type>;
if !not(IsFloat<type>.val) then {
- def : RVVBuiltin<"Uv", "UvPCUe", type>;
+ def : RVVOutBuiltin<"Uv", "UvPCUe", type>;
}
}
}
@@ -589,41 +52,36 @@ let HasNoMaskedOverloaded = false,
multiclass RVVVLEFFBuiltin<list<string> types> {
let Name = NAME # "_v",
IRName = "vleff",
- IRNameMask = "vleff_mask",
- HasNoMaskedOverloaded = false,
+ MaskedIRName = "vleff_mask",
+ SupportOverloading = false,
+ UnMaskedPolicyScheme = HasPassthruOperand,
ManualCodegen = [{
{
- IntrinsicTypes = {ResultType, Ops[2]->getType()};
- Ops[0] = Builder.CreateBitCast(Ops[0], ResultType->getPointerTo());
- Value *NewVL = Ops[1];
- Ops.erase(Ops.begin() + 1);
- llvm::Function *F = CGM.getIntrinsic(ID, IntrinsicTypes);
- llvm::Value *LoadValue = Builder.CreateCall(F, Ops, "");
- llvm::Value *V = Builder.CreateExtractValue(LoadValue, {0});
- // Store new_vl.
- clang::CharUnits Align =
- CGM.getNaturalTypeAlignment(getContext().getSizeType());
- Builder.CreateStore(Builder.CreateExtractValue(LoadValue, {1}),
- Address(NewVL, Align));
- return V;
- }
- }],
- ManualCodegenMask = [{
- {
- // Move mask to right before vl.
- std::rotate(Ops.begin(), Ops.begin() + 1, Ops.end() - 1);
- IntrinsicTypes = {ResultType, Ops[4]->getType()};
- Ops[1] = Builder.CreateBitCast(Ops[1], ResultType->getPointerTo());
+ if (IsMasked) {
+ // Move mask to right before vl.
+ std::rotate(Ops.begin(), Ops.begin() + 1, Ops.end() - 1);
+ if ((PolicyAttrs & RVV_VTA) && (PolicyAttrs & RVV_VMA))
+ Ops.insert(Ops.begin(), llvm::PoisonValue::get(ResultType));
+ Ops.push_back(ConstantInt::get(Ops.back()->getType(), PolicyAttrs));
+ IntrinsicTypes = {ResultType, Ops[4]->getType()};
+ } else {
+ if (PolicyAttrs & RVV_VTA)
+ Ops.insert(Ops.begin(), llvm::PoisonValue::get(ResultType));
+ IntrinsicTypes = {ResultType, Ops[3]->getType()};
+ }
Value *NewVL = Ops[2];
Ops.erase(Ops.begin() + 2);
llvm::Function *F = CGM.getIntrinsic(ID, IntrinsicTypes);
llvm::Value *LoadValue = Builder.CreateCall(F, Ops, "");
llvm::Value *V = Builder.CreateExtractValue(LoadValue, {0});
// Store new_vl.
- clang::CharUnits Align =
- CGM.getNaturalTypeAlignment(getContext().getSizeType());
- Builder.CreateStore(Builder.CreateExtractValue(LoadValue, {1}),
- Address(NewVL, Align));
+ clang::CharUnits Align;
+ if (IsMasked)
+ Align = CGM.getNaturalPointeeTypeAlignment(E->getArg(E->getNumArgs()-2)->getType());
+ else
+ Align = CGM.getNaturalPointeeTypeAlignment(E->getArg(1)->getType());
+ llvm::Value *Val = Builder.CreateExtractValue(LoadValue, {1});
+ Builder.CreateStore(Val, Address(NewVL, Val->getType(), Align));
return V;
}
}] in {
@@ -640,75 +98,71 @@ multiclass RVVVLEFFBuiltin<list<string> types> {
multiclass RVVVLSEBuiltin<list<string> types> {
let Name = NAME # "_v",
IRName = "vlse",
- IRNameMask ="vlse_mask",
- HasNoMaskedOverloaded = false,
- ManualCodegen = [{
- IntrinsicTypes = {ResultType, Ops[2]->getType()};
- Ops[0] = Builder.CreateBitCast(Ops[0], ResultType->getPointerTo());
- }],
- ManualCodegenMask= [{
- // Move mask to right before vl.
- std::rotate(Ops.begin(), Ops.begin() + 1, Ops.end() - 1);
- IntrinsicTypes = {ResultType, Ops[4]->getType()};
- Ops[1] = Builder.CreateBitCast(Ops[1], ResultType->getPointerTo());
- }] in {
+ MaskedIRName ="vlse_mask",
+ SupportOverloading = false,
+ UnMaskedPolicyScheme = HasPassthruOperand in {
foreach type = types in {
- def : RVVBuiltin<"v", "vPCet", type>;
+ def : RVVOutBuiltin<"v", "vPCet", type>;
if !not(IsFloat<type>.val) then {
- def : RVVBuiltin<"Uv", "UvPCUet", type>;
+ def : RVVOutBuiltin<"Uv", "UvPCUet", type>;
}
}
}
}
multiclass RVVIndexedLoad<string op> {
- let ManualCodegen = [{
- IntrinsicTypes = {ResultType, Ops[1]->getType(), Ops[2]->getType()};
- Ops[0] = Builder.CreateBitCast(Ops[0], ResultType->getPointerTo());
- }],
- ManualCodegenMask = [{
- // Move mask to right before vl.
- std::rotate(Ops.begin(), Ops.begin() + 1, Ops.end() - 1);
- IntrinsicTypes = {ResultType, Ops[2]->getType(), Ops[4]->getType()};
- Ops[1] = Builder.CreateBitCast(Ops[1], ResultType->getPointerTo());
- }] in {
- foreach type = TypeList in {
- foreach eew_list = EEWList in {
- defvar eew = eew_list[0];
- defvar eew_type = eew_list[1];
- let Name = op # eew # "_v", IRName = op, IRNameMask = op # "_mask" in {
- def: RVVBuiltin<"v", "vPCe" # eew_type # "Uv", type>;
- if !not(IsFloat<type>.val) then {
- def: RVVBuiltin<"Uv", "UvPCUe" # eew_type # "Uv", type>;
- }
- }
+ let UnMaskedPolicyScheme = HasPassthruOperand in {
+ foreach type = TypeList 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, MaskedIRName = op # "_mask",
+ RequiredFeatures = !if(!eq(type, "x"), ["Zvfhmin"],
+ []<string>) in {
+ def: RVVOutOp1Builtin<"v", "vPCe" # eew_type # "Uv", type>;
+ if !not(IsFloat<type>.val) then {
+ def: RVVOutOp1Builtin<"Uv", "UvPCUe" # eew_type # "Uv", type>;
+ }
}
}
+ defvar eew64 = "64";
+ defvar eew64_type = "(Log2EEW:6)";
+ let Name = op # eew64 # "_v", IRName = op, MaskedIRName = op # "_mask",
+ RequiredFeatures = !if(!eq(type, "x"), ["Zvfhmin", "RV64"],
+ ["RV64"]) in {
+ def: RVVOutOp1Builtin<"v", "vPCe" # eew64_type # "Uv", type>;
+ if !not(IsFloat<type>.val) then {
+ def: RVVOutOp1Builtin<"Uv", "UvPCUe" # eew64_type # "Uv", type>;
+ }
+ }
+ }
}
}
let HasMaskedOffOperand = false,
+ MaskedPolicyScheme = NonePolicy,
ManualCodegen = [{
- // Builtin: (ptr, value, vl). Intrinsic: (value, ptr, vl)
- std::swap(Ops[0], Ops[1]);
- Ops[1] = Builder.CreateBitCast(Ops[1], Ops[0]->getType()->getPointerTo());
- IntrinsicTypes = {Ops[0]->getType(), Ops[2]->getType()};
- }],
- ManualCodegenMask= [{
- // Builtin: (mask, ptr, value, vl). Intrinsic: (value, ptr, mask, vl)
- std::swap(Ops[0], Ops[2]);
- Ops[1] = Builder.CreateBitCast(Ops[1], Ops[0]->getType()->getPointerTo());
- IntrinsicTypes = {Ops[0]->getType(), Ops[3]->getType()};
+ if (IsMasked) {
+ // Builtin: (mask, ptr, value, vl). Intrinsic: (value, ptr, mask, vl)
+ std::swap(Ops[0], Ops[2]);
+ } else {
+ // Builtin: (ptr, value, vl). Intrinsic: (value, ptr, vl)
+ std::swap(Ops[0], Ops[1]);
+ }
+ if (IsMasked)
+ IntrinsicTypes = {Ops[0]->getType(), Ops[3]->getType()};
+ else
+ IntrinsicTypes = {Ops[0]->getType(), Ops[2]->getType()};
}] in {
class RVVVSEMaskBuiltin : RVVBuiltin<"m", "0PUem", "c"> {
- let Name = "vse1_v";
- let IRName = "vse1";
- let HasMask = false;
+ let Name = "vsm_v";
+ let IRName = "vsm";
+ let HasMasked = false;
}
multiclass RVVVSEBuiltin<list<string> types> {
let Name = NAME # "_v",
IRName = "vse",
- IRNameMask = "vse_mask" in {
+ MaskedIRName = "vse_mask" in {
foreach type = types in {
def : RVVBuiltin<"v", "0Pev", type>;
if !not(IsFloat<type>.val) then {
@@ -722,19 +176,21 @@ let HasMaskedOffOperand = false,
multiclass RVVVSSEBuiltin<list<string> types> {
let Name = NAME # "_v",
IRName = "vsse",
- IRNameMask = "vsse_mask",
+ MaskedIRName = "vsse_mask",
HasMaskedOffOperand = false,
+ MaskedPolicyScheme = NonePolicy,
ManualCodegen = [{
- // Builtin: (ptr, stride, value, vl). Intrinsic: (value, ptr, stride, vl)
- std::rotate(Ops.begin(), Ops.begin() + 2, Ops.begin() + 3);
- Ops[1] = Builder.CreateBitCast(Ops[1], Ops[0]->getType()->getPointerTo());
- IntrinsicTypes = {Ops[0]->getType(), Ops[3]->getType()};
- }],
- ManualCodegenMask= [{
- // Builtin: (mask, ptr, stride, value, vl). Intrinsic: (value, ptr, stride, mask, vl)
- std::swap(Ops[0], Ops[3]);
- Ops[1] = Builder.CreateBitCast(Ops[1], Ops[0]->getType()->getPointerTo());
- IntrinsicTypes = {Ops[0]->getType(), Ops[4]->getType()};
+ if (IsMasked) {
+ // Builtin: (mask, ptr, stride, value, vl). Intrinsic: (value, ptr, stride, mask, vl)
+ std::swap(Ops[0], Ops[3]);
+ } else {
+ // Builtin: (ptr, stride, value, vl). Intrinsic: (value, ptr, stride, vl)
+ std::rotate(Ops.begin(), Ops.begin() + 2, Ops.begin() + 3);
+ }
+ if (IsMasked)
+ IntrinsicTypes = {Ops[0]->getType(), Ops[4]->getType()};
+ else
+ IntrinsicTypes = {Ops[0]->getType(), Ops[3]->getType()};
}] in {
foreach type = types in {
def : RVVBuiltin<"v", "0Petv", type>;
@@ -747,34 +203,122 @@ multiclass RVVVSSEBuiltin<list<string> types> {
multiclass RVVIndexedStore<string op> {
let HasMaskedOffOperand = false,
+ MaskedPolicyScheme = NonePolicy,
ManualCodegen = [{
- // Builtin: (ptr, index, value, vl). Intrinsic: (value, ptr, index, vl)
- std::rotate(Ops.begin(), Ops.begin() + 2, Ops.begin() + 3);
- Ops[1] = Builder.CreateBitCast(Ops[1],Ops[0]->getType()->getPointerTo());
- IntrinsicTypes = {Ops[0]->getType(), Ops[2]->getType(), Ops[3]->getType()};
- }],
- ManualCodegenMask= [{
- // Builtin: (mask, ptr, index, value, vl). Intrinsic: (value, ptr, index, mask, vl)
- std::swap(Ops[0], Ops[3]);
- Ops[1] = Builder.CreateBitCast(Ops[1], Ops[0]->getType()->getPointerTo());
- IntrinsicTypes = {Ops[0]->getType(), Ops[2]->getType(), Ops[4]->getType()};
+ if (IsMasked) {
+ // Builtin: (mask, ptr, index, value, vl). Intrinsic: (value, ptr, index, mask, vl)
+ std::swap(Ops[0], Ops[3]);
+ } else {
+ // Builtin: (ptr, index, value, vl). Intrinsic: (value, ptr, index, vl)
+ std::rotate(Ops.begin(), Ops.begin() + 2, Ops.begin() + 3);
+ }
+ if (IsMasked)
+ IntrinsicTypes = {Ops[0]->getType(), Ops[2]->getType(), Ops[4]->getType()};
+ else
+ IntrinsicTypes = {Ops[0]->getType(), Ops[2]->getType(), Ops[3]->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 {
+ let Name = op # eew # "_v", IRName = op, MaskedIRName = op # "_mask",
+ RequiredFeatures = !if(!eq(type, "x"), ["Zvfhmin"],
+ []<string>) in {
def : RVVBuiltin<"v", "0Pe" # eew_type # "Uvv", type>;
if !not(IsFloat<type>.val) then {
def : RVVBuiltin<"Uv", "0PUe" # eew_type # "UvUv", type>;
}
}
}
+ defvar eew64 = "64";
+ defvar eew64_type = "(Log2EEW:6)";
+ let Name = op # eew64 # "_v", IRName = op, MaskedIRName = op # "_mask",
+ RequiredFeatures = !if(!eq(type, "x"), ["Zvfhmin", "RV64"],
+ ["RV64"]) in {
+ def : RVVBuiltin<"v", "0Pe" # eew64_type # "Uvv", type>;
+ if !not(IsFloat<type>.val) then {
+ def : RVVBuiltin<"Uv", "0PUe" # eew64_type # "UvUv", type>;
+ }
+ }
}
}
}
defvar NFList = [2, 3, 4, 5, 6, 7, 8];
+/*
+A segment load builtin has different variants.
+
+Therefore a segment unit-stride load builtin can have 4 variants,
+1. When unmasked and the policies are all specified as agnostic:
+(Address0, ..., Address{NF - 1}, Ptr, VL)
+2. When masked and the policies are all specified as agnostic:
+(Address0, ..., Address{NF - 1}, Mask, Ptr, VL)
+3. When unmasked and one of the policies is specified as undisturbed:
+(Address0, ..., Address{NF - 1}, Maskedoff0, ..., Maskedoff{NF - 1},
+ Ptr, VL)
+4. When masked and one of the policies is specified as undisturbed:
+(Address0, ..., Address{NF - 1}, Mask, Maskedoff0, ..., Maskedoff{NF - 1},
+ Ptr, VL)
+
+Other variants of segment load builtin share the same structure, but they
+have their own extra parameter.
+
+The segment unit-stride fault-only-first load builtin has a 'NewVL'
+operand after the 'Ptr' operand.
+1. When unmasked and the policies are all specified as agnostic:
+(Address0, ..., Address{NF - 1}, Ptr, NewVL, VL)
+2. When masked and the policies are all specified as agnostic:
+(Address0, ..., Address{NF - 1}, Mask, Ptr, NewVL, VL)
+3. When unmasked and one of the policies is specified as undisturbed:
+(Address0, ..., Address{NF - 1}, Maskedoff0, ..., Maskedoff{NF - 1},
+ Ptr, NewVL, VL)
+4. When masked and one of the policies is specified as undisturbed:
+(Address0, ..., Address{NF - 1}, Mask, Maskedoff0, ..., Maskedoff{NF - 1},
+ Ptr, NewVL, VL)
+
+The segment strided load builtin has a 'Stride' operand after the 'Ptr'
+operand.
+1. When unmasked and the policies are all specified as agnostic:
+(Address0, ..., Address{NF - 1}, Ptr, Stride, VL)
+2. When masked and the policies are all specified as agnostic:
+(Address0, ..., Address{NF - 1}, Mask, Ptr, Stride, VL)
+3. When unmasked and one of the policies is specified as undisturbed:
+(Address0, ..., Address{NF - 1}, Maskedoff0, ..., Maskedoff{NF - 1},
+ Ptr, Stride, VL)
+4. When masked and one of the policies is specified as undisturbed:
+(Address0, ..., Address{NF - 1}, Mask, Maskedoff0, ..., Maskedoff{NF - 1},
+ Ptr, Stride, VL)
+
+The segment indexed load builtin has a 'Idx' operand after the 'Ptr' operand.
+1. When unmasked and the policies are all specified as agnostic:
+(Address0, ..., Address{NF - 1}, Ptr, Idx, VL)
+2. When masked and the policies are all specified as agnostic:
+(Address0, ..., Address{NF - 1}, Mask, Ptr, Idx, VL)
+3. When unmasked and one of the policies is specified as undisturbed:
+(Address0, ..., Address{NF - 1}, Maskedoff0, ..., Maskedoff{NF - 1},
+ Ptr, Idx, VL)
+4. When masked and one of the policies is specified as undisturbed:
+(Address0, ..., Address{NF - 1}, Mask, Maskedoff0, ..., Maskedoff{NF - 1},
+ Ptr, Idx, VL)
+
+Segment load intrinsics has different variants similar to their builtins.
+
+Segment unit-stride load intrinsic,
+ Masked: (Vector0, ..., Vector{NF - 1}, Ptr, Mask, VL, Policy)
+ Unmasked: (Vector0, ..., Vector{NF - 1}, Ptr, VL)
+Segment unit-stride fault-only-first load intrinsic,
+ Masked: (Vector0, ..., Vector{NF - 1}, Ptr, Mask, VL, Policy)
+ Unmasked: (Vector0, ..., Vector{NF - 1}, Ptr, VL)
+Segment strided load intrinsic,
+ Masked: (Vector0, ..., Vector{NF - 1}, Ptr, Stride, Mask, VL, Policy)
+ Unmasked: (Vector0, ..., Vector{NF - 1}, Ptr, Stride, VL)
+Segment indexed load intrinsic,
+ Masked: (Vector0, ..., Vector{NF - 1}, Ptr, Index, Mask, VL, Policy)
+ Unmasked: (Vector0, ..., Vector{NF - 1}, Ptr, Index, VL)
+
+The Vector(s) is poison when the policy behavior allows us to not care
+about any masked-off elements.
+*/
class PVString<int nf, bit signed> {
string S =
@@ -787,7 +331,400 @@ class PVString<int nf, bit signed> {
!eq(nf, 8): !if(signed, "PvPvPvPvPvPvPvPv", "PUvPUvPUvPUvPUvPUvPUvPUv"));
}
-multiclass RVVUnitStridedSegLoad<string op> {
+class VString<int nf, bit signed> {
+ string S = !cond(!eq(nf, 2): !if(signed, "vv", "UvUv"),
+ !eq(nf, 3): !if(signed, "vvv", "UvUvUv"),
+ !eq(nf, 4): !if(signed, "vvvv", "UvUvUvUv"),
+ !eq(nf, 5): !if(signed, "vvvvv", "UvUvUvUvUv"),
+ !eq(nf, 6): !if(signed, "vvvvvv", "UvUvUvUvUvUv"),
+ !eq(nf, 7): !if(signed, "vvvvvvv", "UvUvUvUvUvUvUv"),
+ !eq(nf, 8): !if(signed, "vvvvvvvv", "UvUvUvUvUvUvUvUv"));
+}
+
+
+class FixedVString<int fixed_lmul, int num, string vec> {
+ string V = "(LFixedLog2LMUL:" # fixed_lmul # ")" # vec;
+ string S = !interleave(!listsplat(V, num), "");
+}
+
+multiclass RVVNonTupleVCreateBuiltin<int dst_lmul, list<int> src_lmul_list> {
+ defvar dst_v = FixedVString<dst_lmul, 1, "v">.V;
+ defvar dst_uv = FixedVString<dst_lmul, 1, "Uv">.V;
+ foreach src_lmul = src_lmul_list in {
+ defvar num = !shl(1, !sub(dst_lmul, src_lmul));
+
+ defvar src_v = FixedVString<src_lmul, num, "v">.V;
+ defvar src_s = FixedVString<src_lmul, num, "v">.S;
+ def vcreate # src_v # dst_v : RVVBuiltin<src_v # dst_v,
+ dst_v # src_s,
+ "csilxfd", dst_v>;
+
+ defvar src_uv = FixedVString<src_lmul, num, "Uv">.V;
+ defvar src_us = FixedVString<src_lmul, num, "Uv">.S;
+ def vcreate_u # src_uv # dst_uv : RVVBuiltin<src_uv # dst_uv,
+ dst_uv # src_us,
+ "csil", dst_uv>;
+ }
+}
+
+multiclass RVVPseudoUnaryBuiltin<string IR, string type_range> {
+ let Name = NAME,
+ IRName = IR,
+ MaskedIRName = IR # "_mask",
+ UnMaskedPolicyScheme = HasPassthruOperand,
+ ManualCodegen = [{
+ {
+ if (IsMasked) {
+ std::rotate(Ops.begin(), Ops.begin() + 1, Ops.end() - 1);
+ if ((PolicyAttrs & RVV_VTA) && (PolicyAttrs & RVV_VMA))
+ Ops.insert(Ops.begin(), llvm::PoisonValue::get(ResultType));
+ } else {
+ if (PolicyAttrs & RVV_VTA)
+ Ops.insert(Ops.begin(), llvm::PoisonValue::get(ResultType));
+ }
+ auto ElemTy = cast<llvm::VectorType>(ResultType)->getElementType();
+ Ops.insert(Ops.begin() + 2, llvm::Constant::getNullValue(ElemTy));
+
+ if (IsMasked) {
+ Ops.push_back(ConstantInt::get(Ops.back()->getType(), PolicyAttrs));
+ // maskedoff, op1, op2, mask, vl, policy
+ IntrinsicTypes = {ResultType, ElemTy, Ops[4]->getType()};
+ } else {
+ // passthru, op1, op2, vl
+ IntrinsicTypes = {ResultType, ElemTy, Ops[3]->getType()};
+ }
+ break;
+ }
+ }] in {
+ def : RVVBuiltin<"v", "vv", type_range>;
+ }
+}
+
+multiclass RVVPseudoVNotBuiltin<string IR, string type_range> {
+ let Name = NAME,
+ IRName = IR,
+ MaskedIRName = IR # "_mask",
+ UnMaskedPolicyScheme = HasPassthruOperand,
+ ManualCodegen = [{
+ {
+ if (IsMasked) {
+ std::rotate(Ops.begin(), Ops.begin() + 1, Ops.end() - 1);
+ if ((PolicyAttrs & RVV_VTA) && (PolicyAttrs & RVV_VMA))
+ Ops.insert(Ops.begin(), llvm::PoisonValue::get(ResultType));
+ } else {
+ if (PolicyAttrs & RVV_VTA)
+ Ops.insert(Ops.begin(), llvm::PoisonValue::get(ResultType));
+ }
+ auto ElemTy = cast<llvm::VectorType>(ResultType)->getElementType();
+ Ops.insert(Ops.begin() + 2,
+ llvm::Constant::getAllOnesValue(ElemTy));
+ if (IsMasked) {
+ Ops.push_back(ConstantInt::get(Ops.back()->getType(), PolicyAttrs));
+ // maskedoff, op1, po2, mask, vl, policy
+ IntrinsicTypes = {ResultType,
+ ElemTy,
+ Ops[4]->getType()};
+ } else {
+ // passthru, op1, op2, vl
+ IntrinsicTypes = {ResultType,
+ ElemTy,
+ Ops[3]->getType()};
+ }
+ break;
+ }
+ }] in {
+ def : RVVBuiltin<"v", "vv", type_range>;
+ def : RVVBuiltin<"Uv", "UvUv", type_range>;
+ }
+}
+
+multiclass RVVPseudoMaskBuiltin<string IR, string type_range> {
+ let Name = NAME,
+ IRName = IR,
+ HasMasked = false,
+ ManualCodegen = [{
+ {
+ // op1, vl
+ IntrinsicTypes = {ResultType,
+ Ops[1]->getType()};
+ Ops.insert(Ops.begin() + 1, Ops[0]);
+ break;
+ }
+ }] in {
+ def : RVVBuiltin<"m", "mm", type_range>;
+ }
+}
+
+multiclass RVVPseudoVFUnaryBuiltin<string IR, string type_range> {
+ let Name = NAME,
+ IRName = IR,
+ MaskedIRName = IR # "_mask",
+ UnMaskedPolicyScheme = HasPassthruOperand,
+ ManualCodegen = [{
+ {
+ if (IsMasked) {
+ std::rotate(Ops.begin(), Ops.begin() + 1, Ops.end() - 1);
+ if ((PolicyAttrs & RVV_VTA) && (PolicyAttrs & RVV_VMA))
+ Ops.insert(Ops.begin(), llvm::PoisonValue::get(ResultType));
+ Ops.insert(Ops.begin() + 2, Ops[1]);
+ Ops.push_back(ConstantInt::get(Ops.back()->getType(), PolicyAttrs));
+ // maskedoff, op1, op2, mask, vl
+ IntrinsicTypes = {ResultType,
+ Ops[2]->getType(),
+ Ops.back()->getType()};
+ } else {
+ if (PolicyAttrs & RVV_VTA)
+ Ops.insert(Ops.begin(), llvm::PoisonValue::get(ResultType));
+ // op1, po2, vl
+ IntrinsicTypes = {ResultType,
+ Ops[1]->getType(), Ops[2]->getType()};
+ Ops.insert(Ops.begin() + 2, Ops[1]);
+ break;
+ }
+ break;
+ }
+ }] in {
+ def : RVVBuiltin<"v", "vv", type_range>;
+ }
+}
+
+multiclass RVVPseudoVWCVTBuiltin<string IR, string MName, string type_range,
+ list<list<string>> suffixes_prototypes> {
+ let Name = NAME,
+ OverloadedName = MName,
+ IRName = IR,
+ MaskedIRName = IR # "_mask",
+ UnMaskedPolicyScheme = HasPassthruOperand,
+ ManualCodegen = [{
+ {
+ if (IsMasked) {
+ std::rotate(Ops.begin(), Ops.begin() + 1, Ops.end() - 1);
+ if ((PolicyAttrs & RVV_VTA) && (PolicyAttrs & RVV_VMA))
+ Ops.insert(Ops.begin(), llvm::PoisonValue::get(ResultType));
+ } else {
+ if (PolicyAttrs & RVV_VTA)
+ Ops.insert(Ops.begin(), llvm::PoisonValue::get(ResultType));
+ }
+ auto ElemTy = cast<llvm::VectorType>(ResultType)->getElementType();
+ Ops.insert(Ops.begin() + 2, llvm::Constant::getNullValue(ElemTy));
+ if (IsMasked) {
+ Ops.push_back(ConstantInt::get(Ops.back()->getType(), PolicyAttrs));
+ // maskedoff, op1, op2, mask, vl, policy
+ IntrinsicTypes = {ResultType,
+ Ops[1]->getType(),
+ ElemTy,
+ Ops[4]->getType()};
+ } else {
+ // passtru, op1, op2, vl
+ IntrinsicTypes = {ResultType,
+ Ops[1]->getType(),
+ ElemTy,
+ Ops[3]->getType()};
+ }
+ break;
+ }
+ }] in {
+ foreach s_p = suffixes_prototypes in {
+ def : RVVBuiltin<s_p[0], s_p[1], type_range>;
+ }
+ }
+}
+
+multiclass RVVPseudoVNCVTBuiltin<string IR, string MName, string type_range,
+ list<list<string>> suffixes_prototypes> {
+ let Name = NAME,
+ OverloadedName = MName,
+ IRName = IR,
+ MaskedIRName = IR # "_mask",
+ UnMaskedPolicyScheme = HasPassthruOperand,
+ ManualCodegen = [{
+ {
+ if (IsMasked) {
+ std::rotate(Ops.begin(), Ops.begin() + 1, Ops.end() - 1);
+ if ((PolicyAttrs & RVV_VTA) && (PolicyAttrs & RVV_VMA))
+ Ops.insert(Ops.begin(), llvm::PoisonValue::get(ResultType));
+ } else {
+ if (PolicyAttrs & RVV_VTA)
+ Ops.insert(Ops.begin(), llvm::PoisonValue::get(ResultType));
+ }
+ Ops.insert(Ops.begin() + 2, llvm::Constant::getNullValue(Ops.back()->getType()));
+ if (IsMasked) {
+ Ops.push_back(ConstantInt::get(Ops.back()->getType(), PolicyAttrs));
+ // maskedoff, op1, xlen, mask, vl
+ IntrinsicTypes = {ResultType,
+ Ops[1]->getType(),
+ Ops[4]->getType(),
+ Ops[4]->getType()};
+ } else {
+ // passthru, op1, xlen, vl
+ IntrinsicTypes = {ResultType,
+ Ops[1]->getType(),
+ Ops[3]->getType(),
+ Ops[3]->getType()};
+ }
+ break;
+ }
+ }] in {
+ foreach s_p = suffixes_prototypes in {
+ def : RVVBuiltin<s_p[0], s_p[1], type_range>;
+ }
+ }
+}
+
+let HeaderCode =
+[{
+#define __riscv_vlenb() __builtin_rvv_vlenb()
+}] in
+def vlenb_macro: RVVHeader;
+
+let HasBuiltinAlias = false, HasVL = false, HasMasked = false,
+ UnMaskedPolicyScheme = NonePolicy, MaskedPolicyScheme = NonePolicy,
+ Log2LMUL = [0], IRName = "",
+ ManualCodegen = [{
+ {
+ LLVMContext &Context = CGM.getLLVMContext();
+ llvm::MDBuilder MDHelper(Context);
+
+ llvm::Metadata *Ops[] = {llvm::MDString::get(Context, "vlenb")};
+ llvm::MDNode *RegName = llvm::MDNode::get(Context, Ops);
+ llvm::Value *Metadata = llvm::MetadataAsValue::get(Context, RegName);
+ llvm::Function *F =
+ CGM.getIntrinsic(llvm::Intrinsic::read_register, {SizeTy});
+ return Builder.CreateCall(F, Metadata);
+ }
+ }] in
+{
+ def vlenb : RVVBuiltin<"", "u", "i">;
+}
+
+// 6. Configuration-Setting Instructions
+// 6.1. vsetvli/vsetvl instructions
+
+// vsetvl/vsetvlmax are a macro because they require constant integers in SEW
+// and LMUL.
+let HeaderCode =
+[{
+#define __riscv_vsetvl_e8mf4(avl) __builtin_rvv_vsetvli((size_t)(avl), 0, 6)
+#define __riscv_vsetvl_e8mf2(avl) __builtin_rvv_vsetvli((size_t)(avl), 0, 7)
+#define __riscv_vsetvl_e8m1(avl) __builtin_rvv_vsetvli((size_t)(avl), 0, 0)
+#define __riscv_vsetvl_e8m2(avl) __builtin_rvv_vsetvli((size_t)(avl), 0, 1)
+#define __riscv_vsetvl_e8m4(avl) __builtin_rvv_vsetvli((size_t)(avl), 0, 2)
+#define __riscv_vsetvl_e8m8(avl) __builtin_rvv_vsetvli((size_t)(avl), 0, 3)
+
+#define __riscv_vsetvl_e16mf2(avl) __builtin_rvv_vsetvli((size_t)(avl), 1, 7)
+#define __riscv_vsetvl_e16m1(avl) __builtin_rvv_vsetvli((size_t)(avl), 1, 0)
+#define __riscv_vsetvl_e16m2(avl) __builtin_rvv_vsetvli((size_t)(avl), 1, 1)
+#define __riscv_vsetvl_e16m4(avl) __builtin_rvv_vsetvli((size_t)(avl), 1, 2)
+#define __riscv_vsetvl_e16m8(avl) __builtin_rvv_vsetvli((size_t)(avl), 1, 3)
+
+#define __riscv_vsetvl_e32m1(avl) __builtin_rvv_vsetvli((size_t)(avl), 2, 0)
+#define __riscv_vsetvl_e32m2(avl) __builtin_rvv_vsetvli((size_t)(avl), 2, 1)
+#define __riscv_vsetvl_e32m4(avl) __builtin_rvv_vsetvli((size_t)(avl), 2, 2)
+#define __riscv_vsetvl_e32m8(avl) __builtin_rvv_vsetvli((size_t)(avl), 2, 3)
+
+#if __riscv_v_elen >= 64
+#define __riscv_vsetvl_e8mf8(avl) __builtin_rvv_vsetvli((size_t)(avl), 0, 5)
+#define __riscv_vsetvl_e16mf4(avl) __builtin_rvv_vsetvli((size_t)(avl), 1, 6)
+#define __riscv_vsetvl_e32mf2(avl) __builtin_rvv_vsetvli((size_t)(avl), 2, 7)
+
+#define __riscv_vsetvl_e64m1(avl) __builtin_rvv_vsetvli((size_t)(avl), 3, 0)
+#define __riscv_vsetvl_e64m2(avl) __builtin_rvv_vsetvli((size_t)(avl), 3, 1)
+#define __riscv_vsetvl_e64m4(avl) __builtin_rvv_vsetvli((size_t)(avl), 3, 2)
+#define __riscv_vsetvl_e64m8(avl) __builtin_rvv_vsetvli((size_t)(avl), 3, 3)
+#endif
+
+#define __riscv_vsetvlmax_e8mf4() __builtin_rvv_vsetvlimax(0, 6)
+#define __riscv_vsetvlmax_e8mf2() __builtin_rvv_vsetvlimax(0, 7)
+#define __riscv_vsetvlmax_e8m1() __builtin_rvv_vsetvlimax(0, 0)
+#define __riscv_vsetvlmax_e8m2() __builtin_rvv_vsetvlimax(0, 1)
+#define __riscv_vsetvlmax_e8m4() __builtin_rvv_vsetvlimax(0, 2)
+#define __riscv_vsetvlmax_e8m8() __builtin_rvv_vsetvlimax(0, 3)
+
+#define __riscv_vsetvlmax_e16mf2() __builtin_rvv_vsetvlimax(1, 7)
+#define __riscv_vsetvlmax_e16m1() __builtin_rvv_vsetvlimax(1, 0)
+#define __riscv_vsetvlmax_e16m2() __builtin_rvv_vsetvlimax(1, 1)
+#define __riscv_vsetvlmax_e16m4() __builtin_rvv_vsetvlimax(1, 2)
+#define __riscv_vsetvlmax_e16m8() __builtin_rvv_vsetvlimax(1, 3)
+
+#define __riscv_vsetvlmax_e32m1() __builtin_rvv_vsetvlimax(2, 0)
+#define __riscv_vsetvlmax_e32m2() __builtin_rvv_vsetvlimax(2, 1)
+#define __riscv_vsetvlmax_e32m4() __builtin_rvv_vsetvlimax(2, 2)
+#define __riscv_vsetvlmax_e32m8() __builtin_rvv_vsetvlimax(2, 3)
+
+#if __riscv_v_elen >= 64
+#define __riscv_vsetvlmax_e8mf8() __builtin_rvv_vsetvlimax(0, 5)
+#define __riscv_vsetvlmax_e16mf4() __builtin_rvv_vsetvlimax(1, 6)
+#define __riscv_vsetvlmax_e32mf2() __builtin_rvv_vsetvlimax(2, 7)
+
+#define __riscv_vsetvlmax_e64m1() __builtin_rvv_vsetvlimax(3, 0)
+#define __riscv_vsetvlmax_e64m2() __builtin_rvv_vsetvlimax(3, 1)
+#define __riscv_vsetvlmax_e64m4() __builtin_rvv_vsetvlimax(3, 2)
+#define __riscv_vsetvlmax_e64m8() __builtin_rvv_vsetvlimax(3, 3)
+#endif
+
+}] in
+def vsetvl_macro: RVVHeader;
+
+let HasBuiltinAlias = false,
+ HasVL = false,
+ HasMasked = false,
+ MaskedPolicyScheme = NonePolicy,
+ Log2LMUL = [0],
+ ManualCodegen = [{IntrinsicTypes = {ResultType};}] in // Set XLEN type
+{
+ def vsetvli : RVVBuiltin<"", "zzKzKz", "i">;
+ def vsetvlimax : RVVBuiltin<"", "zKzKz", "i">;
+}
+
+// 7. Vector Loads and Stores
+// 7.4. Vector Unit-Stride Instructions
+def vlm: RVVVLEMaskBuiltin;
+defm vle8: RVVVLEBuiltin<["c"]>;
+defm vle16: RVVVLEBuiltin<["s"]>;
+let Name = "vle16_v", RequiredFeatures = ["Zvfhmin"] in
+ defm vle16_h: RVVVLEBuiltin<["x"]>;
+defm vle32: RVVVLEBuiltin<["i","f"]>;
+defm vle64: RVVVLEBuiltin<["l","d"]>;
+
+def vsm : RVVVSEMaskBuiltin;
+defm vse8 : RVVVSEBuiltin<["c"]>;
+defm vse16: RVVVSEBuiltin<["s"]>;
+let Name = "vse16_v", RequiredFeatures = ["Zvfhmin"] in
+ defm vse16_h: RVVVSEBuiltin<["x"]>;
+defm vse32: RVVVSEBuiltin<["i","f"]>;
+defm vse64: RVVVSEBuiltin<["l","d"]>;
+
+// 7.5. Vector Strided Instructions
+defm vlse8: RVVVLSEBuiltin<["c"]>;
+defm vlse16: RVVVLSEBuiltin<["s"]>;
+let Name = "vlse16_v", RequiredFeatures = ["Zvfhmin"] in
+ defm vlse16_h: RVVVLSEBuiltin<["x"]>;
+defm vlse32: RVVVLSEBuiltin<["i","f"]>;
+defm vlse64: RVVVLSEBuiltin<["l","d"]>;
+
+defm vsse8 : RVVVSSEBuiltin<["c"]>;
+defm vsse16: RVVVSSEBuiltin<["s"]>;
+let Name = "vsse16_v", RequiredFeatures = ["Zvfhmin"] in
+ defm vsse16_h: RVVVSSEBuiltin<["x"]>;
+defm vsse32: RVVVSSEBuiltin<["i","f"]>;
+defm vsse64: RVVVSSEBuiltin<["l","d"]>;
+
+// 7.6. Vector Indexed Instructions
+defm : RVVIndexedLoad<"vluxei">;
+defm : RVVIndexedLoad<"vloxei">;
+
+defm : RVVIndexedStore<"vsuxei">;
+defm : RVVIndexedStore<"vsoxei">;
+
+// 7.7. Unit-stride Fault-Only-First Loads
+defm vle8ff: RVVVLEFFBuiltin<["c"]>;
+defm vle16ff: RVVVLEFFBuiltin<["s"]>;
+let Name = "vle16ff_v", RequiredFeatures = ["Zvfhmin"] in
+ defm vle16ff: RVVVLEFFBuiltin<["x"]>;
+defm vle32ff: RVVVLEFFBuiltin<["i", "f"]>;
+defm vle64ff: RVVVLEFFBuiltin<["l", "d"]>;
+
+multiclass RVVUnitStridedSegLoadTuple<string op> {
foreach type = TypeList in {
defvar eew = !cond(!eq(type, "c") : "8",
!eq(type, "s") : "16",
@@ -799,65 +736,56 @@ multiclass RVVUnitStridedSegLoad<string op> {
foreach nf = NFList in {
let Name = op # nf # "e" # eew # "_v",
IRName = op # nf,
- IRNameMask = op # nf # "_mask",
+ MaskedIRName = op # nf # "_mask",
NF = nf,
- HasNoMaskedOverloaded = false,
+ RequiredFeatures = !if(!eq(type, "x"), ["Zvfhmin"],
+ []<string>),
ManualCodegen = [{
{
- // builtin: (val0 address, val1 address, ..., ptr, vl)
- IntrinsicTypes = {Ops[0]->getType()->getPointerElementType(),
- Ops[NF + 1]->getType()};
- // intrinsic: (ptr, vl)
- llvm::Value *Operands[] = {Ops[NF], Ops[NF + 1]};
- llvm::Function *F = CGM.getIntrinsic(ID, IntrinsicTypes);
- llvm::Value *LoadValue = Builder.CreateCall(F, Operands, "");
- clang::CharUnits Align = CharUnits::fromQuantity(
- IntrinsicTypes[0]->getScalarSizeInBits() / 8);
- llvm::Value *V;
- for (unsigned I = 0; I < NF; ++I) {
- V = Builder.CreateStore(Builder.CreateExtractValue(LoadValue, {I}),
- Address(Ops[I], Align));
- }
- return V;
- }
- }],
- ManualCodegenMask = [{
- {
- // builtin: (val0 address, ..., mask, maskedoff0, ..., ptr, vl)
- // intrinsic: (maskedoff0, ..., ptr, mask, vl)
- IntrinsicTypes = {Ops[0]->getType()->getPointerElementType(),
- Ops[2 * NF + 2]->getType()};
+ llvm::Type *ElementVectorType = cast<StructType>(ResultType)->elements()[0];
+ IntrinsicTypes = {ElementVectorType, Ops.back()->getType()};
SmallVector<llvm::Value*, 12> Operands;
- for (unsigned I = 0; I < NF; ++I)
- Operands.push_back(Ops[NF + I + 1]);
- Operands.push_back(Ops[2 * NF + 1]);
- Operands.push_back(Ops[NF]);
- Operands.push_back(Ops[2 * NF + 2]);
- assert(Operands.size() == NF + 3);
+
+ bool NoPassthru =
+ (IsMasked && (PolicyAttrs & RVV_VTA) && (PolicyAttrs & RVV_VMA)) |
+ (!IsMasked && (PolicyAttrs & RVV_VTA));
+ unsigned Offset = IsMasked ? NoPassthru ? 1 : 2 : NoPassthru ? 0 : 1;
+
+ if (NoPassthru) { // Push poison into passthru
+ Operands.append(NF, llvm::PoisonValue::get(ElementVectorType));
+ } else { // Push intrinsics operands into passthru
+ llvm::Value *PassthruOperand = IsMasked ? Ops[1] : Ops[0];
+ for (unsigned I = 0; I < NF; ++I)
+ Operands.push_back(Builder.CreateExtractValue(PassthruOperand, {I}));
+ }
+
+ Operands.push_back(Ops[Offset]); // Ptr
+ if (IsMasked)
+ Operands.push_back(Ops[0]);
+ Operands.push_back(Ops[Offset + 1]); // VL
+ if (IsMasked)
+ Operands.push_back(ConstantInt::get(Ops.back()->getType(), PolicyAttrs));
+
llvm::Function *F = CGM.getIntrinsic(ID, IntrinsicTypes);
+
llvm::Value *LoadValue = Builder.CreateCall(F, Operands, "");
- clang::CharUnits Align = CharUnits::fromQuantity(
- IntrinsicTypes[0]->getScalarSizeInBits() / 8);
- llvm::Value *V;
- for (unsigned I = 0; I < NF; ++I) {
- V = Builder.CreateStore(Builder.CreateExtractValue(LoadValue, {I}),
- Address(Ops[I], Align));
- }
- return V;
+ if (ReturnValue.isNull())
+ return LoadValue;
+ else
+ return Builder.CreateStore(LoadValue, ReturnValue.getValue());
}
- }] in {
- defvar PV = PVString<nf, /*signed=*/true>.S;
- defvar PUV = PVString<nf, /*signed=*/false>.S;
- def : RVVBuiltin<"v", "0" # PV # "PCe", type>;
- if !not(IsFloat<type>.val) then {
- def : RVVBuiltin<"Uv", "0" # PUV # "PCUe", type>;
+ }] in {
+ defvar T = "(Tuple:" # nf # ")";
+ def : RVVBuiltin<T # "v", T # "vPCe", type>;
+ if !not(IsFloat<type>.val) then {
+ def : RVVBuiltin<T # "Uv", T # "UvPCUe", type>;
}
}
}
}
}
-multiclass RVVUnitStridedSegLoadFF<string op> {
+multiclass RVVUnitStridedSegStoreTuple<string op> {
foreach type = TypeList in {
defvar eew = !cond(!eq(type, "c") : "8",
!eq(type, "s") : "16",
@@ -867,71 +795,50 @@ multiclass RVVUnitStridedSegLoadFF<string op> {
!eq(type, "f") : "32",
!eq(type, "d") : "64");
foreach nf = NFList in {
- let Name = op # nf # "e" # eew # "ff_v",
- IRName = op # nf # "ff",
- IRNameMask = op # nf # "ff_mask",
- NF = nf,
- HasNoMaskedOverloaded = false,
- ManualCodegen = [{
- {
- // builtin: (val0 address, val1 address, ..., ptr, new_vl, vl)
- IntrinsicTypes = {Ops[0]->getType()->getPointerElementType(),
- Ops[NF + 2]->getType()};
- // intrinsic: (ptr, vl)
- llvm::Value *Operands[] = {Ops[NF], Ops[NF + 2]};
- Value *NewVL = Ops[NF + 1];
- llvm::Function *F = CGM.getIntrinsic(ID, IntrinsicTypes);
- llvm::Value *LoadValue = Builder.CreateCall(F, Operands, "");
- clang::CharUnits Align = CharUnits::fromQuantity(
- IntrinsicTypes[0]->getScalarSizeInBits() / 8);
- for (unsigned I = 0; I < NF; ++I) {
- Builder.CreateStore(Builder.CreateExtractValue(LoadValue, {I}),
- Address(Ops[I], Align));
- }
- // Store new_vl.
- return Builder.CreateStore(Builder.CreateExtractValue(LoadValue, {NF}),
- Address(NewVL, Align));
- }
- }],
- ManualCodegenMask = [{
+ let Name = op # nf # "e" # eew # "_v",
+ IRName = op # nf,
+ MaskedIRName = op # nf # "_mask",
+ NF = nf,
+ HasMaskedOffOperand = false,
+ RequiredFeatures = !if(!eq(type, "x"), ["Zvfhmin"],
+ []<string>),
+ ManualCodegen = [{
{
- // builtin: (val0 address, ..., mask, maskedoff0, ..., ptr, new_vl, vl)
- // intrinsic: (maskedoff0, ..., ptr, mask, vl)
- IntrinsicTypes = {Ops[0]->getType()->getPointerElementType(),
- Ops[2 * NF + 3]->getType()};
+ // Masked
+ // Builtin: (mask, ptr, v_tuple, vl)
+ // Intrinsic: (val0, val1, ..., ptr, mask, vl)
+ // Unmasked
+ // Builtin: (ptr, v_tuple, vl)
+ // Intrinsic: (val0, val1, ..., ptr, vl)
+ unsigned Offset = IsMasked ? 1 : 0;
+ llvm::Value *VTupleOperand = Ops[Offset + 1];
+
SmallVector<llvm::Value*, 12> Operands;
- for (unsigned I = 0; I < NF; ++I)
- Operands.push_back(Ops[NF + I + 1]);
- Operands.push_back(Ops[2 * NF + 1]);
- Operands.push_back(Ops[NF]);
- Operands.push_back(Ops[2 * NF + 3]);
- Value *NewVL = Ops[2 * NF + 2];
- assert(Operands.size() == NF + 3);
- llvm::Function *F = CGM.getIntrinsic(ID, IntrinsicTypes);
- llvm::Value *LoadValue = Builder.CreateCall(F, Operands, "");
- clang::CharUnits Align = CharUnits::fromQuantity(
- IntrinsicTypes[0]->getScalarSizeInBits() / 8);
for (unsigned I = 0; I < NF; ++I) {
- Builder.CreateStore(Builder.CreateExtractValue(LoadValue, {I}),
- Address(Ops[I], Align));
+ llvm::Value *V = Builder.CreateExtractValue(VTupleOperand, {I});
+ Operands.push_back(V);
}
- // Store new_vl.
- return Builder.CreateStore(Builder.CreateExtractValue(LoadValue, {NF}),
- Address(NewVL, Align));
- }
- }] in {
- defvar PV = PVString<nf, /*signed=*/true>.S;
- defvar PUV = PVString<nf, /*signed=*/false>.S;
- def : RVVBuiltin<"v", "0" # PV # "PCe" # "Pz", type>;
- if !not(IsFloat<type>.val) then {
- def : RVVBuiltin<"Uv", "0" # PUV # "PCUe" # "Pz", type>;
+ Operands.push_back(Ops[Offset]); // Ptr
+ if (IsMasked)
+ Operands.push_back(Ops[0]);
+ Operands.push_back(Ops[Offset + 2]); // VL
+
+ IntrinsicTypes = {Operands[0]->getType(), Operands.back()->getType()};
+ llvm::Function *F = CGM.getIntrinsic(ID, IntrinsicTypes);
+ return Builder.CreateCall(F, Operands, "");
+ }
+ }] in {
+ defvar T = "(Tuple:" # nf # ")";
+ def : RVVBuiltin<T # "v", "0Pe" # T # "v", type>;
+ if !not(IsFloat<type>.val) then {
+ def : RVVBuiltin<T # "Uv", "0PUe" # T # "Uv", type>;
}
}
}
}
}
-multiclass RVVStridedSegLoad<string op> {
+multiclass RVVUnitStridedSegLoadFFTuple<string op> {
foreach type = TypeList in {
defvar eew = !cond(!eq(type, "c") : "8",
!eq(type, "s") : "16",
@@ -941,145 +848,134 @@ multiclass RVVStridedSegLoad<string op> {
!eq(type, "f") : "32",
!eq(type, "d") : "64");
foreach nf = NFList in {
- let Name = op # nf # "e" # eew # "_v",
- IRName = op # nf,
- IRNameMask = op # nf # "_mask",
+ let Name = op # nf # "e" # eew # "ff_v",
+ IRName = op # nf # "ff",
+ MaskedIRName = op # nf # "ff_mask",
NF = nf,
- HasNoMaskedOverloaded = false,
+ RequiredFeatures = !if(!eq(type, "x"), ["Zvfhmin"],
+ []<string>),
ManualCodegen = [{
{
- // builtin: (val0 address, val1 address, ..., ptr, stride, vl)
- IntrinsicTypes = {Ops[0]->getType()->getPointerElementType(),
- Ops[NF + 2]->getType()};
- // intrinsic: (ptr, stride, vl)
- llvm::Value *Operands[] = {Ops[NF], Ops[NF + 1], Ops[NF + 2]};
- llvm::Function *F = CGM.getIntrinsic(ID, IntrinsicTypes);
- llvm::Value *LoadValue = Builder.CreateCall(F, Operands, "");
- clang::CharUnits Align = CharUnits::fromQuantity(
- IntrinsicTypes[0]->getScalarSizeInBits() / 8);
- llvm::Value *V;
- for (unsigned I = 0; I < NF; ++I) {
- V = Builder.CreateStore(Builder.CreateExtractValue(LoadValue, {I}),
- Address(Ops[I], Align));
- }
- return V;
- }
- }],
- ManualCodegenMask = [{
- {
- // builtin: (val0 address, ..., mask, maskedoff0, ..., ptr, stride, vl)
- // intrinsic: (maskedoff0, ..., ptr, stride, mask, vl)
- IntrinsicTypes = {Ops[0]->getType()->getPointerElementType(),
- Ops[2 * NF + 3]->getType()};
+ llvm::Type *ElementVectorType = cast<StructType>(ResultType)->elements()[0];
+ IntrinsicTypes = {ElementVectorType, Ops.back()->getType()};
SmallVector<llvm::Value*, 12> Operands;
- for (unsigned I = 0; I < NF; ++I)
- Operands.push_back(Ops[NF + I + 1]);
- Operands.push_back(Ops[2 * NF + 1]);
- Operands.push_back(Ops[2 * NF + 2]);
- Operands.push_back(Ops[NF]);
- Operands.push_back(Ops[2 * NF + 3]);
- assert(Operands.size() == NF + 4);
+
+ bool NoPassthru =
+ (IsMasked && (PolicyAttrs & RVV_VTA) && (PolicyAttrs & RVV_VMA)) |
+ (!IsMasked && (PolicyAttrs & RVV_VTA));
+ unsigned Offset = IsMasked ? NoPassthru ? 1 : 2 : NoPassthru ? 0 : 1;
+
+ if (NoPassthru) { // Push poison into passthru
+ Operands.append(NF, llvm::PoisonValue::get(ElementVectorType));
+ } else { // Push intrinsics operands into passthru
+ llvm::Value *PassthruOperand = IsMasked ? Ops[1] : Ops[0];
+ for (unsigned I = 0; I < NF; ++I)
+ Operands.push_back(Builder.CreateExtractValue(PassthruOperand, {I}));
+ }
+
+ Operands.push_back(Ops[Offset]); // Ptr
+ if (IsMasked)
+ Operands.push_back(Ops[0]);
+ Operands.push_back(Ops[Offset + 2]); // vl
+ if (IsMasked)
+ Operands.push_back(ConstantInt::get(Ops.back()->getType(), PolicyAttrs));
+
llvm::Function *F = CGM.getIntrinsic(ID, IntrinsicTypes);
+
llvm::Value *LoadValue = Builder.CreateCall(F, Operands, "");
- clang::CharUnits Align = CharUnits::fromQuantity(
- IntrinsicTypes[0]->getScalarSizeInBits() / 8);
- llvm::Value *V;
+ // Get alignment from the new vl operand
+ clang::CharUnits Align =
+ CGM.getNaturalPointeeTypeAlignment(E->getArg(Offset + 1)->getType());
+
+ llvm::Value *ReturnTuple = llvm::PoisonValue::get(ResultType);
for (unsigned I = 0; I < NF; ++I) {
- V = Builder.CreateStore(Builder.CreateExtractValue(LoadValue, {I}),
- Address(Ops[I], Align));
+ llvm::Value *V = Builder.CreateExtractValue(LoadValue, {I});
+ ReturnTuple = Builder.CreateInsertValue(ReturnTuple, V, {I});
}
- return V;
+
+ // Store new_vl
+ llvm::Value *V = Builder.CreateExtractValue(LoadValue, {NF});
+ Builder.CreateStore(V, Address(Ops[Offset + 1], V->getType(), Align));
+
+ if (ReturnValue.isNull())
+ return ReturnTuple;
+ else
+ return Builder.CreateStore(ReturnTuple, ReturnValue.getValue());
}
- }] in {
- defvar PV = PVString<nf, /*signed=*/true>.S;
- defvar PUV = PVString<nf, /*signed=*/false>.S;
- def : RVVBuiltin<"v", "0" # PV # "PCe" # "t", type>;
- if !not(IsFloat<type>.val) then {
- def : RVVBuiltin<"Uv", "0" # PUV # "PCUe" # "t", type>;
+ }] in {
+ defvar T = "(Tuple:" # nf # ")";
+ def : RVVBuiltin<T # "v", T # "vPCePz", type>;
+ if !not(IsFloat<type>.val) then {
+ def : RVVBuiltin<T # "Uv", T # "UvPCUePz", type>;
}
}
}
}
}
-multiclass RVVIndexedSegLoad<string op> {
+multiclass RVVStridedSegLoadTuple<string op> {
foreach type = TypeList in {
- foreach eew_info = EEWList in {
- defvar eew = eew_info[0];
- defvar eew_type = eew_info[1];
+ defvar eew = !cond(!eq(type, "c") : "8",
+ !eq(type, "s") : "16",
+ !eq(type, "i") : "32",
+ !eq(type, "l") : "64",
+ !eq(type, "x") : "16",
+ !eq(type, "f") : "32",
+ !eq(type, "d") : "64");
foreach nf = NFList in {
- let Name = op # nf # "ei" # eew # "_v",
+ let Name = op # nf # "e" # eew # "_v",
IRName = op # nf,
- IRNameMask = op # nf # "_mask",
+ MaskedIRName = op # nf # "_mask",
NF = nf,
+ RequiredFeatures = !if(!eq(type, "x"), ["Zvfhmin"],
+ []<string>),
ManualCodegen = [{
{
- // builtin: (val0 address, val1 address, ..., ptr, index, vl)
- IntrinsicTypes = {Ops[0]->getType()->getPointerElementType(),
- Ops[NF + 1]->getType(), Ops[NF + 2]->getType()};
- // intrinsic: (ptr, index, vl)
- llvm::Value *Operands[] = {Ops[NF], Ops[NF + 1], Ops[NF + 2]};
- llvm::Function *F = CGM.getIntrinsic(ID, IntrinsicTypes);
- llvm::Value *LoadValue = Builder.CreateCall(F, Operands, "");
- clang::CharUnits Align = CharUnits::fromQuantity(
- IntrinsicTypes[0]->getScalarSizeInBits() / 8);
- llvm::Value *V;
- for (unsigned I = 0; I < NF; ++I) {
- V = Builder.CreateStore(Builder.CreateExtractValue(LoadValue, {I}),
- Address(Ops[I], Align));
- }
- return V;
- }
- }],
- ManualCodegenMask = [{
- {
- // builtin: (val0 address, ..., mask, maskedoff0, ..., ptr, index, vl)
- IntrinsicTypes = {Ops[0]->getType()->getPointerElementType(),
- Ops[2 * NF + 2]->getType(), Ops[2 * NF + 3]->getType()};
- // intrinsic: (maskedoff0, ..., ptr, index, mask, vl)
+ llvm::Type *ElementVectorType = cast<StructType>(ResultType)->elements()[0];
+ IntrinsicTypes = {ElementVectorType, Ops.back()->getType()};
SmallVector<llvm::Value*, 12> Operands;
- for (unsigned I = 0; I < NF; ++I)
- Operands.push_back(Ops[NF + I + 1]);
- Operands.push_back(Ops[2 * NF + 1]);
- Operands.push_back(Ops[2 * NF + 2]);
- Operands.push_back(Ops[NF]);
- Operands.push_back(Ops[2 * NF + 3]);
- assert(Operands.size() == NF + 4);
+
+ bool NoPassthru =
+ (IsMasked && (PolicyAttrs & RVV_VTA) && (PolicyAttrs & RVV_VMA)) |
+ (!IsMasked && (PolicyAttrs & RVV_VTA));
+ unsigned Offset = IsMasked ? NoPassthru ? 1 : 2 : NoPassthru ? 0 : 1;
+
+ if (NoPassthru) { // Push poison into passthru
+ Operands.append(NF, llvm::PoisonValue::get(ElementVectorType));
+ } else { // Push intrinsics operands into passthru
+ llvm::Value *PassthruOperand = IsMasked ? Ops[1] : Ops[0];
+ for (unsigned I = 0; I < NF; ++I)
+ Operands.push_back(Builder.CreateExtractValue(PassthruOperand, {I}));
+ }
+
+ Operands.push_back(Ops[Offset]); // Ptr
+ Operands.push_back(Ops[Offset + 1]); // Stride
+ if (IsMasked)
+ Operands.push_back(Ops[0]);
+ Operands.push_back(Ops[Offset + 2]); // VL
+ if (IsMasked)
+ Operands.push_back(ConstantInt::get(Ops.back()->getType(), PolicyAttrs));
+
llvm::Function *F = CGM.getIntrinsic(ID, IntrinsicTypes);
llvm::Value *LoadValue = Builder.CreateCall(F, Operands, "");
- clang::CharUnits Align = CharUnits::fromQuantity(
- IntrinsicTypes[0]->getScalarSizeInBits() / 8);
- llvm::Value *V;
- for (unsigned I = 0; I < NF; ++I) {
- V = Builder.CreateStore(Builder.CreateExtractValue(LoadValue, {I}),
- Address(Ops[I], Align));
- }
- return V;
+
+ if (ReturnValue.isNull())
+ return LoadValue;
+ else
+ return Builder.CreateStore(LoadValue, ReturnValue.getValue());
}
- }] in {
- defvar PV = PVString<nf, /*signed=*/true>.S;
- defvar PUV = PVString<nf, /*signed=*/false>.S;
- def : RVVBuiltin<"v", "0" # PV # "PCe" # eew_type # "Uv", type>;
- if !not(IsFloat<type>.val) then {
- def : RVVBuiltin<"Uv", "0" # PUV # "PCUe" # eew_type # "Uv", type>;
- }
+ }] in {
+ defvar T = "(Tuple:" # nf # ")";
+ def : RVVBuiltin<T # "v", T # "vPCet", type>;
+ if !not(IsFloat<type>.val) then {
+ def : RVVBuiltin<T # "Uv", T # "UvPCUet", type>;
}
}
}
}
}
-class VString<int nf, bit signed> {
- string S = !cond(!eq(nf, 2): !if(signed, "vv", "UvUv"),
- !eq(nf, 3): !if(signed, "vvv", "UvUvUv"),
- !eq(nf, 4): !if(signed, "vvvv", "UvUvUvUv"),
- !eq(nf, 5): !if(signed, "vvvvv", "UvUvUvUvUv"),
- !eq(nf, 6): !if(signed, "vvvvvv", "UvUvUvUvUvUv"),
- !eq(nf, 7): !if(signed, "vvvvvvv", "UvUvUvUvUvUvUv"),
- !eq(nf, 8): !if(signed, "vvvvvvvv", "UvUvUvUvUvUvUvUv"));
-}
-
-multiclass RVVUnitStridedSegStore<string op> {
+multiclass RVVStridedSegStoreTuple<string op> {
foreach type = TypeList in {
defvar eew = !cond(!eq(type, "c") : "8",
!eq(type, "s") : "16",
@@ -1091,85 +987,111 @@ multiclass RVVUnitStridedSegStore<string op> {
foreach nf = NFList in {
let Name = op # nf # "e" # eew # "_v",
IRName = op # nf,
- IRNameMask = op # nf # "_mask",
+ MaskedIRName = op # nf # "_mask",
NF = nf,
HasMaskedOffOperand = false,
+ MaskedPolicyScheme = NonePolicy,
+ RequiredFeatures = !if(!eq(type, "x"), ["Zvfhmin"],
+ []<string>),
ManualCodegen = [{
{
- // Builtin: (ptr, val0, val1, ..., vl)
- // Intrinsic: (val0, val1, ..., ptr, vl)
- std::rotate(Ops.begin(), Ops.begin() + 1, Ops.end() - 1);
- IntrinsicTypes = {Ops[0]->getType(), Ops[NF + 1]->getType()};
- assert(Ops.size() == NF + 2);
- }
- }],
- ManualCodegenMask = [{
- {
- // Builtin: (mask, ptr, val0, val1, ..., vl)
- // Intrinsic: (val0, val1, ..., ptr, mask, vl)
- std::rotate(Ops.begin(), Ops.begin() + 2, Ops.end() - 1);
- std::swap(Ops[NF], Ops[NF + 1]);
- IntrinsicTypes = {Ops[0]->getType(), Ops[NF + 2]->getType()};
- assert(Ops.size() == NF + 3);
+ // Masked
+ // Builtin: (mask, ptr, stride, v_tuple, vl)
+ // Intrinsic: (val0, val1, ..., ptr, stride, mask, vl)
+ // Unmasked
+ // Builtin: (ptr, stride, v_tuple, vl)
+ // Intrinsic: (val0, val1, ..., ptr, stride, vl)
+ unsigned Offset = IsMasked ? 1 : 0;
+ llvm::Value *VTupleOperand = Ops[Offset + 2];
+
+ SmallVector<llvm::Value*, 12> Operands;
+ for (unsigned I = 0; I < NF; ++I) {
+ llvm::Value *V = Builder.CreateExtractValue(VTupleOperand, {I});
+ Operands.push_back(V);
+ }
+ Operands.push_back(Ops[Offset]); // Ptr
+ Operands.push_back(Ops[Offset + 1]); // Stride
+ if (IsMasked)
+ Operands.push_back(Ops[0]);
+ Operands.push_back(Ops[Offset + 3]); // VL
+
+ IntrinsicTypes = {Operands[0]->getType(), Operands.back()->getType()};
+ llvm::Function *F = CGM.getIntrinsic(ID, IntrinsicTypes);
+ return Builder.CreateCall(F, Operands, "");
}
}] in {
- defvar V = VString<nf, /*signed=*/true>.S;
- defvar UV = VString<nf, /*signed=*/false>.S;
- def : RVVBuiltin<"v", "0Pe" # V, type>;
- if !not(IsFloat<type>.val) then {
- def : RVVBuiltin<"Uv", "0PUe" # UV, type>;
+ defvar T = "(Tuple:" # nf # ")";
+ def : RVVBuiltin<T # "v", "0Pet" # T # "v", type>;
+ if !not(IsFloat<type>.val) then {
+ def : RVVBuiltin<T # "Uv", "0PUet" # T # "Uv", type>;
}
}
}
}
}
-multiclass RVVStridedSegStore<string op> {
+multiclass RVVIndexedSegLoadTuple<string op> {
foreach type = TypeList in {
- defvar eew = !cond(!eq(type, "c") : "8",
- !eq(type, "s") : "16",
- !eq(type, "i") : "32",
- !eq(type, "l") : "64",
- !eq(type, "x") : "16",
- !eq(type, "f") : "32",
- !eq(type, "d") : "64");
+ foreach eew_info = EEWList in {
+ defvar eew = eew_info[0];
+ defvar eew_type = eew_info[1];
foreach nf = NFList in {
- let Name = op # nf # "e" # eew # "_v",
+ let Name = op # nf # "ei" # eew # "_v",
IRName = op # nf,
- IRNameMask = op # nf # "_mask",
+ MaskedIRName = op # nf # "_mask",
NF = nf,
- HasMaskedOffOperand = false,
+ RequiredFeatures = !if(!eq(type, "x"), ["Zvfhmin"],
+ []<string>),
ManualCodegen = [{
{
- // Builtin: (ptr, stride, val0, val1, ..., vl).
- // Intrinsic: (val0, val1, ..., ptr, stride, vl)
- std::rotate(Ops.begin(), Ops.begin() + 2, Ops.end() - 1);
- IntrinsicTypes = {Ops[0]->getType(), Ops[NF + 1]->getType()};
- assert(Ops.size() == NF + 3);
- }
- }],
- ManualCodegenMask = [{
- {
- // Builtin: (mask, ptr, stride, val0, val1, ..., vl).
- // Intrinsic: (val0, val1, ..., ptr, stride, mask, vl)
- std::rotate(Ops.begin(), Ops.begin() + 3, Ops.end() - 1);
- std::rotate(Ops.begin() + NF, Ops.begin() + NF + 1, Ops.begin() + NF + 3);
- IntrinsicTypes = {Ops[0]->getType(), Ops[NF + 1]->getType()};
- assert(Ops.size() == NF + 4);
+ llvm::Type *ElementVectorType = cast<StructType>(ResultType)->elements()[0];
+ IntrinsicTypes = {ElementVectorType, Ops.back()->getType()};
+ SmallVector<llvm::Value*, 12> Operands;
+
+ bool NoPassthru =
+ (IsMasked && (PolicyAttrs & RVV_VTA) && (PolicyAttrs & RVV_VMA)) |
+ (!IsMasked && (PolicyAttrs & RVV_VTA));
+ unsigned Offset = IsMasked ? NoPassthru ? 1 : 2 : NoPassthru ? 0 : 1;
+
+ if (NoPassthru) { // Push poison into passthru
+ Operands.append(NF, llvm::PoisonValue::get(ElementVectorType));
+ } else { // Push intrinsics operands into passthru
+ llvm::Value *PassthruOperand = IsMasked ? Ops[1] : Ops[0];
+ for (unsigned I = 0; I < NF; ++I)
+ Operands.push_back(Builder.CreateExtractValue(PassthruOperand, {I}));
+ }
+
+ Operands.push_back(Ops[Offset]); // Ptr
+ Operands.push_back(Ops[Offset + 1]); // Idx
+ if (IsMasked)
+ Operands.push_back(Ops[0]);
+ Operands.push_back(Ops[Offset + 2]); // VL
+ if (IsMasked)
+ Operands.push_back(ConstantInt::get(Ops.back()->getType(), PolicyAttrs));
+
+ IntrinsicTypes = {ElementVectorType, Ops[Offset + 1]->getType(),
+ Ops.back()->getType()};
+ llvm::Function *F = CGM.getIntrinsic(ID, IntrinsicTypes);
+ llvm::Value *LoadValue = Builder.CreateCall(F, Operands, "");
+
+ if (ReturnValue.isNull())
+ return LoadValue;
+ else
+ return Builder.CreateStore(LoadValue, ReturnValue.getValue());
}
- }] in {
- defvar V = VString<nf, /*signed=*/true>.S;
- defvar UV = VString<nf, /*signed=*/false>.S;
- def : RVVBuiltin<"v", "0Pet" # V, type>;
+ }] in {
+ defvar T = "(Tuple:" # nf # ")";
+ def : RVVBuiltin<T # "v", T # "vPCe" # eew_type # "Uv", type>;
if !not(IsFloat<type>.val) then {
- def : RVVBuiltin<"Uv", "0PUet" # UV, type>;
+ def : RVVBuiltin<T # "Uv", T # "UvPCUe" # eew_type # "Uv", type>;
+ }
}
}
}
}
}
-multiclass RVVIndexedSegStore<string op> {
+multiclass RVVIndexedSegStoreTuple<string op> {
foreach type = TypeList in {
foreach eew_info = EEWList in {
defvar eew = eew_info[0];
@@ -1177,35 +1099,44 @@ multiclass RVVIndexedSegStore<string op> {
foreach nf = NFList in {
let Name = op # nf # "ei" # eew # "_v",
IRName = op # nf,
- IRNameMask = op # nf # "_mask",
+ MaskedIRName = op # nf # "_mask",
NF = nf,
HasMaskedOffOperand = false,
+ MaskedPolicyScheme = NonePolicy,
+ RequiredFeatures = !if(!eq(type, "x"), ["Zvfhmin"],
+ []<string>),
ManualCodegen = [{
{
- // Builtin: (ptr, index, val0, val1, ..., vl)
- // Intrinsic: (val0, val1, ..., ptr, index, vl)
- std::rotate(Ops.begin(), Ops.begin() + 2, Ops.end() - 1);
- IntrinsicTypes = {Ops[0]->getType(),
- Ops[NF + 1]->getType(), Ops[NF + 2]->getType()};
- assert(Ops.size() == NF + 3);
- }
- }],
- ManualCodegenMask = [{
- {
- // Builtin: (mask, ptr, index, val0, val1, ..., vl)
+ // Masked
+ // Builtin: (mask, ptr, index, v_tuple, vl)
// Intrinsic: (val0, val1, ..., ptr, index, mask, vl)
- std::rotate(Ops.begin(), Ops.begin() + 3, Ops.end() - 1);
- std::rotate(Ops.begin() + NF, Ops.begin() + NF + 1, Ops.begin() + NF + 3);
- IntrinsicTypes = {Ops[0]->getType(),
- Ops[NF + 1]->getType(), Ops[NF + 3]->getType()};
- assert(Ops.size() == NF + 4);
+ // Unmasked
+ // Builtin: (ptr, index, v_tuple, vl)
+ // Intrinsic: (val0, val1, ..., ptr, index, vl)
+ unsigned Offset = IsMasked ? 1 : 0;
+ llvm::Value *VTupleOperand = Ops[Offset + 2];
+
+ SmallVector<llvm::Value*, 12> Operands;
+ for (unsigned I = 0; I < NF; ++I) {
+ llvm::Value *V = Builder.CreateExtractValue(VTupleOperand, {I});
+ Operands.push_back(V);
+ }
+ Operands.push_back(Ops[Offset]); // Ptr
+ Operands.push_back(Ops[Offset + 1]); // Idx
+ if (IsMasked)
+ Operands.push_back(Ops[0]);
+ Operands.push_back(Ops[Offset + 3]); // VL
+
+ IntrinsicTypes = {Operands[0]->getType(), Ops[Offset + 1]->getType(),
+ Operands.back()->getType()};
+ llvm::Function *F = CGM.getIntrinsic(ID, IntrinsicTypes);
+ return Builder.CreateCall(F, Operands, "");
}
}] in {
- defvar V = VString<nf, /*signed=*/true>.S;
- defvar UV = VString<nf, /*signed=*/false>.S;
- def : RVVBuiltin<"v", "0Pe" # eew_type # "Uv" # V, type>;
+ defvar T = "(Tuple:" # nf # ")";
+ def : RVVBuiltin<T # "v", "0Pe" # eew_type # "Uv" # T # "v", type>;
if !not(IsFloat<type>.val) then {
- def : RVVBuiltin<"Uv", "0PUe" # eew_type # "Uv" # UV, type>;
+ def : RVVBuiltin<T # "Uv", "0PUe" # eew_type # "Uv" # T # "Uv", type>;
}
}
}
@@ -1213,358 +1144,39 @@ multiclass RVVIndexedSegStore<string op> {
}
}
-multiclass RVVAMOBuiltinSet<bit has_signed = false, bit has_unsigned = false,
- bit has_fp = false> {
- defvar type_list = !if(has_fp, ["i","l","f","d"], ["i","l"]);
- foreach type = type_list in
- foreach eew_list = EEWList in {
- defvar eew = eew_list[0];
- defvar eew_index = eew_list[1];
- let Name = NAME # "ei" # eew # "_" # "v",
- IRName = NAME,
- IRNameMask = NAME # "_mask",
- HasMaskedOffOperand = false,
- ManualCodegen = [{
- // base, bindex, value, vl
- IntrinsicTypes = {ResultType, Ops[1]->getType(), Ops[3]->getType()};
- Ops[0] = Builder.CreateBitCast(Ops[0], ResultType->getPointerTo());
- }],
- ManualCodegenMask = [{
- std::rotate(Ops.begin(), Ops.begin() + 1, Ops.end() - 1);
- IntrinsicTypes = {ResultType, Ops[1]->getType(), Ops[4]->getType()};
- Ops[0] = Builder.CreateBitCast(Ops[0], ResultType->getPointerTo());
- }] in {
- if has_signed then
- def : RVVBuiltin<"v", "vPe" # eew_index # "Uvv", type>;
- if !and(!not(IsFloat<type>.val), has_unsigned) then
- def : RVVBuiltin<"Uv", "UvPUe" # eew_index # "UvUv", type>;
- }
- }
-}
-
-multiclass RVVPseudoUnaryBuiltin<string IR, string type_range> {
- let Name = NAME,
- IRName = IR,
- IRNameMask = IR # "_mask",
- ManualCodegen = [{
- {
- // op1, vl
- IntrinsicTypes = {ResultType,
- cast<llvm::VectorType>(ResultType)->getElementType(),
- Ops[1]->getType()};
- Ops.insert(Ops.begin() + 1, llvm::Constant::getNullValue(IntrinsicTypes[1]));
- break;
- }
- }],
- ManualCodegenMask = [{
- {
- std::rotate(Ops.begin(), Ops.begin() + 1, Ops.end() - 1);
- // maskedoff, op1, mask, vl
- IntrinsicTypes = {ResultType,
- cast<llvm::VectorType>(ResultType)->getElementType(),
- Ops[3]->getType()};
- Ops.insert(Ops.begin() + 2, llvm::Constant::getNullValue(IntrinsicTypes[1]));
- break;
- }
- }] in {
- def : RVVBuiltin<"v", "vv", type_range>;
- }
-}
-
-multiclass RVVPseudoVNotBuiltin<string IR, string type_range> {
- let Name = NAME,
- IRName = IR,
- IRNameMask = IR # "_mask",
- ManualCodegen = [{
- {
- // op1, vl
- IntrinsicTypes = {ResultType,
- cast<llvm::VectorType>(ResultType)->getElementType(),
- Ops[1]->getType()};
- Ops.insert(Ops.begin() + 1,
- llvm::Constant::getAllOnesValue(IntrinsicTypes[1]));
- break;
- }
- }],
- ManualCodegenMask = [{
- {
- std::rotate(Ops.begin(), Ops.begin() + 1, Ops.end() - 1);
- // maskedoff, op1, mask, vl
- IntrinsicTypes = {ResultType,
- cast<llvm::VectorType>(ResultType)->getElementType(),
- Ops[3]->getType()};
- Ops.insert(Ops.begin() + 2,
- llvm::Constant::getAllOnesValue(IntrinsicTypes[1]));
- break;
- }
- }] in {
- def : RVVBuiltin<"v", "vv", type_range>;
- def : RVVBuiltin<"Uv", "UvUv", type_range>;
- }
-}
-
-multiclass RVVPseudoMaskBuiltin<string IR, string type_range> {
- let Name = NAME,
- IRName = IR,
- HasMask = false,
- ManualCodegen = [{
- {
- // op1, vl
- IntrinsicTypes = {ResultType,
- Ops[1]->getType()};
- Ops.insert(Ops.begin() + 1, Ops[0]);
- break;
- }
- }] in {
- def : RVVBuiltin<"m", "mm", type_range>;
- }
-}
-
-multiclass RVVPseudoVFUnaryBuiltin<string IR, string type_range> {
- let Name = NAME,
- IRName = IR,
- IRNameMask = IR # "_mask",
- ManualCodegen = [{
- {
- // op1, vl
- IntrinsicTypes = {ResultType,
- Ops[0]->getType(), Ops[1]->getType()};
- Ops.insert(Ops.begin() + 1, Ops[0]);
- break;
- }
- }],
- ManualCodegenMask = [{
- {
- std::rotate(Ops.begin(), Ops.begin() + 1, Ops.end() - 1);
- // maskedoff, op1, mask, vl
- IntrinsicTypes = {ResultType,
- Ops[1]->getType(),
- Ops[3]->getType()};
- Ops.insert(Ops.begin() + 2, Ops[1]);
- break;
- }
- }] in {
- def : RVVBuiltin<"v", "vv", type_range>;
- }
-}
-
-multiclass RVVPseudoVWCVTBuiltin<string IR, string MName, string type_range,
- list<list<string>> suffixes_prototypes> {
- let Name = NAME,
- MangledName = MName,
- IRName = IR,
- IRNameMask = IR # "_mask",
- ManualCodegen = [{
- {
- // op1, vl
- IntrinsicTypes = {ResultType,
- Ops[0]->getType(),
- cast<llvm::VectorType>(Ops[0]->getType())->getElementType(),
- Ops[1]->getType()};
- Ops.insert(Ops.begin() + 1, llvm::Constant::getNullValue(IntrinsicTypes[2]));
- break;
- }
- }],
- ManualCodegenMask = [{
- {
- std::rotate(Ops.begin(), Ops.begin() + 1, Ops.end() - 1);
- // maskedoff, op1, mask, vl
- IntrinsicTypes = {ResultType,
- Ops[1]->getType(),
- cast<llvm::VectorType>(Ops[1]->getType())->getElementType(),
- Ops[3]->getType()};
- Ops.insert(Ops.begin() + 2, llvm::Constant::getNullValue(IntrinsicTypes[2]));
- break;
- }
- }] in {
- foreach s_p = suffixes_prototypes in {
- def : RVVBuiltin<s_p[0], s_p[1], type_range>;
- }
- }
-}
-
-multiclass RVVPseudoVNCVTBuiltin<string IR, string MName, string type_range,
- list<list<string>> suffixes_prototypes> {
- let Name = NAME,
- MangledName = MName,
- IRName = IR,
- IRNameMask = IR # "_mask",
- ManualCodegen = [{
- {
- // op1, vl
- IntrinsicTypes = {ResultType,
- Ops[0]->getType(),
- Ops[1]->getType(),
- Ops[1]->getType()};
- Ops.insert(Ops.begin() + 1, llvm::Constant::getNullValue(IntrinsicTypes[2]));
- break;
- }
- }],
- ManualCodegenMask = [{
- {
- std::rotate(Ops.begin(), Ops.begin() + 1, Ops.end() - 1);
- // maskedoff, op1, mask, vl
- IntrinsicTypes = {ResultType,
- Ops[1]->getType(),
- Ops[3]->getType(),
- Ops[3]->getType()};
- Ops.insert(Ops.begin() + 2, llvm::Constant::getNullValue(IntrinsicTypes[2]));
- break;
- }
- }] in {
- foreach s_p = suffixes_prototypes in {
- def : RVVBuiltin<s_p[0], s_p[1], type_range>;
- }
- }
-}
-
-// 6. Configuration-Setting Instructions
-// 6.1. vsetvli/vsetvl instructions
-let HasVL = false,
- HasMask = false,
- HasSideEffects = true,
- Log2LMUL = [0],
- ManualCodegen = [{IntrinsicTypes = {ResultType};}] in // Set XLEN type
-{
- // vsetvl is a macro because for it require constant integers in SEW and LMUL.
- let HeaderCode =
-[{
-#define vsetvl_e8mf8(avl) __builtin_rvv_vsetvli((size_t)(avl), 0, 5)
-#define vsetvl_e8mf4(avl) __builtin_rvv_vsetvli((size_t)(avl), 0, 6)
-#define vsetvl_e8mf2(avl) __builtin_rvv_vsetvli((size_t)(avl), 0, 7)
-#define vsetvl_e8m1(avl) __builtin_rvv_vsetvli((size_t)(avl), 0, 0)
-#define vsetvl_e8m2(avl) __builtin_rvv_vsetvli((size_t)(avl), 0, 1)
-#define vsetvl_e8m4(avl) __builtin_rvv_vsetvli((size_t)(avl), 0, 2)
-#define vsetvl_e8m8(avl) __builtin_rvv_vsetvli((size_t)(avl), 0, 3)
-
-#define vsetvl_e16mf4(avl) __builtin_rvv_vsetvli((size_t)(avl), 1, 6)
-#define vsetvl_e16mf2(avl) __builtin_rvv_vsetvli((size_t)(avl), 1, 7)
-#define vsetvl_e16m1(avl) __builtin_rvv_vsetvli((size_t)(avl), 1, 0)
-#define vsetvl_e16m2(avl) __builtin_rvv_vsetvli((size_t)(avl), 1, 1)
-#define vsetvl_e16m4(avl) __builtin_rvv_vsetvli((size_t)(avl), 1, 2)
-#define vsetvl_e16m8(avl) __builtin_rvv_vsetvli((size_t)(avl), 1, 3)
-
-#define vsetvl_e32mf2(avl) __builtin_rvv_vsetvli((size_t)(avl), 2, 7)
-#define vsetvl_e32m1(avl) __builtin_rvv_vsetvli((size_t)(avl), 2, 0)
-#define vsetvl_e32m2(avl) __builtin_rvv_vsetvli((size_t)(avl), 2, 1)
-#define vsetvl_e32m4(avl) __builtin_rvv_vsetvli((size_t)(avl), 2, 2)
-#define vsetvl_e32m8(avl) __builtin_rvv_vsetvli((size_t)(avl), 2, 3)
-
-#define vsetvl_e64m1(avl) __builtin_rvv_vsetvli((size_t)(avl), 3, 0)
-#define vsetvl_e64m2(avl) __builtin_rvv_vsetvli((size_t)(avl), 3, 1)
-#define vsetvl_e64m4(avl) __builtin_rvv_vsetvli((size_t)(avl), 3, 2)
-#define vsetvl_e64m8(avl) __builtin_rvv_vsetvli((size_t)(avl), 3, 3)
-
-}] in
- def vsetvli : RVVBuiltin<"", "zzKzKz", "i">;
-
- let HeaderCode =
-[{
-#define vsetvlmax_e8mf8() __builtin_rvv_vsetvlimax(0, 5)
-#define vsetvlmax_e8mf4() __builtin_rvv_vsetvlimax(0, 6)
-#define vsetvlmax_e8mf2() __builtin_rvv_vsetvlimax(0, 7)
-#define vsetvlmax_e8m1() __builtin_rvv_vsetvlimax(0, 0)
-#define vsetvlmax_e8m2() __builtin_rvv_vsetvlimax(0, 1)
-#define vsetvlmax_e8m4() __builtin_rvv_vsetvlimax(0, 2)
-#define vsetvlmax_e8m8() __builtin_rvv_vsetvlimax(0, 3)
-
-#define vsetvlmax_e16mf4() __builtin_rvv_vsetvlimax(1, 6)
-#define vsetvlmax_e16mf2() __builtin_rvv_vsetvlimax(1, 7)
-#define vsetvlmax_e16m1() __builtin_rvv_vsetvlimax(1, 0)
-#define vsetvlmax_e16m2() __builtin_rvv_vsetvlimax(1, 1)
-#define vsetvlmax_e16m4() __builtin_rvv_vsetvlimax(1, 2)
-#define vsetvlmax_e16m8() __builtin_rvv_vsetvlimax(1, 3)
-
-#define vsetvlmax_e32mf2() __builtin_rvv_vsetvlimax(2, 7)
-#define vsetvlmax_e32m1() __builtin_rvv_vsetvlimax(2, 0)
-#define vsetvlmax_e32m2() __builtin_rvv_vsetvlimax(2, 1)
-#define vsetvlmax_e32m4() __builtin_rvv_vsetvlimax(2, 2)
-#define vsetvlmax_e32m8() __builtin_rvv_vsetvlimax(2, 3)
-
-#define vsetvlmax_e64m1() __builtin_rvv_vsetvlimax(3, 0)
-#define vsetvlmax_e64m2() __builtin_rvv_vsetvlimax(3, 1)
-#define vsetvlmax_e64m4() __builtin_rvv_vsetvlimax(3, 2)
-#define vsetvlmax_e64m8() __builtin_rvv_vsetvlimax(3, 3)
-
-}] in
- def vsetvlimax : RVVBuiltin<"", "zKzKz", "i">;
-}
-
-// 7. Vector Loads and Stores
-// 7.4. Vector Unit-Stride Instructions
-def vle1: RVVVLEMaskBuiltin;
-defm vle8: RVVVLEBuiltin<["c"]>;
-defm vle16: RVVVLEBuiltin<["s","x"]>;
-defm vle32: RVVVLEBuiltin<["i","f"]>;
-defm vle64: RVVVLEBuiltin<["l","d"]>;
-
-def vse1 : RVVVSEMaskBuiltin;
-defm vse8 : RVVVSEBuiltin<["c"]>;
-defm vse16: RVVVSEBuiltin<["s","x"]>;
-defm vse32: RVVVSEBuiltin<["i","f"]>;
-defm vse64: RVVVSEBuiltin<["l","d"]>;
-
-// 7.5. Vector Strided Instructions
-defm vlse8: RVVVLSEBuiltin<["c"]>;
-defm vlse16: RVVVLSEBuiltin<["s","x"]>;
-defm vlse32: RVVVLSEBuiltin<["i","f"]>;
-defm vlse64: RVVVLSEBuiltin<["l","d"]>;
-
-defm vsse8 : RVVVSSEBuiltin<["c"]>;
-defm vsse16: RVVVSSEBuiltin<["s","x"]>;
-defm vsse32: RVVVSSEBuiltin<["i","f"]>;
-defm vsse64: RVVVSSEBuiltin<["l","d"]>;
-
-// 7.6. Vector Indexed Instructions
-defm : RVVIndexedLoad<"vluxei">;
-defm : RVVIndexedLoad<"vloxei">;
-
-defm : RVVIndexedStore<"vsuxei">;
-defm : RVVIndexedStore<"vsoxei">;
-
-// 7.7. Unit-stride Fault-Only-First Loads
-defm vle8ff: RVVVLEFFBuiltin<["c"]>;
-defm vle16ff: RVVVLEFFBuiltin<["s","x"]>;
-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">;
-defm : RVVIndexedSegLoad<"vluxseg">;
-defm : RVVIndexedSegLoad<"vloxseg">;
-defm : RVVUnitStridedSegStore<"vsseg">;
-defm : RVVStridedSegStore<"vssseg">;
-defm : RVVIndexedSegStore<"vsuxseg">;
-defm : RVVIndexedSegStore<"vsoxseg">;
-}
-
-// 8. Vector AMO Operations
-let RequiredExtension = "Zvamo" in {
-defm vamoswap : RVVAMOBuiltinSet< /* hasSigned */ true, /* hasUnsigned */ true, /* hasFP */ true>;
-defm vamoadd : RVVAMOBuiltinSet< /* hasSigned */ true, /* hasUnsigned */ true>;
-defm vamoxor : RVVAMOBuiltinSet< /* hasSigned */ true, /* hasUnsigned */ true>;
-defm vamoand : RVVAMOBuiltinSet< /* hasSigned */ true, /* hasUnsigned */ true>;
-defm vamoor : RVVAMOBuiltinSet< /* hasSigned */ true, /* hasUnsigned */ true>;
-defm vamomin : RVVAMOBuiltinSet< /* hasSigned */ true>;
-defm vamomax : RVVAMOBuiltinSet< /* hasSigned */ true>;
-defm vamominu : RVVAMOBuiltinSet< /* hasSigned */ false, /* hasUnsigned */ true>;
-defm vamomaxu : RVVAMOBuiltinSet< /* hasSigned */ false, /* hasUnsigned */ true>;
-}
-
-// 12. Vector Integer Arithmetic Instructions
-// 12.1. Vector Single-Width Integer Add and Subtract
+let UnMaskedPolicyScheme = HasPassthruOperand,
+ IsTuple = true in {
+ defm : RVVUnitStridedSegLoadTuple<"vlseg">;
+ defm : RVVUnitStridedSegLoadFFTuple<"vlseg">;
+ defm : RVVStridedSegLoadTuple<"vlsseg">;
+ defm : RVVIndexedSegLoadTuple<"vluxseg">;
+ defm : RVVIndexedSegLoadTuple<"vloxseg">;
+}
+
+let UnMaskedPolicyScheme = NonePolicy,
+ MaskedPolicyScheme = NonePolicy,
+ IsTuple = true in {
+defm : RVVUnitStridedSegStoreTuple<"vsseg">;
+defm : RVVStridedSegStoreTuple<"vssseg">;
+defm : RVVIndexedSegStoreTuple<"vsuxseg">;
+defm : RVVIndexedSegStoreTuple<"vsoxseg">;
+}
+
+// 11. Vector Integer Arithmetic Instructions
+// 11.1. Vector Single-Width Integer Add and Subtract
+let UnMaskedPolicyScheme = HasPassthruOperand in {
defm vadd : RVVIntBinBuiltinSet;
defm vsub : RVVIntBinBuiltinSet;
defm vrsub : RVVOutOp1BuiltinSet<"vrsub", "csil",
[["vx", "v", "vve"],
["vx", "Uv", "UvUvUe"]]>;
+}
defm vneg_v : RVVPseudoUnaryBuiltin<"vrsub", "csil">;
-// 12.2. Vector Widening Integer Add/Subtract
+// 11.2. Vector Widening Integer Add/Subtract
// Widening unsigned integer add/subtract, 2*SEW = SEW +/- SEW
+let UnMaskedPolicyScheme = HasPassthruOperand in {
defm vwaddu : RVVUnsignedWidenBinBuiltinSet;
defm vwsubu : RVVUnsignedWidenBinBuiltinSet;
// Widening signed integer add/subtract, 2*SEW = SEW +/- SEW
@@ -1576,12 +1188,14 @@ defm vwsubu : RVVUnsignedWidenOp0BinBuiltinSet;
// Widening signed integer add/subtract, 2*SEW = 2*SEW +/- SEW
defm vwadd : RVVSignedWidenOp0BinBuiltinSet;
defm vwsub : RVVSignedWidenOp0BinBuiltinSet;
+}
defm vwcvtu_x_x_v : RVVPseudoVWCVTBuiltin<"vwaddu", "vwcvtu_x", "csi",
[["Uw", "UwUv"]]>;
defm vwcvt_x_x_v : RVVPseudoVWCVTBuiltin<"vwadd", "vwcvt_x", "csi",
[["w", "wv"]]>;
-// 12.3. Vector Integer Extension
+// 11.3. Vector Integer Extension
+let UnMaskedPolicyScheme = HasPassthruOperand in {
let Log2LMUL = [-3, -2, -1, 0, 1, 2] in {
def vsext_vf2 : RVVIntExt<"vsext", "w", "wv", "csi">;
def vzext_vf2 : RVVIntExt<"vzext", "Uw", "UwUv", "csi">;
@@ -1594,36 +1208,45 @@ let Log2LMUL = [-3, -2, -1, 0] in {
def vsext_vf8 : RVVIntExt<"vsext", "o", "ov", "c">;
def vzext_vf8 : RVVIntExt<"vzext", "Uo", "UoUv", "c">;
}
+}
-// 12.4. Vector Integer Add-with-Carry / Subtract-with-Borrow Instructions
-let HasMask = false in {
- defm vadc : RVVCarryinBuiltinSet;
+// 11.4. Vector Integer Add-with-Carry / Subtract-with-Borrow Instructions
+let HasMasked = false, MaskedPolicyScheme = NonePolicy in {
+ let UnMaskedPolicyScheme = HasPassthruOperand in {
+ defm vadc : RVVCarryinBuiltinSet;
+ defm vsbc : RVVCarryinBuiltinSet;
+ }
defm vmadc : RVVCarryOutInBuiltinSet<"vmadc_carry_in">;
defm vmadc : RVVIntMaskOutBuiltinSet;
- defm vsbc : RVVCarryinBuiltinSet;
defm vmsbc : RVVCarryOutInBuiltinSet<"vmsbc_borrow_in">;
defm vmsbc : RVVIntMaskOutBuiltinSet;
}
-// 12.5. Vector Bitwise Logical Instructions
+// 11.5. Vector Bitwise Logical Instructions
+let UnMaskedPolicyScheme = HasPassthruOperand in {
defm vand : RVVIntBinBuiltinSet;
defm vxor : RVVIntBinBuiltinSet;
defm vor : RVVIntBinBuiltinSet;
+}
defm vnot_v : RVVPseudoVNotBuiltin<"vxor", "csil">;
-// 12.6. Vector Single-Width Bit Shift Instructions
+// 11.6. Vector Single-Width Shift Instructions
+let UnMaskedPolicyScheme = HasPassthruOperand in {
defm vsll : RVVShiftBuiltinSet;
defm vsrl : RVVUnsignedShiftBuiltinSet;
defm vsra : RVVSignedShiftBuiltinSet;
-// 12.7. Vector Narrowing Integer Right Shift Instructions
+// 11.7. Vector Narrowing Integer Right Shift Instructions
defm vnsrl : RVVUnsignedNShiftBuiltinSet;
defm vnsra : RVVSignedNShiftBuiltinSet;
+}
defm vncvt_x_x_w : RVVPseudoVNCVTBuiltin<"vnsrl", "vncvt_x", "csi",
[["v", "vw"],
["Uv", "UvUw"]]>;
-// 12.8. Vector Integer Comparison Instructions
+// 11.8. Vector Integer Compare Instructions
+let MaskedPolicyScheme = HasPassthruOperand,
+ HasTailPolicy = false in {
defm vmseq : RVVIntMaskOutBuiltinSet;
defm vmsne : RVVIntMaskOutBuiltinSet;
defm vmsltu : RVVUnsignedMaskOutBuiltinSet;
@@ -1634,14 +1257,16 @@ defm vmsgtu : RVVUnsignedMaskOutBuiltinSet;
defm vmsgt : RVVSignedMaskOutBuiltinSet;
defm vmsgeu : RVVUnsignedMaskOutBuiltinSet;
defm vmsge : RVVSignedMaskOutBuiltinSet;
+}
-// 12.9. Vector Integer Min/Max Instructions
+// 11.9. Vector Integer Min/Max Instructions
+let UnMaskedPolicyScheme = HasPassthruOperand in {
defm vminu : RVVUnsignedBinBuiltinSet;
defm vmin : RVVSignedBinBuiltinSet;
defm vmaxu : RVVUnsignedBinBuiltinSet;
defm vmax : RVVSignedBinBuiltinSet;
-// 12.10. Vector Single-Width Integer Multiply Instructions
+// 11.10. Vector Single-Width Integer Multiply Instructions
defm vmul : RVVIntBinBuiltinSet;
defm vmulh : RVVSignedBinBuiltinSet;
defm vmulhu : RVVUnsignedBinBuiltinSet;
@@ -1649,14 +1274,15 @@ defm vmulhsu : RVVOutOp1BuiltinSet<"vmulhsu", "csil",
[["vv", "v", "vvUv"],
["vx", "v", "vvUe"]]>;
-// 12.11. Vector Integer Divide Instructions
+// 11.11. Vector Integer Divide Instructions
defm vdivu : RVVUnsignedBinBuiltinSet;
defm vdiv : RVVSignedBinBuiltinSet;
defm vremu : RVVUnsignedBinBuiltinSet;
defm vrem : RVVSignedBinBuiltinSet;
+}
-// 12.12. Vector Widening Integer Multiply Instructions
-let Log2LMUL = [-3, -2, -1, 0, 1, 2] in {
+// 11.12. Vector Widening Integer Multiply Instructions
+let Log2LMUL = [-3, -2, -1, 0, 1, 2], UnMaskedPolicyScheme = HasPassthruOperand in {
defm vwmul : RVVOutOp0Op1BuiltinSet<"vwmul", "csi",
[["vv", "w", "wvv"],
["vx", "w", "wve"]]>;
@@ -1668,13 +1294,14 @@ defm vwmulsu : RVVOutOp0Op1BuiltinSet<"vwmulsu", "csi",
["vx", "w", "wvUe"]]>;
}
-// 12.13. Vector Single-Width Integer Multiply-Add Instructions
+// 11.13. Vector Single-Width Integer Multiply-Add Instructions
+let UnMaskedPolicyScheme = HasPolicyOperand in {
defm vmacc : RVVIntTerBuiltinSet;
defm vnmsac : RVVIntTerBuiltinSet;
defm vmadd : RVVIntTerBuiltinSet;
defm vnmsub : RVVIntTerBuiltinSet;
-// 12.14. Vector Widening Integer Multiply-Add Instructions
+// 11.14. Vector Widening Integer Multiply-Add Instructions
let HasMaskedOffOperand = false,
Log2LMUL = [-3, -2, -1, 0, 1, 2] in {
defm vwmaccu : RVVOutOp1Op2BuiltinSet<"vwmaccu", "csi",
@@ -1689,184 +1316,713 @@ defm vwmaccsu : RVVOutOp1Op2BuiltinSet<"vwmaccsu", "csi",
defm vwmaccus : RVVOutOp1Op2BuiltinSet<"vwmaccus", "csi",
[["vx", "w", "wwUev"]]>;
}
+}
-// 12.15. Vector Integer Merge Instructions
-// C/C++ Operand: (mask, op1, op2, vl), Intrinsic: (op1, op2, mask, vl)
-let HasMask = false,
+// 11.15. Vector Integer Merge Instructions
+// C/C++ Operand: (mask, op1, op2, vl), Intrinsic: (passthru, op1, op2, mask, vl)
+let HasMasked = false,
+ UnMaskedPolicyScheme = HasPassthruOperand,
+ MaskedPolicyScheme = NonePolicy,
ManualCodegen = [{
- std::rotate(Ops.begin(), Ops.begin() + 1, Ops.begin() + 3);
- IntrinsicTypes = {ResultType, Ops[1]->getType(), Ops[3]->getType()};
+ // insert poison passthru
+ if (PolicyAttrs & RVV_VTA)
+ Ops.insert(Ops.begin(), llvm::PoisonValue::get(ResultType));
+ IntrinsicTypes = {ResultType, Ops[2]->getType(), Ops.back()->getType()};
}] in {
defm vmerge : RVVOutOp1BuiltinSet<"vmerge", "csil",
- [["vvm", "v", "vmvv"],
- ["vxm", "v", "vmve"],
- ["vvm", "Uv", "UvmUvUv"],
- ["vxm", "Uv", "UvmUvUe"]]>;
+ [["vvm", "v", "vvvm"],
+ ["vxm", "v", "vvem"],
+ ["vvm", "Uv", "UvUvUvm"],
+ ["vxm", "Uv", "UvUvUem"]]>;
}
-// 12.16. Vector Integer Move Instructions
-let HasMask = false in {
- let MangledName = "vmv_v" in {
+// 11.16. Vector Integer Move Instructions
+let HasMasked = false,
+ UnMaskedPolicyScheme = HasPassthruOperand,
+ MaskedPolicyScheme = NonePolicy,
+ OverloadedName = "vmv_v" in {
defm vmv_v : RVVOutBuiltinSet<"vmv_v_v", "csil",
[["v", "Uv", "UvUv"]]>;
- defm vmv_v : RVVOutBuiltinSet<"vmv_v_v", "csilxfd",
+ defm vmv_v : RVVOutBuiltinSet<"vmv_v_v", "csilfd",
[["v", "v", "vv"]]>;
- }
- let HasNoMaskedOverloaded = false in
+ let RequiredFeatures = ["Zvfhmin"] in
+ defm vmv_v : RVVOutBuiltinSet<"vmv_v_v", "x",
+ [["v", "v", "vv"]]>;
+ let SupportOverloading = false in
defm vmv_v : RVVOutBuiltinSet<"vmv_v_x", "csil",
[["x", "v", "ve"],
["x", "Uv", "UvUe"]]>;
}
-// 13. Vector Fixed-Point Arithmetic Instructions
-// 13.1. Vector Single-Width Saturating Add and Subtract
+// 12. Vector Fixed-Point Arithmetic Instructions
+let HeaderCode =
+[{
+enum __RISCV_VXRM {
+ __RISCV_VXRM_RNU = 0,
+ __RISCV_VXRM_RNE = 1,
+ __RISCV_VXRM_RDN = 2,
+ __RISCV_VXRM_ROD = 3,
+};
+}] in
+def vxrm_enum : RVVHeader;
+
+// 12.1. Vector Single-Width Saturating Add and Subtract
+let UnMaskedPolicyScheme = HasPassthruOperand in {
defm vsaddu : RVVUnsignedBinBuiltinSet;
defm vsadd : RVVSignedBinBuiltinSet;
defm vssubu : RVVUnsignedBinBuiltinSet;
defm vssub : RVVSignedBinBuiltinSet;
-// 13.2. Vector Single-Width Averaging Add and Subtract
-defm vaaddu : RVVUnsignedBinBuiltinSet;
-defm vaadd : RVVSignedBinBuiltinSet;
-defm vasubu : RVVUnsignedBinBuiltinSet;
-defm vasub : RVVSignedBinBuiltinSet;
-
-// 13.3. Vector Single-Width Fractional Multiply with Rounding and Saturation
-defm vsmul : RVVSignedBinBuiltinSet;
-
-// 13.4. Vector Single-Width Scaling Shift Instructions
-defm vssrl : RVVUnsignedShiftBuiltinSet;
-defm vssra : RVVSignedShiftBuiltinSet;
-
-// 13.5. Vector Narrowing Fixed-Point Clip Instructions
-defm vnclipu : RVVUnsignedNShiftBuiltinSet;
-defm vnclip : RVVSignedNShiftBuiltinSet;
-
-// 14. Vector Floating-Point Instructions
-// 14.2. Vector Single-Width Floating-Point Add/Subtract Instructions
-defm vfadd : RVVFloatingBinBuiltinSet;
-defm vfsub : RVVFloatingBinBuiltinSet;
-defm vfrsub : RVVFloatingBinVFBuiltinSet;
-
-// 14.3. Vector Widening Floating-Point Add/Subtract Instructions
-// Widening FP add/subtract, 2*SEW = SEW +/- SEW
-defm vfwadd : RVVFloatingWidenBinBuiltinSet;
-defm vfwsub : RVVFloatingWidenBinBuiltinSet;
-// Widening FP add/subtract, 2*SEW = 2*SEW +/- SEW
-defm vfwadd : RVVFloatingWidenOp0BinBuiltinSet;
-defm vfwsub : RVVFloatingWidenOp0BinBuiltinSet;
-
-// 14.4. Vector Single-Width Floating-Point Multiply/Divide Instructions
-defm vfmul : RVVFloatingBinBuiltinSet;
-defm vfdiv : RVVFloatingBinBuiltinSet;
-defm vfrdiv : RVVFloatingBinVFBuiltinSet;
-
-// 14.5. Vector Widening Floating-Point Multiply
-let Log2LMUL = [-2, -1, 0, 1, 2] in {
- defm vfwmul : RVVOutOp0Op1BuiltinSet<"vfwmul", "xf",
- [["vv", "w", "wvv"],
- ["vf", "w", "wve"]]>;
-}
-
-// 14.6. Vector Single-Width Floating-Point Fused Multiply-Add Instructions
-defm vfmacc : RVVFloatingTerBuiltinSet;
-defm vfnmacc : RVVFloatingTerBuiltinSet;
-defm vfmsac : RVVFloatingTerBuiltinSet;
-defm vfnmsac : RVVFloatingTerBuiltinSet;
-defm vfmadd : RVVFloatingTerBuiltinSet;
-defm vfnmadd : RVVFloatingTerBuiltinSet;
-defm vfmsub : RVVFloatingTerBuiltinSet;
-defm vfnmsub : RVVFloatingTerBuiltinSet;
-
-// 14.7. Vector Widening Floating-Point Fused Multiply-Add Instructions
-defm vfwmacc : RVVFloatingWidenTerBuiltinSet;
-defm vfwnmacc : RVVFloatingWidenTerBuiltinSet;
-defm vfwmsac : RVVFloatingWidenTerBuiltinSet;
-defm vfwnmsac : RVVFloatingWidenTerBuiltinSet;
-
-// 14.8. Vector Floating-Point Square-Root Instruction
-def vfsqrt : RVVFloatingUnaryVVBuiltin;
-
-// 14.9. Vector Floating-Point Reciprocal Square-Root Estimate Instruction
-def vfrsqrt7 : RVVFloatingUnaryVVBuiltin;
+let ManualCodegen = [{
+ {
+ // LLVM intrinsic
+ // Unmasked: (passthru, op0, op1, round_mode, vl)
+ // Masked: (passthru, vector_in, vector_in/scalar_in, mask, vxrm, vl, policy)
+
+ SmallVector<llvm::Value*, 7> Operands;
+ bool HasMaskedOff = !(
+ (IsMasked && (PolicyAttrs & RVV_VTA) && (PolicyAttrs & RVV_VMA)) ||
+ (!IsMasked && PolicyAttrs & RVV_VTA));
+ unsigned Offset = IsMasked ?
+ (HasMaskedOff ? 2 : 1) : (HasMaskedOff ? 1 : 0);
+
+ if (!HasMaskedOff)
+ Operands.push_back(llvm::PoisonValue::get(ResultType));
+ else
+ Operands.push_back(Ops[IsMasked ? 1 : 0]);
+
+ Operands.push_back(Ops[Offset]); // op0
+ Operands.push_back(Ops[Offset + 1]); // op1
+
+ if (IsMasked)
+ Operands.push_back(Ops[0]); // mask
+
+ Operands.push_back(Ops[Offset + 2]); // vxrm
+ Operands.push_back(Ops[Offset + 3]); // vl
+
+ if (IsMasked)
+ Operands.push_back(ConstantInt::get(Ops.back()->getType(), PolicyAttrs));
+
+ IntrinsicTypes = {ResultType, Ops[Offset + 1]->getType(), Ops.back()->getType()};
+ llvm::Function *F = CGM.getIntrinsic(ID, IntrinsicTypes);
+ return Builder.CreateCall(F, Operands, "");
+ }
+}] in {
+ // 12.2. Vector Single-Width Averaging Add and Subtract
+ defm vaaddu : RVVUnsignedBinBuiltinSetRoundingMode;
+ defm vaadd : RVVSignedBinBuiltinSetRoundingMode;
+ defm vasubu : RVVUnsignedBinBuiltinSetRoundingMode;
+ defm vasub : RVVSignedBinBuiltinSetRoundingMode;
+
+ // 12.3. Vector Single-Width Fractional Multiply with Rounding and Saturation
+ defm vsmul : RVVSignedBinBuiltinSetRoundingMode;
+
+ // 12.4. Vector Single-Width Scaling Shift Instructions
+ defm vssrl : RVVUnsignedShiftBuiltinSetRoundingMode;
+ defm vssra : RVVSignedShiftBuiltinSetRoundingMode;
+}
+
+let ManualCodegen = [{
+ {
+ // LLVM intrinsic
+ // Unmasked: (passthru, op0, op1, round_mode, vl)
+ // Masked: (passthru, vector_in, vector_in/scalar_in, mask, vxrm, vl, policy)
+
+ SmallVector<llvm::Value*, 7> Operands;
+ bool HasMaskedOff = !(
+ (IsMasked && (PolicyAttrs & RVV_VTA) && (PolicyAttrs & RVV_VMA)) ||
+ (!IsMasked && PolicyAttrs & RVV_VTA));
+ unsigned Offset = IsMasked ?
+ (HasMaskedOff ? 2 : 1) : (HasMaskedOff ? 1 : 0);
+
+ if (!HasMaskedOff)
+ Operands.push_back(llvm::PoisonValue::get(ResultType));
+ else
+ Operands.push_back(Ops[IsMasked ? 1 : 0]);
+
+ Operands.push_back(Ops[Offset]); // op0
+ Operands.push_back(Ops[Offset + 1]); // op1
+
+ if (IsMasked)
+ Operands.push_back(Ops[0]); // mask
+
+ Operands.push_back(Ops[Offset + 2]); // vxrm
+ Operands.push_back(Ops[Offset + 3]); // vl
+
+ if (IsMasked)
+ Operands.push_back(ConstantInt::get(Ops.back()->getType(), PolicyAttrs));
+
+ IntrinsicTypes = {ResultType, Ops[Offset]->getType(), Ops[Offset + 1]->getType(),
+ Ops.back()->getType()};
+ llvm::Function *F = CGM.getIntrinsic(ID, IntrinsicTypes);
+ return Builder.CreateCall(F, Operands, "");
+ }
+}] in {
+ // 12.5. Vector Narrowing Fixed-Point Clip Instructions
+ defm vnclipu : RVVUnsignedNShiftBuiltinSetRoundingMode;
+ defm vnclip : RVVSignedNShiftBuiltinSetRoundingMode;
+}
+}
+
+// 13. Vector Floating-Point Instructions
+let HeaderCode =
+[{
+enum __RISCV_FRM {
+ __RISCV_FRM_RNE = 0,
+ __RISCV_FRM_RTZ = 1,
+ __RISCV_FRM_RDN = 2,
+ __RISCV_FRM_RUP = 3,
+ __RISCV_FRM_RMM = 4,
+};
+}] in def frm_enum : RVVHeader;
+
+let UnMaskedPolicyScheme = HasPassthruOperand in {
+let ManualCodegen = [{
+ {
+ // LLVM intrinsic
+ // Unmasked: (passthru, op0, op1, round_mode, vl)
+ // Masked: (passthru, vector_in, vector_in/scalar_in, mask, frm, vl, policy)
+
+ SmallVector<llvm::Value*, 7> Operands;
+ bool HasMaskedOff = !(
+ (IsMasked && (PolicyAttrs & RVV_VTA) && (PolicyAttrs & RVV_VMA)) ||
+ (!IsMasked && PolicyAttrs & RVV_VTA));
+ bool HasRoundModeOp = IsMasked ?
+ (HasMaskedOff ? Ops.size() == 6 : Ops.size() == 5) :
+ (HasMaskedOff ? Ops.size() == 5 : Ops.size() == 4);
+
+ unsigned Offset = IsMasked ?
+ (HasMaskedOff ? 2 : 1) : (HasMaskedOff ? 1 : 0);
+
+ if (!HasMaskedOff)
+ Operands.push_back(llvm::PoisonValue::get(ResultType));
+ else
+ Operands.push_back(Ops[IsMasked ? 1 : 0]);
+
+ Operands.push_back(Ops[Offset]); // op0
+ Operands.push_back(Ops[Offset + 1]); // op1
+
+ if (IsMasked)
+ Operands.push_back(Ops[0]); // mask
+
+ if (HasRoundModeOp) {
+ Operands.push_back(Ops[Offset + 2]); // frm
+ Operands.push_back(Ops[Offset + 3]); // vl
+ } else {
+ Operands.push_back(ConstantInt::get(Ops[Offset + 2]->getType(), 7)); // frm
+ Operands.push_back(Ops[Offset + 2]); // vl
+ }
+
+ if (IsMasked)
+ Operands.push_back(ConstantInt::get(Ops.back()->getType(), PolicyAttrs));
+
+ IntrinsicTypes = {ResultType, Ops[Offset + 1]->getType(),
+ Operands.back()->getType()};
+ llvm::Function *F = CGM.getIntrinsic(ID, IntrinsicTypes);
+ return Builder.CreateCall(F, Operands, "");
+ }
+}] in {
+ let HasFRMRoundModeOp = true in {
+ // 13.2. Vector Single-Width Floating-Point Add/Subtract Instructions
+ defm vfadd : RVVFloatingBinBuiltinSetRoundingMode;
+ defm vfsub : RVVFloatingBinBuiltinSetRoundingMode;
+ defm vfrsub : RVVFloatingBinVFBuiltinSetRoundingMode;
+
+ // 13.3. Vector Widening Floating-Point Add/Subtract Instructions
+ // Widening FP add/subtract, 2*SEW = 2*SEW +/- SEW
+ defm vfwadd : RVVFloatingWidenOp0BinBuiltinSetRoundingMode;
+ defm vfwsub : RVVFloatingWidenOp0BinBuiltinSetRoundingMode;
+
+ // 13.4. Vector Single-Width Floating-Point Multiply/Divide Instructions
+ defm vfmul : RVVFloatingBinBuiltinSetRoundingMode;
+ defm vfdiv : RVVFloatingBinBuiltinSetRoundingMode;
+ defm vfrdiv : RVVFloatingBinVFBuiltinSetRoundingMode;
+ }
+ // 13.2. Vector Single-Width Floating-Point Add/Subtract Instructions
+ defm vfadd : RVVFloatingBinBuiltinSet;
+ defm vfsub : RVVFloatingBinBuiltinSet;
+ defm vfrsub : RVVFloatingBinVFBuiltinSet;
+
+ // 13.3. Vector Widening Floating-Point Add/Subtract Instructions
+ // Widening FP add/subtract, 2*SEW = 2*SEW +/- SEW
+ defm vfwadd : RVVFloatingWidenOp0BinBuiltinSet;
+ defm vfwsub : RVVFloatingWidenOp0BinBuiltinSet;
+
+ // 13.4. Vector Single-Width Floating-Point Multiply/Divide Instructions
+ defm vfmul : RVVFloatingBinBuiltinSet;
+ defm vfdiv : RVVFloatingBinBuiltinSet;
+ defm vfrdiv : RVVFloatingBinVFBuiltinSet;
+}
+
+let ManualCodegen = [{
+ {
+ // LLVM intrinsic
+ // Unmasked: (passthru, op0, op1, round_mode, vl)
+ // Masked: (passthru, vector_in, vector_in/scalar_in, mask, frm, vl, policy)
+
+ SmallVector<llvm::Value*, 7> Operands;
+ bool HasMaskedOff = !(
+ (IsMasked && (PolicyAttrs & RVV_VTA) && (PolicyAttrs & RVV_VMA)) ||
+ (!IsMasked && PolicyAttrs & RVV_VTA));
+ bool HasRoundModeOp = IsMasked ?
+ (HasMaskedOff ? Ops.size() == 6 : Ops.size() == 5) :
+ (HasMaskedOff ? Ops.size() == 5 : Ops.size() == 4);
+
+ unsigned Offset = IsMasked ?
+ (HasMaskedOff ? 2 : 1) : (HasMaskedOff ? 1 : 0);
+
+ if (!HasMaskedOff)
+ Operands.push_back(llvm::PoisonValue::get(ResultType));
+ else
+ Operands.push_back(Ops[IsMasked ? 1 : 0]);
+
+ Operands.push_back(Ops[Offset]); // op0
+ Operands.push_back(Ops[Offset + 1]); // op1
+
+ if (IsMasked)
+ Operands.push_back(Ops[0]); // mask
+
+ if (HasRoundModeOp) {
+ Operands.push_back(Ops[Offset + 2]); // frm
+ Operands.push_back(Ops[Offset + 3]); // vl
+ } else {
+ Operands.push_back(ConstantInt::get(Ops[Offset + 2]->getType(), 7)); // frm
+ Operands.push_back(Ops[Offset + 2]); // vl
+ }
+
+ if (IsMasked)
+ Operands.push_back(ConstantInt::get(Ops.back()->getType(), PolicyAttrs));
+
+ IntrinsicTypes = {ResultType, Ops[Offset]->getType(), Ops[Offset + 1]->getType(),
+ Ops.back()->getType()};
+ llvm::Function *F = CGM.getIntrinsic(ID, IntrinsicTypes);
+ return Builder.CreateCall(F, Operands, "");
+ }
+}] in {
+ let HasFRMRoundModeOp = true in {
+ // 13.3. Vector Widening Floating-Point Add/Subtract Instructions
+ // Widening FP add/subtract, 2*SEW = SEW +/- SEW
+ defm vfwadd : RVVFloatingWidenBinBuiltinSetRoundingMode;
+ defm vfwsub : RVVFloatingWidenBinBuiltinSetRoundingMode;
+
+ // 13.5. Vector Widening Floating-Point Multiply
+ let Log2LMUL = [-2, -1, 0, 1, 2] in {
+ defm vfwmul : RVVOutOp0Op1BuiltinSet<"vfwmul", "xf",
+ [["vv", "w", "wvvu"],
+ ["vf", "w", "wveu"]]>;
+ }
+ }
+ // 13.3. Vector Widening Floating-Point Add/Subtract Instructions
+ // Widening FP add/subtract, 2*SEW = SEW +/- SEW
+ defm vfwadd : RVVFloatingWidenBinBuiltinSet;
+ defm vfwsub : RVVFloatingWidenBinBuiltinSet;
+
+ // 13.5. Vector Widening Floating-Point Multiply
+ let Log2LMUL = [-2, -1, 0, 1, 2] in {
+ defm vfwmul : RVVOutOp0Op1BuiltinSet<"vfwmul", "xf",
+ [["vv", "w", "wvv"],
+ ["vf", "w", "wve"]]>;
+ }
+}
+}
+
+
+let UnMaskedPolicyScheme = HasPolicyOperand in {
+let ManualCodegen = [{
+ {
+ // LLVM intrinsic
+ // Unmasked: (passthru, op0, op1, round_mode, vl)
+ // Masked: (passthru, vector_in, vector_in/scalar_in, mask, frm, vl, policy)
+
+ SmallVector<llvm::Value*, 7> Operands;
+ bool HasRoundModeOp = IsMasked ? Ops.size() == 6 : Ops.size() == 5;
+
+ unsigned Offset = IsMasked ? 2 : 1;
+
+ Operands.push_back(Ops[IsMasked ? 1 : 0]); // passthrough
+
+ Operands.push_back(Ops[Offset]); // op0
+ Operands.push_back(Ops[Offset + 1]); // op1
+
+ if (IsMasked)
+ Operands.push_back(Ops[0]); // mask
+
+ if (HasRoundModeOp) {
+ Operands.push_back(Ops[Offset + 2]); // frm
+ Operands.push_back(Ops[Offset + 3]); // vl
+ } else {
+ Operands.push_back(ConstantInt::get(Ops[Offset + 2]->getType(), 7)); // frm
+ Operands.push_back(Ops[Offset + 2]); // vl
+ }
+
+ Operands.push_back(ConstantInt::get(Ops.back()->getType(), PolicyAttrs));
+
+ IntrinsicTypes = {ResultType, Ops[Offset]->getType(),
+ Operands.back()->getType()};
+
+ llvm::Function *F = CGM.getIntrinsic(ID, IntrinsicTypes);
+
+ return Builder.CreateCall(F, Operands, "");
+ }
+}] in {
+ let HasFRMRoundModeOp = 1 in {
+ // 13.6. Vector Single-Width Floating-Point Fused Multiply-Add Instructions
+ defm vfmacc : RVVFloatingTerBuiltinSetRoundingMode;
+ defm vfnmacc : RVVFloatingTerBuiltinSetRoundingMode;
+ defm vfmsac : RVVFloatingTerBuiltinSetRoundingMode;
+ defm vfnmsac : RVVFloatingTerBuiltinSetRoundingMode;
+ defm vfmadd : RVVFloatingTerBuiltinSetRoundingMode;
+ defm vfnmadd : RVVFloatingTerBuiltinSetRoundingMode;
+ defm vfmsub : RVVFloatingTerBuiltinSetRoundingMode;
+ defm vfnmsub : RVVFloatingTerBuiltinSetRoundingMode;
+ }
+ // 13.6. Vector Single-Width Floating-Point Fused Multiply-Add Instructions
+ defm vfmacc : RVVFloatingTerBuiltinSet;
+ defm vfnmacc : RVVFloatingTerBuiltinSet;
+ defm vfmsac : RVVFloatingTerBuiltinSet;
+ defm vfnmsac : RVVFloatingTerBuiltinSet;
+ defm vfmadd : RVVFloatingTerBuiltinSet;
+ defm vfnmadd : RVVFloatingTerBuiltinSet;
+ defm vfmsub : RVVFloatingTerBuiltinSet;
+ defm vfnmsub : RVVFloatingTerBuiltinSet;
+}
+
+let ManualCodegen = [{
+ {
+ // LLVM intrinsic
+ // Unmasked: (passthru, op0, op1, round_mode, vl)
+ // Masked: (passthru, vector_in, vector_in/scalar_in, mask, frm, vl, policy)
+
+ SmallVector<llvm::Value*, 7> Operands;
+ bool HasRoundModeOp = IsMasked ? Ops.size() == 6 : Ops.size() == 5;
+
+ unsigned Offset = IsMasked ? 2 : 1;
+
+ Operands.push_back(Ops[IsMasked ? 1 : 0]); // passthrough
+
+ Operands.push_back(Ops[Offset]); // op0
+ Operands.push_back(Ops[Offset + 1]); // op1
+
+ if (IsMasked)
+ Operands.push_back(Ops[0]); // mask
+
+ if (HasRoundModeOp) {
+ Operands.push_back(Ops[Offset + 2]); // frm
+ Operands.push_back(Ops[Offset + 3]); // vl
+ } else {
+ Operands.push_back(ConstantInt::get(Ops[Offset + 2]->getType(), 7)); // frm
+ Operands.push_back(Ops[Offset + 2]); // vl
+ }
+
+ Operands.push_back(ConstantInt::get(Ops.back()->getType(), PolicyAttrs));
+
+ IntrinsicTypes = {ResultType, Ops[Offset]->getType(), Ops[Offset + 1]->getType(),
+ Operands.back()->getType()};
+
+ llvm::Function *F = CGM.getIntrinsic(ID, IntrinsicTypes);
+
+ return Builder.CreateCall(F, Operands, "");
+ }
+}] in {
+ let HasFRMRoundModeOp = 1 in {
+ // 13.7. Vector Widening Floating-Point Fused Multiply-Add Instructions
+ defm vfwmacc : RVVFloatingWidenTerBuiltinSetRoundingMode;
+ defm vfwnmacc : RVVFloatingWidenTerBuiltinSetRoundingMode;
+ defm vfwmsac : RVVFloatingWidenTerBuiltinSetRoundingMode;
+ defm vfwnmsac : RVVFloatingWidenTerBuiltinSetRoundingMode;
+ }
+ // 13.7. Vector Widening Floating-Point Fused Multiply-Add Instructions
+ defm vfwmacc : RVVFloatingWidenTerBuiltinSet;
+ defm vfwnmacc : RVVFloatingWidenTerBuiltinSet;
+ defm vfwmsac : RVVFloatingWidenTerBuiltinSet;
+ defm vfwnmsac : RVVFloatingWidenTerBuiltinSet;
+}
+
+}
+
+let UnMaskedPolicyScheme = HasPassthruOperand in {
+let ManualCodegen = [{
+ {
+ // LLVM intrinsic
+ // Unmasked: (passthru, op0, round_mode, vl)
+ // Masked: (passthru, op0, mask, frm, vl, policy)
+
+ SmallVector<llvm::Value*, 7> Operands;
+ bool HasMaskedOff = !(
+ (IsMasked && (PolicyAttrs & RVV_VTA) && (PolicyAttrs & RVV_VMA)) ||
+ (!IsMasked && PolicyAttrs & RVV_VTA));
+ bool HasRoundModeOp = IsMasked ?
+ (HasMaskedOff ? Ops.size() == 5 : Ops.size() == 4) :
+ (HasMaskedOff ? Ops.size() == 4 : Ops.size() == 3);
+
+ unsigned Offset = IsMasked ?
+ (HasMaskedOff ? 2 : 1) : (HasMaskedOff ? 1 : 0);
+
+ if (!HasMaskedOff)
+ Operands.push_back(llvm::PoisonValue::get(ResultType));
+ else
+ Operands.push_back(Ops[IsMasked ? 1 : 0]);
+
+ Operands.push_back(Ops[Offset]); // op0
-// 14.10. Vector Floating-Point Reciprocal Estimate Instruction
-def vfrec7 : RVVFloatingUnaryVVBuiltin;
+ if (IsMasked)
+ Operands.push_back(Ops[0]); // mask
-// 14.11. Vector Floating-Point MIN/MAX Instructions
+ if (HasRoundModeOp) {
+ Operands.push_back(Ops[Offset + 1]); // frm
+ Operands.push_back(Ops[Offset + 2]); // vl
+ } else {
+ Operands.push_back(ConstantInt::get(Ops[Offset + 1]->getType(), 7)); // frm
+ Operands.push_back(Ops[Offset + 1]); // vl
+ }
+
+ if (IsMasked)
+ Operands.push_back(ConstantInt::get(Ops.back()->getType(), PolicyAttrs));
+
+ IntrinsicTypes = {ResultType, Operands.back()->getType()};
+ llvm::Function *F = CGM.getIntrinsic(ID, IntrinsicTypes);
+ return Builder.CreateCall(F, Operands, "");
+ }
+}] in {
+ let HasFRMRoundModeOp = 1 in {
+ // 13.8. Vector Floating-Point Square-Root Instruction
+ defm vfsqrt : RVVOutBuiltinSet<"vfsqrt", "xfd", [["v", "v", "vvu"]]>;
+
+ // 13.10. Vector Floating-Point Reciprocal Estimate Instruction
+ defm vfrec7 : RVVOutBuiltinSet<"vfrec7", "xfd", [["v", "v", "vvu"]]>;
+ }
+ // 13.8. Vector Floating-Point Square-Root Instruction
+ defm vfsqrt : RVVOutBuiltinSet<"vfsqrt", "xfd", [["v", "v", "vv"]]>;
+
+ // 13.10. Vector Floating-Point Reciprocal Estimate Instruction
+ defm vfrec7 : RVVOutBuiltinSet<"vfrec7", "xfd", [["v", "v", "vv"]]>;
+}
+
+// 13.9. Vector Floating-Point Reciprocal Square-Root Estimate Instruction
+def vfrsqrt7 : RVVFloatingUnaryVVBuiltin;
+
+// 13.11. Vector Floating-Point MIN/MAX Instructions
defm vfmin : RVVFloatingBinBuiltinSet;
defm vfmax : RVVFloatingBinBuiltinSet;
-// 14.12. Vector Floating-Point Sign-Injection Instructions
+// 13.12. Vector Floating-Point Sign-Injection Instructions
defm vfsgnj : RVVFloatingBinBuiltinSet;
defm vfsgnjn : RVVFloatingBinBuiltinSet;
defm vfsgnjx : RVVFloatingBinBuiltinSet;
+}
defm vfneg_v : RVVPseudoVFUnaryBuiltin<"vfsgnjn", "xfd">;
defm vfabs_v : RVVPseudoVFUnaryBuiltin<"vfsgnjx", "xfd">;
-// 14.13. Vector Floating-Point Compare Instructions
+// 13.13. Vector Floating-Point Compare Instructions
+let MaskedPolicyScheme = HasPassthruOperand,
+ HasTailPolicy = false in {
defm vmfeq : RVVFloatingMaskOutBuiltinSet;
defm vmfne : RVVFloatingMaskOutBuiltinSet;
defm vmflt : RVVFloatingMaskOutBuiltinSet;
defm vmfle : RVVFloatingMaskOutBuiltinSet;
defm vmfgt : RVVFloatingMaskOutBuiltinSet;
defm vmfge : RVVFloatingMaskOutBuiltinSet;
+}
-// 14.14. Vector Floating-Point Classify Instruction
-let Name = "vfclass_v" in
+// 13.14. Vector Floating-Point Classify Instruction
+let Name = "vfclass_v", UnMaskedPolicyScheme = HasPassthruOperand in
def vfclass : RVVOp0Builtin<"Uv", "Uvv", "xfd">;
-// 14.15. Vector Floating-Point Merge Instructio
+// 13.15. Vector Floating-Point Merge Instruction
// C/C++ Operand: (mask, op1, op2, vl), Builtin: (op1, op2, mask, vl)
-let HasMask = false,
+let HasMasked = false,
+ UnMaskedPolicyScheme = HasPassthruOperand,
+ MaskedPolicyScheme = NonePolicy,
ManualCodegen = [{
- std::rotate(Ops.begin(), Ops.begin() + 1, Ops.begin() + 3);
- IntrinsicTypes = {ResultType, Ops[1]->getType(), Ops[3]->getType()};
+ // insert poison passthru
+ if (PolicyAttrs & RVV_VTA)
+ Ops.insert(Ops.begin(), llvm::PoisonValue::get(ResultType));
+ IntrinsicTypes = {ResultType, Ops[2]->getType(), Ops.back()->getType()};
}] in {
- defm vmerge : RVVOutOp1BuiltinSet<"vfmerge", "xfd",
- [["vvm", "v", "vmvv"]]>;
+ defm vmerge : RVVOutOp1BuiltinSet<"vmerge", "fd",
+ [["vvm", "v", "vvvm"]]>;
+ let RequiredFeatures = ["Zvfhmin"] in
+ defm vmerge : RVVOutOp1BuiltinSet<"vmerge", "x",
+ [["vvm", "v", "vvvm"]]>;
defm vfmerge : RVVOutOp1BuiltinSet<"vfmerge", "xfd",
- [["vfm", "v", "vmve"]]>;
+ [["vfm", "v", "vvem"]]>;
}
-// 14.16. Vector Floating-Point Move Instruction
-let HasMask = false, HasNoMaskedOverloaded = false in
+// 13.16. Vector Floating-Point Move Instruction
+let HasMasked = false,
+ UnMaskedPolicyScheme = HasPassthruOperand,
+ SupportOverloading = false,
+ MaskedPolicyScheme = NonePolicy,
+ OverloadedName = "vfmv_v" in
defm vfmv_v : RVVOutBuiltinSet<"vfmv_v_f", "xfd",
[["f", "v", "ve"]]>;
-// 14.17. Single-Width Floating-Point/Integer Type-Convert Instructions
-def vfcvt_xu_f_v : RVVConvToUnsignedBuiltin<"vfcvt_xu">;
-def vfcvt_x_f_v : RVVConvToSignedBuiltin<"vfcvt_x">;
+// 13.17. Single-Width Floating-Point/Integer Type-Convert Instructions
+let UnMaskedPolicyScheme = HasPassthruOperand in {
def vfcvt_rtz_xu_f_v : RVVConvToUnsignedBuiltin<"vfcvt_rtz_xu">;
def vfcvt_rtz_x_f_v : RVVConvToSignedBuiltin<"vfcvt_rtz_x">;
-def vfcvt_f_xu_v : RVVConvBuiltin<"Fv", "FvUv", "sil", "vfcvt_f">;
-def vfcvt_f_x_v : RVVConvBuiltin<"Fv", "Fvv", "sil", "vfcvt_f">;
-// 14.18. Widening Floating-Point/Integer Type-Convert Instructions
+// 13.18. Widening Floating-Point/Integer Type-Convert Instructions
let Log2LMUL = [-3, -2, -1, 0, 1, 2] in {
- def vfwcvt_xu_f_v : RVVConvToWidenUnsignedBuiltin<"vfwcvt_xu">;
- def vfwcvt_x_f_v : RVVConvToWidenSignedBuiltin<"vfwcvt_x">;
def vfwcvt_rtz_xu_f_v : RVVConvToWidenUnsignedBuiltin<"vfwcvt_rtz_xu">;
def vfwcvt_rtz_x_f_v : RVVConvToWidenSignedBuiltin<"vfwcvt_rtz_x">;
def vfwcvt_f_xu_v : RVVConvBuiltin<"Fw", "FwUv", "csi", "vfwcvt_f">;
def vfwcvt_f_x_v : RVVConvBuiltin<"Fw", "Fwv", "csi", "vfwcvt_f">;
- def vfwcvt_f_f_v : RVVConvBuiltin<"w", "wv", "xf", "vfwcvt_f">;
+ def vfwcvt_f_f_v : RVVConvBuiltin<"w", "wv", "f", "vfwcvt_f">;
+ let RequiredFeatures = ["Zvfhmin"] in
+ def vfwcvt_f_f_v_fp16 : RVVConvBuiltin<"w", "wv", "x", "vfwcvt_f"> {
+ let Name = "vfwcvt_f_f_v";
+ let IRName = "vfwcvt_f_f_v";
+ let MaskedIRName = "vfwcvt_f_f_v_mask";
+ }
}
-// 14.19. Narrowing Floating-Point/Integer Type-Convert Instructions
+// 13.19. Narrowing Floating-Point/Integer Type-Convert Instructions
let Log2LMUL = [-3, -2, -1, 0, 1, 2] in {
- def vfncvt_xu_f_w : RVVConvToNarrowingUnsignedBuiltin<"vfncvt_xu">;
- def vfncvt_x_f_w : RVVConvToNarrowingSignedBuiltin<"vfncvt_x">;
def vfncvt_rtz_xu_f_w : RVVConvToNarrowingUnsignedBuiltin<"vfncvt_rtz_xu">;
def vfncvt_rtz_x_f_w : RVVConvToNarrowingSignedBuiltin<"vfncvt_rtz_x">;
- def vfncvt_f_xu_w : RVVConvBuiltin<"Fv", "FvUw", "csi", "vfncvt_f">;
- def vfncvt_f_x_w : RVVConvBuiltin<"Fv", "Fvw", "csi", "vfncvt_f">;
- def vfncvt_f_f_w : RVVConvBuiltin<"v", "vw", "xf", "vfncvt_f">;
def vfncvt_rod_f_f_w : RVVConvBuiltin<"v", "vw", "xf", "vfncvt_rod_f">;
}
+let ManualCodegen = [{
+ {
+ // LLVM intrinsic
+ // Unmasked: (passthru, op0, frm, vl)
+ // Masked: (passthru, op0, mask, frm, vl, policy)
+ SmallVector<llvm::Value*, 7> Operands;
+ bool HasMaskedOff = !(
+ (IsMasked && (PolicyAttrs & RVV_VTA) && (PolicyAttrs & RVV_VMA)) ||
+ (!IsMasked && PolicyAttrs & RVV_VTA));
+ bool HasRoundModeOp = IsMasked ?
+ (HasMaskedOff ? Ops.size() == 5 : Ops.size() == 4) :
+ (HasMaskedOff ? Ops.size() == 4 : Ops.size() == 3);
+
+ unsigned Offset = IsMasked ?
+ (HasMaskedOff ? 2 : 1) : (HasMaskedOff ? 1 : 0);
+
+ if (!HasMaskedOff)
+ Operands.push_back(llvm::PoisonValue::get(ResultType));
+ else
+ Operands.push_back(Ops[IsMasked ? 1 : 0]);
+
+ Operands.push_back(Ops[Offset]); // op0
+
+ if (IsMasked)
+ Operands.push_back(Ops[0]); // mask
+
+ if (HasRoundModeOp) {
+ Operands.push_back(Ops[Offset + 1]); // frm
+ Operands.push_back(Ops[Offset + 2]); // vl
+ } else {
+ Operands.push_back(ConstantInt::get(Ops[Offset + 1]->getType(), 7)); // frm
+ Operands.push_back(Ops[Offset + 1]); // vl
+ }
-// 15. Vector Reduction Operations
-// 15.1. Vector Single-Width Integer Reduction Instructions
+ if (IsMasked)
+ Operands.push_back(ConstantInt::get(Ops.back()->getType(), PolicyAttrs));
+
+ IntrinsicTypes = {ResultType, Ops[Offset]->getType(),
+ Operands.back()->getType()};
+ llvm::Function *F = CGM.getIntrinsic(ID, IntrinsicTypes);
+ return Builder.CreateCall(F, Operands, "");
+ }
+}] in {
+ let HasFRMRoundModeOp = 1 in {
+ // 14.17. Single-Width Floating-Point/Integer Type-Convert Instructions
+ let OverloadedName = "vfcvt_x" in
+ defm :
+ RVVConvBuiltinSet<"vfcvt_x_f_v", "xfd", [["Iv", "Ivvu"]]>;
+ let OverloadedName = "vfcvt_xu" in
+ defm :
+ RVVConvBuiltinSet<"vfcvt_xu_f_v", "xfd", [["Uv", "Uvvu"]]>;
+ let OverloadedName = "vfcvt_f" in {
+ defm :
+ RVVConvBuiltinSet<"vfcvt_f_x_v", "sil", [["Fv", "Fvvu"]]>;
+ defm :
+ RVVConvBuiltinSet<"vfcvt_f_xu_v", "sil", [["Fv", "FvUvu"]]>;
+ }
+
+ // 13.18. Widening Floating-Point/Integer Type-Convert Instructions
+ let Log2LMUL = [-3, -2, -1, 0, 1, 2] in {
+ let OverloadedName = "vfwcvt_x" in
+ defm :
+ RVVConvBuiltinSet<"vfwcvt_x_f_v", "xf", [["Iw", "Iwvu"]]>;
+ let OverloadedName = "vfwcvt_xu" in
+ defm :
+ RVVConvBuiltinSet<"vfwcvt_xu_f_v", "xf", [["Uw", "Uwvu"]]>;
+ }
+ // 13.19. Narrowing Floating-Point/Integer Type-Convert Instructions
+ let Log2LMUL = [-3, -2, -1, 0, 1, 2] in {
+ let OverloadedName = "vfncvt_x" in
+ defm :
+ RVVConvBuiltinSet<"vfncvt_x_f_w", "csi", [["Iv", "IvFwu"]]>;
+ let OverloadedName = "vfncvt_xu" in
+ defm :
+ RVVConvBuiltinSet<"vfncvt_xu_f_w", "csi", [["Uv", "UvFwu"]]>;
+ let OverloadedName = "vfncvt_f" in {
+ defm :
+ RVVConvBuiltinSet<"vfncvt_f_x_w", "csi", [["Fv", "Fvwu"]]>;
+ defm :
+ RVVConvBuiltinSet<"vfncvt_f_xu_w", "csi", [["Fv", "FvUwu"]]>;
+ }
+ let OverloadedName = "vfncvt_f" in {
+ defm : RVVConvBuiltinSet<"vfncvt_f_f_w", "f", [["v", "vwu"]]>;
+ let RequiredFeatures = ["Zvfhmin"] in
+ defm : RVVConvBuiltinSet<"vfncvt_f_f_w", "x", [["v", "vwu"]]>;
+ }
+ }
+ }
+
+ // 13.17. Single-Width Floating-Point/Integer Type-Convert Instructions
+ let OverloadedName = "vfcvt_x" in
+ defm :
+ RVVConvBuiltinSet<"vfcvt_x_f_v", "xfd", [["Iv", "Ivv"]]>;
+ let OverloadedName = "vfcvt_xu" in
+ defm :
+ RVVConvBuiltinSet<"vfcvt_xu_f_v", "xfd", [["Uv", "Uvv"]]>;
+ let OverloadedName = "vfcvt_f" in {
+ defm :
+ RVVConvBuiltinSet<"vfcvt_f_x_v", "sil", [["Fv", "Fvv"]]>;
+ defm :
+ RVVConvBuiltinSet<"vfcvt_f_xu_v", "sil", [["Fv", "FvUv"]]>;
+ }
+
+ // 13.18. Widening Floating-Point/Integer Type-Convert Instructions
+ let Log2LMUL = [-3, -2, -1, 0, 1, 2] in {
+ let OverloadedName = "vfwcvt_x" in
+ defm :
+ RVVConvBuiltinSet<"vfwcvt_x_f_v", "xf", [["Iw", "Iwv"]]>;
+ let OverloadedName = "vfwcvt_xu" in
+ defm :
+ RVVConvBuiltinSet<"vfwcvt_xu_f_v", "xf", [["Uw", "Uwv"]]>;
+ }
+ // 13.19. Narrowing Floating-Point/Integer Type-Convert Instructions
+ let Log2LMUL = [-3, -2, -1, 0, 1, 2] in {
+ let OverloadedName = "vfncvt_x" in
+ defm :
+ RVVConvBuiltinSet<"vfncvt_x_f_w", "csi", [["Iv", "IvFw"]]>;
+ let OverloadedName = "vfncvt_xu" in
+ defm :
+ RVVConvBuiltinSet<"vfncvt_xu_f_w", "csi", [["Uv", "UvFw"]]>;
+ let OverloadedName = "vfncvt_f" in {
+ defm :
+ RVVConvBuiltinSet<"vfncvt_f_x_w", "csi", [["Fv", "Fvw"]]>;
+ defm :
+ RVVConvBuiltinSet<"vfncvt_f_xu_w", "csi", [["Fv", "FvUw"]]>;
+ }
+ let OverloadedName = "vfncvt_f" in {
+ defm : RVVConvBuiltinSet<"vfncvt_f_f_w", "f", [["v", "vw"]]>;
+ let RequiredFeatures = ["Zvfhmin"] in
+ defm : RVVConvBuiltinSet<"vfncvt_f_f_w", "x", [["v", "vw"]]>;
+ }
+ }
+}
+}
+
+// 14. Vector Reduction Operations
+// 14.1. Vector Single-Width Integer Reduction Instructions
+let UnMaskedPolicyScheme = HasPassthruOperand,
+ MaskedPolicyScheme = HasPassthruOperand,
+ HasMaskPolicy = false in {
defm vredsum : RVVIntReductionBuiltinSet;
defm vredmaxu : RVVUnsignedReductionBuiltin;
defm vredmax : RVVSignedReductionBuiltin;
@@ -1876,34 +2032,88 @@ defm vredand : RVVIntReductionBuiltinSet;
defm vredor : RVVIntReductionBuiltinSet;
defm vredxor : RVVIntReductionBuiltinSet;
-// 15.2. Vector Widening Integer Reduction Instructions
+// 14.2. Vector Widening Integer Reduction Instructions
// Vector Widening Integer Reduction Operations
-let HasMaskedOffOperand = false in {
- defm vwredsum : RVVOutOp1BuiltinSet<"vwredsum", "csi",
- [["vs", "vSw", "SwSwvSw"]]>;
- defm vwredsumu : RVVOutOp1BuiltinSet<"vwredsumu", "csi",
- [["vs", "UvUSw", "USwUSwUvUSw"]]>;
+let HasMaskedOffOperand = true in {
+ defm vwredsum : RVVOutOp0BuiltinSet<"vwredsum", "csi",
+ [["vs", "vSw", "SwvSw"]]>;
+ defm vwredsumu : RVVOutOp0BuiltinSet<"vwredsumu", "csi",
+ [["vs", "UvUSw", "USwUvUSw"]]>;
}
-// 15.3. Vector Single-Width Floating-Point Reduction Instructions
+// 14.3. Vector Single-Width Floating-Point Reduction Instructions
defm vfredmax : RVVFloatingReductionBuiltin;
defm vfredmin : RVVFloatingReductionBuiltin;
-defm vfredsum : RVVFloatingReductionBuiltin;
-defm vfredosum : RVVFloatingReductionBuiltin;
+let ManualCodegen = [{
+ {
+ // LLVM intrinsic
+ // Unmasked: (passthru, op0, op1, round_mode, vl)
+ // Masked: (passthru, vector_in, vector_in/scalar_in, mask, frm, vl, policy)
+
+ SmallVector<llvm::Value*, 7> Operands;
+ bool HasMaskedOff = !(
+ (IsMasked && (PolicyAttrs & RVV_VTA) && (PolicyAttrs & RVV_VMA)) ||
+ (!IsMasked && PolicyAttrs & RVV_VTA));
+ bool HasRoundModeOp = IsMasked ?
+ (HasMaskedOff ? Ops.size() == 6 : Ops.size() == 5) :
+ (HasMaskedOff ? Ops.size() == 5 : Ops.size() == 4);
+
+ unsigned Offset = IsMasked ?
+ (HasMaskedOff ? 2 : 1) : (HasMaskedOff ? 1 : 0);
+
+ if (!HasMaskedOff)
+ Operands.push_back(llvm::PoisonValue::get(ResultType));
+ else
+ Operands.push_back(Ops[IsMasked ? 1 : 0]);
+
+ Operands.push_back(Ops[Offset]); // op0
+ Operands.push_back(Ops[Offset + 1]); // op1
+
+ if (IsMasked)
+ Operands.push_back(Ops[0]); // mask
+
+ if (HasRoundModeOp) {
+ Operands.push_back(Ops[Offset + 2]); // frm
+ Operands.push_back(Ops[Offset + 3]); // vl
+ } else {
+ Operands.push_back(ConstantInt::get(Ops[Offset + 2]->getType(), 7)); // frm
+ Operands.push_back(Ops[Offset + 2]); // vl
+ }
-// 15.4. Vector Widening Floating-Point Reduction Instructions
-defm vfwredsum : RVVFloatingWidenReductionBuiltin;
-defm vfwredosum : RVVFloatingWidenReductionBuiltin;
+ IntrinsicTypes = {ResultType, Ops[Offset]->getType(),
+ Ops.back()->getType()};
+ llvm::Function *F = CGM.getIntrinsic(ID, IntrinsicTypes);
+ return Builder.CreateCall(F, Operands, "");
+ }
+}] in {
+ let HasFRMRoundModeOp = 1 in {
+ // 14.3. Vector Single-Width Floating-Point Reduction Instructions
+ defm vfredusum : RVVFloatingReductionBuiltinRoundingMode;
+ defm vfredosum : RVVFloatingReductionBuiltinRoundingMode;
+
+ // 14.4. Vector Widening Floating-Point Reduction Instructions
+ defm vfwredusum : RVVFloatingWidenReductionBuiltinRoundingMode;
+ defm vfwredosum : RVVFloatingWidenReductionBuiltinRoundingMode;
+ }
+ // 14.3. Vector Single-Width Floating-Point Reduction Instructions
+ defm vfredusum : RVVFloatingReductionBuiltin;
+ defm vfredosum : RVVFloatingReductionBuiltin;
-// 16. Vector Mask Instructions
-// 16.1. Vector Mask-Register Logical Instructions
+ // 14.4. Vector Widening Floating-Point Reduction Instructions
+ defm vfwredusum : RVVFloatingWidenReductionBuiltin;
+ defm vfwredosum : RVVFloatingWidenReductionBuiltin;
+}
+}
+
+// 15. Vector Mask Instructions
+// 15.1. Vector Mask-Register Logical Instructions
def vmand : RVVMaskBinBuiltin;
def vmnand : RVVMaskBinBuiltin;
-def vmandnot : RVVMaskBinBuiltin;
+def vmandn : RVVMaskBinBuiltin;
def vmxor : RVVMaskBinBuiltin;
def vmor : RVVMaskBinBuiltin;
def vmnor : RVVMaskBinBuiltin;
-def vmornot : RVVMaskBinBuiltin;
+def vmorn : RVVMaskBinBuiltin;
def vmxnor : RVVMaskBinBuiltin;
// pseudoinstructions
def vmclr : RVVMaskNullaryBuiltin;
@@ -1911,69 +2121,79 @@ def vmset : RVVMaskNullaryBuiltin;
defm vmmv_m : RVVPseudoMaskBuiltin<"vmand", "c">;
defm vmnot_m : RVVPseudoMaskBuiltin<"vmnand", "c">;
-// 16.2. Vector mask population count vpopc
-def vpopc : RVVMaskOp0Builtin<"um">;
+let MaskedPolicyScheme = NonePolicy in {
+// 15.2. Vector count population in mask vcpop.m
+def vcpop : RVVMaskOp0Builtin<"um">;
-// 16.3. vfirst find-first-set mask bit
+// 15.3. vfirst find-first-set mask bit
def vfirst : RVVMaskOp0Builtin<"lm">;
+}
-// 16.4. vmsbf.m set-before-first mask bit
+let MaskedPolicyScheme = HasPassthruOperand,
+ HasTailPolicy = false in {
+// 15.4. vmsbf.m set-before-first mask bit
def vmsbf : RVVMaskUnaryBuiltin;
-// 16.5. vmsif.m set-including-first mask bit
+// 15.5. vmsif.m set-including-first mask bit
def vmsif : RVVMaskUnaryBuiltin;
-// 16.6. vmsof.m set-only-first mask bit
+// 15.6. vmsof.m set-only-first mask bit
def vmsof : RVVMaskUnaryBuiltin;
+}
-let HasNoMaskedOverloaded = false in {
- // 16.8. Vector Iota Instruction
+let UnMaskedPolicyScheme = HasPassthruOperand, SupportOverloading = false in {
+ // 15.8. Vector Iota Instruction
defm viota : RVVOutBuiltinSet<"viota", "csil", [["m", "Uv", "Uvm"]]>;
- // 16.9. Vector Element Index Instruction
+ // 15.9. Vector Element Index Instruction
defm vid : RVVOutBuiltinSet<"vid", "csil", [["v", "v", "v"],
["v", "Uv", "Uv"]]>;
}
-// 17. Vector Permutation Instructions
-// 17.1. Integer Scalar Move Instructions
-let HasMask = false in {
- let HasVL = false, MangledName = "vmv_x" in
+// 16. Vector Permutation Instructions
+// 16.1. Integer Scalar Move Instructions
+let HasMasked = false, MaskedPolicyScheme = NonePolicy in {
+ let HasVL = false, OverloadedName = "vmv_x" in
defm vmv_x : RVVOp0BuiltinSet<"vmv_x_s", "csil",
[["s", "ve", "ev"],
["s", "UvUe", "UeUv"]]>;
- let MangledName = "vmv_s" in
+ let OverloadedName = "vmv_s",
+ UnMaskedPolicyScheme = HasPassthruOperand,
+ SupportOverloading = false in
defm vmv_s : RVVOutBuiltinSet<"vmv_s_x", "csil",
- [["x", "v", "vve"],
- ["x", "Uv", "UvUvUe"]]>;
+ [["x", "v", "ve"],
+ ["x", "Uv", "UvUe"]]>;
}
-// 17.2. Floating-Point Scalar Move Instructions
-let HasMask = false in {
- let HasVL = false, MangledName = "vfmv_f" in
+// 16.2. Floating-Point Scalar Move Instructions
+let HasMasked = false, MaskedPolicyScheme = NonePolicy in {
+ let HasVL = false, OverloadedName = "vfmv_f" in
defm vfmv_f : RVVOp0BuiltinSet<"vfmv_f_s", "xfd",
[["s", "ve", "ev"]]>;
- let MangledName = "vfmv_s" in
+ let OverloadedName = "vfmv_s",
+ UnMaskedPolicyScheme = HasPassthruOperand,
+ SupportOverloading = false in
defm vfmv_s : RVVOutBuiltinSet<"vfmv_s_f", "xfd",
- [["f", "v", "vve"],
- ["x", "Uv", "UvUvUe"]]>;
+ [["f", "v", "ve"],
+ ["x", "Uv", "UvUe"]]>;
}
-// 17.3. Vector Slide Instructions
-// 17.3.1. Vector Slideup Instructions
-defm vslideup : RVVSlideBuiltinSet;
-// 17.3.2. Vector Slidedown Instructions
-defm vslidedown : RVVSlideBuiltinSet;
+// 16.3. Vector Slide Instructions
+// 16.3.1. Vector Slideup Instructions
+defm vslideup : RVVSlideUpBuiltinSet;
+// 16.3.2. Vector Slidedown Instructions
+defm vslidedown : RVVSlideDownBuiltinSet;
-// 17.3.3. Vector Slide1up Instructions
+// 16.3.3. Vector Slide1up Instructions
+let UnMaskedPolicyScheme = HasPassthruOperand in {
defm vslide1up : RVVSlideOneBuiltinSet;
defm vfslide1up : RVVFloatingBinVFBuiltinSet;
-// 17.3.4. Vector Slide1down Instruction
+// 16.3.4. Vector Slide1down Instruction
defm vslide1down : RVVSlideOneBuiltinSet;
defm vfslide1down : RVVFloatingBinVFBuiltinSet;
-// 17.4. Vector Register Gather Instructions
+// 16.4. Vector Register Gather Instructions
// signed and floating type
defm vrgather : RVVOutBuiltinSet<"vrgather_vv", "csilxfd",
[["vv", "v", "vvUv"]]>;
@@ -1988,34 +2208,75 @@ defm vrgather : RVVOutBuiltinSet<"vrgather_vx", "csil",
[["vx", "Uv", "UvUvz"]]>;
defm vrgatherei16 : RVVOutBuiltinSet<"vrgatherei16_vv", "csil",
[["vv", "Uv", "UvUv(Log2EEW:4)Uv"]]>;
+}
-// 17.5. Vector Compress Instruction
-let HasMask = false,
+// 16.5. Vector Compress Instruction
+let HasMasked = false,
+ UnMaskedPolicyScheme = HasPassthruOperand,
+ MaskedPolicyScheme = NonePolicy,
ManualCodegen = [{
- std::rotate(Ops.begin(), Ops.begin() + 1, Ops.begin() + 3);
- IntrinsicTypes = {ResultType, Ops[3]->getType()};
+ // insert poison passthru
+ if (PolicyAttrs & RVV_VTA)
+ Ops.insert(Ops.begin(), llvm::PoisonValue::get(ResultType));
+ IntrinsicTypes = {ResultType, Ops.back()->getType()};
}] in {
// signed and floating type
defm vcompress : RVVOutBuiltinSet<"vcompress", "csilxfd",
- [["vm", "v", "vmvv"]]>;
+ [["vm", "v", "vvm"]]>;
// unsigned type
defm vcompress : RVVOutBuiltinSet<"vcompress", "csil",
- [["vm", "Uv", "UvmUvUv"]]>;
+ [["vm", "Uv", "UvUvm"]]>;
}
// Miscellaneous
-let HasMask = false, HasVL = false, IRName = "" in {
- let Name = "vreinterpret_v",
+let HasMasked = false, HasVL = false, IRName = "" in {
+ let Name = "vreinterpret_v", MaskedPolicyScheme = NonePolicy,
ManualCodegen = [{
+ if (ResultType->isIntOrIntVectorTy(1) ||
+ Ops[0]->getType()->isIntOrIntVectorTy(1)) {
+ assert(isa<ScalableVectorType>(ResultType) &&
+ isa<ScalableVectorType>(Ops[0]->getType()));
+
+ LLVMContext &Context = CGM.getLLVMContext();
+ ScalableVectorType *Boolean64Ty =
+ ScalableVectorType::get(llvm::Type::getInt1Ty(Context), 64);
+
+ if (ResultType->isIntOrIntVectorTy(1)) {
+ // Casting from m1 vector integer -> vector boolean
+ // Ex: <vscale x 8 x i8>
+ // --(bitcast)--------> <vscale x 64 x i1>
+ // --(vector_extract)-> <vscale x 8 x i1>
+ llvm::Value *BitCast = Builder.CreateBitCast(Ops[0], Boolean64Ty);
+ return Builder.CreateExtractVector(ResultType, BitCast,
+ ConstantInt::get(Int64Ty, 0));
+ } else {
+ // Casting from vector boolean -> m1 vector integer
+ // Ex: <vscale x 1 x i1>
+ // --(vector_insert)-> <vscale x 64 x i1>
+ // --(bitcast)-------> <vscale x 8 x i8>
+ llvm::Value *Boolean64Val =
+ Builder.CreateInsertVector(Boolean64Ty,
+ llvm::PoisonValue::get(Boolean64Ty),
+ Ops[0],
+ ConstantInt::get(Int64Ty, 0));
+ return Builder.CreateBitCast(Boolean64Val, ResultType);
+ }
+ }
return Builder.CreateBitCast(Ops[0], ResultType);
}] in {
// Reinterpret between different type under the same SEW and LMUL
def vreinterpret_i_u : RVVBuiltin<"Uvv", "vUv", "csil", "v">;
- def vreinterpret_i_f : RVVBuiltin<"Fvv", "vFv", "sil", "v">;
+ def vreinterpret_i_f : RVVBuiltin<"Fvv", "vFv", "il", "v">;
def vreinterpret_u_i : RVVBuiltin<"vUv", "Uvv", "csil", "Uv">;
- def vreinterpret_u_f : RVVBuiltin<"FvUv", "UvFv", "sil", "Uv">;
- def vreinterpret_f_i : RVVBuiltin<"vFv", "Fvv", "sil", "Fv">;
- def vreinterpret_f_u : RVVBuiltin<"UvFv", "FvUv", "sil", "Fv">;
+ def vreinterpret_u_f : RVVBuiltin<"FvUv", "UvFv", "il", "Uv">;
+ def vreinterpret_f_i : RVVBuiltin<"vFv", "Fvv", "il", "Fv">;
+ def vreinterpret_f_u : RVVBuiltin<"UvFv", "FvUv", "il", "Fv">;
+ let RequiredFeatures = ["Zvfhmin"] in {
+ def vreinterpret_i_h : RVVBuiltin<"Fvv", "vFv", "s", "v">;
+ def vreinterpret_u_h : RVVBuiltin<"FvUv", "UvFv", "s", "Uv">;
+ def vreinterpret_h_i : RVVBuiltin<"vFv", "Fvv", "s", "Fv">;
+ def vreinterpret_h_u : RVVBuiltin<"UvFv", "FvUv", "s", "Fv">;
+ }
// Reinterpret between different SEW under the same LMUL
foreach dst_sew = ["(FixedSEW:8)", "(FixedSEW:16)", "(FixedSEW:32)",
@@ -2025,24 +2286,80 @@ let HasMask = false, HasVL = false, IRName = "" in {
def vreinterpret_u_ # dst_sew : RVVBuiltin<"Uv" # dst_sew # "Uv",
dst_sew # "UvUv", "csil", dst_sew # "Uv">;
}
+
+ // Existing users of FixedSEW - the reinterpretation between different SEW
+ // and same LMUL has the implicit assumption that if FixedSEW is set to the
+ // given element width, then the type will be identified as invalid, thus
+ // skipping definition of reinterpret of SEW=8 to SEW=8. However this blocks
+ // our usage here of defining all possible combinations of a fixed SEW to
+ // any boolean. So we need to separately define SEW=8 here.
+ // Reinterpret from LMUL=1 integer type to vector boolean type
+ def vreintrepret_m1_b8_signed :
+ RVVBuiltin<"Svm",
+ "mSv",
+ "c", "m">;
+ def vreintrepret_m1_b8_usigned :
+ RVVBuiltin<"USvm",
+ "mUSv",
+ "c", "m">;
+
+ // Reinterpret from vector boolean type to LMUL=1 integer type
+ def vreintrepret_b8_m1_signed :
+ RVVBuiltin<"mSv",
+ "Svm",
+ "c", "Sv">;
+ def vreintrepret_b8_m1_usigned :
+ RVVBuiltin<"mUSv",
+ "USvm",
+ "c", "USv">;
+
+ foreach dst_sew = ["16", "32", "64"] in {
+ // Reinterpret from LMUL=1 integer type to vector boolean type
+ def vreinterpret_m1_b # dst_sew # _signed:
+ RVVBuiltin<"(FixedSEW:" # dst_sew # ")Svm",
+ "m(FixedSEW:" # dst_sew # ")Sv",
+ "c", "m">;
+ def vreinterpret_m1_b # dst_sew # _unsigned:
+ RVVBuiltin<"(FixedSEW:" # dst_sew # ")USvm",
+ "m(FixedSEW:" # dst_sew # ")USv",
+ "c", "m">;
+ // Reinterpret from vector boolean type to LMUL=1 integer type
+ def vreinterpret_b # dst_sew # _m1_signed:
+ RVVBuiltin<"m(FixedSEW:" # dst_sew # ")Sv",
+ "(FixedSEW:" # dst_sew # ")Svm",
+ "c", "(FixedSEW:" # dst_sew # ")Sv">;
+ def vreinterpret_b # dst_sew # _m1_unsigned:
+ RVVBuiltin<"m(FixedSEW:" # dst_sew # ")USv",
+ "(FixedSEW:" # dst_sew # ")USvm",
+ "c", "(FixedSEW:" # dst_sew # ")USv">;
+ }
}
- let Name = "vundefined", HasNoMaskedOverloaded = false,
+ let Name = "vundefined", SupportOverloading = false,
+ MaskedPolicyScheme = NonePolicy,
ManualCodegen = [{
- return llvm::UndefValue::get(ResultType);
+ return llvm::PoisonValue::get(ResultType);
}] in {
def vundefined : RVVBuiltin<"v", "v", "csilxfd">;
def vundefined_u : RVVBuiltin<"Uv", "Uv", "csil">;
+
+ foreach nf = NFList in {
+ let NF = nf in {
+ defvar T = "(Tuple:" # nf # ")";
+ def : RVVBuiltin<T # "v", T # "v", "csilxfd">;
+ def : RVVBuiltin<T # "Uv", T # "Uv", "csil">;
+ }
+ }
+
}
// LMUL truncation
// C/C++ Operand: VecTy, IR Operand: VecTy, Index
- let Name = "vlmul_trunc_v", MangledName = "vlmul_trunc",
+ let Name = "vlmul_trunc_v", OverloadedName = "vlmul_trunc",
+ MaskedPolicyScheme = NonePolicy,
ManualCodegen = [{ {
- ID = Intrinsic::experimental_vector_extract;
- IntrinsicTypes = {ResultType, Ops[0]->getType()};
- Ops.push_back(ConstantInt::get(Int64Ty, 0));
- return Builder.CreateCall(CGM.getIntrinsic(ID, IntrinsicTypes), Ops, "");
+ return Builder.CreateExtractVector(ResultType, Ops[0],
+ ConstantInt::get(Int64Ty, 0));
} }] in {
foreach dst_lmul = ["(SFixedLog2LMUL:-3)", "(SFixedLog2LMUL:-2)", "(SFixedLog2LMUL:-1)",
"(SFixedLog2LMUL:0)", "(SFixedLog2LMUL:1)", "(SFixedLog2LMUL:2)"] in {
@@ -2055,14 +2372,12 @@ let HasMask = false, HasVL = false, IRName = "" in {
// LMUL extension
// C/C++ Operand: SubVecTy, IR Operand: VecTy, SubVecTy, Index
- let Name = "vlmul_ext_v", MangledName = "vlmul_ext",
+ let Name = "vlmul_ext_v", OverloadedName = "vlmul_ext",
+ MaskedPolicyScheme = NonePolicy,
ManualCodegen = [{
- ID = Intrinsic::experimental_vector_insert;
- IntrinsicTypes = {ResultType, Ops[0]->getType()};
- Ops.push_back(llvm::UndefValue::get(ResultType));
- std::swap(Ops[0], Ops[1]);
- Ops.push_back(ConstantInt::get(Int64Ty, 0));
- return Builder.CreateCall(CGM.getIntrinsic(ID, IntrinsicTypes), Ops, "");
+ return Builder.CreateInsertVector(ResultType,
+ llvm::PoisonValue::get(ResultType),
+ Ops[0], ConstantInt::get(Int64Ty, 0));
}] in {
foreach dst_lmul = ["(LFixedLog2LMUL:-2)", "(LFixedLog2LMUL:-1)", "(LFixedLog2LMUL:-0)",
"(LFixedLog2LMUL:1)", "(LFixedLog2LMUL:2)", "(LFixedLog2LMUL:3)"] in {
@@ -2073,40 +2388,225 @@ let HasMask = false, HasVL = false, IRName = "" in {
}
}
- let Name = "vget_v",
+ let Name = "vget_v", MaskedPolicyScheme = NonePolicy,
ManualCodegen = [{
{
- ID = Intrinsic::experimental_vector_extract;
- ScalableVectorType *VecTy = cast<ScalableVectorType>(ResultType);
+ if (isa<StructType>(Ops[0]->getType())) // For tuple type
+ // Extract value from index (operand 1) of vtuple (operand 0)
+ return Builder.CreateExtractValue(
+ Ops[0],
+ {(unsigned)cast<ConstantInt>(Ops[1])->getZExtValue()});
+ auto *VecTy = cast<ScalableVectorType>(ResultType);
+ auto *OpVecTy = cast<ScalableVectorType>(Ops[0]->getType());
+ // Mask to only valid indices.
+ unsigned MaxIndex = OpVecTy->getMinNumElements() / VecTy->getMinNumElements();
+ assert(isPowerOf2_32(MaxIndex));
+ Ops[1] = Builder.CreateZExt(Ops[1], Builder.getInt64Ty());
+ Ops[1] = Builder.CreateAnd(Ops[1], MaxIndex - 1);
Ops[1] = Builder.CreateMul(Ops[1],
ConstantInt::get(Ops[1]->getType(),
VecTy->getMinNumElements()));
- IntrinsicTypes = {ResultType, Ops[0]->getType()};
- return Builder.CreateCall(CGM.getIntrinsic(ID, IntrinsicTypes), Ops, "");
+ return Builder.CreateExtractVector(ResultType, Ops[0], Ops[1]);
}
}] in {
foreach dst_lmul = ["(SFixedLog2LMUL:0)", "(SFixedLog2LMUL:1)", "(SFixedLog2LMUL:2)"] in {
- def : RVVBuiltin<"v" # dst_lmul # "v", dst_lmul # "vvKz", "csilfd", dst_lmul # "v">;
+ def : RVVBuiltin<"v" # dst_lmul # "v", dst_lmul # "vvKz", "csilxfd", dst_lmul # "v">;
def : RVVBuiltin<"Uv" # dst_lmul # "Uv", dst_lmul # "UvUvKz", "csil", dst_lmul # "Uv">;
}
+ foreach nf = NFList in {
+ defvar T = "(Tuple:" # nf # ")";
+ def : RVVBuiltin<T # "vv", "v" # T # "vKz", "csilxfd", "v">;
+ def : RVVBuiltin<T # "UvUv", "Uv" # T # "UvKz", "csil", "Uv">;
+ }
}
- let Name = "vset_v", Log2LMUL = [0, 1, 2],
+ let Name = "vset_v", MaskedPolicyScheme = NonePolicy,
ManualCodegen = [{
{
- ID = Intrinsic::experimental_vector_insert;
- IntrinsicTypes = {ResultType, Ops[2]->getType()};
- ScalableVectorType *VecTy = cast<ScalableVectorType>(Ops[2]->getType());
+ if (isa<StructType>(ResultType)) // For tuple type
+ // Insert value (operand 2) into index (operand 1) of vtuple (operand 0)
+ return Builder.CreateInsertValue(
+ Ops[0], Ops[2],
+ {(unsigned)cast<ConstantInt>(Ops[1])->getZExtValue()});
+ auto *ResVecTy = cast<ScalableVectorType>(ResultType);
+ auto *VecTy = cast<ScalableVectorType>(Ops[2]->getType());
+ // Mask to only valid indices.
+ unsigned MaxIndex = ResVecTy->getMinNumElements() / VecTy->getMinNumElements();
+ assert(isPowerOf2_32(MaxIndex));
+ Ops[1] = Builder.CreateZExt(Ops[1], Builder.getInt64Ty());
+ Ops[1] = Builder.CreateAnd(Ops[1], MaxIndex - 1);
Ops[1] = Builder.CreateMul(Ops[1],
ConstantInt::get(Ops[1]->getType(),
VecTy->getMinNumElements()));
- std::swap(Ops[1], Ops[2]);
- return Builder.CreateCall(CGM.getIntrinsic(ID, IntrinsicTypes), Ops, "");
+ return Builder.CreateInsertVector(ResultType, Ops[0], Ops[2], Ops[1]);
}
}] in {
foreach dst_lmul = ["(LFixedLog2LMUL:1)", "(LFixedLog2LMUL:2)", "(LFixedLog2LMUL:3)"] in {
- def : RVVBuiltin<"v" # dst_lmul # "v", dst_lmul # "v" # dst_lmul # "vKzv", "csilfd">;
+ def : RVVBuiltin<"v" # dst_lmul # "v", dst_lmul # "v" # dst_lmul # "vKzv", "csilxfd">;
def : RVVBuiltin<"Uv" # dst_lmul # "Uv", dst_lmul # "Uv" # dst_lmul #"UvKzUv", "csil">;
}
+ foreach nf = NFList in {
+ defvar T = "(Tuple:" # nf # ")";
+ def : RVVBuiltin<"v" # T # "v", T # "v" # T # "vKzv", "csilxfd">;
+ def : RVVBuiltin<"Uv" # T # "Uv", T # "Uv" # T # "UvKzUv", "csil">;
+ }
+ }
+
+ let Name = "vcreate_v",
+ UnMaskedPolicyScheme = NonePolicy,
+ MaskedPolicyScheme = NonePolicy,
+ SupportOverloading = false,
+ ManualCodegen = [{
+ {
+ if (isa<StructType>(ResultType)) {
+ unsigned NF = cast<StructType>(ResultType)->getNumElements();
+ llvm::Value *ReturnTuple = llvm::PoisonValue::get(ResultType);
+ for (unsigned I = 0; I < NF; ++I) {
+ ReturnTuple = Builder.CreateInsertValue(ReturnTuple, Ops[I], {I});
+ }
+ return ReturnTuple;
+ }
+ llvm::Value *ReturnVector = llvm::PoisonValue::get(ResultType);
+ auto *VecTy = cast<ScalableVectorType>(Ops[0]->getType());
+ for (unsigned I = 0, N = Ops.size(); I < N; ++I) {
+ llvm::Value *Idx =
+ ConstantInt::get(Builder.getInt64Ty(),
+ VecTy->getMinNumElements() * I);
+ ReturnVector =
+ Builder.CreateInsertVector(ResultType, ReturnVector, Ops[I], Idx);
+ }
+ return ReturnVector;
+ }
+ }] in {
+
+ defm : RVVNonTupleVCreateBuiltin<1, [0]>;
+ defm : RVVNonTupleVCreateBuiltin<2, [0, 1]>;
+ defm : RVVNonTupleVCreateBuiltin<3, [0, 1, 2]>;
+
+ foreach nf = NFList in {
+ let NF = nf in {
+ defvar T = "(Tuple:" # nf # ")";
+ defvar V = VString<nf, /*signed=*/true>.S;
+ defvar UV = VString<nf, /*signed=*/false>.S;
+ def : RVVBuiltin<T # "v", T # "v" # V, "csilxfd">;
+ def : RVVBuiltin<T # "Uv", T # "Uv" # UV, "csil">;
+ }
+ }
+ }
+}
+
+multiclass RVVOutBuiltinSetZvbb {
+ let OverloadedName = NAME in
+ defm "" : RVVOutBuiltinSet<NAME, "csil", [["v", "v", "vv"],
+ ["v", "Uv", "UvUv"]]>;
+}
+
+multiclass RVVOutBuiltinSetZvk<bit HasVV = 1, bit HasVS = 1> {
+ // vaesz only has 'vs' and vgmul only has 'vv' and they do not have ambiguous
+ // prototypes like other zvkned instructions (e.g. vaesdf), so we don't
+ // need to encode the operand mnemonics into its intrinsic function name.
+ if HasVV then {
+ defvar name = NAME # !if(!eq(NAME, "vgmul"), "", "_vv");
+ let OverloadedName = name in
+ defm "" : RVVOutBuiltinSet<NAME # "_vv", "i",
+ [["vv", "Uv", "UvUvUv"]]>;
+ }
+
+ if HasVS then {
+ foreach vs2_lmul = ["(SEFixedLog2LMUL:-1)", "(SEFixedLog2LMUL:0)",
+ "(SEFixedLog2LMUL:1)", "(SEFixedLog2LMUL:2)",
+ "(SEFixedLog2LMUL:3)"] in {
+ defvar name = NAME # !if(!eq(NAME, "vaesz"), "", "_vs");
+ let OverloadedName = name, IRName = NAME # "_vs", Name = NAME # "_vs",
+ IntrinsicTypes = [-1, 1] in
+ def NAME # vs2_lmul
+ : RVVBuiltin<vs2_lmul # "UvUv", "UvUv" # vs2_lmul # "Uv", "i">;
+ }
+ }
+}
+
+multiclass RVVOutOp2BuiltinSetVVZvk<string type_range = "i">
+ : RVVOutOp2BuiltinSet<NAME, type_range, [["vv", "Uv", "UvUvUvUv"]]>;
+
+multiclass RVVOutOp2BuiltinSetVIZvk<string type_range = "i">
+ : RVVOutOp2BuiltinSet<NAME, type_range, [["vi", "Uv", "UvUvUvKz"]]>;
+
+multiclass RVVSignedWidenBinBuiltinSetVwsll
+ : RVVWidenBuiltinSet<NAME, "csi",
+ [["vv", "Uw", "UwUvUv"],
+ ["vx", "Uw", "UwUvz"]]>;
+
+let UnMaskedPolicyScheme = HasPassthruOperand in {
+ // zvkb
+ let RequiredFeatures = ["Zvkb", "Experimental"] in {
+ defm vandn : RVVUnsignedBinBuiltinSet;
+ defm vbrev8 : RVVOutBuiltinSetZvbb;
+ defm vrev8 : RVVOutBuiltinSetZvbb;
+ defm vrol : RVVUnsignedShiftBuiltinSet;
+ defm vror : RVVUnsignedShiftBuiltinSet;
+ }
+
+ // zvbb
+ let RequiredFeatures = ["Zvbb", "Experimental"] in {
+ defm vbrev : RVVOutBuiltinSetZvbb;
+ defm vclz : RVVOutBuiltinSetZvbb;
+ defm vctz : RVVOutBuiltinSetZvbb;
+ defm vcpopv : RVVOutBuiltinSetZvbb;
+ let OverloadedName = "vwsll" in
+ defm vwsll : RVVSignedWidenBinBuiltinSetVwsll;
+ }
+
+ // zvbc
+ let RequiredFeatures = ["Zvbc", "Experimental"] in {
+ defm vclmul : RVVInt64BinBuiltinSet;
+ defm vclmulh : RVVInt64BinBuiltinSet;
+ }
+}
+
+let UnMaskedPolicyScheme = HasPolicyOperand, HasMasked = false in {
+ // zvkg
+ let RequiredFeatures = ["Zvkg", "Experimental"] in {
+ defm vghsh : RVVOutOp2BuiltinSetVVZvk;
+ defm vgmul : RVVOutBuiltinSetZvk<HasVV=1, HasVS=0>;
+ }
+
+ // zvkned
+ let RequiredFeatures = ["Zvkned", "Experimental"] in {
+ defm vaesdf : RVVOutBuiltinSetZvk;
+ defm vaesdm : RVVOutBuiltinSetZvk;
+ defm vaesef : RVVOutBuiltinSetZvk;
+ defm vaesem : RVVOutBuiltinSetZvk;
+ let UnMaskedPolicyScheme = HasPassthruOperand in
+ defm vaeskf1 : RVVOutOp1BuiltinSet<"vaeskf1", "i", [["vi", "Uv", "UvUvKz"]]>;
+ defm vaeskf2 : RVVOutOp2BuiltinSetVIZvk;
+ defm vaesz : RVVOutBuiltinSetZvk<HasVV=0>;
+ }
+
+ // zvknha
+ let RequiredFeatures = ["Zvknha", "Experimental"] in {
+ defm vsha2ch : RVVOutOp2BuiltinSetVVZvk<"i">;
+ defm vsha2cl : RVVOutOp2BuiltinSetVVZvk<"i">;
+ defm vsha2ms : RVVOutOp2BuiltinSetVVZvk<"i">;
+ }
+
+ // zvknhb
+ let RequiredFeatures = ["Zvknhb", "Experimental"] in {
+ defm vsha2ch : RVVOutOp2BuiltinSetVVZvk<"il">;
+ defm vsha2cl : RVVOutOp2BuiltinSetVVZvk<"il">;
+ defm vsha2ms : RVVOutOp2BuiltinSetVVZvk<"il">;
+ }
+
+ // zvksed
+ let RequiredFeatures = ["Zvksed", "Experimental"] in {
+ let UnMaskedPolicyScheme = HasPassthruOperand in
+ defm vsm4k : RVVOutOp1BuiltinSet<"vsm4k", "i", [["vi", "Uv", "UvUvKz"]]>;
+ defm vsm4r : RVVOutBuiltinSetZvk;
+ }
+
+ // zvksh
+ let RequiredFeatures = ["Zvksh", "Experimental"] in {
+ defm vsm3c : RVVOutOp2BuiltinSetVIZvk;
+ let UnMaskedPolicyScheme = HasPassthruOperand in
+ defm vsm3me : RVVOutOp1BuiltinSet<"vsm3me", "i", [["vv", "Uv", "UvUvUv"]]>;
}
}
diff --git a/contrib/llvm-project/clang/include/clang/Basic/riscv_vector_common.td b/contrib/llvm-project/clang/include/clang/Basic/riscv_vector_common.td
new file mode 100644
index 000000000000..040db6f0cdbf
--- /dev/null
+++ b/contrib/llvm-project/clang/include/clang/Basic/riscv_vector_common.td
@@ -0,0 +1,713 @@
+//==------ riscv_vector_common.td - RISC-V V-ext builtin class ------------===//
+//
+// 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 RVV builtin base class for RISC-V V-extension.
+//
+//===----------------------------------------------------------------------===//
+
+//===----------------------------------------------------------------------===//
+// Instruction definitions
+//===----------------------------------------------------------------------===//
+// Each record of the class RVVBuiltin defines a collection of builtins (i.e.
+// "def vadd : RVVBuiltin" will be used to define things like "vadd_vv_i32m1",
+// "vadd_vv_i32m2", etc).
+//
+// The elements of this collection are defined by an instantiation process the
+// range of which is specified by the cross product of the LMUL attribute and
+// every element in the attribute TypeRange. By default builtins have LMUL = [1,
+// 2, 4, 8, 1/2, 1/4, 1/8] so the process is repeated 7 times. In tablegen we
+// use the Log2LMUL [0, 1, 2, 3, -1, -2, -3] to represent the LMUL.
+//
+// LMUL represents the fact that the types of values used by that builtin are
+// values generated by instructions that are executed under that LMUL. However,
+// this does not mean the builtin is necessarily lowered into an instruction
+// that executes under the specified LMUL. An example where this happens are
+// loads and stores of masks. A mask like `vbool8_t` can be generated, for
+// instance, by comparing two `__rvv_int8m1_t` (this is LMUL=1) or comparing two
+// `__rvv_int16m2_t` (this is LMUL=2). The actual load or store, however, will
+// be performed under LMUL=1 because mask registers are not grouped.
+//
+// TypeRange is a non-empty sequence of basic types:
+//
+// c: int8_t (i8)
+// s: int16_t (i16)
+// i: int32_t (i32)
+// l: int64_t (i64)
+// x: float16_t (half)
+// f: float32_t (float)
+// d: float64_t (double)
+// y: bfloat16_t (bfloat16)
+//
+// This way, given an LMUL, a record with a TypeRange "sil" will cause the
+// definition of 3 builtins. Each type "t" in the TypeRange (in this example
+// they are int16_t, int32_t, int64_t) is used as a parameter that drives the
+// definition of that particular builtin (for the given LMUL).
+//
+// During the instantiation, types can be transformed or modified using type
+// transformers. Given a type "t" the following primitive type transformers can
+// be applied to it to yield another type.
+//
+// e: type of "t" as is (identity)
+// v: computes a vector type whose element type is "t" for the current LMUL
+// w: computes a vector type identical to what 'v' computes except for the
+// element type which is twice as wide as the element type of 'v'
+// q: computes a vector type identical to what 'v' computes except for the
+// element type which is four times as wide as the element type of 'v'
+// o: computes a vector type identical to what 'v' computes except for the
+// element type which is eight times as wide as the element type of 'v'
+// m: computes a vector type identical to what 'v' computes except for the
+// element type which is bool
+// 0: void type, ignores "t"
+// z: size_t, ignores "t"
+// t: ptrdiff_t, ignores "t"
+// u: unsigned long, ignores "t"
+// l: long, ignores "t"
+// f: float32, ignores "t"
+//
+// So for instance if t is "i", i.e. int, then "e" will yield int again. "v"
+// will yield an RVV vector type (assume LMUL=1), so __rvv_int32m1_t.
+// Accordingly "w" would yield __rvv_int64m2_t.
+//
+// A type transformer can be prefixed by other non-primitive type transformers.
+//
+// P: constructs a pointer to the current type
+// C: adds const to the type
+// K: requires the integer type to be a constant expression
+// U: given an integer type or vector type, computes its unsigned variant
+// I: given a vector type, compute the vector type with integer type
+// elements of the same width
+// F: given a vector type, compute the vector type with floating-point type
+// elements of the same width
+// S: given a vector type, computes its equivalent one for LMUL=1. This is a
+// no-op if the vector was already LMUL=1
+// (Log2EEW:Value): Log2EEW value could be 3/4/5/6 (8/16/32/64), given a
+// vector type (SEW and LMUL) and EEW (8/16/32/64), computes its
+// equivalent integer vector type with EEW and corresponding ELMUL (elmul =
+// (eew/sew) * lmul). For example, vector type is __rvv_float16m4
+// (SEW=16, LMUL=4) and Log2EEW is 3 (EEW=8), and then equivalent vector
+// type is __rvv_uint8m2_t (elmul=(8/16)*4 = 2). Ignore to define a new
+// builtins if its equivalent type has illegal lmul.
+// (FixedSEW:Value): Given a vector type (SEW and LMUL), and computes another
+// vector type which only changed SEW as given value. Ignore to define a new
+// builtin if its equivalent type has illegal lmul or the SEW does not changed.
+// (SFixedLog2LMUL:Value): Smaller Fixed Log2LMUL. Given a vector type (SEW
+// and LMUL), and computes another vector type which only changed LMUL as
+// given value. The new LMUL should be smaller than the old one. Ignore to
+// define a new builtin if its equivalent type has illegal lmul.
+// (SEFixedLog2LMUL:Value): Smaller or Equal Fixed Log2LMUL. Given a vector
+// type (SEW and LMUL), and computes another vector type which only
+// changed LMUL as given value. The new LMUL should be smaller than or
+// equal to the old one. Ignore to define a new builtin if its equivalent
+// type has illegal lmul.
+// (LFixedLog2LMUL:Value): Larger Fixed Log2LMUL. Given a vector type (SEW
+// and LMUL), and computes another vector type which only changed LMUL as
+// given value. The new LMUL should be larger than the old one. Ignore to
+// define a new builtin if its equivalent type has illegal lmul.
+//
+// Following with the example above, if t is "i", then "Ue" will yield unsigned
+// int and "Fv" will yield __rvv_float32m1_t (again assuming LMUL=1), Fw would
+// yield __rvv_float64m2_t, etc.
+//
+// Each builtin is then defined by applying each type in TypeRange against the
+// sequence of type transformers described in Suffix and Prototype.
+//
+// The name of the builtin is defined by the Name attribute (which defaults to
+// the name of the class) appended (separated with an underscore) the Suffix
+// attribute. For instance with Name="foo", Suffix = "v" and TypeRange = "il",
+// the builtin generated will be __builtin_rvv_foo_i32m1 and
+// __builtin_rvv_foo_i64m1 (under LMUL=1). If Suffix contains more than one
+// type transformer (say "vv") each of the types is separated with an
+// underscore as in "__builtin_rvv_foo_i32m1_i32m1".
+//
+// The C/C++ prototype of the builtin is defined by the Prototype attribute.
+// Prototype is a non-empty sequence of type transformers, the first of which
+// is the return type of the builtin and the rest are the parameters of the
+// builtin, in order. For instance if Prototype is "wvv" and TypeRange is "si"
+// a first builtin will have type
+// __rvv_int32m2_t (__rvv_int16m1_t, __rvv_int16m1_t) and the second builtin
+// will have type __rvv_int64m2_t (__rvv_int32m1_t, __rvv_int32m1_t) (again
+// under LMUL=1).
+//
+// There are a number of attributes that are used to constraint the number and
+// shape of the builtins generated. Refer to the comments below for them.
+
+class PolicyScheme<int val>{
+ int Value = val;
+}
+def NonePolicy : PolicyScheme<0>;
+def HasPassthruOperand : PolicyScheme<1>;
+def HasPolicyOperand : PolicyScheme<2>;
+
+class RVVBuiltin<string suffix, string prototype, string type_range,
+ string overloaded_suffix = ""> {
+ // Base name that will be prepended in __builtin_rvv_ and appended the
+ // computed Suffix.
+ string Name = NAME;
+
+ // If not empty, each instantiated builtin will have this appended after an
+ // underscore (_). It is instantiated like Prototype.
+ string Suffix = suffix;
+
+ // If empty, default OverloadedName is sub string of `Name` which end of first
+ // '_'. For example, the default overloaded name is `vadd` for Name `vadd_vv`.
+ // It's used for describe some special naming cases.
+ string OverloadedName = "";
+
+ // If not empty, each OverloadedName will have this appended after an
+ // underscore (_). It is instantiated like Prototype.
+ string OverloadedSuffix = overloaded_suffix;
+
+ // The different variants of the builtin, parameterised with a type.
+ string TypeRange = type_range;
+
+ // We use each type described in TypeRange and LMUL with prototype to
+ // instantiate a specific element of the set of builtins being defined.
+ // Prototype attribute defines the C/C++ prototype of the builtin. It is a
+ // non-empty sequence of type transformers, the first of which is the return
+ // type of the builtin and the rest are the parameters of the builtin, in
+ // order. For instance if Prototype is "wvv", TypeRange is "si" and LMUL=1, a
+ // first builtin will have type
+ // __rvv_int32m2_t (__rvv_int16m1_t, __rvv_int16m1_t), and the second builtin
+ // will have type __rvv_int64m2_t (__rvv_int32m1_t, __rvv_int32m1_t).
+ string Prototype = prototype;
+
+ // This builtin has a masked form.
+ bit HasMasked = true;
+
+ // If HasMasked, this flag states that this builtin has a maskedoff operand. It
+ // is always the first operand in builtin and IR intrinsic.
+ bit HasMaskedOffOperand = true;
+
+ // This builtin has a granted vector length parameter.
+ bit HasVL = true;
+
+ // The policy scheme for masked intrinsic IR.
+ // It could be NonePolicy or HasPolicyOperand.
+ // HasPolicyOperand: Has a policy operand. 0 is tail and mask undisturbed, 1 is
+ // tail agnostic, 2 is mask undisturbed, and 3 is tail and mask agnostic. The
+ // policy operand is located at the last position.
+ PolicyScheme MaskedPolicyScheme = HasPolicyOperand;
+
+ // The policy scheme for unmasked intrinsic IR.
+ // It could be NonePolicy, HasPassthruOperand or HasPolicyOperand.
+ // HasPassthruOperand: Has a passthru operand to decide tail policy. If it is
+ // poison, tail policy is tail agnostic, otherwise policy is tail undisturbed.
+ // HasPolicyOperand: Has a policy operand. 1 is tail agnostic and 0 is tail
+ // undisturbed.
+ PolicyScheme UnMaskedPolicyScheme = NonePolicy;
+
+ // This builtin support tail agnostic and undisturbed policy.
+ bit HasTailPolicy = true;
+ // This builtin support mask agnostic and undisturbed policy.
+ bit HasMaskPolicy = true;
+
+ // This builtin prototype with TA or TAMA policy could not support overloading
+ // API. Other policy intrinsic functions would support overloading API with
+ // suffix `_tu`, `tumu`, `tuma`, `tamu` and `tama`.
+ bit SupportOverloading = true;
+
+ // This builtin is valid for the given Log2LMULs.
+ list<int> Log2LMUL = [0, 1, 2, 3, -1, -2, -3];
+
+ // Manual code in clang codegen riscv_vector_builtin_cg.inc
+ code ManualCodegen = [{}];
+
+ // When emit the automatic clang codegen, it describes what types we have to use
+ // to obtain the specific LLVM intrinsic. -1 means the return type, otherwise,
+ // k >= 0 meaning the k-th operand (counting from zero) of the codegen'd
+ // parameter of the unmasked version. k can't be the mask operand's position.
+ list<int> IntrinsicTypes = [];
+
+ // If these names are not empty, this is the ID of the LLVM intrinsic
+ // we want to lower to.
+ string IRName = NAME;
+
+ // If HasMasked, this is the ID of the LLVM intrinsic we want to lower to.
+ string MaskedIRName = NAME #"_mask";
+
+ // Use clang_builtin_alias to save the number of builtins.
+ bit HasBuiltinAlias = true;
+
+ // Features required to enable for this builtin.
+ list<string> RequiredFeatures = [];
+
+ // Number of fields for Load/Store Segment instructions.
+ int NF = 1;
+
+ // Set to true if the builtin is associated with tuple types.
+ bit IsTuple = false;
+
+ // Set to true if the builtin has a parameter that models floating-point
+ // rounding mode control
+ bit HasFRMRoundModeOp = false;
+}
+
+// This is the code emitted in the header.
+class RVVHeader {
+ code HeaderCode;
+}
+
+//===----------------------------------------------------------------------===//
+// Basic classes with automatic codegen.
+//===----------------------------------------------------------------------===//
+
+class RVVOutBuiltin<string suffix, string prototype, string type_range>
+ : RVVBuiltin<suffix, prototype, type_range> {
+ let IntrinsicTypes = [-1];
+}
+
+class RVVOp0Builtin<string suffix, string prototype, string type_range>
+ : RVVBuiltin<suffix, prototype, type_range> {
+ let IntrinsicTypes = [0];
+}
+
+class RVVOutOp1Builtin<string suffix, string prototype, string type_range>
+ : RVVBuiltin<suffix, prototype, type_range> {
+ let IntrinsicTypes = [-1, 1];
+}
+
+class RVVOutOp0Op1Builtin<string suffix, string prototype, string type_range>
+ : RVVBuiltin<suffix, prototype, type_range> {
+ let IntrinsicTypes = [-1, 0, 1];
+}
+
+multiclass RVVBuiltinSet<string intrinsic_name, string type_range,
+ list<list<string>> suffixes_prototypes,
+ list<int> intrinsic_types> {
+ let IRName = intrinsic_name, MaskedIRName = intrinsic_name # "_mask",
+ IntrinsicTypes = intrinsic_types in {
+ foreach s_p = suffixes_prototypes in {
+ let Name = NAME # "_" # s_p[0] in {
+ defvar suffix = s_p[1];
+ defvar prototype = s_p[2];
+ def : RVVBuiltin<suffix, prototype, type_range>;
+ }
+ }
+ }
+}
+
+// IntrinsicTypes is output, op0, op1 [-1, 0, 1]
+multiclass RVVOutOp0Op1BuiltinSet<string intrinsic_name, string type_range,
+ list<list<string>> suffixes_prototypes>
+ : RVVBuiltinSet<intrinsic_name, type_range, suffixes_prototypes,
+ [-1, 0, 1]>;
+
+multiclass RVVOutBuiltinSet<string intrinsic_name, string type_range,
+ list<list<string>> suffixes_prototypes>
+ : RVVBuiltinSet<intrinsic_name, type_range, suffixes_prototypes, [-1]>;
+
+multiclass RVVOp0BuiltinSet<string intrinsic_name, string type_range,
+ list<list<string>> suffixes_prototypes>
+ : RVVBuiltinSet<intrinsic_name, type_range, suffixes_prototypes, [0]>;
+
+// IntrinsicTypes is output, op1 [-1, 0]
+multiclass RVVOutOp0BuiltinSet<string intrinsic_name, string type_range,
+ list<list<string>> suffixes_prototypes>
+ : RVVBuiltinSet<intrinsic_name, type_range, suffixes_prototypes, [-1, 0]>;
+
+// IntrinsicTypes is output, op1 [-1, 1]
+multiclass RVVOutOp1BuiltinSet<string intrinsic_name, string type_range,
+ list<list<string>> suffixes_prototypes>
+ : RVVBuiltinSet<intrinsic_name, type_range, suffixes_prototypes, [-1, 1]>;
+
+multiclass RVVOp0Op1BuiltinSet<string intrinsic_name, string type_range,
+ list<list<string>> suffixes_prototypes>
+ : RVVBuiltinSet<intrinsic_name, type_range, suffixes_prototypes, [0, 1]>;
+
+multiclass RVVOutOp1Op2BuiltinSet<string intrinsic_name, string type_range,
+ list<list<string>> suffixes_prototypes>
+ : RVVBuiltinSet<intrinsic_name, type_range, suffixes_prototypes, [-1, 1, 2]>;
+
+// IntrinsicTypes is output, op2 [-1, 2]
+multiclass RVVOutOp2BuiltinSet<string intrinsic_name, string type_range,
+ list<list<string>> suffixes_prototypes>
+ : RVVBuiltinSet<intrinsic_name, type_range, suffixes_prototypes, [-1, 2]>;
+
+multiclass RVVSignedBinBuiltinSet
+ : RVVOutOp1BuiltinSet<NAME, "csil",
+ [["vv", "v", "vvv"],
+ ["vx", "v", "vve"]]>;
+
+multiclass RVVSignedBinBuiltinSetRoundingMode
+ : RVVOutOp1BuiltinSet<NAME, "csil",
+ [["vv", "v", "vvvu"],
+ ["vx", "v", "vveu"]]>;
+
+multiclass RVVUnsignedBinBuiltinSet
+ : RVVOutOp1BuiltinSet<NAME, "csil",
+ [["vv", "Uv", "UvUvUv"],
+ ["vx", "Uv", "UvUvUe"]]>;
+
+multiclass RVVUnsignedBinBuiltinSetRoundingMode
+ : RVVOutOp1BuiltinSet<NAME, "csil",
+ [["vv", "Uv", "UvUvUvu"],
+ ["vx", "Uv", "UvUvUeu"]]>;
+
+multiclass RVVIntBinBuiltinSet
+ : RVVSignedBinBuiltinSet,
+ RVVUnsignedBinBuiltinSet;
+
+multiclass RVVInt64BinBuiltinSet
+ : RVVOutOp1BuiltinSet<NAME, "l",
+ [["vv", "v", "vvv"],
+ ["vx", "v", "vve"]]>,
+ RVVOutOp1BuiltinSet<NAME, "l",
+ [["vv", "Uv", "UvUvUv"],
+ ["vx", "Uv", "UvUvUe"]]>;
+
+multiclass RVVSlideOneBuiltinSet
+ : RVVOutOp1BuiltinSet<NAME, "csil",
+ [["vx", "v", "vve"],
+ ["vx", "Uv", "UvUvUe"]]>;
+
+multiclass RVVSignedShiftBuiltinSet
+ : RVVOutOp1BuiltinSet<NAME, "csil",
+ [["vv", "v", "vvUv"],
+ ["vx", "v", "vvz"]]>;
+
+multiclass RVVSignedShiftBuiltinSetRoundingMode
+ : RVVOutOp1BuiltinSet<NAME, "csil",
+ [["vv", "v", "vvUvu"],
+ ["vx", "v", "vvzu"]]>;
+
+multiclass RVVUnsignedShiftBuiltinSet
+ : RVVOutOp1BuiltinSet<NAME, "csil",
+ [["vv", "Uv", "UvUvUv"],
+ ["vx", "Uv", "UvUvz"]]>;
+
+multiclass RVVUnsignedShiftBuiltinSetRoundingMode
+ : RVVOutOp1BuiltinSet<NAME, "csil",
+ [["vv", "Uv", "UvUvUvu"],
+ ["vx", "Uv", "UvUvzu"]]>;
+
+multiclass RVVShiftBuiltinSet
+ : RVVSignedShiftBuiltinSet,
+ RVVUnsignedShiftBuiltinSet;
+
+let Log2LMUL = [-3, -2, -1, 0, 1, 2] in {
+ multiclass RVVSignedNShiftBuiltinSet
+ : RVVOutOp0Op1BuiltinSet<NAME, "csil",
+ [["wv", "v", "vwUv"],
+ ["wx", "v", "vwz"]]>;
+
+ multiclass RVVSignedNShiftBuiltinSetRoundingMode
+ : RVVOutOp0Op1BuiltinSet<NAME, "csil",
+ [["wv", "v", "vwUvu"],
+ ["wx", "v", "vwzu"]]>;
+
+ multiclass RVVUnsignedNShiftBuiltinSet
+ : RVVOutOp0Op1BuiltinSet<NAME, "csil",
+ [["wv", "Uv", "UvUwUv"],
+ ["wx", "Uv", "UvUwz"]]>;
+
+ multiclass RVVUnsignedNShiftBuiltinSetRoundingMode
+ : RVVOutOp0Op1BuiltinSet<NAME, "csil",
+ [["wv", "Uv", "UvUwUvu"],
+ ["wx", "Uv", "UvUwzu"]]>;
+
+}
+
+multiclass RVVCarryinBuiltinSet
+ : RVVOutOp1BuiltinSet<NAME, "csil",
+ [["vvm", "v", "vvvm"],
+ ["vxm", "v", "vvem"],
+ ["vvm", "Uv", "UvUvUvm"],
+ ["vxm", "Uv", "UvUvUem"]]>;
+
+multiclass RVVCarryOutInBuiltinSet<string intrinsic_name>
+ : RVVOp0Op1BuiltinSet<intrinsic_name, "csil",
+ [["vvm", "vm", "mvvm"],
+ ["vxm", "vm", "mvem"],
+ ["vvm", "Uvm", "mUvUvm"],
+ ["vxm", "Uvm", "mUvUem"]]>;
+
+multiclass RVVSignedMaskOutBuiltinSet
+ : RVVOp0Op1BuiltinSet<NAME, "csil",
+ [["vv", "vm", "mvv"],
+ ["vx", "vm", "mve"]]>;
+
+multiclass RVVUnsignedMaskOutBuiltinSet
+ : RVVOp0Op1BuiltinSet<NAME, "csil",
+ [["vv", "Uvm", "mUvUv"],
+ ["vx", "Uvm", "mUvUe"]]>;
+
+multiclass RVVIntMaskOutBuiltinSet
+ : RVVSignedMaskOutBuiltinSet,
+ RVVUnsignedMaskOutBuiltinSet;
+
+class RVVIntExt<string intrinsic_name, string suffix, string prototype,
+ string type_range>
+ : RVVBuiltin<suffix, prototype, type_range> {
+ let IRName = intrinsic_name;
+ let MaskedIRName = intrinsic_name # "_mask";
+ let OverloadedName = NAME;
+ let IntrinsicTypes = [-1, 0];
+}
+
+let HasMaskedOffOperand = false in {
+ multiclass RVVIntTerBuiltinSet {
+ defm "" : RVVOutOp1BuiltinSet<NAME, "csil",
+ [["vv", "v", "vvvv"],
+ ["vx", "v", "vvev"],
+ ["vv", "Uv", "UvUvUvUv"],
+ ["vx", "Uv", "UvUvUeUv"]]>;
+ }
+ multiclass RVVFloatingTerBuiltinSet {
+ defm "" : RVVOutOp1BuiltinSet<NAME, "xfd",
+ [["vv", "v", "vvvv"],
+ ["vf", "v", "vvev"]]>;
+ }
+ multiclass RVVFloatingTerBuiltinSetRoundingMode {
+ defm "" : RVVOutOp1BuiltinSet<NAME, "xfd",
+ [["vv", "v", "vvvvu"],
+ ["vf", "v", "vvevu"]]>;
+ }
+}
+
+let HasMaskedOffOperand = false, Log2LMUL = [-2, -1, 0, 1, 2] in {
+ multiclass RVVFloatingWidenTerBuiltinSet {
+ defm "" : RVVOutOp1Op2BuiltinSet<NAME, "xf",
+ [["vv", "w", "wwvv"],
+ ["vf", "w", "wwev"]]>;
+ }
+ multiclass RVVFloatingWidenTerBuiltinSetRoundingMode {
+ defm "" : RVVOutOp1Op2BuiltinSet<NAME, "xf",
+ [["vv", "w", "wwvvu"],
+ ["vf", "w", "wwevu"]]>;
+ }
+}
+
+multiclass RVVFloatingBinBuiltinSet
+ : RVVOutOp1BuiltinSet<NAME, "xfd",
+ [["vv", "v", "vvv"],
+ ["vf", "v", "vve"]]>;
+
+multiclass RVVFloatingBinBuiltinSetRoundingMode
+ : RVVOutOp1BuiltinSet<NAME, "xfd",
+ [["vv", "v", "vvvu"],
+ ["vf", "v", "vveu"]]>;
+
+multiclass RVVFloatingBinVFBuiltinSet
+ : RVVOutOp1BuiltinSet<NAME, "xfd",
+ [["vf", "v", "vve"]]>;
+
+multiclass RVVFloatingBinVFBuiltinSetRoundingMode
+ : RVVOutOp1BuiltinSet<NAME, "xfd",
+ [["vf", "v", "vveu"]]>;
+
+multiclass RVVFloatingMaskOutBuiltinSet
+ : RVVOp0Op1BuiltinSet<NAME, "xfd",
+ [["vv", "vm", "mvv"],
+ ["vf", "vm", "mve"]]>;
+
+multiclass RVVFloatingMaskOutVFBuiltinSet
+ : RVVOp0Op1BuiltinSet<NAME, "fd",
+ [["vf", "vm", "mve"]]>;
+
+multiclass RVVConvBuiltinSet<string intrinsic_name, string type_range,
+ list<list<string>> suffixes_prototypes> {
+let Name = intrinsic_name,
+ IRName = intrinsic_name,
+ MaskedIRName = intrinsic_name # "_mask",
+ IntrinsicTypes = [-1, 0] in {
+ foreach s_p = suffixes_prototypes in {
+ defvar suffix = s_p[0];
+ defvar prototype = s_p[1];
+ def : RVVBuiltin<suffix, prototype, type_range>;
+ }
+ }
+}
+
+
+class RVVMaskBinBuiltin : RVVOutBuiltin<"m", "mmm", "c"> {
+ let Name = NAME # "_mm";
+ let HasMasked = false;
+}
+
+class RVVMaskUnaryBuiltin : RVVOutBuiltin<"m", "mm", "c"> {
+ let Name = NAME # "_m";
+}
+
+class RVVMaskNullaryBuiltin : RVVOutBuiltin<"m", "m", "c"> {
+ let Name = NAME # "_m";
+ let HasMasked = false;
+ let SupportOverloading = false;
+}
+
+class RVVMaskOp0Builtin<string prototype> : RVVOp0Builtin<"m", prototype, "c"> {
+ let Name = NAME # "_m";
+ let HasMaskedOffOperand = false;
+}
+
+let UnMaskedPolicyScheme = HasPolicyOperand,
+ HasMaskedOffOperand = false in {
+ multiclass RVVSlideUpBuiltinSet {
+ defm "" : RVVOutBuiltinSet<NAME, "csilxfd",
+ [["vx","v", "vvvz"]]>;
+ defm "" : RVVOutBuiltinSet<NAME, "csil",
+ [["vx","Uv", "UvUvUvz"]]>;
+ }
+}
+
+let UnMaskedPolicyScheme = HasPassthruOperand,
+ ManualCodegen = [{
+ if (IsMasked) {
+ std::rotate(Ops.begin(), Ops.begin() + 1, Ops.end() - 1);
+ if ((PolicyAttrs & RVV_VTA) && (PolicyAttrs & RVV_VMA))
+ Ops.insert(Ops.begin(), llvm::PoisonValue::get(ResultType));
+ } else {
+ if (PolicyAttrs & RVV_VTA)
+ Ops.insert(Ops.begin(), llvm::PoisonValue::get(ResultType));
+ }
+
+ Ops.push_back(ConstantInt::get(Ops.back()->getType(), PolicyAttrs));
+ IntrinsicTypes = {ResultType, Ops.back()->getType()};
+ }] in {
+ multiclass RVVSlideDownBuiltinSet {
+ defm "" : RVVOutBuiltinSet<NAME, "csilxfd",
+ [["vx","v", "vvz"]]>;
+ defm "" : RVVOutBuiltinSet<NAME, "csil",
+ [["vx","Uv", "UvUvz"]]>;
+ }
+}
+
+class RVVFloatingUnaryBuiltin<string builtin_suffix, string ir_suffix,
+ string prototype>
+ : RVVOutBuiltin<ir_suffix, prototype, "xfd"> {
+ let Name = NAME # "_" # builtin_suffix;
+}
+
+class RVVFloatingUnaryVVBuiltin : RVVFloatingUnaryBuiltin<"v", "v", "vv">;
+
+class RVVConvBuiltin<string suffix, string prototype, string type_range,
+ string overloaded_name>
+ : RVVBuiltin<suffix, prototype, type_range> {
+ let IntrinsicTypes = [-1, 0];
+ let OverloadedName = overloaded_name;
+}
+
+class RVVConvToSignedBuiltin<string overloaded_name>
+ : RVVConvBuiltin<"Iv", "Ivv", "xfd", overloaded_name>;
+
+class RVVConvToUnsignedBuiltin<string overloaded_name>
+ : RVVConvBuiltin<"Uv", "Uvv", "xfd", overloaded_name>;
+
+class RVVConvToWidenSignedBuiltin<string overloaded_name>
+ : RVVConvBuiltin<"Iw", "Iwv", "xf", overloaded_name>;
+
+class RVVConvToWidenUnsignedBuiltin<string overloaded_name>
+ : RVVConvBuiltin<"Uw", "Uwv", "xf", overloaded_name>;
+
+class RVVConvToNarrowingSignedBuiltin<string overloaded_name>
+ : RVVConvBuiltin<"Iv", "IvFw", "csi", overloaded_name>;
+
+class RVVConvToNarrowingUnsignedBuiltin<string overloaded_name>
+ : RVVConvBuiltin<"Uv", "UvFw", "csi", overloaded_name>;
+
+let HasMaskedOffOperand = true in {
+ multiclass RVVSignedReductionBuiltin {
+ defm "" : RVVOutOp0BuiltinSet<NAME, "csil",
+ [["vs", "vSv", "SvvSv"]]>;
+ }
+ multiclass RVVUnsignedReductionBuiltin {
+ defm "" : RVVOutOp0BuiltinSet<NAME, "csil",
+ [["vs", "UvUSv", "USvUvUSv"]]>;
+ }
+ multiclass RVVFloatingReductionBuiltin {
+ defm "" : RVVOutOp0BuiltinSet<NAME, "xfd",
+ [["vs", "vSv", "SvvSv"]]>;
+ }
+ multiclass RVVFloatingReductionBuiltinRoundingMode {
+ defm "" : RVVOutOp0BuiltinSet<NAME, "xfd",
+ [["vs", "vSv", "SvvSvu"]]>;
+ }
+ multiclass RVVFloatingWidenReductionBuiltin {
+ defm "" : RVVOutOp0BuiltinSet<NAME, "xf",
+ [["vs", "vSw", "SwvSw"]]>;
+ }
+ multiclass RVVFloatingWidenReductionBuiltinRoundingMode {
+ defm "" : RVVOutOp0BuiltinSet<NAME, "xf",
+ [["vs", "vSw", "SwvSwu"]]>;
+ }
+}
+
+multiclass RVVIntReductionBuiltinSet
+ : RVVSignedReductionBuiltin,
+ RVVUnsignedReductionBuiltin;
+
+// For widen operation which has different mangling name.
+multiclass RVVWidenBuiltinSet<string intrinsic_name, string type_range,
+ list<list<string>> suffixes_prototypes> {
+ let Log2LMUL = [-3, -2, -1, 0, 1, 2],
+ IRName = intrinsic_name, MaskedIRName = intrinsic_name # "_mask" in {
+ foreach s_p = suffixes_prototypes in {
+ let Name = NAME # "_" # s_p[0],
+ OverloadedName = NAME # "_" # s_p[0] in {
+ defvar suffix = s_p[1];
+ defvar prototype = s_p[2];
+ def : RVVOutOp0Op1Builtin<suffix, prototype, type_range>;
+ }
+ }
+ }
+}
+
+// For widen operation with widen operand which has different mangling name.
+multiclass RVVWidenWOp0BuiltinSet<string intrinsic_name, string type_range,
+ list<list<string>> suffixes_prototypes> {
+ let Log2LMUL = [-3, -2, -1, 0, 1, 2],
+ IRName = intrinsic_name, MaskedIRName = intrinsic_name # "_mask" in {
+ foreach s_p = suffixes_prototypes in {
+ let Name = NAME # "_" # s_p[0],
+ OverloadedName = NAME # "_" # s_p[0] in {
+ defvar suffix = s_p[1];
+ defvar prototype = s_p[2];
+ def : RVVOutOp1Builtin<suffix, prototype, type_range>;
+ }
+ }
+ }
+}
+
+multiclass RVVSignedWidenBinBuiltinSet
+ : RVVWidenBuiltinSet<NAME, "csi",
+ [["vv", "w", "wvv"],
+ ["vx", "w", "wve"]]>;
+
+multiclass RVVSignedWidenOp0BinBuiltinSet
+ : RVVWidenWOp0BuiltinSet<NAME # "_w", "csi",
+ [["wv", "w", "wwv"],
+ ["wx", "w", "wwe"]]>;
+
+multiclass RVVUnsignedWidenBinBuiltinSet
+ : RVVWidenBuiltinSet<NAME, "csi",
+ [["vv", "Uw", "UwUvUv"],
+ ["vx", "Uw", "UwUvUe"]]>;
+
+multiclass RVVUnsignedWidenOp0BinBuiltinSet
+ : RVVWidenWOp0BuiltinSet<NAME # "_w", "csi",
+ [["wv", "Uw", "UwUwUv"],
+ ["wx", "Uw", "UwUwUe"]]>;
+
+multiclass RVVFloatingWidenBinBuiltinSet
+ : RVVWidenBuiltinSet<NAME, "xf",
+ [["vv", "w", "wvv"],
+ ["vf", "w", "wve"]]>;
+
+multiclass RVVFloatingWidenBinBuiltinSetRoundingMode
+ : RVVWidenBuiltinSet<NAME, "xf",
+ [["vv", "w", "wvvu"],
+ ["vf", "w", "wveu"]]>;
+
+multiclass RVVFloatingWidenOp0BinBuiltinSet
+ : RVVWidenWOp0BuiltinSet<NAME # "_w", "xf",
+ [["wv", "w", "wwv"],
+ ["wf", "w", "wwe"]]>;
+
+multiclass RVVFloatingWidenOp0BinBuiltinSetRoundingMode
+ : RVVWidenWOp0BuiltinSet<NAME # "_w", "xf",
+ [["wv", "w", "wwvu"],
+ ["wf", "w", "wweu"]]>;
diff --git a/contrib/llvm-project/clang/include/clang/CodeGen/BackendUtil.h b/contrib/llvm-project/clang/include/clang/CodeGen/BackendUtil.h
index 77d500079f01..fc8ed4f011f9 100644
--- a/contrib/llvm-project/clang/include/clang/CodeGen/BackendUtil.h
+++ b/contrib/llvm-project/clang/include/clang/CodeGen/BackendUtil.h
@@ -16,8 +16,12 @@
namespace llvm {
class BitcodeModule;
template <typename T> class Expected;
+ template <typename T> class IntrusiveRefCntPtr;
class Module;
class MemoryBufferRef;
+ namespace vfs {
+ class FileSystem;
+ } // namespace vfs
}
namespace clang {
@@ -26,6 +30,7 @@ namespace clang {
class CodeGenOptions;
class TargetOptions;
class LangOptions;
+ class BackendConsumer;
enum BackendAction {
Backend_EmitAssembly, ///< Emit native assembly files
@@ -40,10 +45,15 @@ namespace clang {
const CodeGenOptions &CGOpts,
const TargetOptions &TOpts, const LangOptions &LOpts,
StringRef TDesc, llvm::Module *M, BackendAction Action,
- std::unique_ptr<raw_pwrite_stream> OS);
+ llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS,
+ std::unique_ptr<raw_pwrite_stream> OS,
+ BackendConsumer *BC = nullptr);
void EmbedBitcode(llvm::Module *M, const CodeGenOptions &CGOpts,
llvm::MemoryBufferRef Buf);
+
+ void EmbedObject(llvm::Module *M, const CodeGenOptions &CGOpts,
+ DiagnosticsEngine &Diags);
}
#endif
diff --git a/contrib/llvm-project/clang/include/clang/CodeGen/CGFunctionInfo.h b/contrib/llvm-project/clang/include/clang/CodeGen/CGFunctionInfo.h
index 4899c9deda6a..e388901b8a50 100644
--- a/contrib/llvm-project/clang/include/clang/CodeGen/CGFunctionInfo.h
+++ b/contrib/llvm-project/clang/include/clang/CodeGen/CGFunctionInfo.h
@@ -250,7 +250,7 @@ public:
static ABIArgInfo getCoerceAndExpand(llvm::StructType *coerceToType,
llvm::Type *unpaddedCoerceToType) {
#ifndef NDEBUG
- // Sanity checks on unpaddedCoerceToType.
+ // Check that unpaddedCoerceToType has roughly the right shape.
// Assert that we only have a struct type if there are multiple elements.
auto unpaddedStruct = dyn_cast<llvm::StructType>(unpaddedCoerceToType);
@@ -371,7 +371,7 @@ public:
dyn_cast<llvm::StructType>(UnpaddedCoerceAndExpandType)) {
return structTy->elements();
} else {
- return llvm::makeArrayRef(&UnpaddedCoerceAndExpandType, 1);
+ return llvm::ArrayRef(&UnpaddedCoerceAndExpandType, 1);
}
}
@@ -527,6 +527,11 @@ public:
return NumRequired;
}
+ /// Return true if the argument at a given index is required.
+ bool isRequiredArg(unsigned argIdx) const {
+ return argIdx == ~0U || argIdx < NumRequired;
+ }
+
unsigned getOpaqueData() const { return NumRequired; }
static RequiredArgs getFromOpaqueData(unsigned value) {
if (value == ~0U) return All;
@@ -567,6 +572,10 @@ class CGFunctionInfo final
/// Whether this is a chain call.
unsigned ChainCall : 1;
+ /// Whether this function is called by forwarding arguments.
+ /// This doesn't support inalloca or varargs.
+ unsigned DelegateCall : 1;
+
/// Whether this function is a CMSE nonsecure call
unsigned CmseNSCall : 1;
@@ -586,6 +595,9 @@ class CGFunctionInfo final
/// Whether this function has nocf_check attribute.
unsigned NoCfCheck : 1;
+ /// Log 2 of the maximum vector width.
+ unsigned MaxVectorWidth : 4;
+
RequiredArgs Required;
/// The struct representing all arguments passed in memory. Only used when
@@ -613,14 +625,11 @@ class CGFunctionInfo final
CGFunctionInfo() : Required(RequiredArgs::All) {}
public:
- static CGFunctionInfo *create(unsigned llvmCC,
- bool instanceMethod,
- bool chainCall,
- const FunctionType::ExtInfo &extInfo,
- ArrayRef<ExtParameterInfo> paramInfos,
- CanQualType resultType,
- ArrayRef<CanQualType> argTypes,
- RequiredArgs required);
+ static CGFunctionInfo *
+ create(unsigned llvmCC, bool instanceMethod, bool chainCall,
+ bool delegateCall, const FunctionType::ExtInfo &extInfo,
+ ArrayRef<ExtParameterInfo> paramInfos, CanQualType resultType,
+ ArrayRef<CanQualType> argTypes, RequiredArgs required);
void operator delete(void *p) { ::operator delete(p); }
// Friending class TrailingObjects is apparently not good enough for MSVC,
@@ -660,6 +669,8 @@ public:
bool isChainCall() const { return ChainCall; }
+ bool isDelegateCall() const { return DelegateCall; }
+
bool isCmseNSCall() const { return CmseNSCall; }
bool isNoReturn() const { return NoReturn; }
@@ -710,7 +721,7 @@ public:
ArrayRef<ExtParameterInfo> getExtParameterInfos() const {
if (!HasExtParameterInfos) return {};
- return llvm::makeArrayRef(getExtParameterInfosBuffer(), NumArgs);
+ return llvm::ArrayRef(getExtParameterInfosBuffer(), NumArgs);
}
ExtParameterInfo getExtParameterInfo(unsigned argIndex) const {
assert(argIndex <= NumArgs);
@@ -731,10 +742,22 @@ public:
ArgStructAlign = Align.getQuantity();
}
+ /// Return the maximum vector width in the arguments.
+ unsigned getMaxVectorWidth() const {
+ return MaxVectorWidth ? 1U << (MaxVectorWidth - 1) : 0;
+ }
+
+ /// Set the maximum vector width in the arguments.
+ void setMaxVectorWidth(unsigned Width) {
+ assert(llvm::isPowerOf2_32(Width) && "Expected power of 2 vector");
+ MaxVectorWidth = llvm::countr_zero(Width) + 1;
+ }
+
void Profile(llvm::FoldingSetNodeID &ID) {
ID.AddInteger(getASTCallingConvention());
ID.AddBoolean(InstanceMethod);
ID.AddBoolean(ChainCall);
+ ID.AddBoolean(DelegateCall);
ID.AddBoolean(NoReturn);
ID.AddBoolean(ReturnsRetained);
ID.AddBoolean(NoCallerSavedRegs);
@@ -752,17 +775,16 @@ public:
for (const auto &I : arguments())
I.type.Profile(ID);
}
- static void Profile(llvm::FoldingSetNodeID &ID,
- bool InstanceMethod,
- bool ChainCall,
+ static void Profile(llvm::FoldingSetNodeID &ID, bool InstanceMethod,
+ bool ChainCall, bool IsDelegateCall,
const FunctionType::ExtInfo &info,
ArrayRef<ExtParameterInfo> paramInfos,
- RequiredArgs required,
- CanQualType resultType,
+ RequiredArgs required, CanQualType resultType,
ArrayRef<CanQualType> argTypes) {
ID.AddInteger(info.getCC());
ID.AddBoolean(InstanceMethod);
ID.AddBoolean(ChainCall);
+ ID.AddBoolean(IsDelegateCall);
ID.AddBoolean(info.getNoReturn());
ID.AddBoolean(info.getProducesResult());
ID.AddBoolean(info.getNoCallerSavedRegs());
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/CodeGenAction.h b/contrib/llvm-project/clang/include/clang/CodeGen/CodeGenAction.h
index b5721344046d..7ad2988e589e 100644
--- a/contrib/llvm-project/clang/include/clang/CodeGen/CodeGenAction.h
+++ b/contrib/llvm-project/clang/include/clang/CodeGen/CodeGenAction.h
@@ -53,6 +53,9 @@ private:
std::unique_ptr<llvm::Module> loadModule(llvm::MemoryBufferRef MBRef);
+ /// Load bitcode modules to link into our module from the options.
+ bool loadLinkModules(CompilerInstance &CI);
+
protected:
/// Create a new code generation action. If the optional \p _VMContext
/// parameter is supplied, the action uses it without taking ownership,
@@ -80,7 +83,7 @@ public:
CodeGenerator *getCodeGenerator() const;
- BackendConsumer *BEConsumer;
+ BackendConsumer *BEConsumer = nullptr;
};
class EmitAssemblyAction : public CodeGenAction {
diff --git a/contrib/llvm-project/clang/include/clang/CodeGen/ConstantInitBuilder.h b/contrib/llvm-project/clang/include/clang/CodeGen/ConstantInitBuilder.h
index 88e357a0c29c..498acfd38013 100644
--- a/contrib/llvm-project/clang/include/clang/CodeGen/ConstantInitBuilder.h
+++ b/contrib/llvm-project/clang/include/clang/CodeGen/ConstantInitBuilder.h
@@ -41,7 +41,7 @@ class CodeGenModule;
/// for (auto &widget : widgets) {
/// auto widgetDesc = widgetArray.beginStruct();
/// widgetDesc.addInt(CGM.SizeTy, widget.getPower());
-/// widgetDesc.add(CGM.GetAddrOfConstantString(widget.getName()));
+/// widgetDesc.add(CGM.GetAddrOfConstantStringFromLiteral(widget.getName()));
/// widgetDesc.add(CGM.GetAddrOfGlobal(widget.getInitializerDecl()));
/// widgetDesc.finishAndAddTo(widgetArray);
/// }
@@ -204,11 +204,6 @@ public:
add(llvm::ConstantPointerNull::get(ptrTy));
}
- /// Add a bitcast of a value to a specific type.
- void addBitCast(llvm::Constant *value, llvm::Type *type) {
- add(llvm::ConstantExpr::getBitCast(value, type));
- }
-
/// Add a bunch of new values to this initializer.
void addAll(llvm::ArrayRef<llvm::Constant *> values) {
assert(!Finished && "cannot add more values after finishing builder");
diff --git a/contrib/llvm-project/clang/include/clang/CodeGen/ModuleBuilder.h b/contrib/llvm-project/clang/include/clang/CodeGen/ModuleBuilder.h
index f9d056ed8b1e..edacd82bf899 100644
--- a/contrib/llvm-project/clang/include/clang/CodeGen/ModuleBuilder.h
+++ b/contrib/llvm-project/clang/include/clang/CodeGen/ModuleBuilder.h
@@ -14,12 +14,17 @@
#define LLVM_CLANG_CODEGEN_MODULEBUILDER_H
#include "clang/AST/ASTConsumer.h"
+#include "clang/Basic/LLVM.h"
namespace llvm {
class Constant;
class LLVMContext;
class Module;
class StringRef;
+
+ namespace vfs {
+ class FileSystem;
+ }
}
namespace clang {
@@ -74,6 +79,10 @@ public:
/// This may return null if there was no matching declaration.
const Decl *GetDeclForMangledName(llvm::StringRef MangledName);
+ /// Given a global declaration, return a mangled name for this declaration
+ /// which has been added to this code generator via a Handle method.
+ llvm::StringRef GetMangledName(GlobalDecl GD);
+
/// Return the LLVM address of the given global entity.
///
/// \param isForDefinition If true, the caller intends to define the
@@ -94,10 +103,11 @@ public:
/// the allocated CodeGenerator instance.
CodeGenerator *CreateLLVMCodeGen(DiagnosticsEngine &Diags,
llvm::StringRef ModuleName,
+ IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS,
const HeaderSearchOptions &HeaderSearchOpts,
const PreprocessorOptions &PreprocessorOpts,
const CodeGenOptions &CGO,
- llvm::LLVMContext& C,
+ llvm::LLVMContext &C,
CoverageSourceInfo *CoverageInfo = nullptr);
} // end namespace clang
diff --git a/contrib/llvm-project/clang/include/clang/CodeGen/ObjectFilePCHContainerOperations.h b/contrib/llvm-project/clang/include/clang/CodeGen/ObjectFilePCHContainerOperations.h
index 8821cd70362e..7a02d8725885 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"
@@ -32,7 +32,7 @@ class ObjectFilePCHContainerWriter : public PCHContainerWriter {
/// A PCHContainerReader implementation that uses LLVM to
/// wraps Clang modules inside a COFF, ELF, or Mach-O container.
class ObjectFilePCHContainerReader : public PCHContainerReader {
- StringRef getFormat() const override { return "obj"; }
+ ArrayRef<StringRef> getFormats() const override;
/// Returns the serialized AST inside the PCH container Buffer.
StringRef ExtractPCH(llvm::MemoryBufferRef Buffer) const override;
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/CrossTU/CrossTranslationUnit.h b/contrib/llvm-project/clang/include/clang/CrossTU/CrossTranslationUnit.h
index d9f9c51fccd9..e6b608a10e61 100644
--- a/contrib/llvm-project/clang/include/clang/CrossTU/CrossTranslationUnit.h
+++ b/contrib/llvm-project/clang/include/clang/CrossTU/CrossTranslationUnit.h
@@ -18,11 +18,11 @@
#include "clang/Analysis/MacroExpansionContext.h"
#include "clang/Basic/LLVM.h"
#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/Optional.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/Path.h"
+#include <optional>
namespace clang {
class CompilerInstance;
@@ -101,7 +101,7 @@ std::string createCrossTUIndexString(const llvm::StringMap<std::string> &Index);
using InvocationListTy = llvm::StringMap<llvm::SmallVector<std::string, 32>>;
/// Parse the YAML formatted invocation list file content \p FileContent.
-/// The format is expected to be a mapping from from absolute source file
+/// The format is expected to be a mapping from absolute source file
/// paths in the filesystem to a list of command-line parts, which
/// constitute the invocation needed to compile that file. That invocation
/// will be used to produce the AST of the TU.
@@ -109,8 +109,10 @@ llvm::Expected<InvocationListTy> parseInvocationList(
StringRef FileContent,
llvm::sys::path::Style PathStyle = llvm::sys::path::Style::posix);
-// Returns true if the variable or any field of a record variable is const.
-bool containsConst(const VarDecl *VD, const ASTContext &ACtx);
+/// Returns true if it makes sense to import a foreign variable definition.
+/// For instance, we don't want to import variables that have non-trivial types
+/// because the constructor might have side-effects.
+bool shouldImport(const VarDecl *VD, const ASTContext &ACtx);
/// This class is used for tools that requires cross translation
/// unit capability.
@@ -179,7 +181,7 @@ public:
ASTUnit *Unit);
/// Get a name to identify a named decl.
- static llvm::Optional<std::string> getLookupName(const NamedDecl *ND);
+ static std::optional<std::string> getLookupName(const NamedDecl *ND);
/// Emit diagnostics for the user for potential configuration errors.
void emitCrossTUDiagnostics(const IndexError &IE);
@@ -191,10 +193,18 @@ public:
/// source-location, empty is returned.
/// \note Macro expansion tracking for imported TUs is not implemented yet.
/// It returns empty unconditionally.
- llvm::Optional<clang::MacroExpansionContext>
+ std::optional<clang::MacroExpansionContext>
getMacroExpansionContextForSourceLocation(
const clang::SourceLocation &ToLoc) const;
+ /// Returns true if the given Decl is newly created during the import.
+ bool isImportedAsNew(const Decl *ToDecl) const;
+
+ /// Returns true if the given Decl is mapped (or created) during an import
+ /// but there was an unrecoverable error (the AST node cannot be erased, it
+ /// is marked with an Error object in this case).
+ bool hasError(const Decl *ToDecl) const;
+
private:
void lazyInitImporterSharedSt(TranslationUnitDecl *ToTU);
ASTImporter &getOrCreateASTImporter(ASTUnit *Unit);
@@ -226,7 +236,7 @@ private:
StringRef InvocationListFilePath);
/// Load the ASTUnit by its identifier found in the index file. If the
- /// indentifier is suffixed with '.ast' it is considered a dump. Otherwise
+ /// identifier is suffixed with '.ast' it is considered a dump. Otherwise
/// it is treated as source-file, and on-demand parsed. Relative paths are
/// prefixed with CTUDir.
LoadResultTy load(StringRef Identifier);
@@ -253,7 +263,7 @@ private:
StringRef InvocationListFilePath;
/// In case of on-demand parsing, the invocations for parsing the source
/// files is stored.
- llvm::Optional<InvocationListTy> InvocationList;
+ std::optional<InvocationListTy> InvocationList;
index_error_code PreviousParsingResult = index_error_code::success;
};
@@ -291,7 +301,7 @@ private:
/// \param DisplayCTUProgress Display a message about loading new ASTs.
///
/// \return An Expected instance which contains the ASTUnit pointer or the
- /// error occured during the load.
+ /// error occurred during the load.
llvm::Expected<ASTUnit *> getASTUnitForFunction(StringRef FunctionName,
StringRef CrossTUDir,
StringRef IndexName,
diff --git a/contrib/llvm-project/clang/include/clang/DirectoryWatcher/DirectoryWatcher.h b/contrib/llvm-project/clang/include/clang/DirectoryWatcher/DirectoryWatcher.h
index 4475807dfce9..d879b6411c9e 100644
--- a/contrib/llvm-project/clang/include/clang/DirectoryWatcher/DirectoryWatcher.h
+++ b/contrib/llvm-project/clang/include/clang/DirectoryWatcher/DirectoryWatcher.h
@@ -20,7 +20,7 @@ namespace clang {
/// Provides notifications for file changes in a directory.
///
/// Invokes client-provided function on every filesystem event in the watched
-/// directory. Initially the the watched directory is scanned and for every file
+/// directory. Initially the watched directory is scanned and for every file
/// found, an event is synthesized as if the file was added.
///
/// This is not a general purpose directory monitoring tool - list of
diff --git a/contrib/llvm-project/clang/include/clang/Driver/Action.h b/contrib/llvm-project/clang/include/clang/Driver/Action.h
index ba84d886a6cf..04fa8b01b418 100644
--- a/contrib/llvm-project/clang/include/clang/Driver/Action.h
+++ b/contrib/llvm-project/clang/include/clang/Driver/Action.h
@@ -58,7 +58,7 @@ public:
OffloadClass,
PreprocessJobClass,
PrecompileJobClass,
- HeaderModulePrecompileJobClass,
+ ExtractAPIJobClass,
AnalyzeJobClass,
MigrateJobClass,
CompileJobClass,
@@ -72,11 +72,13 @@ public:
VerifyPCHJobClass,
OffloadBundlingJobClass,
OffloadUnbundlingJobClass,
- OffloadWrapperJobClass,
+ OffloadPackagerJobClass,
+ LinkerWrapperJobClass,
StaticLibJobClass,
+ BinaryAnalyzeJobClass,
JobClassFirst = PreprocessJobClass,
- JobClassLast = StaticLibJobClass
+ JobClassLast = BinaryAnalyzeJobClass
};
// The offloading kind determines if this action is binded to a particular
@@ -126,6 +128,9 @@ protected:
/// The Offloading architecture associated with this action.
const char *OffloadingArch = nullptr;
+ /// The Offloading toolchain associated with this device action.
+ const ToolChain *OffloadingToolChain = nullptr;
+
Action(ActionClass Kind, types::ID Type) : Action(Kind, ActionList(), Type) {}
Action(ActionClass Kind, Action *Input, types::ID Type)
: Action(Kind, ActionList({Input}), Type) {}
@@ -182,12 +187,18 @@ public:
/// Set the device offload info of this action and propagate it to its
/// dependences.
- void propagateDeviceOffloadInfo(OffloadKind OKind, const char *OArch);
+ void propagateDeviceOffloadInfo(OffloadKind OKind, const char *OArch,
+ const ToolChain *OToolChain);
/// Append the host offload info of this action and propagate it to its
/// dependences.
void propagateHostOffloadInfo(unsigned OKinds, const char *OArch);
+ void setHostOffloadInfo(unsigned OKinds, const char *OArch) {
+ ActiveOffloadKindMask |= OKinds;
+ OffloadingArch = OArch;
+ }
+
/// Set the offload info of this action to be the same as the provided action,
/// and propagate it to its dependences.
void propagateOffloadInfo(const Action *A);
@@ -198,10 +209,13 @@ public:
OffloadKind getOffloadingDeviceKind() const { return OffloadingDeviceKind; }
const char *getOffloadingArch() const { return OffloadingArch; }
+ const ToolChain *getOffloadingToolChain() const {
+ return OffloadingToolChain;
+ }
/// Check if this action have any offload kinds. Note that host offload kinds
/// are only set if the action is a dependence to a host offload action.
- bool isHostOffloading(OffloadKind OKind) const {
+ bool isHostOffloading(unsigned int OKind) const {
return ActiveOffloadKindMask & OKind;
}
bool isDeviceOffloading(OffloadKind OKind) const {
@@ -282,11 +296,16 @@ public:
OffloadKindList DeviceOffloadKinds;
public:
- /// Add a action along with the associated toolchain, bound arch, and
+ /// Add an action along with the associated toolchain, bound arch, and
/// offload kind.
void add(Action &A, const ToolChain &TC, const char *BoundArch,
OffloadKind OKind);
+ /// Add an action along with the associated toolchain, bound arch, and
+ /// offload kinds.
+ void add(Action &A, const ToolChain &TC, const char *BoundArch,
+ unsigned OffloadKindMask);
+
/// Get each of the individual arrays.
const ActionList &getActions() const { return DeviceActions; }
const ToolChainList &getToolChains() const { return DeviceToolChains; }
@@ -412,29 +431,21 @@ public:
PrecompileJobAction(Action *Input, types::ID OutputType);
static bool classof(const Action *A) {
- return A->getKind() == PrecompileJobClass ||
- A->getKind() == HeaderModulePrecompileJobClass;
+ return A->getKind() == PrecompileJobClass;
}
};
-class HeaderModulePrecompileJobAction : public PrecompileJobAction {
+class ExtractAPIJobAction : public JobAction {
void anchor() override;
- const char *ModuleName;
-
public:
- HeaderModulePrecompileJobAction(Action *Input, types::ID OutputType,
- const char *ModuleName);
+ ExtractAPIJobAction(Action *Input, types::ID OutputType);
static bool classof(const Action *A) {
- return A->getKind() == HeaderModulePrecompileJobClass;
+ return A->getKind() == ExtractAPIJobClass;
}
- void addModuleHeaderInput(Action *Input) {
- getInputs().push_back(Input);
- }
-
- const char *getModuleName() const { return ModuleName; }
+ void addHeaderInput(Action *Input) { getInputs().push_back(Input); }
};
class AnalyzeJobAction : public JobAction {
@@ -631,14 +642,25 @@ public:
}
};
-class OffloadWrapperJobAction : public JobAction {
+class OffloadPackagerJobAction : public JobAction {
void anchor() override;
public:
- OffloadWrapperJobAction(ActionList &Inputs, types::ID Type);
+ OffloadPackagerJobAction(ActionList &Inputs, types::ID Type);
static bool classof(const Action *A) {
- return A->getKind() == OffloadWrapperJobClass;
+ return A->getKind() == OffloadPackagerJobClass;
+ }
+};
+
+class LinkerWrapperJobAction : public JobAction {
+ void anchor() override;
+
+public:
+ LinkerWrapperJobAction(ActionList &Inputs, types::ID Type);
+
+ static bool classof(const Action *A) {
+ return A->getKind() == LinkerWrapperJobClass;
}
};
@@ -653,6 +675,17 @@ public:
}
};
+class BinaryAnalyzeJobAction : public JobAction {
+ void anchor() override;
+
+public:
+ BinaryAnalyzeJobAction(Action *Input, types::ID Type);
+
+ static bool classof(const Action *A) {
+ return A->getKind() == BinaryAnalyzeJobClass;
+ }
+};
+
} // namespace driver
} // namespace clang
diff --git a/contrib/llvm-project/clang/include/clang/Driver/ClangOptionDocs.td b/contrib/llvm-project/clang/include/clang/Driver/ClangOptionDocs.td
index 3f914afea735..a5ee577c5f45 100644
--- a/contrib/llvm-project/clang/include/clang/Driver/ClangOptionDocs.td
+++ b/contrib/llvm-project/clang/include/clang/Driver/ClangOptionDocs.td
@@ -28,8 +28,10 @@ GCC-compatible ``clang`` and ``clang++`` drivers.
}];
string Program = "clang";
- list<string> ExcludedFlags = ["HelpHidden", "NoDriverOption",
- "CLOption", "Unsupported", "Ignored", "FlangOnlyOption"];
+ // Note: We *must* use DefaultVis and not ClangOption, since that's
+ // the name of the actual TableGen record. The alias will not work.
+ list<string> VisibilityMask = ["DefaultVis"];
+ list<string> IgnoreFlags = ["HelpHidden", "Unsupported", "Ignored"];
}
include "Options.td"
diff --git a/contrib/llvm-project/clang/include/clang/Driver/Compilation.h b/contrib/llvm-project/clang/include/clang/Driver/Compilation.h
index 89a43b5b7dc0..36ae85c42451 100644
--- a/contrib/llvm-project/clang/include/clang/Driver/Compilation.h
+++ b/contrib/llvm-project/clang/include/clang/Driver/Compilation.h
@@ -15,13 +15,13 @@
#include "clang/Driver/Util.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/Optional.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Option/Option.h"
#include <cassert>
#include <iterator>
#include <map>
#include <memory>
+#include <optional>
#include <utility>
#include <vector>
@@ -112,8 +112,11 @@ class Compilation {
/// only be removed if we crash.
ArgStringMap FailureResultFiles;
+ /// -ftime-trace result files.
+ ArgStringMap TimeTraceFiles;
+
/// Optional redirection for stdin, stdout, stderr.
- std::vector<Optional<StringRef>> Redirects;
+ std::vector<std::optional<StringRef>> Redirects;
/// Callback called after compilation job has been finished.
/// Arguments of the callback are the compilation job as an instance of
@@ -143,6 +146,8 @@ public:
return ActiveOffloadMask & Kind;
}
+ unsigned getActiveOffloadKinds() const { return ActiveOffloadMask; }
+
/// Iterator that visits device toolchains of a given kind.
using const_offload_toolchains_iterator =
const std::multimap<Action::OffloadKind,
@@ -156,6 +161,11 @@ public:
return OrderedOffloadingToolchains.equal_range(Kind);
}
+ const_offload_toolchains_range
+ getOffloadToolChains(Action::OffloadKind Kind) const {
+ return OrderedOffloadingToolchains.equal_range(Kind);
+ }
+
/// Return true if an offloading tool chain of a given kind exists.
template <Action::OffloadKind Kind> bool hasOffloadToolChain() const {
return OrderedOffloadingToolchains.find(Kind) !=
@@ -209,6 +219,7 @@ public:
void addCommand(std::unique_ptr<Command> C) { Jobs.addJob(std::move(C)); }
+ llvm::opt::ArgStringList &getTempFiles() { return TempFiles; }
const llvm::opt::ArgStringList &getTempFiles() const { return TempFiles; }
const ArgStringMap &getResultFiles() const { return ResultFiles; }
@@ -261,6 +272,14 @@ public:
return Name;
}
+ const char *getTimeTraceFile(const JobAction *JA) const {
+ return TimeTraceFiles.lookup(JA);
+ }
+ void addTimeTraceFile(const char *Name, const JobAction *JA) {
+ assert(!TimeTraceFiles.contains(JA));
+ TimeTraceFiles[JA] = Name;
+ }
+
/// CleanupFile - Delete a given file.
///
/// \param IssueErrors - Report failures as errors.
@@ -288,16 +307,22 @@ public:
///
/// \param FailingCommand - For non-zero results, this will be set to the
/// Command which failed, if any.
+ /// \param LogOnly - When true, only tries to log the command, not actually
+ /// execute it.
/// \return The result code of the subprocess.
- int ExecuteCommand(const Command &C, const Command *&FailingCommand) const;
+ int ExecuteCommand(const Command &C, const Command *&FailingCommand,
+ bool LogOnly = false) const;
/// ExecuteJob - Execute a single job.
///
/// \param FailingCommands - For non-zero results, this will be a vector of
/// failing commands and their associated result code.
- void ExecuteJobs(
- const JobList &Jobs,
- SmallVectorImpl<std::pair<int, const Command *>> &FailingCommands) const;
+ /// \param LogOnly - When true, only tries to log the command, not actually
+ /// execute it.
+ void
+ ExecuteJobs(const JobList &Jobs,
+ SmallVectorImpl<std::pair<int, const Command *>> &FailingCommands,
+ bool LogOnly = false) const;
/// initCompilationForDiagnostics - Remove stale state and suppress output
/// so compilation can be reexecuted to generate additional diagnostic
@@ -318,8 +343,8 @@ public:
///
/// \param Redirects - array of optional paths. The array should have a size
/// of three. The inferior process's stdin(0), stdout(1), and stderr(2) will
- /// be redirected to the corresponding paths, if provided (not llvm::None).
- void Redirect(ArrayRef<Optional<StringRef>> Redirects);
+ /// be redirected to the corresponding paths, if provided (not std::nullopt).
+ void Redirect(ArrayRef<std::optional<StringRef>> Redirects);
};
} // namespace driver
diff --git a/contrib/llvm-project/clang/include/clang/Driver/Distro.h b/contrib/llvm-project/clang/include/clang/Driver/Distro.h
index 0d2a0939639e..a8de94163e8b 100644
--- a/contrib/llvm-project/clang/include/clang/Driver/Distro.h
+++ b/contrib/llvm-project/clang/include/clang/Driver/Distro.h
@@ -9,8 +9,8 @@
#ifndef LLVM_CLANG_DRIVER_DISTRO_H
#define LLVM_CLANG_DRIVER_DISTRO_H
-#include "llvm/ADT/Triple.h"
#include "llvm/Support/VirtualFileSystem.h"
+#include "llvm/TargetParser/Triple.h"
namespace clang {
namespace driver {
@@ -37,6 +37,8 @@ public:
DebianStretch,
DebianBuster,
DebianBullseye,
+ DebianBookworm,
+ DebianTrixie,
Exherbo,
RHEL5,
RHEL6,
@@ -72,6 +74,11 @@ public:
UbuntuGroovy,
UbuntuHirsute,
UbuntuImpish,
+ UbuntuJammy,
+ UbuntuKinetic,
+ UbuntuLunar,
+ UbuntuMantic,
+ UbuntuNoble,
UnknownDistro
};
@@ -119,11 +126,11 @@ public:
bool IsOpenSUSE() const { return DistroVal == OpenSUSE; }
bool IsDebian() const {
- return DistroVal >= DebianLenny && DistroVal <= DebianBullseye;
+ return DistroVal >= DebianLenny && DistroVal <= DebianTrixie;
}
bool IsUbuntu() const {
- return DistroVal >= UbuntuHardy && DistroVal <= UbuntuImpish;
+ return DistroVal >= UbuntuHardy && DistroVal <= UbuntuNoble;
}
bool IsAlpineLinux() const { return DistroVal == AlpineLinux; }
diff --git a/contrib/llvm-project/clang/include/clang/Driver/Driver.h b/contrib/llvm-project/clang/include/clang/Driver/Driver.h
index da7e8386a151..3ee1bcf2a69c 100644
--- a/contrib/llvm-project/clang/include/clang/Driver/Driver.h
+++ b/contrib/llvm-project/clang/include/clang/Driver/Driver.h
@@ -10,13 +10,18 @@
#define LLVM_CLANG_DRIVER_DRIVER_H
#include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/HeaderInclude.h"
#include "clang/Basic/LLVM.h"
#include "clang/Driver/Action.h"
+#include "clang/Driver/DriverDiagnostic.h"
+#include "clang/Driver/InputInfo.h"
#include "clang/Driver/Options.h"
#include "clang/Driver/Phases.h"
#include "clang/Driver/ToolChain.h"
#include "clang/Driver/Types.h"
#include "clang/Driver/Util.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/STLFunctionalExtras.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Option/Arg.h"
@@ -26,25 +31,28 @@
#include <list>
#include <map>
#include <string>
+#include <vector>
namespace llvm {
class Triple;
namespace vfs {
class FileSystem;
}
+namespace cl {
+class ExpansionContext;
+}
} // namespace llvm
namespace clang {
namespace driver {
- class Command;
- class Compilation;
- class InputInfo;
- class JobList;
- class JobAction;
- class SanitizerArgs;
- class ToolChain;
+typedef SmallVector<InputInfo, 4> InputInfoList;
+
+class Command;
+class Compilation;
+class JobAction;
+class ToolChain;
/// Describes the kind of LTO mode selected via -f(no-)?lto(=.*)? options.
enum LTOKind {
@@ -54,6 +62,16 @@ enum LTOKind {
LTOK_Unknown
};
+/// Whether headers used to construct C++20 module units should be looked
+/// up by the path supplied on the command line, or in the user or system
+/// search paths.
+enum ModuleHeaderMode {
+ HeaderMode_None,
+ HeaderMode_Default,
+ HeaderMode_User,
+ HeaderMode_System
+};
+
/// Driver - Encapsulate logic for constructing compilation processes
/// from a set of gcc-driver-like command line arguments.
class Driver {
@@ -66,7 +84,8 @@ class Driver {
GXXMode,
CPPMode,
CLMode,
- FlangMode
+ FlangMode,
+ DXCMode
} Mode;
enum SaveTempsMode {
@@ -81,6 +100,19 @@ class Driver {
EmbedBitcode
} BitcodeEmbed;
+ enum OffloadMode {
+ OffloadHostDevice,
+ OffloadHost,
+ OffloadDevice,
+ } Offload;
+
+ /// Header unit mode set by -fmodule-header={user,system}.
+ ModuleHeaderMode CXX20HeaderType;
+
+ /// Set if we should process inputs and jobs with C++20 module
+ /// interpretation.
+ bool ModulesModeCXX20;
+
/// LTO mode selected via -f(no-)?lto(=.*)? options.
LTOKind LTOMode;
@@ -162,6 +194,9 @@ public:
/// The file to log CC_PRINT_PROC_STAT_FILE output to, if enabled.
std::string CCPrintStatReportFilename;
+ /// The file to log CC_PRINT_INTERNAL_STAT_FILE output to, if enabled.
+ std::string CCPrintInternalStatReportFilename;
+
/// The file to log CC_PRINT_OPTIONS output to, if enabled.
std::string CCPrintOptionsFilename;
@@ -171,9 +206,11 @@ public:
/// The file to log CC_LOG_DIAGNOSTICS output to, if enabled.
std::string CCLogDiagnosticsFilename;
+ /// An input type and its arguments.
+ using InputTy = std::pair<types::ID, const llvm::opt::Arg *>;
+
/// A list of inputs and their types for the given arguments.
- typedef SmallVector<std::pair<types::ID, const llvm::opt::Arg *>, 16>
- InputList;
+ using InputList = SmallVector<InputTy, 16>;
/// Whether the driver should follow g++ like behavior.
bool CCCIsCXX() const { return Mode == GXXMode; }
@@ -191,6 +228,9 @@ public:
/// Other modes fall back to calling gcc which in turn calls gfortran.
bool IsFlangMode() const { return Mode == FlangMode; }
+ /// Whether the driver should follow dxc.exe like behavior.
+ bool IsDXCMode() const { return Mode == DXCMode; }
+
/// Only print tool bindings, don't build any jobs.
unsigned CCCPrintBindings : 1;
@@ -198,9 +238,16 @@ public:
/// CCPrintOptionsFilename or to stderr.
unsigned CCPrintOptions : 1;
- /// Set CC_PRINT_HEADERS mode, which causes the frontend to log header include
- /// information to CCPrintHeadersFilename or to stderr.
- unsigned CCPrintHeaders : 1;
+ /// The format of the header information that is emitted. If CC_PRINT_HEADERS
+ /// is set, the format is textual. Otherwise, the format is determined by the
+ /// enviroment variable CC_PRINT_HEADERS_FORMAT.
+ HeaderIncludeFormatKind CCPrintHeadersFormat = HIFMT_None;
+
+ /// This flag determines whether clang should filter the header information
+ /// that is emitted. If enviroment variable CC_PRINT_HEADERS_FILTERING is set
+ /// to "only-direct-system", only system headers that are directly included
+ /// from non-system headers are emitted.
+ HeaderIncludeFilteringKind CCPrintHeadersFiltering = HIFIL_None;
/// Set CC_LOG_DIAGNOSTICS mode, which causes the frontend to log diagnostics
/// to CCLogDiagnosticsFilename or to stderr, in a stable machine readable
@@ -214,11 +261,16 @@ public:
/// performance report to CC_PRINT_PROC_STAT_FILE or to stdout.
unsigned CCPrintProcessStats : 1;
+ /// Set CC_PRINT_INTERNAL_STAT mode, which causes the driver to dump internal
+ /// performance report to CC_PRINT_INTERNAL_STAT_FILE or to stdout.
+ unsigned CCPrintInternalStats : 1;
+
/// Pointer to the ExecuteCC1Tool function, if available.
/// When the clangDriver lib is used through clang.exe, this provides a
/// shortcut for executing the -cc1 command-line directly, in the same
/// process.
- typedef int (*CC1ToolFunc)(SmallVectorImpl<const char *> &ArgV);
+ using CC1ToolFunc =
+ llvm::function_ref<int(SmallVectorImpl<const char *> &ArgV)>;
CC1ToolFunc CC1Main = nullptr;
private:
@@ -228,8 +280,8 @@ private:
/// Name to use when invoking gcc/g++.
std::string CCCGenericGCCName;
- /// Name of configuration file if used.
- std::string ConfigFile;
+ /// Paths to configuration files used.
+ std::vector<std::string> ConfigFiles;
/// Allocator for string saver.
llvm::BumpPtrAllocator Alloc;
@@ -243,15 +295,27 @@ private:
/// Arguments originated from command line.
std::unique_ptr<llvm::opt::InputArgList> CLOptions;
+ /// If this is non-null, the driver will prepend this argument before
+ /// reinvoking clang. This is useful for the llvm-driver where clang's
+ /// realpath will be to the llvm binary and not clang, so it must pass
+ /// "clang" as it's first argument.
+ const char *PrependArg;
+
/// Whether to check that input files exist when constructing compilation
/// jobs.
unsigned CheckInputsExist : 1;
+ /// Whether to probe for PCH files on disk, in order to upgrade
+ /// -include foo.h to -include-pch foo.h.pch.
+ unsigned ProbePrecompiled : 1;
public:
- /// Force clang to emit reproducer for driver invocation. This is enabled
- /// indirectly by setting FORCE_CLANG_DIAGNOSTICS_CRASH environment variable
- /// or when using the -gen-reproducer driver flag.
- unsigned GenReproducer : 1;
+ // getFinalPhase - Determine which compilation mode we are in and record
+ // which option we used to determine the final phase.
+ // TODO: Much of what getFinalPhase returns are not actually true compiler
+ // modes. Fold this functionality into Types::getCompilationPhases and
+ // handleArguments.
+ phases::ID getFinalPhase(const llvm::opt::DerivedArgList &DAL,
+ llvm::opt::Arg **FinalPhaseArg = nullptr) const;
private:
/// Certain options suppress the 'no input files' warning.
@@ -264,20 +328,17 @@ private:
/// stored in it, and will clean them up when torn down.
mutable llvm::StringMap<std::unique_ptr<ToolChain>> ToolChains;
+ /// Cache of known offloading architectures for the ToolChain already derived.
+ /// This should only be modified when we first initialize the offloading
+ /// toolchains.
+ llvm::DenseMap<const ToolChain *, llvm::DenseSet<llvm::StringRef>> KnownArchs;
+
private:
/// TranslateInputArgs - Create a new derived argument list from the input
/// arguments, after applying the standard argument translations.
llvm::opt::DerivedArgList *
TranslateInputArgs(const llvm::opt::InputArgList &Args) const;
- // getFinalPhase - Determine which compilation mode we are in and record
- // which option we used to determine the final phase.
- // TODO: Much of what getFinalPhase returns are not actually true compiler
- // modes. Fold this functionality into Types::getCompilationPhases and
- // handleArguments.
- phases::ID getFinalPhase(const llvm::opt::DerivedArgList &DAL,
- llvm::opt::Arg **FinalPhaseArg = nullptr) const;
-
// handleArguments - All code related to claiming and printing diagnostics
// related to arguments to the driver are done here.
void handleArguments(Compilation &C, llvm::opt::DerivedArgList &Args,
@@ -320,7 +381,9 @@ public:
/// Name to use when invoking gcc/g++.
const std::string &getCCCGenericGCCName() const { return CCCGenericGCCName; }
- const std::string &getConfigFile() const { return ConfigFile; }
+ llvm::ArrayRef<std::string> getConfigFiles() const {
+ return ConfigFiles;
+ }
const llvm::opt::OptTable &getOpts() const { return getDriverOptTable(); }
@@ -332,6 +395,12 @@ public:
void setCheckInputsExist(bool Value) { CheckInputsExist = Value; }
+ bool getProbePrecompiled() const { return ProbePrecompiled; }
+ void setProbePrecompiled(bool Value) { ProbePrecompiled = Value; }
+
+ const char *getPrependArg() const { return PrependArg; }
+ void setPrependArg(const char *Value) { PrependArg = Value; }
+
void setTargetAndMode(const ParsedClangName &TM) { ClangNameParts = TM; }
const std::string &getTitle() { return DriverTitle; }
@@ -359,6 +428,9 @@ public:
bool embedBitcodeInObject() const { return (BitcodeEmbed == EmbedBitcode); }
bool embedBitcodeMarkerOnly() const { return (BitcodeEmbed == EmbedMarker); }
+ bool offloadHostOnly() const { return Offload == OffloadHost; }
+ bool offloadDeviceOnly() const { return Offload == OffloadDevice; }
+
/// Compute the desired OpenMP runtime from the flags provided.
OpenMPRuntimeKind getOpenMPRuntime(const llvm::opt::ArgList &Args) const;
@@ -383,7 +455,7 @@ public:
/// ParseArgStrings - Parse the given list of strings into an
/// ArgList.
llvm::opt::InputArgList ParseArgStrings(ArrayRef<const char *> Args,
- bool IsClCompatMode,
+ bool UseDriverMode,
bool &ContainsError);
/// BuildInputs - Construct the list of inputs and their types from
@@ -413,6 +485,26 @@ public:
void BuildUniversalActions(Compilation &C, const ToolChain &TC,
const InputList &BAInputs) const;
+ /// BuildOffloadingActions - Construct the list of actions to perform for the
+ /// offloading toolchain that will be embedded in the host.
+ ///
+ /// \param C - The compilation that is being built.
+ /// \param Args - The input arguments.
+ /// \param Input - The input type and arguments
+ /// \param HostAction - The host action used in the offloading toolchain.
+ Action *BuildOffloadingActions(Compilation &C,
+ llvm::opt::DerivedArgList &Args,
+ const InputTy &Input,
+ Action *HostAction) const;
+
+ /// Returns the set of bound architectures active for this offload kind.
+ /// If there are no bound architctures we return a set containing only the
+ /// empty string. The \p SuppressError option is used to suppress errors.
+ llvm::DenseSet<StringRef>
+ getOffloadArchs(Compilation &C, const llvm::opt::DerivedArgList &Args,
+ Action::OffloadKind Kind, const ToolChain *TC,
+ bool SuppressError = false) const;
+
/// Check that the file referenced by Value exists. If it doesn't,
/// issue a diagnostic and return false.
/// If TypoCorrect is true and the file does not exist, see if it looks
@@ -450,6 +542,35 @@ public:
StringRef AdditionalInformation = "",
CompilationDiagnosticReport *GeneratedReport = nullptr);
+ enum class CommandStatus {
+ Crash = 1,
+ Error,
+ Ok,
+ };
+
+ enum class ReproLevel {
+ Off = 0,
+ OnCrash = static_cast<int>(CommandStatus::Crash),
+ OnError = static_cast<int>(CommandStatus::Error),
+ Always = static_cast<int>(CommandStatus::Ok),
+ };
+
+ bool maybeGenerateCompilationDiagnostics(
+ CommandStatus CS, ReproLevel Level, Compilation &C,
+ const Command &FailingCommand, StringRef AdditionalInformation = "",
+ CompilationDiagnosticReport *GeneratedReport = nullptr) {
+ if (static_cast<int>(CS) > static_cast<int>(Level))
+ return false;
+ if (CS != CommandStatus::Crash)
+ Diags.Report(diag::err_drv_force_crash)
+ << !::getenv("FORCE_CLANG_DIAGNOSTICS_CRASH");
+ // Hack to ensure that diagnostic notes get emitted.
+ Diags.setLastDiagnosticIgnored(false);
+ generateCompilationDiagnostics(C, FailingCommand, AdditionalInformation,
+ GeneratedReport);
+ return true;
+ }
+
/// @}
/// @name Helper Methods
/// @{
@@ -503,17 +624,30 @@ public:
/// BuildJobsForAction - Construct the jobs to perform for the action \p A and
/// return an InputInfo for the result of running \p A. Will only construct
/// jobs for a given (Action, ToolChain, BoundArch, DeviceKind) tuple once.
- InputInfo
- BuildJobsForAction(Compilation &C, const Action *A, const ToolChain *TC,
- StringRef BoundArch, bool AtTopLevel, bool MultipleArchs,
- const char *LinkingOutput,
- std::map<std::pair<const Action *, std::string>, InputInfo>
- &CachedResults,
- Action::OffloadKind TargetDeviceOffloadKind) const;
+ InputInfoList BuildJobsForAction(
+ Compilation &C, const Action *A, const ToolChain *TC, StringRef BoundArch,
+ bool AtTopLevel, bool MultipleArchs, const char *LinkingOutput,
+ std::map<std::pair<const Action *, std::string>, InputInfoList>
+ &CachedResults,
+ Action::OffloadKind TargetDeviceOffloadKind) const;
/// Returns the default name for linked images (e.g., "a.out").
const char *getDefaultImageName() const;
+ /// Creates a temp file.
+ /// 1. If \p MultipleArch is false or \p BoundArch is empty, the temp file is
+ /// in the temporary directory with name $Prefix-%%%%%%.$Suffix.
+ /// 2. If \p MultipleArch is true and \p BoundArch is not empty,
+ /// 2a. If \p NeedUniqueDirectory is false, the temp file is in the
+ /// temporary directory with name $Prefix-$BoundArch-%%%%%.$Suffix.
+ /// 2b. If \p NeedUniqueDirectory is true, the temp file is in a unique
+ /// subdiretory with random name under the temporary directory, and
+ /// the temp file itself has name $Prefix-$BoundArch.$Suffix.
+ const char *CreateTempFile(Compilation &C, StringRef Prefix, StringRef Suffix,
+ bool MultipleArchs = false,
+ StringRef BoundArch = {},
+ bool NeedUniqueDirectory = false) const;
+
/// GetNamedOutputPath - Return the name to use for the output of
/// the action \p JA. The result is appended to the compilation's
/// list of temporary or result files, as appropriate.
@@ -555,6 +689,12 @@ public:
/// ShouldEmitStaticLibrary - Should the linker emit a static library.
bool ShouldEmitStaticLibrary(const llvm::opt::ArgList &Args) const;
+ /// Returns true if the user has indicated a C++20 header unit mode.
+ bool hasHeaderMode() const { return CXX20HeaderType != HeaderMode_None; }
+
+ /// Get the mode for handling headers as set by fmodule-header{=}.
+ ModuleHeaderMode getModuleHeaderMode() const { return CXX20HeaderType; }
+
/// Returns true if we are performing any kind of LTO.
bool isUsingLTO(bool IsOffload = false) const {
return getLTOMode(IsOffload) != LTOK_None;
@@ -567,16 +707,23 @@ public:
private:
- /// Tries to load options from configuration file.
+ /// Tries to load options from configuration files.
///
/// \returns true if error occurred.
- bool loadConfigFile();
+ bool loadConfigFiles();
+
+ /// Tries to load options from default configuration files (deduced from
+ /// executable filename).
+ ///
+ /// \returns true if error occurred.
+ bool loadDefaultConfigFiles(llvm::cl::ExpansionContext &ExpCtx);
/// Read options from the specified file.
///
/// \param [in] FileName File to read.
+ /// \param [in] Search and expansion options.
/// \returns true, if error occurred while reading.
- bool readConfigFile(StringRef FileName);
+ bool readConfigFile(StringRef FileName, llvm::cl::ExpansionContext &ExpCtx);
/// Set the driver mode (cl, gcc, etc) from the value of the `--driver-mode`
/// option.
@@ -595,20 +742,39 @@ private:
/// @}
+ /// Retrieves a ToolChain for a particular device \p Target triple
+ ///
+ /// \param[in] HostTC is the host ToolChain paired with the device
+ ///
+ /// \param[in] TargetDeviceOffloadKind (e.g. OFK_Cuda/OFK_OpenMP/OFK_SYCL) is
+ /// an Offloading action that is optionally passed to a ToolChain (used by
+ /// CUDA, to specify if it's used in conjunction with OpenMP)
+ ///
+ /// Will cache ToolChains for the life of the driver object, and create them
+ /// on-demand.
+ const ToolChain &getOffloadingDeviceToolChain(
+ const llvm::opt::ArgList &Args, const llvm::Triple &Target,
+ const ToolChain &HostTC,
+ const Action::OffloadKind &TargetDeviceOffloadKind) const;
+
/// Get bitmasks for which option flags to include and exclude based on
/// the driver mode.
- std::pair<unsigned, unsigned> getIncludeExcludeOptionFlagMasks(bool IsClCompatMode) const;
+ llvm::opt::Visibility
+ getOptionVisibilityMask(bool UseDriverMode = true) const;
/// Helper used in BuildJobsForAction. Doesn't use the cache when building
/// jobs specifically for the given action, but will use the cache when
/// building jobs for the Action's inputs.
- InputInfo BuildJobsForActionNoCache(
+ InputInfoList BuildJobsForActionNoCache(
Compilation &C, const Action *A, const ToolChain *TC, StringRef BoundArch,
bool AtTopLevel, bool MultipleArchs, const char *LinkingOutput,
- std::map<std::pair<const Action *, std::string>, InputInfo>
+ std::map<std::pair<const Action *, std::string>, InputInfoList>
&CachedResults,
Action::OffloadKind TargetDeviceOffloadKind) const;
+ /// Return the typical executable name for the specified driver \p Mode.
+ static const char *getExecutableForDriverMode(DriverMode Mode);
+
public:
/// GetReleaseVersion - Parse (([0-9]+)(.([0-9]+)(.([0-9]+)?))?)? and
/// return the grouped values as integers. Numbers which are not
@@ -650,6 +816,16 @@ llvm::StringRef getDriverMode(StringRef ProgName, ArrayRef<const char *> Args);
/// Checks whether the value produced by getDriverMode is for CL mode.
bool IsClangCL(StringRef DriverMode);
+/// Expand response files from a clang driver or cc1 invocation.
+///
+/// \param Args The arguments that will be expanded.
+/// \param ClangCLMode Whether clang is in CL mode.
+/// \param Alloc Allocator for new arguments.
+/// \param FS Filesystem to use when expanding files.
+llvm::Error expandResponseFiles(SmallVectorImpl<const char *> &Args,
+ bool ClangCLMode, llvm::BumpPtrAllocator &Alloc,
+ llvm::vfs::FileSystem *FS = nullptr);
+
} // end namespace driver
} // end namespace clang
diff --git a/contrib/llvm-project/clang/include/clang/Driver/Job.h b/contrib/llvm-project/clang/include/clang/Driver/Job.h
index 8b287638a271..df9449463c53 100644
--- a/contrib/llvm-project/clang/include/clang/Driver/Job.h
+++ b/contrib/llvm-project/clang/include/clang/Driver/Job.h
@@ -12,13 +12,13 @@
#include "clang/Basic/LLVM.h"
#include "clang/Driver/InputInfo.h"
#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/Optional.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/iterator.h"
#include "llvm/Option/Option.h"
#include "llvm/Support/Program.h"
#include <memory>
+#include <optional>
#include <string>
#include <utility>
#include <vector>
@@ -116,6 +116,9 @@ class Command {
/// The executable to run.
const char *Executable;
+ /// Optional argument to prepend.
+ const char *PrependArg;
+
/// The list of program arguments (not including the implicit first
/// argument, which will be the executable).
llvm::opt::ArgStringList Arguments;
@@ -141,8 +144,11 @@ class Command {
/// See Command::setEnvironment
std::vector<const char *> Environment;
+ /// Optional redirection for stdin, stdout, stderr.
+ std::vector<std::optional<std::string>> RedirectFiles;
+
/// Information on executable run provided by OS.
- mutable Optional<llvm::sys::ProcessStatistics> ProcStat;
+ mutable std::optional<llvm::sys::ProcessStatistics> ProcStat;
/// When a response file is needed, we try to put most arguments in an
/// exclusive file, while others remains as regular command line arguments.
@@ -166,7 +172,8 @@ public:
Command(const Action &Source, const Tool &Creator,
ResponseFileSupport ResponseSupport, const char *Executable,
const llvm::opt::ArgStringList &Arguments, ArrayRef<InputInfo> Inputs,
- ArrayRef<InputInfo> Outputs = None);
+ ArrayRef<InputInfo> Outputs = std::nullopt,
+ const char *PrependArg = nullptr);
// FIXME: This really shouldn't be copyable, but is currently copied in some
// error handling in Driver::generateCompilationDiagnostics.
Command(const Command &) = default;
@@ -175,7 +182,7 @@ public:
virtual void Print(llvm::raw_ostream &OS, const char *Terminator, bool Quote,
CrashReportInfo *CrashInfo = nullptr) const;
- virtual int Execute(ArrayRef<Optional<StringRef>> Redirects,
+ virtual int Execute(ArrayRef<std::optional<StringRef>> Redirects,
std::string *ErrMsg, bool *ExecutionFailed) const;
/// getSource - Return the Action which caused the creation of this job.
@@ -204,6 +211,15 @@ public:
/// from the parent process will be used.
virtual void setEnvironment(llvm::ArrayRef<const char *> NewEnvironment);
+ void
+ setRedirectFiles(const std::vector<std::optional<std::string>> &Redirects);
+
+ void replaceArguments(llvm::opt::ArgStringList List) {
+ Arguments = std::move(List);
+ }
+
+ void replaceExecutable(const char *Exe) { Executable = Exe; }
+
const char *getExecutable() const { return Executable; }
const llvm::opt::ArgStringList &getArguments() const { return Arguments; }
@@ -214,7 +230,7 @@ public:
return OutputFilenames;
}
- Optional<llvm::sys::ProcessStatistics> getProcessStatistics() const {
+ std::optional<llvm::sys::ProcessStatistics> getProcessStatistics() const {
return ProcStat;
}
@@ -229,34 +245,19 @@ public:
CC1Command(const Action &Source, const Tool &Creator,
ResponseFileSupport ResponseSupport, const char *Executable,
const llvm::opt::ArgStringList &Arguments,
- ArrayRef<InputInfo> Inputs, ArrayRef<InputInfo> Outputs = None);
+ ArrayRef<InputInfo> Inputs,
+ ArrayRef<InputInfo> Outputs = std::nullopt,
+ const char *PrependArg = nullptr);
void Print(llvm::raw_ostream &OS, const char *Terminator, bool Quote,
CrashReportInfo *CrashInfo = nullptr) const override;
- int Execute(ArrayRef<Optional<StringRef>> Redirects, std::string *ErrMsg,
+ int Execute(ArrayRef<std::optional<StringRef>> Redirects, std::string *ErrMsg,
bool *ExecutionFailed) const override;
void setEnvironment(llvm::ArrayRef<const char *> NewEnvironment) override;
};
-/// Like Command, but always pretends that the wrapped command succeeded.
-class ForceSuccessCommand : public Command {
-public:
- ForceSuccessCommand(const Action &Source_, const Tool &Creator_,
- ResponseFileSupport ResponseSupport,
- const char *Executable_,
- const llvm::opt::ArgStringList &Arguments_,
- ArrayRef<InputInfo> Inputs,
- ArrayRef<InputInfo> Outputs = None);
-
- void Print(llvm::raw_ostream &OS, const char *Terminator, bool Quote,
- CrashReportInfo *CrashInfo = nullptr) const override;
-
- int Execute(ArrayRef<Optional<StringRef>> Redirects, std::string *ErrMsg,
- bool *ExecutionFailed) const override;
-};
-
/// JobList - A sequence of jobs to perform.
class JobList {
public:
diff --git a/contrib/llvm-project/clang/include/clang/Driver/Multilib.h b/contrib/llvm-project/clang/include/clang/Driver/Multilib.h
index cf2dbf6ff58a..9a2cc9bb1ba1 100644
--- a/contrib/llvm-project/clang/include/clang/Driver/Multilib.h
+++ b/contrib/llvm-project/clang/include/clang/Driver/Multilib.h
@@ -13,7 +13,9 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/StringSet.h"
#include "llvm/Support/Compiler.h"
+#include "llvm/Support/SourceMgr.h"
#include <cassert>
#include <functional>
#include <string>
@@ -24,7 +26,9 @@ namespace clang {
namespace driver {
/// This corresponds to a single GCC Multilib, or a segment of one controlled
-/// by a command line flag
+/// by a command line flag.
+/// See also MultilibBuilder for building a multilib by mutating it
+/// incrementally.
class Multilib {
public:
using flags_list = std::vector<std::string>;
@@ -34,74 +38,47 @@ private:
std::string OSSuffix;
std::string IncludeSuffix;
flags_list Flags;
- int Priority;
+
+ // Optionally, a multilib can be assigned a string tag indicating that it's
+ // part of a group of mutually exclusive possibilities. If two or more
+ // multilibs have the same non-empty value of ExclusiveGroup, then only the
+ // last matching one of them will be selected.
+ //
+ // Setting this to the empty string is a special case, indicating that the
+ // directory is not mutually exclusive with anything else.
+ std::string ExclusiveGroup;
public:
+ /// GCCSuffix, OSSuffix & IncludeSuffix will be appended directly to the
+ /// sysroot string so they must either be empty or begin with a '/' character.
+ /// This is enforced with an assert in the constructor.
Multilib(StringRef GCCSuffix = {}, StringRef OSSuffix = {},
- StringRef IncludeSuffix = {}, int Priority = 0);
+ StringRef IncludeSuffix = {}, const flags_list &Flags = flags_list(),
+ StringRef ExclusiveGroup = {});
/// Get the detected GCC installation path suffix for the multi-arch
/// target variant. Always starts with a '/', unless empty
- const std::string &gccSuffix() const {
- assert(GCCSuffix.empty() ||
- (StringRef(GCCSuffix).front() == '/' && GCCSuffix.size() > 1));
- return GCCSuffix;
- }
-
- /// Set the GCC installation path suffix.
- Multilib &gccSuffix(StringRef S);
+ const std::string &gccSuffix() const { return GCCSuffix; }
/// Get the detected os path suffix for the multi-arch
/// target variant. Always starts with a '/', unless empty
- const std::string &osSuffix() const {
- assert(OSSuffix.empty() ||
- (StringRef(OSSuffix).front() == '/' && OSSuffix.size() > 1));
- return OSSuffix;
- }
-
- /// Set the os path suffix.
- Multilib &osSuffix(StringRef S);
+ const std::string &osSuffix() const { return OSSuffix; }
/// Get the include directory suffix. Always starts with a '/', unless
/// empty
- const std::string &includeSuffix() const {
- assert(IncludeSuffix.empty() ||
- (StringRef(IncludeSuffix).front() == '/' && IncludeSuffix.size() > 1));
- return IncludeSuffix;
- }
-
- /// Set the include directory suffix
- Multilib &includeSuffix(StringRef S);
+ const std::string &includeSuffix() const { return IncludeSuffix; }
/// Get the flags that indicate or contraindicate this multilib's use
- /// All elements begin with either '+' or '-'
+ /// All elements begin with either '-' or '!'
const flags_list &flags() const { return Flags; }
- flags_list &flags() { return Flags; }
-
- /// Returns the multilib priority. When more than one multilib matches flags,
- /// the one with the highest priority is selected, with 0 being the default.
- int priority() const { return Priority; }
-
- /// Add a flag to the flags list
- /// \p Flag must be a flag accepted by the driver with its leading '-' removed,
- /// and replaced with either:
- /// '-' which contraindicates using this multilib with that flag
- /// or:
- /// '+' which promotes using this multilib in the presence of that flag
- /// otherwise '-print-multi-lib' will not emit them correctly.
- Multilib &flag(StringRef F) {
- assert(F.front() == '+' || F.front() == '-');
- Flags.push_back(std::string(F));
- return *this;
- }
+
+ /// Get the exclusive group label.
+ const std::string &exclusiveGroup() const { return ExclusiveGroup; }
LLVM_DUMP_METHOD void dump() const;
/// print summary of the Multilib
void print(raw_ostream &OS) const;
- /// Check whether any of the 'against' flags contradict the 'for' flags.
- bool isValid() const;
-
/// Check whether the default is selected
bool isDefault() const
{ return GCCSuffix.empty() && OSSuffix.empty() && IncludeSuffix.empty(); }
@@ -111,63 +88,57 @@ public:
raw_ostream &operator<<(raw_ostream &OS, const Multilib &M);
+/// See also MultilibSetBuilder for combining multilibs into a set.
class MultilibSet {
public:
using multilib_list = std::vector<Multilib>;
- using iterator = multilib_list::iterator;
using const_iterator = multilib_list::const_iterator;
using IncludeDirsFunc =
std::function<std::vector<std::string>(const Multilib &M)>;
using FilterCallback = llvm::function_ref<bool(const Multilib &)>;
+ /// Uses regular expressions to simplify flags used for multilib selection.
+ /// For example, we may wish both -mfloat-abi=soft and -mfloat-abi=softfp to
+ /// be treated as -mfloat-abi=soft.
+ struct FlagMatcher {
+ std::string Match;
+ std::vector<std::string> Flags;
+ };
+
private:
multilib_list Multilibs;
+ std::vector<FlagMatcher> FlagMatchers;
IncludeDirsFunc IncludeCallback;
IncludeDirsFunc FilePathsCallback;
public:
MultilibSet() = default;
+ MultilibSet(multilib_list &&Multilibs,
+ std::vector<FlagMatcher> &&FlagMatchers = {})
+ : Multilibs(Multilibs), FlagMatchers(FlagMatchers) {}
- /// Add an optional Multilib segment
- MultilibSet &Maybe(const Multilib &M);
-
- /// Add a set of mutually incompatible Multilib segments
- MultilibSet &Either(const Multilib &M1, const Multilib &M2);
- MultilibSet &Either(const Multilib &M1, const Multilib &M2,
- const Multilib &M3);
- MultilibSet &Either(const Multilib &M1, const Multilib &M2,
- const Multilib &M3, const Multilib &M4);
- MultilibSet &Either(const Multilib &M1, const Multilib &M2,
- const Multilib &M3, const Multilib &M4,
- const Multilib &M5);
- MultilibSet &Either(ArrayRef<Multilib> Ms);
+ const multilib_list &getMultilibs() { return Multilibs; }
/// Filter out some subset of the Multilibs using a user defined callback
MultilibSet &FilterOut(FilterCallback F);
- /// Filter out those Multilibs whose gccSuffix matches the given expression
- MultilibSet &FilterOut(const char *Regex);
-
/// Add a completed Multilib to the set
void push_back(const Multilib &M);
- /// Union this set of multilibs with another
- void combineWith(const MultilibSet &MS);
-
- /// Remove all of the multilibs from the set
- void clear() { Multilibs.clear(); }
-
- iterator begin() { return Multilibs.begin(); }
const_iterator begin() const { return Multilibs.begin(); }
-
- iterator end() { return Multilibs.end(); }
const_iterator end() const { return Multilibs.end(); }
- /// Pick the best multilib in the set, \returns false if none are compatible
- bool select(const Multilib::flags_list &Flags, Multilib &M) const;
+ /// Select compatible variants, \returns false if none are compatible
+ bool select(const Multilib::flags_list &Flags,
+ llvm::SmallVectorImpl<Multilib> &) const;
unsigned size() const { return Multilibs.size(); }
+ /// Get the given flags plus flags found by matching them against the
+ /// FlagMatchers and choosing the Flags of each accordingly. The select method
+ /// calls this method so in most cases it's not necessary to call it directly.
+ llvm::StringSet<> expandFlags(const Multilib::flags_list &) const;
+
LLVM_DUMP_METHOD void dump() const;
void print(raw_ostream &OS) const;
@@ -185,12 +156,9 @@ public:
const IncludeDirsFunc &filePathsCallback() const { return FilePathsCallback; }
-private:
- /// Apply the filter to Multilibs and return the subset that remains
- static multilib_list filterCopy(FilterCallback F, const multilib_list &Ms);
-
- /// Apply the filter to the multilib_list, removing those that don't match
- static void filterInPlace(FilterCallback F, multilib_list &Ms);
+ static llvm::ErrorOr<MultilibSet>
+ parseYaml(llvm::MemoryBufferRef, llvm::SourceMgr::DiagHandlerTy = nullptr,
+ void *DiagHandlerCtxt = nullptr);
};
raw_ostream &operator<<(raw_ostream &OS, const MultilibSet &MS);
diff --git a/contrib/llvm-project/clang/include/clang/Driver/MultilibBuilder.h b/contrib/llvm-project/clang/include/clang/Driver/MultilibBuilder.h
new file mode 100644
index 000000000000..61596c5c573f
--- /dev/null
+++ b/contrib/llvm-project/clang/include/clang/Driver/MultilibBuilder.h
@@ -0,0 +1,134 @@
+//===- MultilibBuilder.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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_DRIVER_MULTILIBBUILDER_H
+#define LLVM_CLANG_DRIVER_MULTILIBBUILDER_H
+
+#include "clang/Driver/Multilib.h"
+
+namespace clang {
+namespace driver {
+
+/// This corresponds to a single GCC multilib, or a segment of one controlled
+/// by a command line flag. This class can be used to create a Multilib, and
+/// contains helper functions to mutate it before creating a Multilib instance
+/// with makeMultilib().
+class MultilibBuilder {
+public:
+ using flags_list = std::vector<std::string>;
+
+private:
+ std::string GCCSuffix;
+ std::string OSSuffix;
+ std::string IncludeSuffix;
+ flags_list Flags;
+
+public:
+ MultilibBuilder(StringRef GCCSuffix, StringRef OSSuffix,
+ StringRef IncludeSuffix);
+
+ /// Initializes GCCSuffix, OSSuffix & IncludeSuffix to the same value.
+ MultilibBuilder(StringRef Suffix = {});
+
+ /// Get the detected GCC installation path suffix for the multi-arch
+ /// target variant. Always starts with a '/', unless empty
+ const std::string &gccSuffix() const {
+ assert(GCCSuffix.empty() ||
+ (StringRef(GCCSuffix).front() == '/' && GCCSuffix.size() > 1));
+ return GCCSuffix;
+ }
+
+ /// Set the GCC installation path suffix.
+ MultilibBuilder &gccSuffix(StringRef S);
+
+ /// Get the detected os path suffix for the multi-arch
+ /// target variant. Always starts with a '/', unless empty
+ const std::string &osSuffix() const {
+ assert(OSSuffix.empty() ||
+ (StringRef(OSSuffix).front() == '/' && OSSuffix.size() > 1));
+ return OSSuffix;
+ }
+
+ /// Set the os path suffix.
+ MultilibBuilder &osSuffix(StringRef S);
+
+ /// Get the include directory suffix. Always starts with a '/', unless
+ /// empty
+ const std::string &includeSuffix() const {
+ assert(IncludeSuffix.empty() || (StringRef(IncludeSuffix).front() == '/' &&
+ IncludeSuffix.size() > 1));
+ return IncludeSuffix;
+ }
+
+ /// Set the include directory suffix
+ MultilibBuilder &includeSuffix(StringRef S);
+
+ /// Get the flags that indicate or contraindicate this multilib's use
+ /// All elements begin with either '-' or '!'
+ const flags_list &flags() const { return Flags; }
+ flags_list &flags() { return Flags; }
+
+ /// Add a flag to the flags list
+ /// \p Flag must be a flag accepted by the driver.
+ /// \p Disallow defines whether the flag is negated and therefore disallowed.
+ MultilibBuilder &flag(StringRef Flag, bool Disallow = false);
+
+ Multilib makeMultilib() const;
+
+ /// Check whether any of the 'against' flags contradict the 'for' flags.
+ bool isValid() const;
+
+ /// Check whether the default is selected
+ bool isDefault() const {
+ return GCCSuffix.empty() && OSSuffix.empty() && IncludeSuffix.empty();
+ }
+};
+
+/// This class can be used to create a MultilibSet, and contains helper
+/// functions to add combinations of multilibs before creating a MultilibSet
+/// instance with makeMultilibSet().
+class MultilibSetBuilder {
+public:
+ using multilib_list = std::vector<MultilibBuilder>;
+
+ MultilibSetBuilder() = default;
+
+ /// Add an optional Multilib segment
+ MultilibSetBuilder &Maybe(const MultilibBuilder &M);
+
+ /// Add a set of mutually incompatible Multilib segments
+ MultilibSetBuilder &Either(const MultilibBuilder &M1,
+ const MultilibBuilder &M2);
+ MultilibSetBuilder &Either(const MultilibBuilder &M1,
+ const MultilibBuilder &M2,
+ const MultilibBuilder &M3);
+ MultilibSetBuilder &Either(const MultilibBuilder &M1,
+ const MultilibBuilder &M2,
+ const MultilibBuilder &M3,
+ const MultilibBuilder &M4);
+ MultilibSetBuilder &Either(const MultilibBuilder &M1,
+ const MultilibBuilder &M2,
+ const MultilibBuilder &M3,
+ const MultilibBuilder &M4,
+ const MultilibBuilder &M5);
+ MultilibSetBuilder &Either(ArrayRef<MultilibBuilder> Ms);
+
+ /// Filter out those Multilibs whose gccSuffix matches the given expression
+ MultilibSetBuilder &FilterOut(const char *Regex);
+
+ MultilibSet makeMultilibSet() const;
+
+private:
+ multilib_list Multilibs;
+};
+
+} // namespace driver
+} // namespace clang
+
+#endif // LLVM_CLANG_DRIVER_MULTILIBBUILDER_H
diff --git a/contrib/llvm-project/clang/include/clang/Driver/OffloadBundler.h b/contrib/llvm-project/clang/include/clang/Driver/OffloadBundler.h
new file mode 100644
index 000000000000..84349abe185f
--- /dev/null
+++ b/contrib/llvm-project/clang/include/clang/Driver/OffloadBundler.h
@@ -0,0 +1,126 @@
+//===- OffloadBundler.h - File Bundling and Unbundling ----------*- 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 defines an offload bundling API that bundles different files
+/// that relate with the same source code but different targets into a single
+/// one. Also the implements the opposite functionality, i.e. unbundle files
+/// previous created by this API.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_DRIVER_OFFLOADBUNDLER_H
+#define LLVM_CLANG_DRIVER_OFFLOADBUNDLER_H
+
+#include "llvm/Support/Error.h"
+#include "llvm/TargetParser/Triple.h"
+#include <llvm/Support/MemoryBuffer.h>
+#include <string>
+#include <vector>
+
+namespace clang {
+
+class OffloadBundlerConfig {
+public:
+ OffloadBundlerConfig();
+
+ bool AllowNoHost = false;
+ bool AllowMissingBundles = false;
+ bool CheckInputArchive = false;
+ bool PrintExternalCommands = false;
+ bool HipOpenmpCompatible = false;
+ bool Compress = false;
+ bool Verbose = false;
+
+ unsigned BundleAlignment = 1;
+ unsigned HostInputIndex = ~0u;
+
+ std::string FilesType;
+ std::string ObjcopyPath;
+
+ // TODO: Convert these to llvm::SmallVector
+ std::vector<std::string> TargetNames;
+ std::vector<std::string> InputFileNames;
+ std::vector<std::string> OutputFileNames;
+};
+
+class OffloadBundler {
+public:
+ const OffloadBundlerConfig &BundlerConfig;
+
+ // TODO: Add error checking from ClangOffloadBundler.cpp
+ OffloadBundler(const OffloadBundlerConfig &BC) : BundlerConfig(BC) {}
+
+ // List bundle IDs. Return true if an error was found.
+ static llvm::Error
+ ListBundleIDsInFile(llvm::StringRef InputFileName,
+ const OffloadBundlerConfig &BundlerConfig);
+
+ llvm::Error BundleFiles();
+ llvm::Error UnbundleFiles();
+ llvm::Error UnbundleArchive();
+};
+
+/// Obtain the offload kind, real machine triple, and an optional TargetID
+/// out of the target information specified by the user.
+/// Bundle Entry ID (or, Offload Target String) has following components:
+/// * Offload Kind - Host, OpenMP, or HIP
+/// * Triple - Standard LLVM Triple
+/// * TargetID (Optional) - target ID, like gfx906:xnack+ or sm_30
+struct OffloadTargetInfo {
+ llvm::StringRef OffloadKind;
+ llvm::Triple Triple;
+ llvm::StringRef TargetID;
+
+ const OffloadBundlerConfig &BundlerConfig;
+
+ OffloadTargetInfo(const llvm::StringRef Target,
+ const OffloadBundlerConfig &BC);
+ bool hasHostKind() const;
+ bool isOffloadKindValid() const;
+ bool isOffloadKindCompatible(const llvm::StringRef TargetOffloadKind) const;
+ bool isTripleValid() const;
+ bool operator==(const OffloadTargetInfo &Target) const;
+ std::string str() const;
+};
+
+// CompressedOffloadBundle represents the format for the compressed offload
+// bundles.
+//
+// The format is as follows:
+// - Magic Number (4 bytes) - A constant "CCOB".
+// - Version (2 bytes)
+// - Compression Method (2 bytes) - Uses the values from
+// llvm::compression::Format.
+// - Uncompressed Size (4 bytes).
+// - Truncated MD5 Hash (8 bytes).
+// - Compressed Data (variable length).
+
+class CompressedOffloadBundle {
+private:
+ static inline const size_t MagicSize = 4;
+ static inline const size_t VersionFieldSize = sizeof(uint16_t);
+ static inline const size_t MethodFieldSize = sizeof(uint16_t);
+ static inline const size_t SizeFieldSize = sizeof(uint32_t);
+ static inline const size_t HashFieldSize = 8;
+ static inline const size_t HeaderSize = MagicSize + VersionFieldSize +
+ MethodFieldSize + SizeFieldSize +
+ HashFieldSize;
+ static inline const llvm::StringRef MagicNumber = "CCOB";
+ static inline const uint16_t Version = 1;
+
+public:
+ static llvm::Expected<std::unique_ptr<llvm::MemoryBuffer>>
+ compress(const llvm::MemoryBuffer &Input, bool Verbose = false);
+ static llvm::Expected<std::unique_ptr<llvm::MemoryBuffer>>
+ decompress(const llvm::MemoryBuffer &Input, bool Verbose = false);
+};
+
+} // namespace clang
+
+#endif // LLVM_CLANG_DRIVER_OFFLOADBUNDLER_H
diff --git a/contrib/llvm-project/clang/include/clang/Driver/Options.h b/contrib/llvm-project/clang/include/clang/Driver/Options.h
index 056660192ac5..0797410e9940 100644
--- a/contrib/llvm-project/clang/include/clang/Driver/Options.h
+++ b/contrib/llvm-project/clang/include/clang/Driver/Options.h
@@ -9,11 +9,8 @@
#ifndef LLVM_CLANG_DRIVER_OPTIONS_H
#define LLVM_CLANG_DRIVER_OPTIONS_H
-namespace llvm {
-namespace opt {
-class OptTable;
-}
-}
+#include "llvm/Option/OptTable.h"
+#include "llvm/Option/Option.h"
namespace clang {
namespace driver {
@@ -26,23 +23,27 @@ enum ClangFlags {
LinkerInput = (1 << 5),
NoArgumentUnused = (1 << 6),
Unsupported = (1 << 7),
- CoreOption = (1 << 8),
- CLOption = (1 << 9),
- CC1Option = (1 << 10),
- CC1AsOption = (1 << 11),
- NoDriverOption = (1 << 12),
- LinkOption = (1 << 13),
- FlangOption = (1 << 14),
- FC1Option = (1 << 15),
- FlangOnlyOption = (1 << 16),
- Ignored = (1 << 17),
+ LinkOption = (1 << 8),
+ Ignored = (1 << 9),
+ TargetSpecific = (1 << 10),
+};
+
+// Flags specifically for clang option visibility. We alias DefaultVis to
+// ClangOption, because "DefaultVis" is confusing in Options.td, which is used
+// for multiple drivers (clang, cl, flang, etc).
+enum ClangVisibility {
+ ClangOption = llvm::opt::DefaultVis,
+ CLOption = (1 << 1),
+ CC1Option = (1 << 2),
+ CC1AsOption = (1 << 3),
+ FlangOption = (1 << 4),
+ FC1Option = (1 << 5),
+ DXCOption = (1 << 6),
};
enum ID {
OPT_INVALID = 0, // This is not an option ID.
-#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \
- HELPTEXT, METAVAR, VALUES) \
- OPT_##ID,
+#define OPTION(...) LLVM_MAKE_OPT_ID(__VA_ARGS__),
#include "clang/Driver/Options.inc"
LastOption
#undef OPTION
diff --git a/contrib/llvm-project/clang/include/clang/Driver/Options.td b/contrib/llvm-project/clang/include/clang/Driver/Options.td
index a0cbcae0bdc3..175bedbfb4d0 100644
--- a/contrib/llvm-project/clang/include/clang/Driver/Options.td
+++ b/contrib/llvm-project/clang/include/clang/Driver/Options.td
@@ -35,37 +35,51 @@ def Unsupported : OptionFlag;
// Ignored - The option is unsupported, and the driver will silently ignore it.
def Ignored : OptionFlag;
-// CoreOption - This is considered a "core" Clang option, available in both
-// clang and clang-cl modes.
-def CoreOption : OptionFlag;
+// If an option affects linking, but has a primary group (so Link_Group cannot
+// be used), add this flag.
+def LinkOption : OptionFlag;
+
+// This is a target-specific option for compilation. Using it on an unsupported
+// target will lead to an err_drv_unsupported_opt_for_target error.
+def TargetSpecific : OptionFlag;
+
+// Indicates that this warning is ignored, but accepted with a warning for
+// GCC compatibility.
+class IgnoredGCCCompat : Flags<[HelpHidden]> {}
+
+class TargetSpecific : Flags<[TargetSpecific]> {}
+
+/////////
+// Visibility
+
+// We prefer the name "ClangOption" here rather than "Default" to make
+// it clear that these options will be visible in the clang driver (as
+// opposed to clang -cc1, the CL driver, or the flang driver).
+defvar ClangOption = DefaultVis;
// CLOption - This is a cl.exe compatibility option. Options with this flag
// are made available when the driver is running in CL compatibility mode.
-def CLOption : OptionFlag;
+def CLOption : OptionVisibility;
// CC1Option - This option should be accepted by clang -cc1.
-def CC1Option : OptionFlag;
+def CC1Option : OptionVisibility;
// CC1AsOption - This option should be accepted by clang -cc1as.
-def CC1AsOption : OptionFlag;
-
-// NoDriverOption - This option should not be accepted by the driver.
-def NoDriverOption : OptionFlag;
-
-// If an option affects linking, but has a primary group (so Link_Group cannot
-// be used), add this flag.
-def LinkOption : OptionFlag;
+def CC1AsOption : OptionVisibility;
// FlangOption - This is considered a "core" Flang option, available in
// flang mode.
-def FlangOption : OptionFlag;
-
-// FlangOnlyOption - This option should only be used by Flang (i.e. it is not
-// available for Clang)
-def FlangOnlyOption : OptionFlag;
+def FlangOption : OptionVisibility;
// FC1Option - This option should be accepted by flang -fc1.
-def FC1Option : OptionFlag;
+def FC1Option : OptionVisibility;
+
+// DXCOption - This is a dxc.exe compatibility option. Options with this flag
+// are made available when the driver is running in DXC compatibility mode.
+def DXCOption : OptionVisibility;
+
+/////////
+// Docs
// A short name to show in documentation. The name will be interpreted as rST.
class DocName<string name> { string DocName = name; }
@@ -77,10 +91,6 @@ class DocBrief<code descr> { code DocBrief = descr; }
// documentation.
class DocFlatten { bit DocFlatten = 1; }
-// Indicates that this warning is ignored, but accepted with a warning for
-// GCC compatibility.
-class IgnoredGCCCompat : Flags<[HelpHidden]> {}
-
/////////
// Groups
@@ -90,13 +100,13 @@ def Action_Group : OptionGroup<"<action group>">, DocName<"Actions">,
// Meta-group for options which are only used for compilation,
// and not linking etc.
def CompileOnly_Group : OptionGroup<"<CompileOnly group>">,
- DocName<"Compilation flags">, DocBrief<[{
+ DocName<"Compilation options">, DocBrief<[{
Flags controlling the behavior of Clang during compilation. These flags have
no effect during actions that do not perform compilation.}]>;
def Preprocessor_Group : OptionGroup<"<Preprocessor group>">,
Group<CompileOnly_Group>,
- DocName<"Preprocessor flags">, DocBrief<[{
+ DocName<"Preprocessor options">, DocBrief<[{
Flags controlling the behavior of the Clang preprocessor.}]>;
def IncludePath_Group : OptionGroup<"<I/i group>">, Group<Preprocessor_Group>,
@@ -118,7 +128,7 @@ def d_Group : OptionGroup<"<d group>">, Group<Preprocessor_Group>,
Flags allowing the state of the preprocessor to be dumped in various ways.}]>;
def Diag_Group : OptionGroup<"<W/R group>">, Group<CompileOnly_Group>,
- DocName<"Diagnostic flags">, DocBrief<[{
+ DocName<"Diagnostic options">, DocBrief<[{
Flags controlling which warnings, errors, and remarks Clang will generate.
See the :doc:`full list of warning and remark flags <DiagnosticsReference>`.}]>;
@@ -136,14 +146,28 @@ def f_clang_Group : OptionGroup<"<f (clang-only) group>">,
Group<CompileOnly_Group>, DocFlatten;
def pedantic_Group : OptionGroup<"<pedantic group>">, Group<f_Group>,
DocFlatten;
+
+def offload_Group : OptionGroup<"<offload group>">, Group<f_Group>,
+ DocName<"Common Offloading options">,
+ Visibility<[ClangOption, CLOption]>;
+
def opencl_Group : OptionGroup<"<opencl group>">, Group<f_Group>,
- DocName<"OpenCL flags">;
+ DocName<"OpenCL options">;
def sycl_Group : OptionGroup<"<SYCL group>">, Group<f_Group>,
- DocName<"SYCL flags">;
+ DocName<"SYCL options">;
+
+def cuda_Group : OptionGroup<"<CUDA group>">, Group<f_Group>,
+ DocName<"CUDA options">,
+ Visibility<[ClangOption, CLOption]>;
+
+def hip_Group : OptionGroup<"<HIP group>">, Group<f_Group>,
+ DocName<"HIP options">,
+ Visibility<[ClangOption, CLOption]>;
def m_Group : OptionGroup<"<m group>">, Group<CompileOnly_Group>,
- DocName<"Target-dependent compilation options">;
+ DocName<"Target-dependent compilation options">,
+ Visibility<[ClangOption, CLOption]>;
// Feature groups - these take command line options that correspond directly to
// target specific features and can be translated directly from command line
@@ -156,6 +180,8 @@ def m_arm_Features_Group : OptionGroup<"<arm features group>">,
Group<m_Group>, DocName<"ARM">;
def m_hexagon_Features_Group : OptionGroup<"<hexagon features group>">,
Group<m_Group>, DocName<"Hexagon">;
+def m_sparc_Features_Group : OptionGroup<"<sparc features group>">,
+ Group<m_Group>, DocName<"SPARC">;
// The features added by this group will not be added to target features.
// These are explicitly handled.
def m_hexagon_Features_HVX_Group : OptionGroup<"<hexagon features group>">,
@@ -173,9 +199,17 @@ def m_wasm_Features_Group : OptionGroup<"<wasm features group>">,
def m_wasm_Features_Driver_Group : OptionGroup<"<wasm driver features group>">,
Group<m_Group>, DocName<"WebAssembly Driver">;
def m_x86_Features_Group : OptionGroup<"<x86 features group>">,
- Group<m_Group>, Flags<[CoreOption]>, DocName<"X86">;
+ Group<m_Group>, Visibility<[ClangOption, CLOption]>,
+ DocName<"X86">;
+def m_x86_AVX10_Features_Group : OptionGroup<"<x86 AVX10 features group>">,
+ Group<m_Group>, Visibility<[ClangOption, CLOption]>,
+ DocName<"X86 AVX10">;
def m_riscv_Features_Group : OptionGroup<"<riscv features group>">,
- Group<m_Group>, DocName<"RISCV">;
+ Group<m_Group>, DocName<"RISC-V">;
+def m_ve_Features_Group : OptionGroup<"<ve features group>">,
+ Group<m_Group>, DocName<"VE">;
+def m_loongarch_Features_Group : OptionGroup<"<loongarch features group>">,
+ Group<m_Group>, DocName<"LoongArch">;
def m_libc_Group : OptionGroup<"<m libc group>">, Group<m_mips_Features_Group>,
Flags<[HelpHidden]>;
@@ -197,20 +231,20 @@ def ggdbN_Group : OptionGroup<"<ggdbN group>">, Group<gN_Group>, DocFlatten;
def gTune_Group : OptionGroup<"<gTune group>">, Group<g_Group>,
DocName<"Debugger to tune debug information for">;
def g_flags_Group : OptionGroup<"<g flags group>">, Group<DebugInfo_Group>,
- DocName<"Debug information flags">;
+ DocName<"Debug information options">;
def StaticAnalyzer_Group : OptionGroup<"<Static analyzer group>">,
- DocName<"Static analyzer flags">, DocBrief<[{
+ DocName<"Static analyzer options">, DocBrief<[{
Flags controlling the behavior of the Clang Static Analyzer.}]>;
// gfortran options that we recognize in the driver and pass along when
// invoking GCC to compile Fortran code.
def gfortran_Group : OptionGroup<"<gfortran group>">,
- DocName<"Fortran compilation flags">, DocBrief<[{
+ DocName<"Fortran compilation options">, DocBrief<[{
Flags that will be passed onto the ``gfortran`` compiler when Clang is given
a Fortran input.}]>;
-def Link_Group : OptionGroup<"<T/e/s/t/u group>">, DocName<"Linker flags">,
+def Link_Group : OptionGroup<"<T/e/s/t/u group>">, DocName<"Linker options">,
DocBrief<[{Flags that are passed on to the linker}]>;
def T_Group : OptionGroup<"<T group>">, Group<Link_Group>, DocFlatten;
def u_Group : OptionGroup<"<u group>">, Group<Link_Group>, DocFlatten;
@@ -225,12 +259,20 @@ def clang_ignored_f_Group : OptionGroup<"<clang ignored f group>">,
def clang_ignored_m_Group : OptionGroup<"<clang ignored m group>">,
Group<m_Group>, Flags<[Ignored]>;
+// Unsupported flang groups
+def flang_ignored_w_Group : OptionGroup<"<flang ignored W group>">,
+ Group<W_Group>, Flags<[Ignored]>, Visibility<[FlangOption]>;
+
// Group for clang options in the process of deprecation.
// Please include the version that deprecated the flag as comment to allow
// easier garbage collection.
def clang_ignored_legacy_options_Group : OptionGroup<"<clang legacy flags>">,
Group<f_Group>, Flags<[Ignored]>;
+def LongDouble_Group : OptionGroup<"<LongDouble group>">, Group<m_Group>,
+ DocName<"Long double options">,
+ DocBrief<[{Selects the long double implementation}]>;
+
// Retired with clang-5.0
def : Flag<["-"], "fslp-vectorize-aggressive">, Group<clang_ignored_legacy_options_Group>;
def : Flag<["-"], "fno-slp-vectorize-aggressive">, Group<clang_ignored_legacy_options_Group>;
@@ -272,22 +314,47 @@ class MigratorOpts<string base>
// Args.hasArg(OPT_ffoo) can be used to check that the flag is enabled.
// This is useful if the option is usually disabled.
// Use this only when the option cannot be declared via BoolFOption.
-multiclass OptInFFlag<string name, string pos_prefix, string neg_prefix="",
- string help="", list<OptionFlag> flags=[]> {
- def f#NAME : Flag<["-"], "f"#name>, Flags<[CC1Option] # flags>,
+multiclass OptInCC1FFlag<string name, string pos_prefix, string neg_prefix="",
+ string help="",
+ list<OptionVisibility> vis=[ClangOption]> {
+ def f#NAME : Flag<["-"], "f"#name>, Visibility<[CC1Option] # vis>,
Group<f_Group>, HelpText<pos_prefix # help>;
- def fno_#NAME : Flag<["-"], "fno-"#name>, Flags<flags>,
+ def fno_#NAME : Flag<["-"], "fno-"#name>, Visibility<vis>,
Group<f_Group>, HelpText<neg_prefix # help>;
}
// A boolean option which is opt-out in CC1. The negative option exists in CC1 and
// Args.hasArg(OPT_fno_foo) can be used to check that the flag is disabled.
// Use this only when the option cannot be declared via BoolFOption.
-multiclass OptOutFFlag<string name, string pos_prefix, string neg_prefix,
- string help="", list<OptionFlag> flags=[]> {
- def f#NAME : Flag<["-"], "f"#name>, Flags<flags>,
+multiclass OptOutCC1FFlag<string name, string pos_prefix, string neg_prefix,
+ string help="",
+ list<OptionVisibility> vis=[ClangOption]> {
+ def f#NAME : Flag<["-"], "f"#name>, Visibility<vis>,
Group<f_Group>, HelpText<pos_prefix # help>;
- def fno_#NAME : Flag<["-"], "fno-"#name>, Flags<[CC1Option] # flags>,
+ def fno_#NAME : Flag<["-"], "fno-"#name>, Visibility<[CC1Option] # vis>,
+ Group<f_Group>, HelpText<neg_prefix # help>;
+}
+
+// A boolean option which is opt-in in FC1. The positive option exists in FC1 and
+// Args.hasArg(OPT_ffoo) can be used to check that the flag is enabled.
+// This is useful if the option is usually disabled.
+multiclass OptInFC1FFlag<string name, string pos_prefix, string neg_prefix="",
+ string help="",
+ list<OptionVisibility> vis=[ClangOption]> {
+ def f#NAME : Flag<["-"], "f"#name>, Visibility<[FC1Option] # vis>,
+ Group<f_Group>, HelpText<pos_prefix # help>;
+ def fno_#NAME : Flag<["-"], "fno-"#name>, Visibility<vis>,
+ Group<f_Group>, HelpText<neg_prefix # help>;
+}
+
+// A boolean option which is opt-out in FC1. The negative option exists in FC1 and
+// Args.hasArg(OPT_fno_foo) can be used to check that the flag is disabled.
+multiclass OptOutFC1FFlag<string name, string pos_prefix, string neg_prefix,
+ string help="",
+ list<OptionVisibility> vis=[ClangOption]> {
+ def f#NAME : Flag<["-"], "f"#name>, Visibility<vis>,
+ Group<f_Group>, HelpText<pos_prefix # help>;
+ def fno_#NAME : Flag<["-"], "fno-"#name>, Visibility<[FC1Option] # vis>,
Group<f_Group>, HelpText<neg_prefix # help>;
}
@@ -320,7 +387,8 @@ def SetFalse : Set<false> {}
// Definition of single command line flag. This is an implementation detail, use
// SetTrueBy or SetFalseBy instead.
-class FlagDef<bit polarity, bit value, list<OptionFlag> option_flags,
+class FlagDef<bit polarity, bit value,
+ list<OptionFlag> option_flags, list<OptionVisibility> option_vis,
string help, list<code> implied_by_expressions = []> {
// The polarity. Besides spelling, this also decides whether the TableGen
// record will be prefixed with "no_".
@@ -329,9 +397,12 @@ class FlagDef<bit polarity, bit value, list<OptionFlag> option_flags,
// The value assigned to key path when the flag is present on command line.
bit Value = value;
- // OptionFlags that control visibility of the flag in different tools.
+ // OptionFlags in different tools.
list<OptionFlag> OptionFlags = option_flags;
+ // OptionVisibility flags for different tools.
+ list<OptionVisibility> OptionVisibility = option_vis;
+
// The help text associated with the flag.
string Help = help;
@@ -340,8 +411,11 @@ class FlagDef<bit polarity, bit value, list<OptionFlag> option_flags,
}
// Additional information to be appended to both positive and negative flag.
-class BothFlags<list<OptionFlag> option_flags, string help = ""> {
+class BothFlags<list<OptionFlag> option_flags,
+ list<OptionVisibility> option_vis = [ClangOption],
+ string help = ""> {
list<OptionFlag> OptionFlags = option_flags;
+ list<OptionVisibility> OptionVisibility = option_vis;
string Help = help;
}
@@ -350,23 +424,26 @@ class ApplySuffix<FlagDef flag, BothFlags suffix> {
FlagDef Result
= FlagDef<flag.Polarity, flag.Value,
flag.OptionFlags # suffix.OptionFlags,
+ flag.OptionVisibility # suffix.OptionVisibility,
flag.Help # suffix.Help, flag.ImpliedBy>;
}
// Definition of the command line flag with positive spelling, e.g. "-ffoo".
-class PosFlag<Set value, list<OptionFlag> flags = [], string help = "",
- list<code> implied_by_expressions = []>
- : FlagDef<true, value.Value, flags, help, implied_by_expressions> {}
+class PosFlag<Set value,
+ list<OptionFlag> flags = [], list<OptionVisibility> vis = [],
+ string help = "", list<code> implied_by_expressions = []>
+ : FlagDef<true, value.Value, flags, vis, help, implied_by_expressions> {}
// Definition of the command line flag with negative spelling, e.g. "-fno-foo".
-class NegFlag<Set value, list<OptionFlag> flags = [], string help = "",
- list<code> implied_by_expressions = []>
- : FlagDef<false, value.Value, flags, help, implied_by_expressions> {}
+class NegFlag<Set value,
+ list<OptionFlag> flags = [], list<OptionVisibility> vis = [],
+ string help = "", list<code> implied_by_expressions = []>
+ : FlagDef<false, value.Value, flags, vis, help, implied_by_expressions> {}
// Expanded FlagDef that's convenient for creation of TableGen records.
class FlagDefExpanded<FlagDef flag, string prefix, string name, string spelling>
- : FlagDef<flag.Polarity, flag.Value, flag.OptionFlags, flag.Help,
- flag.ImpliedBy> {
+ : FlagDef<flag.Polarity, flag.Value, flag.OptionFlags, flag.OptionVisibility,
+ flag.Help, flag.ImpliedBy> {
// Name of the TableGen record.
string RecordName = prefix # !if(flag.Polarity, "", "no_") # name;
@@ -384,10 +461,10 @@ class FlagDefExpanded<FlagDef flag, string prefix, string name, string spelling>
class MarshalledFlagRec<FlagDefExpanded flag, FlagDefExpanded other,
FlagDefExpanded implied, KeyPathAndMacro kpm,
Default default>
- : Flag<["-"], flag.Spelling>, Flags<flag.OptionFlags>, HelpText<flag.Help>,
+ : Flag<["-"], flag.Spelling>, Flags<flag.OptionFlags>,
+ Visibility<flag.OptionVisibility>, HelpText<flag.Help>,
MarshallingInfoBooleanFlag<kpm, default.Value, flag.ValueAsCode,
- flag.RecordName, other.ValueAsCode,
- other.RecordName>,
+ other.ValueAsCode, other.RecordName>,
ImpliedByAnyOf<implied.ImpliedBy, implied.ValueAsCode> {}
// Generates TableGen records for two command line flags that control the same
@@ -399,7 +476,7 @@ class MarshalledFlagRec<FlagDefExpanded flag, FlagDefExpanded other,
multiclass BoolOption<string prefix = "", string spelling_base,
KeyPathAndMacro kpm, Default default,
FlagDef flag1_base, FlagDef flag2_base,
- BothFlags suffix = BothFlags<[], "">> {
+ BothFlags suffix = BothFlags<[]>> {
defvar flag1 = FlagDefExpanded<ApplySuffix<flag1_base, suffix>.Result, prefix,
NAME, spelling_base>;
@@ -430,7 +507,7 @@ multiclass BoolOption<string prefix = "", string spelling_base,
/// CompilerInvocation.
multiclass BoolFOption<string flag_base, KeyPathAndMacro kpm,
Default default, FlagDef flag1, FlagDef flag2,
- BothFlags both = BothFlags<[], "">> {
+ BothFlags both = BothFlags<[]>> {
defm NAME : BoolOption<"f", flag_base, kpm, default, flag1, flag2, both>,
Group<f_Group>;
}
@@ -441,11 +518,47 @@ multiclass BoolFOption<string flag_base, KeyPathAndMacro kpm,
// CompilerInvocation.
multiclass BoolGOption<string flag_base, KeyPathAndMacro kpm,
Default default, FlagDef flag1, FlagDef flag2,
- BothFlags both = BothFlags<[], "">> {
+ BothFlags both = BothFlags<[]>> {
defm NAME : BoolOption<"g", flag_base, kpm, default, flag1, flag2, both>,
Group<g_Group>;
}
+// Works like BoolOption except without marshalling
+multiclass BoolOptionWithoutMarshalling<string prefix = "", string spelling_base,
+ FlagDef flag1_base, FlagDef flag2_base,
+ BothFlags suffix = BothFlags<[]>> {
+ defvar flag1 = FlagDefExpanded<ApplySuffix<flag1_base, suffix>.Result, prefix,
+ NAME, spelling_base>;
+
+ defvar flag2 = FlagDefExpanded<ApplySuffix<flag2_base, suffix>.Result, prefix,
+ NAME, spelling_base>;
+
+ // The flags must have different polarity, different values, and only
+ // one can be implied.
+ assert !xor(flag1.Polarity, flag2.Polarity),
+ "the flags must have different polarity: flag1: " #
+ flag1.Polarity # ", flag2: " # flag2.Polarity;
+ assert !ne(flag1.Value, flag2.Value),
+ "the flags must have different values: flag1: " #
+ flag1.Value # ", flag2: " # flag2.Value;
+ assert !not(!and(flag1.CanBeImplied, flag2.CanBeImplied)),
+ "only one of the flags can be implied: flag1: " #
+ flag1.CanBeImplied # ", flag2: " # flag2.CanBeImplied;
+
+ defvar implied = !if(flag1.CanBeImplied, flag1, flag2);
+
+ def flag1.RecordName : Flag<["-"], flag1.Spelling>, Flags<flag1.OptionFlags>,
+ Visibility<flag1.OptionVisibility>,
+ HelpText<flag1.Help>,
+ ImpliedByAnyOf<implied.ImpliedBy, implied.ValueAsCode>
+ {}
+ def flag2.RecordName : Flag<["-"], flag2.Spelling>, Flags<flag2.OptionFlags>,
+ Visibility<flag2.OptionVisibility>,
+ HelpText<flag2.Help>,
+ ImpliedByAnyOf<implied.ImpliedBy, implied.ValueAsCode>
+ {}
+}
+
// FIXME: Diagnose if target does not support protected visibility.
class MarshallingInfoVisibility<KeyPathAndMacro kpm, code default>
: MarshallingInfoEnum<kpm, default>,
@@ -459,7 +572,7 @@ defvar cpp11 = LangOpts<"CPlusPlus11">;
defvar cpp17 = LangOpts<"CPlusPlus17">;
defvar cpp20 = LangOpts<"CPlusPlus20">;
defvar c99 = LangOpts<"C99">;
-defvar c2x = LangOpts<"C2x">;
+defvar c23 = LangOpts<"C23">;
defvar lang_std = LangOpts<"LangStd">;
defvar open_cl = LangOpts<"OpenCL">;
defvar cuda = LangOpts<"CUDA">;
@@ -467,7 +580,7 @@ defvar render_script = LangOpts<"RenderScript">;
defvar hip = LangOpts<"HIP">;
defvar gnu_mode = LangOpts<"GNUMode">;
defvar asm_preprocessor = LangOpts<"AsmPreprocessor">;
-defvar cpp_modules = LangOpts<"CPlusPlusModules">;
+defvar hlsl = LangOpts<"HLSL">;
defvar std = !strconcat("LangStandard::getLangStandardForKind(", lang_std.KeyPath, ")");
@@ -495,7 +608,8 @@ defvar std = !strconcat("LangStandard::getLangStandardForKind(", lang_std.KeyPat
// Developer Driver Options
-def internal_Group : OptionGroup<"<clang internal options>">, Flags<[HelpHidden]>;
+def internal_Group : OptionGroup<"<clang internal options>">,
+ Flags<[HelpHidden]>;
def internal_driver_Group : OptionGroup<"<clang driver internal options>">,
Group<internal_Group>, HelpText<"DRIVER OPTIONS">;
def internal_debug_Group :
@@ -505,20 +619,25 @@ def internal_debug_Group :
class InternalDriverOpt : Group<internal_driver_Group>,
Flags<[NoXarchOption, HelpHidden]>;
def driver_mode : Joined<["--"], "driver-mode=">, Group<internal_driver_Group>,
- Flags<[CoreOption, NoXarchOption, HelpHidden]>,
- HelpText<"Set the driver mode to either 'gcc', 'g++', 'cpp', or 'cl'">;
+ Flags<[NoXarchOption, HelpHidden]>,
+ Visibility<[ClangOption, FlangOption, CLOption, DXCOption]>,
+ HelpText<"Set the driver mode to either 'gcc', 'g++', 'cpp', 'cl' or 'flang'">;
def rsp_quoting : Joined<["--"], "rsp-quoting=">, Group<internal_driver_Group>,
- Flags<[CoreOption, NoXarchOption, HelpHidden]>,
+ Flags<[NoXarchOption, HelpHidden]>,
+ Visibility<[ClangOption, CLOption, DXCOption]>,
HelpText<"Set the rsp quoting to either 'posix', or 'windows'">;
def ccc_gcc_name : Separate<["-"], "ccc-gcc-name">, InternalDriverOpt,
HelpText<"Name for native GCC compiler">,
MetaVarName<"<gcc-path>">;
class InternalDebugOpt : Group<internal_debug_Group>,
- Flags<[NoXarchOption, HelpHidden, CoreOption]>;
+ Flags<[NoXarchOption, HelpHidden]>,
+ Visibility<[ClangOption, CLOption, DXCOption]>;
def ccc_install_dir : Separate<["-"], "ccc-install-dir">, InternalDebugOpt,
HelpText<"Simulate installation in the given directory">;
-def ccc_print_phases : Flag<["-"], "ccc-print-phases">, InternalDebugOpt,
+def ccc_print_phases : Flag<["-"], "ccc-print-phases">,
+ Flags<[NoXarchOption, HelpHidden]>, Visibility<[ClangOption, CLOption, DXCOption,
+ FlangOption]>,
HelpText<"Dump list of actions to perform">;
def ccc_print_bindings : Flag<["-"], "ccc-print-bindings">, InternalDebugOpt,
HelpText<"Show bindings of tools to actions">;
@@ -530,19 +649,26 @@ def ccc_arcmt_modify : Flag<["-"], "ccc-arcmt-modify">, InternalDriverOpt,
def ccc_arcmt_migrate : Separate<["-"], "ccc-arcmt-migrate">, InternalDriverOpt,
HelpText<"Apply modifications and produces temporary files that conform to ARC">;
def arcmt_migrate_report_output : Separate<["-"], "arcmt-migrate-report-output">,
- HelpText<"Output path for the plist report">, Flags<[CC1Option]>,
+ HelpText<"Output path for the plist report">,
+ Visibility<[ClangOption, CC1Option]>,
MarshallingInfoString<FrontendOpts<"ARCMTMigrateReportOut">>;
def arcmt_migrate_emit_arc_errors : Flag<["-"], "arcmt-migrate-emit-errors">,
- HelpText<"Emit ARC errors even if the migrator can fix them">, Flags<[CC1Option]>,
+ HelpText<"Emit ARC errors even if the migrator can fix them">,
+ Visibility<[ClangOption, CC1Option]>,
MarshallingInfoFlag<FrontendOpts<"ARCMTMigrateEmitARCErrors">>;
+def gen_reproducer_eq: Joined<["-"], "gen-reproducer=">,
+ Flags<[NoArgumentUnused]>, Visibility<[ClangOption, CLOption, DXCOption]>,
+ HelpText<"Emit reproducer on (option: off, crash (default), error, always)">;
def gen_reproducer: Flag<["-"], "gen-reproducer">, InternalDebugOpt,
+ Alias<gen_reproducer_eq>, AliasArgs<["always"]>,
HelpText<"Auto-generates preprocessed source files and a reproduction script">;
def gen_cdb_fragment_path: Separate<["-"], "gen-cdb-fragment-path">, InternalDebugOpt,
HelpText<"Emit a compilation database fragment to the specified directory">;
-def round_trip_args : Flag<["-"], "round-trip-args">, Flags<[CC1Option, NoDriverOption]>,
+def round_trip_args : Flag<["-"], "round-trip-args">, Visibility<[CC1Option]>,
HelpText<"Enable command line arguments round-trip.">;
-def no_round_trip_args : Flag<["-"], "no-round-trip-args">, Flags<[CC1Option, NoDriverOption]>,
+def no_round_trip_args : Flag<["-"], "no-round-trip-args">,
+ Visibility<[CC1Option]>,
HelpText<"Disable command line arguments round-trip.">;
def _migrate : Flag<["--"], "migrate">, Flags<[NoXarchOption]>,
@@ -552,99 +678,135 @@ def ccc_objcmt_migrate : Separate<["-"], "ccc-objcmt-migrate">,
HelpText<"Apply modifications and produces temporary files to migrate to "
"modern ObjC syntax">;
-def objcmt_migrate_literals : Flag<["-"], "objcmt-migrate-literals">, Flags<[CC1Option]>,
+def objcmt_migrate_literals : Flag<["-"], "objcmt-migrate-literals">,
+ Visibility<[ClangOption, CC1Option]>,
HelpText<"Enable migration to modern ObjC literals">,
MarshallingInfoBitfieldFlag<FrontendOpts<"ObjCMTAction">, "FrontendOptions::ObjCMT_Literals">;
-def objcmt_migrate_subscripting : Flag<["-"], "objcmt-migrate-subscripting">, Flags<[CC1Option]>,
+def objcmt_migrate_subscripting : Flag<["-"], "objcmt-migrate-subscripting">,
+ Visibility<[ClangOption, CC1Option]>,
HelpText<"Enable migration to modern ObjC subscripting">,
MarshallingInfoBitfieldFlag<FrontendOpts<"ObjCMTAction">, "FrontendOptions::ObjCMT_Subscripting">;
-def objcmt_migrate_property : Flag<["-"], "objcmt-migrate-property">, Flags<[CC1Option]>,
+def objcmt_migrate_property : Flag<["-"], "objcmt-migrate-property">,
+ Visibility<[ClangOption, CC1Option]>,
HelpText<"Enable migration to modern ObjC property">,
MarshallingInfoBitfieldFlag<FrontendOpts<"ObjCMTAction">, "FrontendOptions::ObjCMT_Property">;
-def objcmt_migrate_all : Flag<["-"], "objcmt-migrate-all">, Flags<[CC1Option]>,
+def objcmt_migrate_all : Flag<["-"], "objcmt-migrate-all">,
+ Visibility<[ClangOption, CC1Option]>,
HelpText<"Enable migration to modern ObjC">,
MarshallingInfoBitfieldFlag<FrontendOpts<"ObjCMTAction">, "FrontendOptions::ObjCMT_MigrateDecls">;
-def objcmt_migrate_readonly_property : Flag<["-"], "objcmt-migrate-readonly-property">, Flags<[CC1Option]>,
+def objcmt_migrate_readonly_property : Flag<["-"], "objcmt-migrate-readonly-property">,
+ Visibility<[ClangOption, CC1Option]>,
HelpText<"Enable migration to modern ObjC readonly property">,
MarshallingInfoBitfieldFlag<FrontendOpts<"ObjCMTAction">, "FrontendOptions::ObjCMT_ReadonlyProperty">;
-def objcmt_migrate_readwrite_property : Flag<["-"], "objcmt-migrate-readwrite-property">, Flags<[CC1Option]>,
+def objcmt_migrate_readwrite_property : Flag<["-"], "objcmt-migrate-readwrite-property">,
+ Visibility<[ClangOption, CC1Option]>,
HelpText<"Enable migration to modern ObjC readwrite property">,
MarshallingInfoBitfieldFlag<FrontendOpts<"ObjCMTAction">, "FrontendOptions::ObjCMT_ReadwriteProperty">;
-def objcmt_migrate_property_dot_syntax : Flag<["-"], "objcmt-migrate-property-dot-syntax">, Flags<[CC1Option]>,
+def objcmt_migrate_property_dot_syntax : Flag<["-"], "objcmt-migrate-property-dot-syntax">,
+ Visibility<[ClangOption, CC1Option]>,
HelpText<"Enable migration of setter/getter messages to property-dot syntax">,
MarshallingInfoBitfieldFlag<FrontendOpts<"ObjCMTAction">, "FrontendOptions::ObjCMT_PropertyDotSyntax">;
-def objcmt_migrate_annotation : Flag<["-"], "objcmt-migrate-annotation">, Flags<[CC1Option]>,
+def objcmt_migrate_annotation : Flag<["-"], "objcmt-migrate-annotation">,
+ Visibility<[ClangOption, CC1Option]>,
HelpText<"Enable migration to property and method annotations">,
MarshallingInfoBitfieldFlag<FrontendOpts<"ObjCMTAction">, "FrontendOptions::ObjCMT_Annotation">;
-def objcmt_migrate_instancetype : Flag<["-"], "objcmt-migrate-instancetype">, Flags<[CC1Option]>,
+def objcmt_migrate_instancetype : Flag<["-"], "objcmt-migrate-instancetype">,
+ Visibility<[ClangOption, CC1Option]>,
HelpText<"Enable migration to infer instancetype for method result type">,
MarshallingInfoBitfieldFlag<FrontendOpts<"ObjCMTAction">, "FrontendOptions::ObjCMT_Instancetype">;
-def objcmt_migrate_nsmacros : Flag<["-"], "objcmt-migrate-ns-macros">, Flags<[CC1Option]>,
+def objcmt_migrate_nsmacros : Flag<["-"], "objcmt-migrate-ns-macros">,
+ Visibility<[ClangOption, CC1Option]>,
HelpText<"Enable migration to NS_ENUM/NS_OPTIONS macros">,
MarshallingInfoBitfieldFlag<FrontendOpts<"ObjCMTAction">, "FrontendOptions::ObjCMT_NsMacros">;
-def objcmt_migrate_protocol_conformance : Flag<["-"], "objcmt-migrate-protocol-conformance">, Flags<[CC1Option]>,
+def objcmt_migrate_protocol_conformance : Flag<["-"], "objcmt-migrate-protocol-conformance">,
+ Visibility<[ClangOption, CC1Option]>,
HelpText<"Enable migration to add protocol conformance on classes">,
MarshallingInfoBitfieldFlag<FrontendOpts<"ObjCMTAction">, "FrontendOptions::ObjCMT_ProtocolConformance">;
-def objcmt_atomic_property : Flag<["-"], "objcmt-atomic-property">, Flags<[CC1Option]>,
+def objcmt_atomic_property : Flag<["-"], "objcmt-atomic-property">,
+ Visibility<[ClangOption, CC1Option]>,
HelpText<"Make migration to 'atomic' properties">,
MarshallingInfoBitfieldFlag<FrontendOpts<"ObjCMTAction">, "FrontendOptions::ObjCMT_AtomicProperty">;
-def objcmt_returns_innerpointer_property : Flag<["-"], "objcmt-returns-innerpointer-property">, Flags<[CC1Option]>,
+def objcmt_returns_innerpointer_property : Flag<["-"], "objcmt-returns-innerpointer-property">,
+ Visibility<[ClangOption, CC1Option]>,
HelpText<"Enable migration to annotate property with NS_RETURNS_INNER_POINTER">,
MarshallingInfoBitfieldFlag<FrontendOpts<"ObjCMTAction">, "FrontendOptions::ObjCMT_ReturnsInnerPointerProperty">;
-def objcmt_ns_nonatomic_iosonly: Flag<["-"], "objcmt-ns-nonatomic-iosonly">, Flags<[CC1Option]>,
+def objcmt_ns_nonatomic_iosonly: Flag<["-"], "objcmt-ns-nonatomic-iosonly">,
+ Visibility<[ClangOption, CC1Option]>,
HelpText<"Enable migration to use NS_NONATOMIC_IOSONLY macro for setting property's 'atomic' attribute">,
MarshallingInfoBitfieldFlag<FrontendOpts<"ObjCMTAction">, "FrontendOptions::ObjCMT_NsAtomicIOSOnlyProperty">;
-def objcmt_migrate_designated_init : Flag<["-"], "objcmt-migrate-designated-init">, Flags<[CC1Option]>,
+def objcmt_migrate_designated_init : Flag<["-"], "objcmt-migrate-designated-init">,
+ Visibility<[ClangOption, CC1Option]>,
HelpText<"Enable migration to infer NS_DESIGNATED_INITIALIZER for initializer methods">,
MarshallingInfoBitfieldFlag<FrontendOpts<"ObjCMTAction">, "FrontendOptions::ObjCMT_DesignatedInitializer">;
-def objcmt_whitelist_dir_path: Joined<["-"], "objcmt-whitelist-dir-path=">, Flags<[CC1Option]>,
+def objcmt_allowlist_dir_path: Joined<["-"], "objcmt-allowlist-dir-path=">,
+ Visibility<[ClangOption, CC1Option]>,
HelpText<"Only modify files with a filename contained in the provided directory path">,
- MarshallingInfoString<FrontendOpts<"ObjCMTWhiteListPath">>;
+ MarshallingInfoString<FrontendOpts<"ObjCMTAllowListPath">>;
+def : Joined<["-"], "objcmt-whitelist-dir-path=">,
+ Visibility<[ClangOption, CC1Option]>,
+ HelpText<"Alias for -objcmt-allowlist-dir-path">,
+ Alias<objcmt_allowlist_dir_path>;
// The misspelt "white-list" [sic] alias is due for removal.
-def : Joined<["-"], "objcmt-white-list-dir-path=">, Flags<[CC1Option]>,
- Alias<objcmt_whitelist_dir_path>;
+def : Joined<["-"], "objcmt-white-list-dir-path=">,
+ Visibility<[ClangOption, CC1Option]>,
+ Alias<objcmt_allowlist_dir_path>;
// Make sure all other -ccc- options are rejected.
def ccc_ : Joined<["-"], "ccc-">, Group<internal_Group>, Flags<[Unsupported]>;
// Standard Options
-def _HASH_HASH_HASH : Flag<["-"], "###">, Flags<[NoXarchOption, CoreOption, FlangOption]>,
+def _HASH_HASH_HASH : Flag<["-"], "###">, Flags<[NoXarchOption]>,
+ Visibility<[ClangOption, CLOption, DXCOption, FlangOption]>,
HelpText<"Print (but do not run) the commands to run for this compilation">;
def _DASH_DASH : Option<["--"], "", KIND_REMAINING_ARGS>,
- Flags<[NoXarchOption, CoreOption]>;
-def A : JoinedOrSeparate<["-"], "A">, Flags<[RenderJoined]>, Group<gfortran_Group>;
+ Flags<[NoXarchOption]>, Visibility<[ClangOption, CLOption, DXCOption]>;
+def A : JoinedOrSeparate<["-"], "A">, Flags<[RenderJoined]>,
+ Group<gfortran_Group>;
def B : JoinedOrSeparate<["-"], "B">, MetaVarName<"<prefix>">,
- HelpText<"Search $prefix/$triple-$file and $prefix$file for executables, libraries, "
- "includes, and data files used by the compiler. $prefix may or may not be a directory">;
+ HelpText<"Search $prefix$file for executables, libraries, and data files. "
+ "If $prefix is a directory, search $prefix/$file">;
+def gcc_install_dir_EQ : Joined<["--"], "gcc-install-dir=">,
+ HelpText<"Use GCC installation in the specified directory. The directory ends with path components like 'lib{,32,64}/gcc{,-cross}/$triple/$version'. "
+ "Note: executables (e.g. ld) used by the compiler are not overridden by the selected GCC installation">;
def gcc_toolchain : Joined<["--"], "gcc-toolchain=">, Flags<[NoXarchOption]>,
- HelpText<"Search for GCC installation in the specified directory on targets which commonly use GCC. "
- "The directory usually contains 'lib{,32,64}/gcc{,-cross}/$triple' and 'include'. If specified, "
- "sysroot is skipped for GCC detection. Note: executables (e.g. ld) used by the compiler are not "
- "overridden by the selected GCC installation">;
-def CC : Flag<["-"], "CC">, Flags<[CC1Option]>, Group<Preprocessor_Group>,
+ HelpText<"Specify a directory where Clang can find 'include' and 'lib{,32,64}/gcc{,-cross}/$triple/$version'. "
+ "Clang will use the GCC installation with the largest version">;
+def gcc_triple_EQ : Joined<["--"], "gcc-triple=">,
+ HelpText<"Search for the GCC installation with the specified triple.">;
+def CC : Flag<["-"], "CC">, Visibility<[ClangOption, CC1Option]>,
+ Group<Preprocessor_Group>,
HelpText<"Include comments from within macros in preprocessed output">,
MarshallingInfoFlag<PreprocessorOutputOpts<"ShowMacroComments">>;
-def C : Flag<["-"], "C">, Flags<[CC1Option]>, Group<Preprocessor_Group>,
+def C : Flag<["-"], "C">, Visibility<[ClangOption, CC1Option]>,
+ Group<Preprocessor_Group>,
HelpText<"Include comments in preprocessed output">,
MarshallingInfoFlag<PreprocessorOutputOpts<"ShowComments">>;
def D : JoinedOrSeparate<["-"], "D">, Group<Preprocessor_Group>,
- Flags<[CC1Option, FlangOption, FC1Option]>, MetaVarName<"<macro>=<value>">,
+ Visibility<[ClangOption, CC1Option, FlangOption, FC1Option, DXCOption]>,
+ MetaVarName<"<macro>=<value>">,
HelpText<"Define <macro> to <value> (or 1 if <value> omitted)">;
-def E : Flag<["-"], "E">, Flags<[NoXarchOption,CC1Option, FlangOption, FC1Option]>, Group<Action_Group>,
+def E : Flag<["-"], "E">, Flags<[NoXarchOption]>,
+ Visibility<[ClangOption, CC1Option, FlangOption, FC1Option]>,
+ Group<Action_Group>,
HelpText<"Only run the preprocessor">;
-def F : JoinedOrSeparate<["-"], "F">, Flags<[RenderJoined,CC1Option]>,
+def F : JoinedOrSeparate<["-"], "F">, Flags<[RenderJoined]>,
+ Visibility<[ClangOption, CC1Option]>,
HelpText<"Add directory to framework include search path">;
-def G : JoinedOrSeparate<["-"], "G">, Flags<[NoXarchOption]>, Group<m_Group>,
+def G : JoinedOrSeparate<["-"], "G">, Flags<[NoXarchOption, TargetSpecific]>,
+ Group<m_Group>,
MetaVarName<"<size>">, HelpText<"Put objects of at most <size> bytes "
"into small data section (MIPS / Hexagon)">;
-def G_EQ : Joined<["-"], "G=">, Flags<[NoXarchOption]>, Group<m_Group>, Alias<G>;
-def H : Flag<["-"], "H">, Flags<[CC1Option]>, Group<Preprocessor_Group>,
+def G_EQ : Joined<["-"], "G=">, Flags<[NoXarchOption]>,
+ Group<m_Group>, Alias<G>;
+def H : Flag<["-"], "H">, Visibility<[ClangOption, CC1Option]>,
+ Group<Preprocessor_Group>,
HelpText<"Show header includes and nesting depth">,
MarshallingInfoFlag<DependencyOutputOpts<"ShowHeaderIncludes">>;
def fshow_skipped_includes : Flag<["-"], "fshow-skipped-includes">,
- Flags<[CC1Option]>, HelpText<"Show skipped includes in -H output.">,
+ Visibility<[ClangOption, CC1Option]>,
+ HelpText<"Show skipped includes in -H output.">,
DocBrief<[{#include files may be "skipped" due to include guard optimization
or #pragma once. This flag makes -H show also such includes.}]>,
MarshallingInfoFlag<DependencyOutputOpts<"ShowSkippedHeaderIncludes">>;
@@ -653,7 +815,8 @@ def I_ : Flag<["-"], "I-">, Group<I_Group>,
HelpText<"Restrict all prior -I flags to double-quoted inclusion and "
"remove current directory from include path">;
def I : JoinedOrSeparate<["-"], "I">, Group<I_Group>,
- Flags<[CC1Option,CC1AsOption,FlangOption,FC1Option]>, MetaVarName<"<dir>">,
+ Visibility<[ClangOption, CC1Option, CC1AsOption, FlangOption, FC1Option]>,
+ MetaVarName<"<dir>">,
HelpText<"Add directory to the end of the list of include search paths">,
DocBrief<[{Add directory to include search path. For C++ inputs, if
there are multiple -I options, these directories are searched
@@ -662,6 +825,7 @@ are searched. If the same directory is in the SYSTEM include search
paths, for example if also specified with -isystem, the -I option
will be ignored}]>;
def L : JoinedOrSeparate<["-"], "L">, Flags<[RenderJoined]>, Group<Link_Group>,
+ Visibility<[ClangOption, FlangOption]>,
MetaVarName<"<dir>">, HelpText<"Add directory to library search path">;
def MD : Flag<["-"], "MD">, Group<M_Group>,
HelpText<"Write a depfile containing user and system headers">;
@@ -674,99 +838,112 @@ def MM : Flag<["-"], "MM">, Group<M_Group>,
def MF : JoinedOrSeparate<["-"], "MF">, Group<M_Group>,
HelpText<"Write depfile output from -MMD, -MD, -MM, or -M to <file>">,
MetaVarName<"<file>">;
-def MG : Flag<["-"], "MG">, Group<M_Group>, Flags<[CC1Option]>,
+def MG : Flag<["-"], "MG">, Group<M_Group>, Visibility<[ClangOption, CC1Option]>,
HelpText<"Add missing headers to depfile">,
MarshallingInfoFlag<DependencyOutputOpts<"AddMissingHeaderDeps">>;
def MJ : JoinedOrSeparate<["-"], "MJ">, Group<M_Group>,
HelpText<"Write a compilation database entry per input">;
-def MP : Flag<["-"], "MP">, Group<M_Group>, Flags<[CC1Option]>,
+def MP : Flag<["-"], "MP">, Group<M_Group>, Visibility<[ClangOption, CC1Option]>,
HelpText<"Create phony target for each dependency (other than main file)">,
MarshallingInfoFlag<DependencyOutputOpts<"UsePhonyTargets">>;
-def MQ : JoinedOrSeparate<["-"], "MQ">, Group<M_Group>, Flags<[CC1Option]>,
+def MQ : JoinedOrSeparate<["-"], "MQ">, Group<M_Group>,
+ Visibility<[ClangOption, CC1Option]>,
HelpText<"Specify name of main file output to quote in depfile">;
-def MT : JoinedOrSeparate<["-"], "MT">, Group<M_Group>, Flags<[CC1Option]>,
+def MT : JoinedOrSeparate<["-"], "MT">, Group<M_Group>,
+ Visibility<[ClangOption, CC1Option]>,
HelpText<"Specify name of main file output in depfile">,
MarshallingInfoStringVector<DependencyOutputOpts<"Targets">>;
-def MV : Flag<["-"], "MV">, Group<M_Group>, Flags<[CC1Option]>,
+def MV : Flag<["-"], "MV">, Group<M_Group>, Visibility<[ClangOption, CC1Option]>,
HelpText<"Use NMake/Jom format for the depfile">,
MarshallingInfoFlag<DependencyOutputOpts<"OutputFormat">, "DependencyOutputFormat::Make">,
Normalizer<"makeFlagToValueNormalizer(DependencyOutputFormat::NMake)">;
def Mach : Flag<["-"], "Mach">, Group<Link_Group>;
-def O0 : Flag<["-"], "O0">, Group<O_Group>, Flags<[CC1Option, HelpHidden]>;
-def O4 : Flag<["-"], "O4">, Group<O_Group>, Flags<[CC1Option, HelpHidden]>;
+def O0 : Flag<["-"], "O0">, Group<O_Group>, Flags<[HelpHidden]>,
+ Visibility<[ClangOption, CC1Option, FC1Option, FlangOption]>;
+def O4 : Flag<["-"], "O4">, Group<O_Group>, Flags<[HelpHidden]>,
+ Visibility<[ClangOption, CC1Option, FC1Option, FlangOption]>;
def ObjCXX : Flag<["-"], "ObjC++">, Flags<[NoXarchOption]>,
HelpText<"Treat source input files as Objective-C++ inputs">;
def ObjC : Flag<["-"], "ObjC">, Flags<[NoXarchOption]>,
HelpText<"Treat source input files as Objective-C inputs">;
-def O : Joined<["-"], "O">, Group<O_Group>, Flags<[CC1Option]>;
-def O_flag : Flag<["-"], "O">, Flags<[CC1Option]>, Alias<O>, AliasArgs<["1"]>;
-def Ofast : Joined<["-"], "Ofast">, Group<O_Group>, Flags<[CC1Option]>;
-def P : Flag<["-"], "P">, Flags<[CC1Option]>, Group<Preprocessor_Group>,
+def O : Joined<["-"], "O">, Group<O_Group>,
+ Visibility<[ClangOption, CC1Option, FC1Option, FlangOption]>;
+def O_flag : Flag<["-"], "O">, Visibility<[ClangOption, CC1Option, FC1Option]>,
+ Alias<O>, AliasArgs<["1"]>;
+def Ofast : Joined<["-"], "Ofast">, Group<O_Group>,
+ Visibility<[ClangOption, CC1Option, FlangOption]>;
+def P : Flag<["-"], "P">,
+ Visibility<[ClangOption, CC1Option, FlangOption, FC1Option]>,
+ Group<Preprocessor_Group>,
HelpText<"Disable linemarker output in -E mode">,
MarshallingInfoNegativeFlag<PreprocessorOutputOpts<"ShowLineMarkers">>;
-def Qy : Flag<["-"], "Qy">, Flags<[CC1Option]>,
+def Qy : Flag<["-"], "Qy">, Visibility<[ClangOption, CC1Option]>,
HelpText<"Emit metadata containing compiler name and version">;
-def Qn : Flag<["-"], "Qn">, Flags<[CC1Option]>,
+def Qn : Flag<["-"], "Qn">, Visibility<[ClangOption, CC1Option]>,
HelpText<"Do not emit metadata containing compiler name and version">;
def : Flag<["-"], "fident">, Group<f_Group>, Alias<Qy>,
- Flags<[CoreOption, CC1Option]>;
+ Visibility<[ClangOption, CLOption, DXCOption, CC1Option]>;
def : Flag<["-"], "fno-ident">, Group<f_Group>, Alias<Qn>,
- Flags<[CoreOption, CC1Option]>;
-def Qunused_arguments : Flag<["-"], "Qunused-arguments">, Flags<[NoXarchOption, CoreOption]>,
+ Visibility<[ClangOption, CLOption, DXCOption, CC1Option]>;
+def Qunused_arguments : Flag<["-"], "Qunused-arguments">,
+ Flags<[NoXarchOption]>, Visibility<[ClangOption, CLOption, DXCOption]>,
HelpText<"Don't emit warning for unused driver arguments">;
def Q : Flag<["-"], "Q">, IgnoredGCCCompat;
-def Rpass_EQ : Joined<["-"], "Rpass=">, Group<R_value_Group>, Flags<[CC1Option]>,
- HelpText<"Report transformations performed by optimization passes whose "
- "name matches the given POSIX regular expression">;
-def Rpass_missed_EQ : Joined<["-"], "Rpass-missed=">, Group<R_value_Group>,
- Flags<[CC1Option]>,
- HelpText<"Report missed transformations by optimization passes whose "
- "name matches the given POSIX regular expression">;
-def Rpass_analysis_EQ : Joined<["-"], "Rpass-analysis=">, Group<R_value_Group>,
- Flags<[CC1Option]>,
- HelpText<"Report transformation analysis from optimization passes whose "
- "name matches the given POSIX regular expression">;
-def R_Joined : Joined<["-"], "R">, Group<R_Group>, Flags<[CC1Option, CoreOption]>,
- MetaVarName<"<remark>">, HelpText<"Enable the specified remark">;
-def S : Flag<["-"], "S">, Flags<[NoXarchOption,CC1Option]>, Group<Action_Group>,
+def S : Flag<["-"], "S">, Flags<[NoXarchOption]>,
+ Visibility<[ClangOption, CC1Option, FlangOption, FC1Option]>,
+ Group<Action_Group>,
HelpText<"Only run preprocess and compilation steps">;
-def Tbss : JoinedOrSeparate<["-"], "Tbss">, Group<T_Group>,
- MetaVarName<"<addr>">, HelpText<"Set starting address of BSS to <addr>">;
-def Tdata : JoinedOrSeparate<["-"], "Tdata">, Group<T_Group>,
- MetaVarName<"<addr>">, HelpText<"Set starting address of DATA to <addr>">;
-def Ttext : JoinedOrSeparate<["-"], "Ttext">, Group<T_Group>,
- MetaVarName<"<addr>">, HelpText<"Set starting address of TEXT to <addr>">;
def T : JoinedOrSeparate<["-"], "T">, Group<T_Group>,
MetaVarName<"<script>">, HelpText<"Specify <script> as linker script">;
def U : JoinedOrSeparate<["-"], "U">, Group<Preprocessor_Group>,
- Flags<[CC1Option, FlangOption, FC1Option]>, MetaVarName<"<macro>">, HelpText<"Undefine macro <macro>">;
+ Visibility<[ClangOption, CC1Option, FlangOption, FC1Option]>,
+ MetaVarName<"<macro>">, HelpText<"Undefine macro <macro>">;
def V : JoinedOrSeparate<["-"], "V">, Flags<[NoXarchOption, Unsupported]>;
def Wa_COMMA : CommaJoined<["-"], "Wa,">,
HelpText<"Pass the comma separated arguments in <arg> to the assembler">,
MetaVarName<"<arg>">;
-def Wall : Flag<["-"], "Wall">, Group<W_Group>, Flags<[CC1Option, HelpHidden]>;
-def WCL4 : Flag<["-"], "WCL4">, Group<W_Group>, Flags<[CC1Option, HelpHidden]>;
-def Wdeprecated : Flag<["-"], "Wdeprecated">, Group<W_Group>, Flags<[CC1Option]>,
+def Wall : Flag<["-"], "Wall">, Group<W_Group>, Flags<[HelpHidden]>,
+ Visibility<[ClangOption, CC1Option, FlangOption]>;
+def WCL4 : Flag<["-"], "WCL4">, Group<W_Group>, Flags<[HelpHidden]>,
+ Visibility<[ClangOption, CC1Option]>;
+def Wsystem_headers : Flag<["-"], "Wsystem-headers">, Group<W_Group>,
+ Flags<[HelpHidden]>, Visibility<[ClangOption, CC1Option]>;
+def Wno_system_headers : Flag<["-"], "Wno-system-headers">, Group<W_Group>,
+ Flags<[HelpHidden]>, Visibility<[ClangOption, CC1Option]>;
+def Wsystem_headers_in_module_EQ : Joined<["-"], "Wsystem-headers-in-module=">,
+ Flags<[HelpHidden]>, Visibility<[ClangOption, CC1Option]>,
+ MetaVarName<"<module>">,
+ HelpText<"Enable -Wsystem-headers when building <module>">,
+ MarshallingInfoStringVector<DiagnosticOpts<"SystemHeaderWarningsModules">>;
+def Wdeprecated : Flag<["-"], "Wdeprecated">, Group<W_Group>,
+ Visibility<[ClangOption, CC1Option]>,
HelpText<"Enable warnings for deprecated constructs and define __DEPRECATED">;
-def Wno_deprecated : Flag<["-"], "Wno-deprecated">, Group<W_Group>, Flags<[CC1Option]>;
-def Wl_COMMA : CommaJoined<["-"], "Wl,">, Flags<[LinkerInput, RenderAsInput]>,
+def Wno_deprecated : Flag<["-"], "Wno-deprecated">, Group<W_Group>,
+ Visibility<[ClangOption, CC1Option]>;
+def Wl_COMMA : CommaJoined<["-"], "Wl,">, Visibility<[ClangOption, FlangOption]>,
+ Flags<[LinkerInput, RenderAsInput]>,
HelpText<"Pass the comma separated arguments in <arg> to the linker">,
MetaVarName<"<arg>">, Group<Link_Group>;
// FIXME: This is broken; these should not be Joined arguments.
def Wno_nonportable_cfstrings : Joined<["-"], "Wno-nonportable-cfstrings">, Group<W_Group>,
- Flags<[CC1Option]>;
+ Visibility<[ClangOption, CC1Option]>;
def Wnonportable_cfstrings : Joined<["-"], "Wnonportable-cfstrings">, Group<W_Group>,
- Flags<[CC1Option]>;
+ Visibility<[ClangOption, CC1Option]>;
def Wp_COMMA : CommaJoined<["-"], "Wp,">,
HelpText<"Pass the comma separated arguments in <arg> to the preprocessor">,
MetaVarName<"<arg>">, Group<Preprocessor_Group>;
def Wundef_prefix_EQ : CommaJoined<["-"], "Wundef-prefix=">, Group<W_value_Group>,
- Flags<[CC1Option, CoreOption, HelpHidden]>, MetaVarName<"<arg>">,
+ Flags<[HelpHidden]>,
+ Visibility<[ClangOption, CC1Option, CLOption, DXCOption]>,
+ MetaVarName<"<arg>">,
HelpText<"Enable warnings for undefined macros with a prefix in the comma separated list <arg>">,
MarshallingInfoStringVector<DiagnosticOpts<"UndefPrefixes">>;
-def Wwrite_strings : Flag<["-"], "Wwrite-strings">, Group<W_Group>, Flags<[CC1Option, HelpHidden]>;
-def Wno_write_strings : Flag<["-"], "Wno-write-strings">, Group<W_Group>, Flags<[CC1Option, HelpHidden]>;
-def W_Joined : Joined<["-"], "W">, Group<W_Group>, Flags<[CC1Option, CoreOption, FC1Option, FlangOption]>,
+def Wwrite_strings : Flag<["-"], "Wwrite-strings">, Group<W_Group>,
+ Flags<[HelpHidden]>, Visibility<[ClangOption, CC1Option]>;
+def Wno_write_strings : Flag<["-"], "Wno-write-strings">, Group<W_Group>,
+ Flags<[HelpHidden]>, Visibility<[ClangOption, CC1Option]>;
+def W_Joined : Joined<["-"], "W">, Group<W_Group>,
+ Visibility<[ClangOption, CC1Option, CLOption, DXCOption, FC1Option, FlangOption]>,
MetaVarName<"<warning>">, HelpText<"Enable the specified warning">;
def Xanalyzer : Separate<["-"], "Xanalyzer">,
HelpText<"Pass <arg> to the static analyzer">, MetaVarName<"<arg>">,
@@ -780,131 +957,304 @@ def Xassembler : Separate<["-"], "Xassembler">,
HelpText<"Pass <arg> to the assembler">, MetaVarName<"<arg>">,
Group<CompileOnly_Group>;
def Xclang : Separate<["-"], "Xclang">,
- HelpText<"Pass <arg> to the clang compiler">, MetaVarName<"<arg>">,
- Flags<[NoXarchOption, CoreOption]>, Group<CompileOnly_Group>;
+ HelpText<"Pass <arg> to clang -cc1">, MetaVarName<"<arg>">,
+ Flags<[NoXarchOption]>, Visibility<[ClangOption, CLOption, DXCOption]>,
+ Group<CompileOnly_Group>;
+def : Joined<["-"], "Xclang=">, Group<CompileOnly_Group>,
+ Flags<[NoXarchOption]>, Visibility<[ClangOption, CLOption, DXCOption]>,
+ Alias<Xclang>,
+ HelpText<"Alias for -Xclang">, MetaVarName<"<arg>">;
def Xcuda_fatbinary : Separate<["-"], "Xcuda-fatbinary">,
HelpText<"Pass <arg> to fatbinary invocation">, MetaVarName<"<arg>">;
def Xcuda_ptxas : Separate<["-"], "Xcuda-ptxas">,
HelpText<"Pass <arg> to the ptxas assembler">, MetaVarName<"<arg>">;
-def Xopenmp_target : Separate<["-"], "Xopenmp-target">,
+def Xopenmp_target : Separate<["-"], "Xopenmp-target">, Group<CompileOnly_Group>,
HelpText<"Pass <arg> to the target offloading toolchain.">, MetaVarName<"<arg>">;
-def Xopenmp_target_EQ : JoinedAndSeparate<["-"], "Xopenmp-target=">,
+def Xopenmp_target_EQ : JoinedAndSeparate<["-"], "Xopenmp-target=">, Group<CompileOnly_Group>,
HelpText<"Pass <arg> to the target offloading toolchain identified by <triple>.">,
MetaVarName<"<triple> <arg>">;
-def z : Separate<["-"], "z">, Flags<[LinkerInput, RenderAsInput]>,
+def z : Separate<["-"], "z">, Flags<[LinkerInput]>,
HelpText<"Pass -z <arg> to the linker">, MetaVarName<"<arg>">,
Group<Link_Group>;
+def offload_link : Flag<["--"], "offload-link">, Group<Link_Group>,
+ HelpText<"Use the new offloading linker to perform the link job.">;
def Xlinker : Separate<["-"], "Xlinker">, Flags<[LinkerInput, RenderAsInput]>,
HelpText<"Pass <arg> to the linker">, MetaVarName<"<arg>">,
Group<Link_Group>;
+def Xoffload_linker : JoinedAndSeparate<["-"], "Xoffload-linker">,
+ HelpText<"Pass <arg> to the offload linkers or the ones idenfied by -<triple>">,
+ MetaVarName<"<triple> <arg>">, Group<Link_Group>;
def Xpreprocessor : Separate<["-"], "Xpreprocessor">, Group<Preprocessor_Group>,
HelpText<"Pass <arg> to the preprocessor">, MetaVarName<"<arg>">;
def X_Flag : Flag<["-"], "X">, Group<Link_Group>;
-def X_Joined : Joined<["-"], "X">, IgnoredGCCCompat;
+// Used by some macOS projects. IgnoredGCCCompat is a misnomer since GCC doesn't allow it.
+def : Flag<["-"], "Xparser">, IgnoredGCCCompat;
+// FIXME -Xcompiler is misused by some ChromeOS packages. Remove it after a while.
+def : Flag<["-"], "Xcompiler">, IgnoredGCCCompat;
def Z_Flag : Flag<["-"], "Z">, Group<Link_Group>;
-// FIXME: All we do with this is reject it. Remove.
-def Z_Joined : Joined<["-"], "Z">;
def all__load : Flag<["-"], "all_load">;
def allowable__client : Separate<["-"], "allowable_client">;
def ansi : Flag<["-", "--"], "ansi">, Group<CompileOnly_Group>;
def arch__errors__fatal : Flag<["-"], "arch_errors_fatal">;
-def arch : Separate<["-"], "arch">, Flags<[NoXarchOption]>;
+def arch : Separate<["-"], "arch">, Flags<[NoXarchOption,TargetSpecific]>;
def arch__only : Separate<["-"], "arch_only">;
-def a : Joined<["-"], "a">;
def autocomplete : Joined<["--"], "autocomplete=">;
def bind__at__load : Flag<["-"], "bind_at_load">;
def bundle__loader : Separate<["-"], "bundle_loader">;
def bundle : Flag<["-"], "bundle">;
-def b : JoinedOrSeparate<["-"], "b">, Flags<[Unsupported]>;
-def cl_opt_disable : Flag<["-"], "cl-opt-disable">, Group<opencl_Group>, Flags<[CC1Option]>,
+def b : JoinedOrSeparate<["-"], "b">, Flags<[LinkerInput]>,
+ HelpText<"Pass -b <arg> to the linker on AIX">, MetaVarName<"<arg>">,
+ Group<Link_Group>;
+
+defm offload_uniform_block : BoolFOption<"offload-uniform-block",
+ LangOpts<"OffloadUniformBlock">, Default<"LangOpts->CUDA">,
+ PosFlag<SetTrue, [], [ClangOption, CC1Option], "Assume">,
+ NegFlag<SetFalse, [], [ClangOption, CC1Option], "Don't assume">,
+ BothFlags<[], [ClangOption], " that kernels are launched with uniform block sizes (default true for CUDA/HIP and false otherwise)">>;
+
+def fcx_limited_range : Joined<["-"], "fcx-limited-range">,
+ Group<f_Group>, Visibility<[ClangOption, CC1Option]>,
+ HelpText<"Basic algebraic expansions of complex arithmetic operations "
+ "involving are enabled.">;
+
+def fno_cx_limited_range : Joined<["-"], "fno-cx-limited-range">,
+ Group<f_Group>, Visibility<[ClangOption, CC1Option]>,
+ HelpText<"Basic algebraic expansions of complex arithmetic operations "
+ "involving are disabled.">;
+
+def fcx_fortran_rules : Joined<["-"], "fcx-fortran-rules">,
+ Group<f_Group>, Visibility<[ClangOption, CC1Option]>,
+ HelpText<"Range reduction is enabled for complex arithmetic operations.">;
+
+def fno_cx_fortran_rules : Joined<["-"], "fno-cx-fortran-rules">,
+ Group<f_Group>, Visibility<[ClangOption, CC1Option]>,
+ HelpText<"Range reduction is disabled for complex arithmetic operations.">;
+
+def complex_range_EQ : Joined<["-"], "complex-range=">, Group<f_Group>,
+ Visibility<[CC1Option]>,
+ Values<"full,limited,fortran">, NormalizedValuesScope<"LangOptions">,
+ NormalizedValues<["CX_Full", "CX_Limited", "CX_Fortran"]>,
+ MarshallingInfoEnum<LangOpts<"ComplexRange">, "CX_Full">;
+
+// OpenCL-only Options
+def cl_opt_disable : Flag<["-"], "cl-opt-disable">, Group<opencl_Group>,
+ Visibility<[ClangOption, CC1Option]>,
HelpText<"OpenCL only. This option disables all optimizations. By default optimizations are enabled.">;
-def cl_strict_aliasing : Flag<["-"], "cl-strict-aliasing">, Group<opencl_Group>, Flags<[CC1Option]>,
+def cl_strict_aliasing : Flag<["-"], "cl-strict-aliasing">, Group<opencl_Group>,
+ Visibility<[ClangOption, CC1Option]>,
HelpText<"OpenCL only. This option is added for compatibility with OpenCL 1.0.">;
-def cl_single_precision_constant : Flag<["-"], "cl-single-precision-constant">, Group<opencl_Group>, Flags<[CC1Option]>,
+def cl_single_precision_constant : Flag<["-"], "cl-single-precision-constant">, Group<opencl_Group>,
+ Visibility<[ClangOption, CC1Option]>,
HelpText<"OpenCL only. Treat double precision floating-point constant as single precision constant.">,
MarshallingInfoFlag<LangOpts<"SinglePrecisionConstants">>;
-def cl_finite_math_only : Flag<["-"], "cl-finite-math-only">, Group<opencl_Group>, Flags<[CC1Option]>,
+def cl_finite_math_only : Flag<["-"], "cl-finite-math-only">, Group<opencl_Group>,
+ Visibility<[ClangOption, CC1Option]>,
HelpText<"OpenCL only. Allow floating-point optimizations that assume arguments and results are not NaNs or +-Inf.">,
MarshallingInfoFlag<LangOpts<"CLFiniteMathOnly">>;
-def cl_kernel_arg_info : Flag<["-"], "cl-kernel-arg-info">, Group<opencl_Group>, Flags<[CC1Option]>,
+def cl_kernel_arg_info : Flag<["-"], "cl-kernel-arg-info">, Group<opencl_Group>,
+ Visibility<[ClangOption, CC1Option]>,
HelpText<"OpenCL only. Generate kernel argument metadata.">,
MarshallingInfoFlag<CodeGenOpts<"EmitOpenCLArgMetadata">>;
-def cl_unsafe_math_optimizations : Flag<["-"], "cl-unsafe-math-optimizations">, Group<opencl_Group>, Flags<[CC1Option]>,
+def cl_unsafe_math_optimizations : Flag<["-"], "cl-unsafe-math-optimizations">, Group<opencl_Group>,
+ Visibility<[ClangOption, CC1Option]>,
HelpText<"OpenCL only. Allow unsafe floating-point optimizations. Also implies -cl-no-signed-zeros and -cl-mad-enable.">,
MarshallingInfoFlag<LangOpts<"CLUnsafeMath">>;
-def cl_fast_relaxed_math : Flag<["-"], "cl-fast-relaxed-math">, Group<opencl_Group>, Flags<[CC1Option]>,
+def cl_fast_relaxed_math : Flag<["-"], "cl-fast-relaxed-math">, Group<opencl_Group>,
+ Visibility<[ClangOption, CC1Option]>,
HelpText<"OpenCL only. Sets -cl-finite-math-only and -cl-unsafe-math-optimizations, and defines __FAST_RELAXED_MATH__.">,
MarshallingInfoFlag<LangOpts<"FastRelaxedMath">>;
-def cl_mad_enable : Flag<["-"], "cl-mad-enable">, Group<opencl_Group>, Flags<[CC1Option]>,
+def cl_mad_enable : Flag<["-"], "cl-mad-enable">, Group<opencl_Group>,
+ Visibility<[ClangOption, CC1Option]>,
HelpText<"OpenCL only. Allow use of less precise MAD computations in the generated binary.">,
MarshallingInfoFlag<CodeGenOpts<"LessPreciseFPMAD">>,
ImpliedByAnyOf<[cl_unsafe_math_optimizations.KeyPath, cl_fast_relaxed_math.KeyPath]>;
-def cl_no_signed_zeros : Flag<["-"], "cl-no-signed-zeros">, Group<opencl_Group>, Flags<[CC1Option]>,
+def cl_no_signed_zeros : Flag<["-"], "cl-no-signed-zeros">, Group<opencl_Group>,
+ Visibility<[ClangOption, CC1Option]>,
HelpText<"OpenCL only. Allow use of less precise no signed zeros computations in the generated binary.">,
MarshallingInfoFlag<LangOpts<"CLNoSignedZero">>;
-def cl_std_EQ : Joined<["-"], "cl-std=">, Group<opencl_Group>, Flags<[CC1Option]>,
- HelpText<"OpenCL language standard to compile for.">, Values<"cl,CL,cl1.0,CL1.0,cl1.1,CL1.1,cl1.2,CL1.2,cl2.0,CL2.0,cl3.0,CL3.0,clc++,CLC++">;
+def cl_std_EQ : Joined<["-"], "cl-std=">, Group<opencl_Group>,
+ Visibility<[ClangOption, CC1Option]>,
+ HelpText<"OpenCL language standard to compile for.">,
+ Values<"cl,CL,cl1.0,CL1.0,cl1.1,CL1.1,cl1.2,CL1.2,cl2.0,CL2.0,cl3.0,CL3.0,clc++,CLC++,clc++1.0,CLC++1.0,clc++2021,CLC++2021">;
def cl_denorms_are_zero : Flag<["-"], "cl-denorms-are-zero">, Group<opencl_Group>,
HelpText<"OpenCL only. Allow denormals to be flushed to zero.">;
-def cl_fp32_correctly_rounded_divide_sqrt : Flag<["-"], "cl-fp32-correctly-rounded-divide-sqrt">, Group<opencl_Group>, Flags<[CC1Option]>,
+def cl_fp32_correctly_rounded_divide_sqrt : Flag<["-"], "cl-fp32-correctly-rounded-divide-sqrt">, Group<opencl_Group>,
+ Visibility<[ClangOption, CC1Option]>,
HelpText<"OpenCL only. Specify that single precision floating-point divide and sqrt used in the program source are correctly rounded.">,
MarshallingInfoFlag<CodeGenOpts<"OpenCLCorrectlyRoundedDivSqrt">>;
-def cl_uniform_work_group_size : Flag<["-"], "cl-uniform-work-group-size">, Group<opencl_Group>, Flags<[CC1Option]>,
- HelpText<"OpenCL only. Defines that the global work-size be a multiple of the work-group size specified to clEnqueueNDRangeKernel">,
- MarshallingInfoFlag<CodeGenOpts<"UniformWGSize">>;
+def cl_uniform_work_group_size : Flag<["-"], "cl-uniform-work-group-size">, Group<opencl_Group>,
+ Visibility<[ClangOption, CC1Option]>, Alias<foffload_uniform_block>,
+ HelpText<"OpenCL only. Defines that the global work-size be a multiple of the work-group size specified to clEnqueueNDRangeKernel">;
def cl_no_stdinc : Flag<["-"], "cl-no-stdinc">, Group<opencl_Group>,
HelpText<"OpenCL only. Disables all standard includes containing non-native compiler types and functions.">;
+def cl_ext_EQ : CommaJoined<["-"], "cl-ext=">, Group<opencl_Group>,
+ Visibility<[ClangOption, CC1Option]>,
+ HelpText<"OpenCL only. Enable or disable OpenCL extensions/optional features. The argument is a comma-separated "
+ "sequence of one or more extension names, each prefixed by '+' or '-'.">,
+ MarshallingInfoStringVector<TargetOpts<"OpenCLExtensionsAsWritten">>;
+
def client__name : JoinedOrSeparate<["-"], "client_name">;
def combine : Flag<["-", "--"], "combine">, Flags<[NoXarchOption, Unsupported]>;
def compatibility__version : JoinedOrSeparate<["-"], "compatibility_version">;
-def config : Separate<["--"], "config">, Flags<[NoXarchOption]>,
- HelpText<"Specifies configuration file">;
-def config_system_dir_EQ : Joined<["--"], "config-system-dir=">, Flags<[NoXarchOption, HelpHidden]>,
+def config : Joined<["--"], "config=">, Flags<[NoXarchOption]>,
+ Visibility<[ClangOption, CLOption, DXCOption]>, MetaVarName<"<file>">,
+ HelpText<"Specify configuration file">;
+def : Separate<["--"], "config">, Alias<config>;
+def no_default_config : Flag<["--"], "no-default-config">,
+ Flags<[NoXarchOption]>, Visibility<[ClangOption, CLOption, DXCOption]>,
+ HelpText<"Disable loading default configuration files">;
+def config_system_dir_EQ : Joined<["--"], "config-system-dir=">,
+ Flags<[NoXarchOption, HelpHidden]>,
+ Visibility<[ClangOption, CLOption, DXCOption]>,
HelpText<"System directory for configuration files">;
-def config_user_dir_EQ : Joined<["--"], "config-user-dir=">, Flags<[NoXarchOption, HelpHidden]>,
+def config_user_dir_EQ : Joined<["--"], "config-user-dir=">,
+ Flags<[NoXarchOption, HelpHidden]>,
+ Visibility<[ClangOption, CLOption, DXCOption]>,
HelpText<"User directory for configuration files">;
-def coverage : Flag<["-", "--"], "coverage">, Group<Link_Group>, Flags<[CoreOption]>;
+def coverage : Flag<["-", "--"], "coverage">, Group<Link_Group>,
+ Visibility<[ClangOption, CLOption]>;
def cpp_precomp : Flag<["-"], "cpp-precomp">, Group<clang_ignored_f_Group>;
def current__version : JoinedOrSeparate<["-"], "current_version">;
def cxx_isystem : JoinedOrSeparate<["-"], "cxx-isystem">, Group<clang_i_Group>,
- HelpText<"Add directory to the C++ SYSTEM include search path">, Flags<[CC1Option]>,
+ HelpText<"Add directory to the C++ SYSTEM include search path">,
+ Visibility<[ClangOption, CC1Option]>,
MetaVarName<"<directory>">;
-def c : Flag<["-"], "c">, Flags<[NoXarchOption, FlangOption]>, Group<Action_Group>,
+def c : Flag<["-"], "c">, Flags<[NoXarchOption]>,
+ Visibility<[ClangOption, FlangOption]>, Group<Action_Group>,
HelpText<"Only run preprocess, compile, and assemble steps">;
-def fconvergent_functions : Flag<["-"], "fconvergent-functions">, Group<f_Group>, Flags<[CC1Option]>,
- HelpText<"Assume functions may be convergent">;
+defm convergent_functions : BoolFOption<"convergent-functions",
+ LangOpts<"ConvergentFunctions">, DefaultFalse,
+ NegFlag<SetFalse, [], [ClangOption], "Assume all functions may be convergent.">,
+ PosFlag<SetTrue, [], [ClangOption, CC1Option]>>;
+
+// Common offloading options
+let Group = offload_Group in {
+def offload_arch_EQ : Joined<["--"], "offload-arch=">, Flags<[NoXarchOption]>,
+ Visibility<[ClangOption, FlangOption]>,
+ HelpText<"Specify an offloading device architecture for CUDA, HIP, or OpenMP. (e.g. sm_35). "
+ "If 'native' is used the compiler will detect locally installed architectures. "
+ "For HIP offloading, the device architecture can be followed by target ID features "
+ "delimited by a colon (e.g. gfx908:xnack+:sramecc-). May be specified more than once.">;
+def no_offload_arch_EQ : Joined<["--"], "no-offload-arch=">,
+ Flags<[NoXarchOption]>,
+ Visibility<[ClangOption, FlangOption]>,
+ HelpText<"Remove CUDA/HIP offloading device architecture (e.g. sm_35, gfx906) from the list of devices to compile for. "
+ "'all' resets the list to its default value.">;
+
+def offload_new_driver : Flag<["--"], "offload-new-driver">,
+ Visibility<[ClangOption, CC1Option]>, Group<f_Group>,
+ MarshallingInfoFlag<LangOpts<"OffloadingNewDriver">>, HelpText<"Use the new driver for offloading compilation.">;
+def no_offload_new_driver : Flag<["--"], "no-offload-new-driver">,
+ Visibility<[ClangOption, CC1Option]>, Group<f_Group>,
+ HelpText<"Don't Use the new driver for offloading compilation.">;
+
+def offload_device_only : Flag<["--"], "offload-device-only">,
+ Visibility<[ClangOption, FlangOption]>,
+ HelpText<"Only compile for the offloading device.">;
+def offload_host_only : Flag<["--"], "offload-host-only">,
+ Visibility<[ClangOption, FlangOption]>,
+ HelpText<"Only compile for the offloading host.">;
+def offload_host_device : Flag<["--"], "offload-host-device">,
+ Visibility<[ClangOption, FlangOption]>,
+ HelpText<"Compile for both the offloading host and device (default).">;
def gpu_use_aux_triple_only : Flag<["--"], "gpu-use-aux-triple-only">,
InternalDriverOpt, HelpText<"Prepare '-aux-triple' only without populating "
"'-aux-target-cpu' and '-aux-target-feature'.">;
-def cuda_device_only : Flag<["--"], "cuda-device-only">,
- HelpText<"Compile CUDA code for device only">;
-def cuda_host_only : Flag<["--"], "cuda-host-only">,
- HelpText<"Compile CUDA code for host only. Has no effect on non-CUDA "
- "compilations.">;
-def cuda_compile_host_device : Flag<["--"], "cuda-compile-host-device">,
- HelpText<"Compile CUDA code for both host and device (default). Has no "
- "effect on non-CUDA compilations.">;
-def cuda_include_ptx_EQ : Joined<["--"], "cuda-include-ptx=">, Flags<[NoXarchOption]>,
+def amdgpu_arch_tool_EQ : Joined<["--"], "amdgpu-arch-tool=">,
+ HelpText<"Tool used for detecting AMD GPU arch in the system.">;
+def nvptx_arch_tool_EQ : Joined<["--"], "nvptx-arch-tool=">,
+ HelpText<"Tool used for detecting NVIDIA GPU arch in the system.">;
+
+defm gpu_rdc : BoolFOption<"gpu-rdc",
+ LangOpts<"GPURelocatableDeviceCode">, DefaultFalse,
+ PosFlag<SetTrue, [], [ClangOption, CC1Option],
+ "Generate relocatable device code, also known as separate compilation mode">,
+ NegFlag<SetFalse>>;
+
+defm offload_implicit_host_device_templates :
+ BoolFOption<"offload-implicit-host-device-templates",
+ LangOpts<"OffloadImplicitHostDeviceTemplates">, DefaultFalse,
+ PosFlag<SetTrue, [], [ClangOption, CC1Option],
+ "Template functions or specializations without host, device and "
+ "global attributes have implicit host device attributes (CUDA/HIP only)">,
+ NegFlag<SetFalse>>;
+
+def fgpu_default_stream_EQ : Joined<["-"], "fgpu-default-stream=">,
+ HelpText<"Specify default stream. The default value is 'legacy'. (CUDA/HIP only)">,
+ Visibility<[ClangOption, CC1Option]>,
+ Values<"legacy,per-thread">,
+ NormalizedValuesScope<"LangOptions::GPUDefaultStreamKind">,
+ NormalizedValues<["Legacy", "PerThread"]>,
+ MarshallingInfoEnum<LangOpts<"GPUDefaultStream">, "Legacy">;
+
+def fgpu_flush_denormals_to_zero : Flag<["-"], "fgpu-flush-denormals-to-zero">,
+ HelpText<"Flush denormal floating point values to zero in CUDA/HIP device mode.">;
+def fno_gpu_flush_denormals_to_zero : Flag<["-"], "fno-gpu-flush-denormals-to-zero">;
+
+defm gpu_defer_diag : BoolFOption<"gpu-defer-diag",
+ LangOpts<"GPUDeferDiag">, DefaultFalse,
+ PosFlag<SetTrue, [], [ClangOption, CC1Option], "Defer">,
+ NegFlag<SetFalse, [], [ClangOption], "Don't defer">,
+ BothFlags<[], [ClangOption], " host/device related diagnostic messages for CUDA/HIP">>;
+
+defm gpu_exclude_wrong_side_overloads : BoolFOption<"gpu-exclude-wrong-side-overloads",
+ LangOpts<"GPUExcludeWrongSideOverloads">, DefaultFalse,
+ PosFlag<SetTrue, [], [ClangOption, CC1Option],
+ "Always exclude wrong side overloads">,
+ NegFlag<SetFalse, [], [ClangOption], "Exclude wrong side overloads only if there are same side overloads">,
+ BothFlags<[HelpHidden], [], " in overloading resolution for CUDA/HIP">>;
+
+def cuid_EQ : Joined<["-"], "cuid=">, Visibility<[ClangOption, CC1Option]>,
+ HelpText<"An ID for compilation unit, which should be the same for the same "
+ "compilation unit but different for different compilation units. "
+ "It is used to externalize device-side static variables for single "
+ "source offloading languages CUDA and HIP so that they can be "
+ "accessed by the host code of the same compilation unit.">,
+ MarshallingInfoString<LangOpts<"CUID">>;
+def fuse_cuid_EQ : Joined<["-"], "fuse-cuid=">,
+ HelpText<"Method to generate ID's for compilation units for single source "
+ "offloading languages CUDA and HIP: 'hash' (ID's generated by hashing "
+ "file path and command line options) | 'random' (ID's generated as "
+ "random numbers) | 'none' (disabled). Default is 'hash'. This option "
+ "will be overridden by option '-cuid=[ID]' if it is specified." >;
+
+def fgpu_inline_threshold_EQ : Joined<["-"], "fgpu-inline-threshold=">,
+ Flags<[HelpHidden]>,
+ HelpText<"Inline threshold for device compilation for CUDA/HIP">;
+
+def fgpu_sanitize : Flag<["-"], "fgpu-sanitize">, Group<f_Group>,
+ HelpText<"Enable sanitizer for supported offloading devices">;
+def fno_gpu_sanitize : Flag<["-"], "fno-gpu-sanitize">, Group<f_Group>;
+
+def offload_compress : Flag<["--"], "offload-compress">,
+ HelpText<"Compress offload device binaries (HIP only)">;
+def no_offload_compress : Flag<["--"], "no-offload-compress">;
+}
+
+// CUDA options
+let Group = cuda_Group in {
+def cuda_include_ptx_EQ : Joined<["--"], "cuda-include-ptx=">,
+ Flags<[NoXarchOption]>,
HelpText<"Include PTX for the following GPU architecture (e.g. sm_35) or 'all'. May be specified more than once.">;
-def no_cuda_include_ptx_EQ : Joined<["--"], "no-cuda-include-ptx=">, Flags<[NoXarchOption]>,
+def no_cuda_include_ptx_EQ : Joined<["--"], "no-cuda-include-ptx=">,
+ Flags<[NoXarchOption]>,
HelpText<"Do not include PTX for the following GPU architecture (e.g. sm_35) or 'all'. May be specified more than once.">;
-def offload_arch_EQ : Joined<["--"], "offload-arch=">, Flags<[NoXarchOption]>,
- HelpText<"CUDA offloading device architecture (e.g. sm_35), or HIP offloading target ID in the form of a "
- "device architecture followed by target ID features delimited by a colon. Each target ID feature "
- "is a pre-defined string followed by a plus or minus sign (e.g. gfx908:xnack+:sramecc-). May be "
- "specified more than once.">;
def cuda_gpu_arch_EQ : Joined<["--"], "cuda-gpu-arch=">, Flags<[NoXarchOption]>,
Alias<offload_arch_EQ>;
-def hip_link : Flag<["--"], "hip-link">,
- HelpText<"Link clang-offload-bundler bundles for HIP">;
-def no_offload_arch_EQ : Joined<["--"], "no-offload-arch=">, Flags<[NoXarchOption]>,
- HelpText<"Remove CUDA/HIP offloading device architecture (e.g. sm_35, gfx906) from the list of devices to compile for. "
- "'all' resets the list to its default value.">;
-def emit_static_lib : Flag<["--"], "emit-static-lib">,
- HelpText<"Enable linker job to emit a static library.">;
-def no_cuda_gpu_arch_EQ : Joined<["--"], "no-cuda-gpu-arch=">, Flags<[NoXarchOption]>,
+def cuda_feature_EQ : Joined<["--"], "cuda-feature=">, HelpText<"Manually specify the CUDA feature to use">;
+def no_cuda_gpu_arch_EQ : Joined<["--"], "no-cuda-gpu-arch=">,
+ Flags<[NoXarchOption]>,
Alias<no_offload_arch_EQ>;
+
+def cuda_device_only : Flag<["--"], "cuda-device-only">, Alias<offload_device_only>,
+ HelpText<"Compile CUDA code for device only">;
+def cuda_host_only : Flag<["--"], "cuda-host-only">, Alias<offload_host_only>,
+ HelpText<"Compile CUDA code for host only. Has no effect on non-CUDA compilations.">;
+def cuda_compile_host_device : Flag<["--"], "cuda-compile-host-device">, Alias<offload_host_device>,
+ HelpText<"Compile CUDA code for both host and device (default). Has no "
+ "effect on non-CUDA compilations.">;
+
def cuda_noopt_device_debug : Flag<["--"], "cuda-noopt-device-debug">,
HelpText<"Enable device-side debug info generation. Disables ptxas optimizations.">;
def no_cuda_version_check : Flag<["--"], "no-cuda-version-check">,
@@ -917,121 +1267,177 @@ def cuda_path_ignore_env : Flag<["--"], "cuda-path-ignore-env">, Group<i_Group>,
HelpText<"Ignore environment variables to detect CUDA installation">;
def ptxas_path_EQ : Joined<["--"], "ptxas-path=">, Group<i_Group>,
HelpText<"Path to ptxas (used for compiling CUDA code)">;
-def fgpu_flush_denormals_to_zero : Flag<["-"], "fgpu-flush-denormals-to-zero">,
- HelpText<"Flush denormal floating point values to zero in CUDA/HIP device mode.">;
-def fno_gpu_flush_denormals_to_zero : Flag<["-"], "fno-gpu-flush-denormals-to-zero">;
def fcuda_flush_denormals_to_zero : Flag<["-"], "fcuda-flush-denormals-to-zero">,
Alias<fgpu_flush_denormals_to_zero>;
def fno_cuda_flush_denormals_to_zero : Flag<["-"], "fno-cuda-flush-denormals-to-zero">,
Alias<fno_gpu_flush_denormals_to_zero>;
-defm gpu_rdc : BoolFOption<"gpu-rdc",
- LangOpts<"GPURelocatableDeviceCode">, DefaultFalse,
- PosFlag<SetTrue, [CC1Option], "Generate relocatable device code, also known as separate compilation mode">,
- NegFlag<SetFalse>>;
def : Flag<["-"], "fcuda-rdc">, Alias<fgpu_rdc>;
def : Flag<["-"], "fno-cuda-rdc">, Alias<fno_gpu_rdc>;
defm cuda_short_ptr : BoolFOption<"cuda-short-ptr",
TargetOpts<"NVPTXUseShortPointers">, DefaultFalse,
- PosFlag<SetTrue, [CC1Option], "Use 32-bit pointers for accessing const/local/shared address spaces">,
+ PosFlag<SetTrue, [], [ClangOption, CC1Option],
+ "Use 32-bit pointers for accessing const/local/shared address spaces">,
NegFlag<SetFalse>>;
-def rocm_path_EQ : Joined<["--"], "rocm-path=">, Group<i_Group>,
+}
+
+def emit_static_lib : Flag<["--"], "emit-static-lib">,
+ HelpText<"Enable linker job to emit a static library.">;
+
+def mprintf_kind_EQ : Joined<["-"], "mprintf-kind=">, Group<m_Group>,
+ HelpText<"Specify the printf lowering scheme (AMDGPU only), allowed values are "
+ "\"hostcall\"(printing happens during kernel execution, this scheme "
+ "relies on hostcalls which require system to support pcie atomics) "
+ "and \"buffered\"(printing happens after all kernel threads exit, "
+ "this uses a printf buffer and does not rely on pcie atomic support)">,
+ Visibility<[ClangOption, CC1Option]>,
+ Values<"hostcall,buffered">,
+ NormalizedValuesScope<"TargetOptions::AMDGPUPrintfKind">,
+ NormalizedValues<["Hostcall", "Buffered"]>,
+ MarshallingInfoEnum<TargetOpts<"AMDGPUPrintfKindVal">, "Hostcall">;
+
+// HIP options
+let Group = hip_Group in {
+def hip_link : Flag<["--"], "hip-link">, Group<opencl_Group>,
+ HelpText<"Link clang-offload-bundler bundles for HIP">;
+def no_hip_rt: Flag<["-"], "no-hip-rt">, Group<hip_Group>,
+ HelpText<"Do not link against HIP runtime libraries">;
+def rocm_path_EQ : Joined<["--"], "rocm-path=">, Group<hip_Group>,
HelpText<"ROCm installation path, used for finding and automatically linking required bitcode libraries.">;
-def hip_path_EQ : Joined<["--"], "hip-path=">, Group<i_Group>,
+def hip_path_EQ : Joined<["--"], "hip-path=">, Group<hip_Group>,
HelpText<"HIP runtime installation path, used for finding HIP version and adding HIP include path.">;
-def amdgpu_arch_tool_EQ : Joined<["--"], "amdgpu-arch-tool=">, Group<i_Group>,
- HelpText<"Tool used for detecting AMD GPU arch in the system.">;
-def rocm_device_lib_path_EQ : Joined<["--"], "rocm-device-lib-path=">, Group<Link_Group>,
+def hipstdpar : Flag<["--"], "hipstdpar">,
+ Visibility<[ClangOption, CC1Option]>,
+ Group<CompileOnly_Group>,
+ HelpText<"Enable HIP acceleration for standard parallel algorithms">,
+ MarshallingInfoFlag<LangOpts<"HIPStdPar">>;
+def hipstdpar_interpose_alloc : Flag<["--"], "hipstdpar-interpose-alloc">,
+ Visibility<[ClangOption, CC1Option]>,
+ Group<CompileOnly_Group>,
+ HelpText<"Replace all memory allocation / deallocation calls with "
+ "hipManagedMalloc / hipFree equivalents">,
+ MarshallingInfoFlag<LangOpts<"HIPStdParInterposeAlloc">>;
+// TODO: use MarshallingInfo here
+def hipstdpar_path_EQ : Joined<["--"], "hipstdpar-path=">, Group<i_Group>,
+ HelpText<
+ "HIP Standard Parallel Algorithm Acceleration library path, used for "
+ "finding and implicitly including the library header">;
+def hipstdpar_thrust_path_EQ : Joined<["--"], "hipstdpar-thrust-path=">,
+ Group<i_Group>,
+ HelpText<
+ "rocThrust path, required by the HIP Standard Parallel Algorithm "
+ "Acceleration library, used to implicitly include the rocThrust library">;
+def hipstdpar_prim_path_EQ : Joined<["--"], "hipstdpar-prim-path=">,
+ Group<i_Group>,
+ HelpText<
+ "rocPrim path, required by the HIP Standard Parallel Algorithm "
+ "Acceleration library, used to implicitly include the rocPrim library">;
+def rocm_device_lib_path_EQ : Joined<["--"], "rocm-device-lib-path=">, Group<hip_Group>,
HelpText<"ROCm device library path. Alternative to rocm-path.">;
def : Joined<["--"], "hip-device-lib-path=">, Alias<rocm_device_lib_path_EQ>;
-def hip_device_lib_EQ : Joined<["--"], "hip-device-lib=">, Group<Link_Group>,
+def hip_device_lib_EQ : Joined<["--"], "hip-device-lib=">, Group<hip_Group>,
HelpText<"HIP device library">;
-def hip_version_EQ : Joined<["--"], "hip-version=">,
+def hip_version_EQ : Joined<["--"], "hip-version=">, Group<hip_Group>,
HelpText<"HIP version in the format of major.minor.patch">;
def fhip_dump_offload_linker_script : Flag<["-"], "fhip-dump-offload-linker-script">,
- Group<f_Group>, Flags<[NoArgumentUnused, HelpHidden]>;
+ Group<hip_Group>, Flags<[NoArgumentUnused, HelpHidden]>;
defm hip_new_launch_api : BoolFOption<"hip-new-launch-api",
LangOpts<"HIPUseNewLaunchAPI">, DefaultFalse,
- PosFlag<SetTrue, [CC1Option], "Use">, NegFlag<SetFalse, [], "Don't use">,
- BothFlags<[], " new kernel launching API for HIP">>;
+ PosFlag<SetTrue, [], [ClangOption, CC1Option], "Use">,
+ NegFlag<SetFalse, [], [ClangOption], "Don't use">,
+ BothFlags<[], [ClangOption], " new kernel launching API for HIP">>;
defm hip_fp32_correctly_rounded_divide_sqrt : BoolFOption<"hip-fp32-correctly-rounded-divide-sqrt",
CodeGenOpts<"HIPCorrectlyRoundedDivSqrt">, DefaultTrue,
- PosFlag<SetTrue, [], "Specify">,
- NegFlag<SetFalse, [CC1Option], "Don't specify">,
- BothFlags<[], " that single precision floating-point divide and sqrt used in "
+ PosFlag<SetTrue, [], [ClangOption], "Specify">,
+ NegFlag<SetFalse, [], [ClangOption, CC1Option], "Don't specify">,
+ BothFlags<[], [ClangOption], " that single precision floating-point divide and sqrt used in "
"the program source are correctly rounded (HIP device compilation only)">>,
ShouldParseIf<hip.KeyPath>;
+defm hip_kernel_arg_name : BoolFOption<"hip-kernel-arg-name",
+ CodeGenOpts<"HIPSaveKernelArgName">, DefaultFalse,
+ PosFlag<SetTrue, [], [ClangOption, CC1Option], "Specify">,
+ NegFlag<SetFalse, [], [ClangOption], "Don't specify">,
+ BothFlags<[], [ClangOption], " that kernel argument names are preserved (HIP only)">>,
+ ShouldParseIf<hip.KeyPath>;
+def hipspv_pass_plugin_EQ : Joined<["--"], "hipspv-pass-plugin=">,
+ Group<Link_Group>, MetaVarName<"<dsopath>">,
+ HelpText<"path to a pass plugin for HIP to SPIR-V passes.">;
defm gpu_allow_device_init : BoolFOption<"gpu-allow-device-init",
LangOpts<"GPUAllowDeviceInit">, DefaultFalse,
- PosFlag<SetTrue, [CC1Option], "Allow">, NegFlag<SetFalse, [], "Don't allow">,
- BothFlags<[], " device side init function in HIP (experimental)">>,
+ PosFlag<SetTrue, [], [ClangOption, CC1Option], "Allow">,
+ NegFlag<SetFalse, [], [ClangOption], "Don't allow">,
+ BothFlags<[], [ClangOption], " device side init function in HIP (experimental)">>,
ShouldParseIf<hip.KeyPath>;
-defm gpu_defer_diag : BoolFOption<"gpu-defer-diag",
- LangOpts<"GPUDeferDiag">, DefaultFalse,
- PosFlag<SetTrue, [CC1Option], "Defer">, NegFlag<SetFalse, [], "Don't defer">,
- BothFlags<[], " host/device related diagnostic messages for CUDA/HIP">>;
-defm gpu_exclude_wrong_side_overloads : BoolFOption<"gpu-exclude-wrong-side-overloads",
- LangOpts<"GPUExcludeWrongSideOverloads">, DefaultFalse,
- PosFlag<SetTrue, [CC1Option], "Always exclude wrong side overloads">,
- NegFlag<SetFalse, [], "Exclude wrong side overloads only if there are same side overloads">,
- BothFlags<[HelpHidden], " in overloading resolution for CUDA/HIP">>;
def gpu_max_threads_per_block_EQ : Joined<["--"], "gpu-max-threads-per-block=">,
- Flags<[CC1Option]>,
+ Visibility<[ClangOption, CC1Option]>,
HelpText<"Default max threads per block for kernel launch bounds for HIP">,
MarshallingInfoInt<LangOpts<"GPUMaxThreadsPerBlock">, "1024">,
ShouldParseIf<hip.KeyPath>;
-def fgpu_inline_threshold_EQ : Joined<["-"], "fgpu-inline-threshold=">,
- Flags<[HelpHidden]>,
- HelpText<"Inline threshold for device compilation for CUDA/HIP">;
def gpu_instrument_lib_EQ : Joined<["--"], "gpu-instrument-lib=">,
HelpText<"Instrument device library for HIP, which is a LLVM bitcode containing "
"__cyg_profile_func_enter and __cyg_profile_func_exit">;
-def fgpu_sanitize : Flag<["-"], "fgpu-sanitize">, Group<f_Group>,
- HelpText<"Enable sanitizer for AMDGPU target">;
-def fno_gpu_sanitize : Flag<["-"], "fno-gpu-sanitize">, Group<f_Group>;
def gpu_bundle_output : Flag<["--"], "gpu-bundle-output">,
- Group<f_Group>, HelpText<"Bundle output files of HIP device compilation">;
+ HelpText<"Bundle output files of HIP device compilation">;
def no_gpu_bundle_output : Flag<["--"], "no-gpu-bundle-output">,
- Group<f_Group>, HelpText<"Do not bundle output files of HIP device compilation">;
-def cuid_EQ : Joined<["-"], "cuid=">, Flags<[CC1Option]>,
- HelpText<"An ID for compilation unit, which should be the same for the same "
- "compilation unit but different for different compilation units. "
- "It is used to externalize device-side static variables for single "
- "source offloading languages CUDA and HIP so that they can be "
- "accessed by the host code of the same compilation unit.">,
- MarshallingInfoString<LangOpts<"CUID">>;
-def fuse_cuid_EQ : Joined<["-"], "fuse-cuid=">,
- HelpText<"Method to generate ID's for compilation units for single source "
- "offloading languages CUDA and HIP: 'hash' (ID's generated by hashing "
- "file path and command line options) | 'random' (ID's generated as "
- "random numbers) | 'none' (disabled). Default is 'hash'. This option "
- "will be overriden by option '-cuid=[ID]' if it is specified." >;
-def libomptarget_amdgcn_bc_path_EQ : Joined<["--"], "libomptarget-amdgcn-bc-path=">, Group<i_Group>,
+ Group<hip_Group>, HelpText<"Do not bundle output files of HIP device compilation">;
+def fhip_emit_relocatable : Flag<["-"], "fhip-emit-relocatable">,
+ HelpText<"Compile HIP source to relocatable">;
+def fno_hip_emit_relocatable : Flag<["-"], "fno-hip-emit-relocatable">,
+ HelpText<"Do not override toolchain to compile HIP source to relocatable">;
+}
+
+// Clang specific/exclusive options for OpenACC.
+def openacc_macro_override
+ : Separate<["-"], "fexperimental-openacc-macro-override">,
+ Visibility<[ClangOption, CC1Option]>,
+ Group<f_Group>,
+ HelpText<"Overrides the _OPENACC macro value for experimental testing "
+ "during OpenACC support development">;
+def openacc_macro_override_EQ
+ : Joined<["-"], "fexperimental-openacc-macro-override=">,
+ Alias<openacc_macro_override>;
+
+// End Clang specific/exclusive options for OpenACC.
+
+def libomptarget_amdgpu_bc_path_EQ : Joined<["--"], "libomptarget-amdgpu-bc-path=">, Group<i_Group>,
HelpText<"Path to libomptarget-amdgcn bitcode library">;
+def libomptarget_amdgcn_bc_path_EQ : Joined<["--"], "libomptarget-amdgcn-bc-path=">, Group<i_Group>,
+ HelpText<"Path to libomptarget-amdgcn bitcode library">, Alias<libomptarget_amdgpu_bc_path_EQ>;
def libomptarget_nvptx_bc_path_EQ : Joined<["--"], "libomptarget-nvptx-bc-path=">, Group<i_Group>,
HelpText<"Path to libomptarget-nvptx bitcode library">;
-def dD : Flag<["-"], "dD">, Group<d_Group>, Flags<[CC1Option]>,
+def dD : Flag<["-"], "dD">, Group<d_Group>, Visibility<[ClangOption, CC1Option]>,
HelpText<"Print macro definitions in -E mode in addition to normal output">;
-def dI : Flag<["-"], "dI">, Group<d_Group>, Flags<[CC1Option]>,
+def dI : Flag<["-"], "dI">, Group<d_Group>, Visibility<[ClangOption, CC1Option]>,
HelpText<"Print include directives in -E mode in addition to normal output">,
MarshallingInfoFlag<PreprocessorOutputOpts<"ShowIncludeDirectives">>;
-def dM : Flag<["-"], "dM">, Group<d_Group>, Flags<[CC1Option]>,
+def dM : Flag<["-"], "dM">, Group<d_Group>, Visibility<[ClangOption, CC1Option]>,
HelpText<"Print macro definitions in -E mode instead of normal output">;
def dead__strip : Flag<["-"], "dead_strip">;
-def dependency_file : Separate<["-"], "dependency-file">, Flags<[CC1Option]>,
+def dependency_file : Separate<["-"], "dependency-file">,
+ Visibility<[ClangOption, CC1Option]>,
HelpText<"Filename (or -) to write dependency output to">,
MarshallingInfoString<DependencyOutputOpts<"OutputFile">>;
-def dependency_dot : Separate<["-"], "dependency-dot">, Flags<[CC1Option]>,
+def dependency_dot : Separate<["-"], "dependency-dot">,
+ Visibility<[ClangOption, CC1Option]>,
HelpText<"Filename to write DOT-formatted header dependencies to">,
MarshallingInfoString<DependencyOutputOpts<"DOTOutputFile">>;
def module_dependency_dir : Separate<["-"], "module-dependency-dir">,
- Flags<[CC1Option]>, HelpText<"Directory to dump module dependencies to">,
+ Visibility<[ClangOption, CC1Option]>,
+ HelpText<"Directory to dump module dependencies to">,
MarshallingInfoString<DependencyOutputOpts<"ModuleDependencyOutputDir">>;
def dsym_dir : JoinedOrSeparate<["-"], "dsym-dir">,
Flags<[NoXarchOption, RenderAsInput]>,
HelpText<"Directory to output dSYM's (if any) to">, MetaVarName<"<dir>">;
-def dumpmachine : Flag<["-"], "dumpmachine">;
+// GCC style -dumpdir. We intentionally don't implement the less useful -dumpbase{,-ext}.
+def dumpdir : Separate<["-"], "dumpdir">, Visibility<[ClangOption, CC1Option]>,
+ MetaVarName<"<dumppfx>">,
+ HelpText<"Use <dumpfpx> as a prefix to form auxiliary and dump file names">;
+def dumpmachine : Flag<["-"], "dumpmachine">,
+ Visibility<[ClangOption, FlangOption]>,
+ HelpText<"Display the compiler's target processor">;
+def dumpversion : Flag<["-"], "dumpversion">,
+ Visibility<[ClangOption, FlangOption]>,
+ HelpText<"Display the version of the compiler">;
def dumpspecs : Flag<["-"], "dumpspecs">, Flags<[Unsupported]>;
-def dumpversion : Flag<["-"], "dumpversion">;
def dylib__file : Separate<["-"], "dylib_file">;
def dylinker__install__name : JoinedOrSeparate<["-"], "dylinker_install_name">;
def dylinker : Flag<["-"], "dylinker">;
@@ -1040,54 +1446,97 @@ def dynamic : Flag<["-"], "dynamic">, Flags<[NoArgumentUnused]>;
def d_Flag : Flag<["-"], "d">, Group<d_Group>;
def d_Joined : Joined<["-"], "d">, Group<d_Group>;
def emit_ast : Flag<["-"], "emit-ast">,
+ Visibility<[ClangOption, CLOption, DXCOption]>,
HelpText<"Emit Clang AST files for source inputs">;
-def emit_llvm : Flag<["-"], "emit-llvm">, Flags<[CC1Option]>, Group<Action_Group>,
+def emit_llvm : Flag<["-"], "emit-llvm">,
+ Visibility<[ClangOption, CC1Option, FC1Option, FlangOption]>,
+ Group<Action_Group>,
HelpText<"Use the LLVM representation for assembler and object files">;
-def emit_interface_stubs : Flag<["-"], "emit-interface-stubs">, Flags<[CC1Option]>, Group<Action_Group>,
+def emit_interface_stubs : Flag<["-"], "emit-interface-stubs">,
+ Visibility<[ClangOption, CC1Option]>, Group<Action_Group>,
HelpText<"Generate Interface Stub Files.">;
def emit_merged_ifs : Flag<["-"], "emit-merged-ifs">,
- Flags<[CC1Option]>, Group<Action_Group>,
+ Visibility<[ClangOption, CC1Option]>, Group<Action_Group>,
HelpText<"Generate Interface Stub Files, emit merged text not binary.">;
-def interface_stub_version_EQ : JoinedOrSeparate<["-"], "interface-stub-version=">, Flags<[CC1Option]>;
+def end_no_unused_arguments : Flag<["--"], "end-no-unused-arguments">,
+ Visibility<[ClangOption, CLOption, DXCOption]>,
+ HelpText<"Start emitting warnings for unused driver arguments">;
+def interface_stub_version_EQ : JoinedOrSeparate<["-"], "interface-stub-version=">,
+ Visibility<[ClangOption, CC1Option]>;
def exported__symbols__list : Separate<["-"], "exported_symbols_list">;
-def e : JoinedOrSeparate<["-"], "e">, Flags<[LinkerInput]>, Group<Link_Group>;
-def fmax_tokens_EQ : Joined<["-"], "fmax-tokens=">, Group<f_Group>, Flags<[CC1Option]>,
+def extract_api : Flag<["-"], "extract-api">,
+ Visibility<[ClangOption, CC1Option]>, Group<Action_Group>,
+ HelpText<"Extract API information">;
+def product_name_EQ: Joined<["--"], "product-name=">,
+ Visibility<[ClangOption, CC1Option]>,
+ MarshallingInfoString<FrontendOpts<"ProductName">>;
+def emit_symbol_graph_EQ: JoinedOrSeparate<["--"], "emit-symbol-graph=">,
+ Visibility<[ClangOption, CC1Option]>,
+ HelpText<"Generate Extract API information as a side effect of compilation.">,
+ MarshallingInfoString<FrontendOpts<"SymbolGraphOutputDir">>;
+def extract_api_ignores_EQ: CommaJoined<["--"], "extract-api-ignores=">,
+ Visibility<[ClangOption, CC1Option]>,
+ HelpText<"Comma separated list of files containing a new line separated list of API symbols to ignore when extracting API information.">,
+ MarshallingInfoStringVector<FrontendOpts<"ExtractAPIIgnoresFileList">>;
+def e : Separate<["-"], "e">, Flags<[LinkerInput]>, Group<Link_Group>;
+def fmax_tokens_EQ : Joined<["-"], "fmax-tokens=">, Group<f_Group>,
+ Visibility<[ClangOption, CC1Option]>,
HelpText<"Max total number of preprocessed tokens for -Wmax-tokens.">,
MarshallingInfoInt<LangOpts<"MaxTokens">>;
-def fPIC : Flag<["-"], "fPIC">, Group<f_Group>;
-def fno_PIC : Flag<["-"], "fno-PIC">, Group<f_Group>;
-def fPIE : Flag<["-"], "fPIE">, Group<f_Group>;
-def fno_PIE : Flag<["-"], "fno-PIE">, Group<f_Group>;
defm access_control : BoolFOption<"access-control",
LangOpts<"AccessControl">, DefaultTrue,
- NegFlag<SetFalse, [CC1Option], "Disable C++ access control">,
+ NegFlag<SetFalse, [], [ClangOption, CC1Option],
+ "Disable C++ access control">,
PosFlag<SetTrue>>;
def falign_functions : Flag<["-"], "falign-functions">, Group<f_Group>;
def falign_functions_EQ : Joined<["-"], "falign-functions=">, Group<f_Group>;
+def falign_loops_EQ : Joined<["-"], "falign-loops=">, Group<f_Group>,
+ Visibility<[ClangOption, CC1Option]>, MetaVarName<"<N>">,
+ HelpText<"N must be a power of two. Align loops to the boundary">,
+ MarshallingInfoInt<CodeGenOpts<"LoopAlignment">>;
def fno_align_functions: Flag<["-"], "fno-align-functions">, Group<f_Group>;
defm allow_editor_placeholders : BoolFOption<"allow-editor-placeholders",
LangOpts<"AllowEditorPlaceholders">, DefaultFalse,
- PosFlag<SetTrue, [CC1Option], "Treat editor placeholders as valid source code">,
+ PosFlag<SetTrue, [], [ClangOption, CC1Option],
+ "Treat editor placeholders as valid source code">,
NegFlag<SetFalse>>;
def fallow_unsupported : Flag<["-"], "fallow-unsupported">, Group<f_Group>;
-def fapple_kext : Flag<["-"], "fapple-kext">, Group<f_Group>, Flags<[CC1Option]>,
+def fapple_kext : Flag<["-"], "fapple-kext">, Group<f_Group>,
+ Visibility<[ClangOption, CC1Option]>,
HelpText<"Use Apple's kernel extensions ABI">,
MarshallingInfoFlag<LangOpts<"AppleKext">>;
+def fstrict_flex_arrays_EQ : Joined<["-"], "fstrict-flex-arrays=">, Group<f_Group>,
+ MetaVarName<"<n>">, Values<"0,1,2,3">,
+ LangOpts<"StrictFlexArraysLevel">,
+ Visibility<[ClangOption, CC1Option]>,
+ NormalizedValuesScope<"LangOptions::StrictFlexArraysLevelKind">,
+ NormalizedValues<["Default", "OneZeroOrIncomplete", "ZeroOrIncomplete", "IncompleteOnly"]>,
+ HelpText<"Enable optimizations based on the strict definition of flexible arrays">,
+ MarshallingInfoEnum<LangOpts<"StrictFlexArraysLevel">, "Default">;
defm apple_pragma_pack : BoolFOption<"apple-pragma-pack",
LangOpts<"ApplePragmaPack">, DefaultFalse,
- PosFlag<SetTrue, [CC1Option], "Enable Apple gcc-compatible #pragma pack handling">,
+ PosFlag<SetTrue, [], [ClangOption, CC1Option],
+ "Enable Apple gcc-compatible #pragma pack handling">,
NegFlag<SetFalse>>;
defm xl_pragma_pack : BoolFOption<"xl-pragma-pack",
LangOpts<"XLPragmaPack">, DefaultFalse,
- PosFlag<SetTrue, [CC1Option], "Enable IBM XL #pragma pack handling">,
+ PosFlag<SetTrue, [], [ClangOption, CC1Option],
+ "Enable IBM XL #pragma pack handling">,
NegFlag<SetFalse>>;
def shared_libsan : Flag<["-"], "shared-libsan">,
HelpText<"Dynamically link the sanitizer runtime">;
def static_libsan : Flag<["-"], "static-libsan">,
- HelpText<"Statically link the sanitizer runtime">;
+ HelpText<"Statically link the sanitizer runtime (Not supported for ASan, TSan or UBSan on darwin)">;
def : Flag<["-"], "shared-libasan">, Alias<shared_libsan>;
def fasm : Flag<["-"], "fasm">, Group<f_Group>;
+defm assume_unique_vtables : BoolFOption<"assume-unique-vtables",
+ CodeGenOpts<"AssumeUniqueVTables">, DefaultTrue,
+ PosFlag<SetTrue>,
+ NegFlag<SetFalse, [], [ClangOption, CC1Option],
+ "Disable optimizations based on vtable pointer identity">,
+ BothFlags<[], [ClangOption, CLOption]>>;
+
def fassume_sane_operator_new : Flag<["-"], "fassume-sane-operator-new">, Group<f_Group>;
def fastcp : Flag<["-"], "fastcp">, Group<f_Group>;
def fastf : Flag<["-"], "fastf">, Group<f_Group>;
@@ -1095,24 +1544,64 @@ def fast : Flag<["-"], "fast">, Group<f_Group>;
def fasynchronous_unwind_tables : Flag<["-"], "fasynchronous-unwind-tables">, Group<f_Group>;
defm double_square_bracket_attributes : BoolFOption<"double-square-bracket-attributes",
- LangOpts<"DoubleSquareBracketAttributes">, Default<!strconcat(cpp11.KeyPath, "||", c2x.KeyPath)>,
- PosFlag<SetTrue, [], "Enable">, NegFlag<SetFalse, [], "Disable">,
- BothFlags<[NoXarchOption, CC1Option], " '[[]]' attributes in all C and C++ language modes">>;
+ LangOpts<"DoubleSquareBracketAttributes">, DefaultTrue, PosFlag<SetTrue>,
+ NegFlag<SetFalse>>;
defm autolink : BoolFOption<"autolink",
CodeGenOpts<"Autolink">, DefaultTrue,
- NegFlag<SetFalse, [CC1Option], "Disable generation of linker directives for automatic library linking">,
+ NegFlag<SetFalse, [], [ClangOption, CC1Option],
+ "Disable generation of linker directives for automatic library linking">,
PosFlag<SetTrue>>;
-// C++ Coroutines TS
-defm coroutines_ts : BoolFOption<"coroutines-ts",
+let Flags = [TargetSpecific] in {
+defm auto_import : BoolFOption<"auto-import",
+ CodeGenOpts<"AutoImport">, DefaultTrue,
+ NegFlag<SetFalse, [], [ClangOption, CC1Option],
+ "MinGW specific. Disable support for automatic dllimport in code generation "
+ "and linking">,
+ PosFlag<SetTrue, [], [], "MinGW specific. Enable code generation support for "
+ "automatic dllimport, and enable support for it in the linker. "
+ "Enabled by default.">>;
+} // let Flags = [TargetSpecific]
+
+// In the future this option will be supported by other offloading
+// languages and accept other values such as CPU/GPU architectures,
+// offload kinds and target aliases.
+def offload_EQ : CommaJoined<["--"], "offload=">, Flags<[NoXarchOption]>,
+ HelpText<"Specify comma-separated list of offloading target triples (CUDA and HIP only)">;
+
+// C++ Coroutines
+defm coroutines : BoolFOption<"coroutines",
LangOpts<"Coroutines">, Default<cpp20.KeyPath>,
- PosFlag<SetTrue, [CC1Option], "Enable support for the C++ Coroutines TS">,
+ PosFlag<SetTrue, [], [ClangOption, CC1Option],
+ "Enable support for the C++ Coroutines">,
NegFlag<SetFalse>>;
+defm coro_aligned_allocation : BoolFOption<"coro-aligned-allocation",
+ LangOpts<"CoroAlignedAllocation">, DefaultFalse,
+ PosFlag<SetTrue, [], [ClangOption, CC1Option],
+ "Prefer aligned allocation for C++ Coroutines">,
+ NegFlag<SetFalse>>;
+
+defm experimental_library : BoolFOption<"experimental-library",
+ LangOpts<"ExperimentalLibrary">, DefaultFalse,
+ PosFlag<SetTrue, [], [ClangOption, CC1Option, CLOption],
+ "Control whether unstable and experimental library features are enabled. "
+ "This option enables various library features that are either experimental (also known as TSes), or have been "
+ "but are not stable yet in the selected Standard Library implementation. It is not recommended to use this option "
+ "in production code, since neither ABI nor API stability are guaranteed. This is intended to provide a preview "
+ "of features that will ship in the future for experimentation purposes">,
+ NegFlag<SetFalse>>;
+
+def fembed_offload_object_EQ : Joined<["-"], "fembed-offload-object=">,
+ Group<f_Group>, Flags<[NoXarchOption]>,
+ Visibility<[ClangOption, CC1Option, FC1Option]>,
+ HelpText<"Embed Offloading device-side binary into host object file as a section.">,
+ MarshallingInfoStringVector<CodeGenOpts<"OffloadObjects">>;
def fembed_bitcode_EQ : Joined<["-"], "fembed-bitcode=">,
- Group<f_Group>, Flags<[NoXarchOption, CC1Option, CC1AsOption]>, MetaVarName<"<option>">,
- HelpText<"Embed LLVM bitcode (option: off, all, bitcode, marker)">,
+ Group<f_Group>, Flags<[NoXarchOption]>,
+ Visibility<[ClangOption, CC1Option, CC1AsOption]>, MetaVarName<"<option>">,
+ HelpText<"Embed LLVM bitcode">,
Values<"off,all,bitcode,marker">, NormalizedValuesScope<"CodeGenOptions">,
NormalizedValues<["Embed_Off", "Embed_All", "Embed_Bitcode", "Embed_Marker"]>,
MarshallingInfoEnum<CodeGenOpts<"EmbedBitcode">, "Embed_Off">;
@@ -1124,26 +1613,37 @@ def fembed_bitcode_marker : Flag<["-"], "fembed-bitcode-marker">,
HelpText<"Embed placeholder LLVM IR data as a marker">;
defm gnu_inline_asm : BoolFOption<"gnu-inline-asm",
LangOpts<"GNUAsm">, DefaultTrue,
- NegFlag<SetFalse, [CC1Option], "Disable GNU style inline asm">, PosFlag<SetTrue>>;
+ NegFlag<SetFalse, [], [ClangOption, CC1Option],
+ "Disable GNU style inline asm">,
+ PosFlag<SetTrue>>;
def fprofile_sample_use : Flag<["-"], "fprofile-sample-use">, Group<f_Group>,
- Flags<[CoreOption]>;
+ Visibility<[ClangOption, CLOption]>;
def fno_profile_sample_use : Flag<["-"], "fno-profile-sample-use">, Group<f_Group>,
- Flags<[CoreOption]>;
+ Visibility<[ClangOption, CLOption]>;
def fprofile_sample_use_EQ : Joined<["-"], "fprofile-sample-use=">,
- Group<f_Group>, Flags<[NoXarchOption, CC1Option]>,
+ Group<f_Group>,
+ Visibility<[ClangOption, CC1Option]>,
HelpText<"Enable sample-based profile guided optimizations">,
MarshallingInfoString<CodeGenOpts<"SampleProfileFile">>;
def fprofile_sample_accurate : Flag<["-"], "fprofile-sample-accurate">,
- Group<f_Group>, Flags<[NoXarchOption, CC1Option]>,
+ Group<f_Group>,
+ Visibility<[ClangOption, CC1Option]>,
HelpText<"Specifies that the sample profile is accurate">,
DocBrief<[{Specifies that the sample profile is accurate. If the sample
profile is accurate, callsites without profile samples are marked
as cold. Otherwise, treat callsites without profile samples as if
we have no profile}]>,
MarshallingInfoFlag<CodeGenOpts<"ProfileSampleAccurate">>;
-def fno_profile_sample_accurate : Flag<["-"], "fno-profile-sample-accurate">,
- Group<f_Group>, Flags<[NoXarchOption]>;
+def fsample_profile_use_profi : Flag<["-"], "fsample-profile-use-profi">,
+ Visibility<[ClangOption, CC1Option]>,
+ Group<f_Group>,
+ HelpText<"Use profi to infer block and edge counts">,
+ DocBrief<[{Infer block and edge counts. If the profiles have errors or missing
+ blocks caused by sampling, profile inference (profi) can convert
+ basic block counts to branch probabilites to fix them by extended
+ and re-engineered classic MCMF (min-cost max-flow) approach.}]>;
+def fno_profile_sample_accurate : Flag<["-"], "fno-profile-sample-accurate">, Group<f_Group>;
def fauto_profile : Flag<["-"], "fauto-profile">, Group<f_Group>,
Alias<fprofile_sample_use>;
def fno_auto_profile : Flag<["-"], "fno-auto-profile">, Group<f_Group>,
@@ -1155,255 +1655,396 @@ def fauto_profile_accurate : Flag<["-"], "fauto-profile-accurate">,
def fno_auto_profile_accurate : Flag<["-"], "fno-auto-profile-accurate">,
Group<f_Group>, Alias<fno_profile_sample_accurate>;
def fdebug_compilation_dir_EQ : Joined<["-"], "fdebug-compilation-dir=">,
- Group<f_Group>, Flags<[CC1Option, CC1AsOption, CoreOption]>,
+ Group<f_Group>,
+ Visibility<[ClangOption, CC1Option, CC1AsOption, CLOption, DXCOption]>,
HelpText<"The compilation directory to embed in the debug info">,
MarshallingInfoString<CodeGenOpts<"DebugCompilationDir">>;
def fdebug_compilation_dir : Separate<["-"], "fdebug-compilation-dir">,
- Group<f_Group>, Flags<[CC1Option, CC1AsOption, CoreOption]>,
+ Group<f_Group>,
+ Visibility<[ClangOption, CC1Option, CC1AsOption, CLOption, DXCOption]>,
Alias<fdebug_compilation_dir_EQ>;
def fcoverage_compilation_dir_EQ : Joined<["-"], "fcoverage-compilation-dir=">,
- Group<f_Group>, Flags<[CC1Option, CC1AsOption, CoreOption]>,
+ Group<f_Group>, Visibility<[ClangOption, CC1Option, CC1AsOption, CLOption]>,
HelpText<"The compilation directory to embed in the coverage mapping.">,
MarshallingInfoString<CodeGenOpts<"CoverageCompilationDir">>;
def ffile_compilation_dir_EQ : Joined<["-"], "ffile-compilation-dir=">, Group<f_Group>,
- Flags<[CoreOption]>,
+ Visibility<[ClangOption, CLOption, DXCOption]>,
HelpText<"The compilation directory to embed in the debug info and coverage mapping.">;
defm debug_info_for_profiling : BoolFOption<"debug-info-for-profiling",
CodeGenOpts<"DebugInfoForProfiling">, DefaultFalse,
- PosFlag<SetTrue, [CC1Option], "Emit extra debug info to make sample profile more accurate">,
+ PosFlag<SetTrue, [], [ClangOption, CC1Option],
+ "Emit extra debug info to make sample profile more accurate">,
NegFlag<SetFalse>>;
def fprofile_instr_generate : Flag<["-"], "fprofile-instr-generate">,
- Group<f_Group>, Flags<[CoreOption]>,
+ Group<f_Group>, Visibility<[ClangOption, CLOption]>,
HelpText<"Generate instrumented code to collect execution counts into default.profraw file (overridden by '=' form of option or LLVM_PROFILE_FILE env var)">;
def fprofile_instr_generate_EQ : Joined<["-"], "fprofile-instr-generate=">,
- Group<f_Group>, Flags<[CoreOption]>, MetaVarName<"<file>">,
+ Group<f_Group>, Visibility<[ClangOption, CLOption]>, MetaVarName<"<file>">,
HelpText<"Generate instrumented code to collect execution counts into <file> (overridden by LLVM_PROFILE_FILE env var)">;
def fprofile_instr_use : Flag<["-"], "fprofile-instr-use">, Group<f_Group>,
- Flags<[CoreOption]>;
+ Visibility<[ClangOption, CLOption]>;
def fprofile_instr_use_EQ : Joined<["-"], "fprofile-instr-use=">,
- Group<f_Group>, Flags<[CoreOption]>,
+ Group<f_Group>, Visibility<[ClangOption, CLOption]>,
HelpText<"Use instrumentation data for profile-guided optimization">;
def fprofile_remapping_file_EQ : Joined<["-"], "fprofile-remapping-file=">,
- Group<f_Group>, Flags<[CC1Option, CoreOption]>, MetaVarName<"<file>">,
+ Group<f_Group>, Visibility<[ClangOption, CC1Option, CLOption]>,
+ MetaVarName<"<file>">,
HelpText<"Use the remappings described in <file> to match the profile data against names in the program">,
MarshallingInfoString<CodeGenOpts<"ProfileRemappingFile">>;
defm coverage_mapping : BoolFOption<"coverage-mapping",
CodeGenOpts<"CoverageMapping">, DefaultFalse,
- PosFlag<SetTrue, [CC1Option], "Generate coverage mapping to enable code coverage analysis">,
- NegFlag<SetFalse, [], "Disable code coverage analysis">, BothFlags<[CoreOption]>>;
+ PosFlag<SetTrue, [], [ClangOption, CC1Option],
+ "Generate coverage mapping to enable code coverage analysis">,
+ NegFlag<SetFalse, [], [ClangOption], "Disable code coverage analysis">, BothFlags<
+ [], [ClangOption, CLOption]>>;
+defm mcdc_coverage : BoolFOption<"coverage-mcdc",
+ CodeGenOpts<"MCDCCoverage">, DefaultFalse,
+ PosFlag<SetTrue, [], [ClangOption, CC1Option],
+ "Enable MC/DC criteria when generating code coverage">,
+ NegFlag<SetFalse, [], [ClangOption], "Disable MC/DC coverage criteria">,
+ BothFlags<[], [ClangOption, CLOption]>>;
def fprofile_generate : Flag<["-"], "fprofile-generate">,
- Group<f_Group>, Flags<[CoreOption]>,
+ Group<f_Group>, Visibility<[ClangOption, CLOption]>,
HelpText<"Generate instrumented code to collect execution counts into default.profraw (overridden by LLVM_PROFILE_FILE env var)">;
def fprofile_generate_EQ : Joined<["-"], "fprofile-generate=">,
- Group<f_Group>, Flags<[CoreOption]>, MetaVarName<"<directory>">,
+ Group<f_Group>, Visibility<[ClangOption, CLOption]>,
+ MetaVarName<"<directory>">,
HelpText<"Generate instrumented code to collect execution counts into <directory>/default.profraw (overridden by LLVM_PROFILE_FILE env var)">;
def fcs_profile_generate : Flag<["-"], "fcs-profile-generate">,
- Group<f_Group>, Flags<[CoreOption]>,
+ Group<f_Group>, Visibility<[ClangOption, CLOption]>,
HelpText<"Generate instrumented code to collect context sensitive execution counts into default.profraw (overridden by LLVM_PROFILE_FILE env var)">;
def fcs_profile_generate_EQ : Joined<["-"], "fcs-profile-generate=">,
- Group<f_Group>, Flags<[CoreOption]>, MetaVarName<"<directory>">,
+ Group<f_Group>, Visibility<[ClangOption, CLOption]>,
+ MetaVarName<"<directory>">,
HelpText<"Generate instrumented code to collect context sensitive execution counts into <directory>/default.profraw (overridden by LLVM_PROFILE_FILE env var)">;
def fprofile_use : Flag<["-"], "fprofile-use">, Group<f_Group>,
- Alias<fprofile_instr_use>;
+ Visibility<[ClangOption, CLOption]>, Alias<fprofile_instr_use>;
def fprofile_use_EQ : Joined<["-"], "fprofile-use=">,
- Group<f_Group>, Flags<[NoXarchOption]>, MetaVarName<"<pathname>">,
+ Group<f_Group>,
+ Visibility<[ClangOption, CLOption]>,
+ MetaVarName<"<pathname>">,
HelpText<"Use instrumentation data for profile-guided optimization. If pathname is a directory, it reads from <pathname>/default.profdata. Otherwise, it reads from file <pathname>.">;
def fno_profile_instr_generate : Flag<["-"], "fno-profile-instr-generate">,
- Group<f_Group>, Flags<[CoreOption]>,
+ Group<f_Group>, Visibility<[ClangOption, CLOption]>,
HelpText<"Disable generation of profile instrumentation.">;
def fno_profile_generate : Flag<["-"], "fno-profile-generate">,
- Group<f_Group>, Flags<[CoreOption]>,
+ Group<f_Group>, Visibility<[ClangOption, CLOption]>,
HelpText<"Disable generation of profile instrumentation.">;
def fno_profile_instr_use : Flag<["-"], "fno-profile-instr-use">,
- Group<f_Group>, Flags<[CoreOption]>,
+ Group<f_Group>, Visibility<[ClangOption, CLOption]>,
HelpText<"Disable using instrumentation data for profile-guided optimization">;
def fno_profile_use : Flag<["-"], "fno-profile-use">,
Alias<fno_profile_instr_use>;
-defm profile_arcs : BoolFOption<"profile-arcs",
- CodeGenOpts<"EmitGcovArcs">, DefaultFalse,
- PosFlag<SetTrue, [CC1Option, LinkOption]>, NegFlag<SetFalse>>;
-defm test_coverage : BoolFOption<"test-coverage",
- CodeGenOpts<"EmitGcovNotes">, DefaultFalse,
- PosFlag<SetTrue, [CC1Option]>, NegFlag<SetFalse>>;
+def ftest_coverage : Flag<["-"], "ftest-coverage">, Group<f_Group>,
+ HelpText<"Produce gcov notes files (*.gcno)">;
+def fno_test_coverage : Flag<["-"], "fno-test-coverage">, Group<f_Group>;
+def fprofile_arcs : Flag<["-"], "fprofile-arcs">, Group<f_Group>,
+ HelpText<"Instrument code to produce gcov data files (*.gcda)">;
+def fno_profile_arcs : Flag<["-"], "fno-profile-arcs">, Group<f_Group>;
def fprofile_filter_files_EQ : Joined<["-"], "fprofile-filter-files=">,
- Group<f_Group>, Flags<[CC1Option, CoreOption]>,
+ Group<f_Group>, Visibility<[ClangOption, CC1Option, CLOption]>,
HelpText<"Instrument only functions from files where names match any regex separated by a semi-colon">,
- MarshallingInfoString<CodeGenOpts<"ProfileFilterFiles">>,
- ShouldParseIf<!strconcat(fprofile_arcs.KeyPath, "||", ftest_coverage.KeyPath)>;
+ MarshallingInfoString<CodeGenOpts<"ProfileFilterFiles">>;
def fprofile_exclude_files_EQ : Joined<["-"], "fprofile-exclude-files=">,
- Group<f_Group>, Flags<[CC1Option, CoreOption]>,
+ Group<f_Group>, Visibility<[ClangOption, CC1Option, CLOption]>,
HelpText<"Instrument only functions from files where names don't match all the regexes separated by a semi-colon">,
- MarshallingInfoString<CodeGenOpts<"ProfileExcludeFiles">>,
- ShouldParseIf<!strconcat(fprofile_arcs.KeyPath, "||", ftest_coverage.KeyPath)>;
+ MarshallingInfoString<CodeGenOpts<"ProfileExcludeFiles">>;
def fprofile_update_EQ : Joined<["-"], "fprofile-update=">,
- Group<f_Group>, Flags<[CC1Option, CoreOption]>, Values<"atomic,prefer-atomic,single">,
- MetaVarName<"<method>">, HelpText<"Set update method of profile counters (atomic,prefer-atomic,single)">,
+ Group<f_Group>, Visibility<[ClangOption, CC1Option, CLOption]>,
+ Values<"atomic,prefer-atomic,single">,
+ MetaVarName<"<method>">, HelpText<"Set update method of profile counters">,
MarshallingInfoFlag<CodeGenOpts<"AtomicProfileUpdate">>;
defm pseudo_probe_for_profiling : BoolFOption<"pseudo-probe-for-profiling",
CodeGenOpts<"PseudoProbeForProfiling">, DefaultFalse,
- PosFlag<SetTrue, [], "Emit">, NegFlag<SetFalse, [], "Do not emit">,
- BothFlags<[NoXarchOption, CC1Option], " pseudo probes for sample profiling">>;
+ PosFlag<SetTrue, [], [ClangOption], "Emit">,
+ NegFlag<SetFalse, [], [ClangOption], "Do not emit">,
+ BothFlags<[], [ClangOption, CC1Option],
+ " pseudo probes for sample profiling">>;
def forder_file_instrumentation : Flag<["-"], "forder-file-instrumentation">,
- Group<f_Group>, Flags<[CC1Option, CoreOption]>,
+ Group<f_Group>, Visibility<[ClangOption, CC1Option, CLOption]>,
HelpText<"Generate instrumented code to collect order file into default.profraw file (overridden by '=' form of option or LLVM_PROFILE_FILE env var)">;
def fprofile_list_EQ : Joined<["-"], "fprofile-list=">,
- Group<f_Group>, Flags<[CC1Option, CoreOption]>,
- HelpText<"Filename defining the list of functions/files to instrument">,
+ Group<f_Group>, Visibility<[ClangOption, CC1Option, CLOption]>,
+ HelpText<"Filename defining the list of functions/files to instrument. "
+ "The file uses the sanitizer special case list format.">,
MarshallingInfoStringVector<LangOpts<"ProfileListFiles">>;
+def fprofile_function_groups : Joined<["-"], "fprofile-function-groups=">,
+ Group<f_Group>, Visibility<[ClangOption, CC1Option]>, MetaVarName<"<N>">,
+ HelpText<"Partition functions into N groups and select only functions in group i to be instrumented using -fprofile-selected-function-group">,
+ MarshallingInfoInt<CodeGenOpts<"ProfileTotalFunctionGroups">, "1">;
+def fprofile_selected_function_group :
+ Joined<["-"], "fprofile-selected-function-group=">, Group<f_Group>,
+ Visibility<[ClangOption, CC1Option]>, MetaVarName<"<i>">,
+ HelpText<"Partition functions into N groups using -fprofile-function-groups and select only functions in group i to be instrumented. The valid range is 0 to N-1 inclusive">,
+ MarshallingInfoInt<CodeGenOpts<"ProfileSelectedFunctionGroup">>;
+def fswift_async_fp_EQ : Joined<["-"], "fswift-async-fp=">,
+ Group<f_Group>,
+ Visibility<[ClangOption, CC1Option, CC1AsOption, CLOption]>,
+ MetaVarName<"<option>">,
+ HelpText<"Control emission of Swift async extended frame info">,
+ Values<"auto,always,never">,
+ NormalizedValuesScope<"CodeGenOptions::SwiftAsyncFramePointerKind">,
+ NormalizedValues<["Auto", "Always", "Never"]>,
+ MarshallingInfoEnum<CodeGenOpts<"SwiftAsyncFramePointer">, "Always">;
+defm apinotes : BoolOption<"f", "apinotes",
+ LangOpts<"APINotes">, DefaultFalse,
+ PosFlag<SetTrue, [], [ClangOption], "Enable">,
+ NegFlag<SetFalse, [], [ClangOption], "Disable">,
+ BothFlags<[], [ClangOption, CC1Option], "external API notes support">>,
+ Group<f_clang_Group>;
+defm apinotes_modules : BoolOption<"f", "apinotes-modules",
+ LangOpts<"APINotesModules">, DefaultFalse,
+ PosFlag<SetTrue, [], [ClangOption], "Enable">,
+ NegFlag<SetFalse, [], [ClangOption], "Disable">,
+ BothFlags<[], [ClangOption, CC1Option], "module-based external API notes support">>,
+ Group<f_clang_Group>;
+def fapinotes_swift_version : Joined<["-"], "fapinotes-swift-version=">,
+ Group<f_clang_Group>, Visibility<[ClangOption, CC1Option]>,
+ MetaVarName<"<version>">,
+ HelpText<"Specify the Swift version to use when filtering API notes">;
defm addrsig : BoolFOption<"addrsig",
CodeGenOpts<"Addrsig">, DefaultFalse,
- PosFlag<SetTrue, [CC1Option], "Emit">, NegFlag<SetFalse, [], "Don't emit">,
- BothFlags<[CoreOption], " an address-significance table">>;
-defm blocks : OptInFFlag<"blocks", "Enable the 'blocks' language feature", "", "", [CoreOption]>;
+ PosFlag<SetTrue, [], [ClangOption, CC1Option], "Emit">,
+ NegFlag<SetFalse, [], [ClangOption], "Don't emit">,
+ BothFlags<[], [ClangOption, CLOption],
+ " an address-significance table">>;
+defm blocks : OptInCC1FFlag<"blocks", "Enable the 'blocks' language feature",
+ "", "", [ClangOption, CLOption]>;
def fbootclasspath_EQ : Joined<["-"], "fbootclasspath=">, Group<f_Group>;
defm borland_extensions : BoolFOption<"borland-extensions",
LangOpts<"Borland">, DefaultFalse,
- PosFlag<SetTrue, [CC1Option], "Accept non-standard constructs supported by the Borland compiler">,
+ PosFlag<SetTrue, [], [ClangOption, CC1Option],
+ "Accept non-standard constructs supported by the Borland compiler">,
NegFlag<SetFalse>>;
-def fbuiltin : Flag<["-"], "fbuiltin">, Group<f_Group>, Flags<[CoreOption]>;
+def fbuiltin : Flag<["-"], "fbuiltin">, Group<f_Group>,
+ Visibility<[ClangOption, CLOption, DXCOption]>;
def fbuiltin_module_map : Flag <["-"], "fbuiltin-module-map">, Group<f_Group>,
- Flags<[NoXarchOption]>, HelpText<"Load the clang builtins module map file.">;
+ Flags<[]>, HelpText<"Load the clang builtins module map file.">;
defm caret_diagnostics : BoolFOption<"caret-diagnostics",
DiagnosticOpts<"ShowCarets">, DefaultTrue,
- NegFlag<SetFalse, [CC1Option]>, PosFlag<SetTrue>>;
+ NegFlag<SetFalse, [], [ClangOption, CC1Option]>,
+ PosFlag<SetTrue>>;
def fclang_abi_compat_EQ : Joined<["-"], "fclang-abi-compat=">, Group<f_clang_Group>,
- Flags<[CC1Option]>, MetaVarName<"<version>">, Values<"<major>.<minor>,latest">,
+ Visibility<[ClangOption, CC1Option]>,
+ MetaVarName<"<version>">, Values<"<major>.<minor>,latest">,
HelpText<"Attempt to match the ABI of Clang <version>">;
def fclasspath_EQ : Joined<["-"], "fclasspath=">, Group<f_Group>;
-defm color_diagnostics : OptInFFlag<"color-diagnostics", "Enable", "Disable", " colors in diagnostics",
- [CoreOption, FlangOption]>;
-def fdiagnostics_color : Flag<["-"], "fdiagnostics-color">, Group<f_Group>,
- Flags<[CoreOption, NoXarchOption]>;
+def fcolor_diagnostics : Flag<["-"], "fcolor-diagnostics">, Group<f_Group>,
+
+ Visibility<[ClangOption, CLOption, DXCOption, CC1Option, FlangOption, FC1Option]>,
+ HelpText<"Enable colors in diagnostics">;
+def fno_color_diagnostics : Flag<["-"], "fno-color-diagnostics">, Group<f_Group>,
+ Visibility<[ClangOption, CLOption, DXCOption, FlangOption]>,
+ HelpText<"Disable colors in diagnostics">;
+def : Flag<["-"], "fdiagnostics-color">, Group<f_Group>,
+ Visibility<[ClangOption, CLOption, DXCOption]>, Alias<fcolor_diagnostics>;
+def : Flag<["-"], "fno-diagnostics-color">, Group<f_Group>,
+ Visibility<[ClangOption, CLOption, DXCOption]>, Alias<fno_color_diagnostics>;
def fdiagnostics_color_EQ : Joined<["-"], "fdiagnostics-color=">, Group<f_Group>;
def fansi_escape_codes : Flag<["-"], "fansi-escape-codes">, Group<f_Group>,
- Flags<[CoreOption, CC1Option]>, HelpText<"Use ANSI escape codes for diagnostics">,
+ Visibility<[ClangOption, CLOption, DXCOption, CC1Option]>,
+ HelpText<"Use ANSI escape codes for diagnostics">,
MarshallingInfoFlag<DiagnosticOpts<"UseANSIEscapeCodes">>;
-def fcomment_block_commands : CommaJoined<["-"], "fcomment-block-commands=">, Group<f_clang_Group>, Flags<[CC1Option]>,
+def fcomment_block_commands : CommaJoined<["-"], "fcomment-block-commands=">, Group<f_clang_Group>,
+ Visibility<[ClangOption, CC1Option]>,
HelpText<"Treat each comma separated argument in <arg> as a documentation comment block command">,
MetaVarName<"<arg>">, MarshallingInfoStringVector<LangOpts<"CommentOpts.BlockCommandNames">>;
-def fparse_all_comments : Flag<["-"], "fparse-all-comments">, Group<f_clang_Group>, Flags<[CC1Option]>,
+defm define_target_os_macros : OptInCC1FFlag<"define-target-os-macros",
+ "Enable", "Disable", " predefined target OS macros",
+ [ClangOption, CC1Option]>;
+def fparse_all_comments : Flag<["-"], "fparse-all-comments">, Group<f_clang_Group>,
+ Visibility<[ClangOption, CC1Option]>,
MarshallingInfoFlag<LangOpts<"CommentOpts.ParseAllComments">>;
def frecord_command_line : Flag<["-"], "frecord-command-line">,
+ DocBrief<[{Generate a section named ".GCC.command.line" containing the clang
+driver command-line. After linking, the section may contain multiple command
+lines, which will be individually terminated by null bytes. Separate arguments
+within a command line are combined with spaces; spaces and backslashes within an
+argument are escaped with backslashes. This format differs from the format of
+the equivalent section produced by GCC with the -frecord-gcc-switches flag.
+This option is currently only supported on ELF targets.}]>,
Group<f_clang_Group>;
def fno_record_command_line : Flag<["-"], "fno-record-command-line">,
Group<f_clang_Group>;
def : Flag<["-"], "frecord-gcc-switches">, Alias<frecord_command_line>;
def : Flag<["-"], "fno-record-gcc-switches">, Alias<fno_record_command_line>;
def fcommon : Flag<["-"], "fcommon">, Group<f_Group>,
- Flags<[CoreOption, CC1Option]>, HelpText<"Place uninitialized global variables in a common block">,
- MarshallingInfoNegativeFlag<CodeGenOpts<"NoCommon">>;
+ Visibility<[ClangOption, CLOption, CC1Option]>,
+ HelpText<"Place uninitialized global variables in a common block">,
+ MarshallingInfoNegativeFlag<CodeGenOpts<"NoCommon">>,
+ DocBrief<[{Place definitions of variables with no storage class and no initializer
+(tentative definitions) in a common block, instead of generating individual
+zero-initialized definitions (default -fno-common).}]>;
def fcompile_resource_EQ : Joined<["-"], "fcompile-resource=">, Group<f_Group>;
defm complete_member_pointers : BoolOption<"f", "complete-member-pointers",
LangOpts<"CompleteMemberPointers">, DefaultFalse,
- PosFlag<SetTrue, [CC1Option], "Require">, NegFlag<SetFalse, [], "Do not require">,
- BothFlags<[CoreOption], " member pointer base types to be complete if they"
+ PosFlag<SetTrue, [], [ClangOption, CC1Option], "Require">,
+ NegFlag<SetFalse, [], [ClangOption], "Do not require">,
+ BothFlags<[], [ClangOption, CLOption],
+ " member pointer base types to be complete if they"
" would be significant under the Microsoft ABI">>,
Group<f_clang_Group>;
def fcf_runtime_abi_EQ : Joined<["-"], "fcf-runtime-abi=">, Group<f_Group>,
- Flags<[CC1Option]>, Values<"unspecified,standalone,objc,swift,swift-5.0,swift-4.2,swift-4.1">,
+ Visibility<[ClangOption, CC1Option]>,
+ Values<"unspecified,standalone,objc,swift,swift-5.0,swift-4.2,swift-4.1">,
NormalizedValuesScope<"LangOptions::CoreFoundationABI">,
NormalizedValues<["ObjectiveC", "ObjectiveC", "ObjectiveC", "Swift5_0", "Swift5_0", "Swift4_2", "Swift4_1"]>,
MarshallingInfoEnum<LangOpts<"CFRuntime">, "ObjectiveC">;
defm constant_cfstrings : BoolFOption<"constant-cfstrings",
LangOpts<"NoConstantCFStrings">, DefaultFalse,
- NegFlag<SetTrue, [CC1Option], "Disable creation of CodeFoundation-type constant strings">,
+ NegFlag<SetTrue, [], [ClangOption, CC1Option],
+ "Disable creation of CodeFoundation-type constant strings">,
PosFlag<SetFalse>>;
def fconstant_string_class_EQ : Joined<["-"], "fconstant-string-class=">, Group<f_Group>;
-def fconstexpr_depth_EQ : Joined<["-"], "fconstexpr-depth=">, Group<f_Group>;
-def fconstexpr_steps_EQ : Joined<["-"], "fconstexpr-steps=">, Group<f_Group>;
+def fconstexpr_depth_EQ : Joined<["-"], "fconstexpr-depth=">, Group<f_Group>,
+ Visibility<[ClangOption, CC1Option]>,
+ HelpText<"Set the maximum depth of recursive constexpr function calls">,
+ MarshallingInfoInt<LangOpts<"ConstexprCallDepth">, "512">;
+def fconstexpr_steps_EQ : Joined<["-"], "fconstexpr-steps=">, Group<f_Group>,
+ Visibility<[ClangOption, CC1Option]>,
+ HelpText<"Set the maximum number of steps in constexpr function evaluation">,
+ MarshallingInfoInt<LangOpts<"ConstexprStepLimit">, "1048576">;
def fexperimental_new_constant_interpreter : Flag<["-"], "fexperimental-new-constant-interpreter">, Group<f_Group>,
- HelpText<"Enable the experimental new constant interpreter">, Flags<[CC1Option]>,
+ HelpText<"Enable the experimental new constant interpreter">,
+ Visibility<[ClangOption, CC1Option]>,
MarshallingInfoFlag<LangOpts<"EnableNewConstInterp">>;
-def fconstexpr_backtrace_limit_EQ : Joined<["-"], "fconstexpr-backtrace-limit=">,
- Group<f_Group>;
-def fno_crash_diagnostics : Flag<["-"], "fno-crash-diagnostics">, Group<f_clang_Group>, Flags<[NoArgumentUnused, CoreOption]>,
+def fconstexpr_backtrace_limit_EQ : Joined<["-"], "fconstexpr-backtrace-limit=">, Group<f_Group>,
+ Visibility<[ClangOption, CC1Option]>,
+ HelpText<"Set the maximum number of entries to print in a constexpr evaluation backtrace (0 = no limit)">,
+ MarshallingInfoInt<DiagnosticOpts<"ConstexprBacktraceLimit">, "DiagnosticOptions::DefaultConstexprBacktraceLimit">;
+def fcrash_diagnostics_EQ : Joined<["-"], "fcrash-diagnostics=">, Group<f_clang_Group>,
+ Flags<[NoArgumentUnused]>, Visibility<[ClangOption, CLOption, DXCOption]>,
+ HelpText<"Set level of crash diagnostic reporting, (option: off, compiler, all)">;
+def fcrash_diagnostics : Flag<["-"], "fcrash-diagnostics">, Group<f_clang_Group>,
+ Flags<[NoArgumentUnused]>, Visibility<[ClangOption, CLOption, DXCOption]>,
+ HelpText<"Enable crash diagnostic reporting (default)">, Alias<fcrash_diagnostics_EQ>, AliasArgs<["compiler"]>;
+def fno_crash_diagnostics : Flag<["-"], "fno-crash-diagnostics">, Group<f_clang_Group>,
+ Flags<[NoArgumentUnused]>, Visibility<[ClangOption, CLOption, DXCOption]>,
+ Alias<gen_reproducer_eq>, AliasArgs<["off"]>,
HelpText<"Disable auto-generation of preprocessed source files and a script for reproduction during a clang crash">;
def fcrash_diagnostics_dir : Joined<["-"], "fcrash-diagnostics-dir=">,
- Group<f_clang_Group>, Flags<[NoArgumentUnused, CoreOption]>,
+ Group<f_clang_Group>, Flags<[NoArgumentUnused]>,
+ Visibility<[ClangOption, CLOption, DXCOption]>,
HelpText<"Put crash-report files in <dir>">, MetaVarName<"<dir>">;
def fcreate_profile : Flag<["-"], "fcreate-profile">, Group<f_Group>;
defm cxx_exceptions: BoolFOption<"cxx-exceptions",
LangOpts<"CXXExceptions">, DefaultFalse,
- PosFlag<SetTrue, [CC1Option], "Enable C++ exceptions">, NegFlag<SetFalse>>;
+ PosFlag<SetTrue, [], [ClangOption, CC1Option], "Enable C++ exceptions">,
+ NegFlag<SetFalse>>;
defm async_exceptions: BoolFOption<"async-exceptions",
LangOpts<"EHAsynch">, DefaultFalse,
- PosFlag<SetTrue, [CC1Option], "Enable EH Asynchronous exceptions">, NegFlag<SetFalse>>;
-def fcxx_modules : Flag <["-"], "fcxx-modules">, Group<f_Group>,
- Flags<[NoXarchOption]>;
+ PosFlag<SetTrue, [], [ClangOption, CC1Option],
+ "Enable EH Asynchronous exceptions">,
+ NegFlag<SetFalse>>;
+defm cxx_modules : BoolFOption<"cxx-modules",
+ LangOpts<"CPlusPlusModules">, Default<cpp20.KeyPath>,
+ NegFlag<SetFalse, [], [ClangOption, CC1Option], "Disable">,
+ PosFlag<SetTrue, [], [ClangOption], "Enable">,
+ BothFlags<[], [], " modules for C++">>,
+ ShouldParseIf<cplusplus.KeyPath>;
def fdebug_pass_arguments : Flag<["-"], "fdebug-pass-arguments">, Group<f_Group>;
def fdebug_pass_structure : Flag<["-"], "fdebug-pass-structure">, Group<f_Group>;
def fdepfile_entry : Joined<["-"], "fdepfile-entry=">,
- Group<f_clang_Group>, Flags<[CC1Option]>;
+ Group<f_clang_Group>, Visibility<[ClangOption, CC1Option]>;
def fdiagnostics_fixit_info : Flag<["-"], "fdiagnostics-fixit-info">, Group<f_clang_Group>;
def fno_diagnostics_fixit_info : Flag<["-"], "fno-diagnostics-fixit-info">, Group<f_Group>,
- Flags<[CC1Option]>, HelpText<"Do not include fixit information in diagnostics">,
+ Visibility<[ClangOption, CC1Option]>,
+ HelpText<"Do not include fixit information in diagnostics">,
MarshallingInfoNegativeFlag<DiagnosticOpts<"ShowFixits">>;
def fdiagnostics_parseable_fixits : Flag<["-"], "fdiagnostics-parseable-fixits">, Group<f_clang_Group>,
- Flags<[CoreOption, CC1Option]>, HelpText<"Print fix-its in machine parseable form">,
+ Visibility<[ClangOption, CLOption, DXCOption, CC1Option]>,
+ HelpText<"Print fix-its in machine parseable form">,
MarshallingInfoFlag<DiagnosticOpts<"ShowParseableFixits">>;
def fdiagnostics_print_source_range_info : Flag<["-"], "fdiagnostics-print-source-range-info">,
- Group<f_clang_Group>, Flags<[CC1Option]>,
+ Group<f_clang_Group>, Visibility<[ClangOption, CC1Option]>,
HelpText<"Print source range spans in numeric form">,
MarshallingInfoFlag<DiagnosticOpts<"ShowSourceRanges">>;
defm diagnostics_show_hotness : BoolFOption<"diagnostics-show-hotness",
CodeGenOpts<"DiagnosticsWithHotness">, DefaultFalse,
- PosFlag<SetTrue, [CC1Option], "Enable profile hotness information in diagnostic line">,
+ PosFlag<SetTrue, [], [ClangOption, CC1Option],
+ "Enable profile hotness information in diagnostic line">,
NegFlag<SetFalse>>;
def fdiagnostics_hotness_threshold_EQ : Joined<["-"], "fdiagnostics-hotness-threshold=">,
- Group<f_Group>, Flags<[CC1Option]>, MetaVarName<"<value>">,
+ Group<f_Group>, Visibility<[ClangOption, CC1Option]>,
+ MetaVarName<"<value>">,
HelpText<"Prevent optimization remarks from being output if they do not have at least this profile count. "
"Use 'auto' to apply the threshold from profile summary">;
+def fdiagnostics_misexpect_tolerance_EQ : Joined<["-"], "fdiagnostics-misexpect-tolerance=">,
+ Group<f_Group>, Visibility<[ClangOption, CC1Option]>,
+ MetaVarName<"<value>">,
+ HelpText<"Prevent misexpect diagnostics from being output if the profile counts are within N% of the expected. ">;
defm diagnostics_show_option : BoolFOption<"diagnostics-show-option",
DiagnosticOpts<"ShowOptionNames">, DefaultTrue,
- NegFlag<SetFalse, [CC1Option]>, PosFlag<SetTrue, [], "Print option name with mappable diagnostics">>;
+ NegFlag<SetFalse, [], [ClangOption, CC1Option]>,
+ PosFlag<SetTrue, [], [ClangOption], "Print option name with mappable diagnostics">>;
defm diagnostics_show_note_include_stack : BoolFOption<"diagnostics-show-note-include-stack",
DiagnosticOpts<"ShowNoteIncludeStack">, DefaultFalse,
- PosFlag<SetTrue, [], "Display include stacks for diagnostic notes">,
- NegFlag<SetFalse>, BothFlags<[CC1Option]>>;
+ PosFlag<SetTrue, [], [ClangOption], "Display include stacks for diagnostic notes">,
+ NegFlag<SetFalse>, BothFlags<[], [ClangOption, CC1Option]>>;
def fdiagnostics_format_EQ : Joined<["-"], "fdiagnostics-format=">, Group<f_clang_Group>;
def fdiagnostics_show_category_EQ : Joined<["-"], "fdiagnostics-show-category=">, Group<f_clang_Group>;
def fdiagnostics_show_template_tree : Flag<["-"], "fdiagnostics-show-template-tree">,
- Group<f_Group>, Flags<[CC1Option]>,
+ Group<f_Group>, Visibility<[ClangOption, CC1Option]>,
HelpText<"Print a template comparison tree for differing templates">,
MarshallingInfoFlag<DiagnosticOpts<"ShowTemplateTree">>;
-def fdiscard_value_names : Flag<["-"], "fdiscard-value-names">, Group<f_clang_Group>,
- HelpText<"Discard value names in LLVM IR">, Flags<[NoXarchOption]>;
-def fno_discard_value_names : Flag<["-"], "fno-discard-value-names">, Group<f_clang_Group>,
- HelpText<"Do not discard value names in LLVM IR">, Flags<[NoXarchOption]>;
+defm safe_buffer_usage_suggestions : BoolFOption<"safe-buffer-usage-suggestions",
+ DiagnosticOpts<"ShowSafeBufferUsageSuggestions">, DefaultFalse,
+ PosFlag<SetTrue, [], [ClangOption, CC1Option],
+ "Display suggestions to update code associated with -Wunsafe-buffer-usage warnings">,
+ NegFlag<SetFalse>>;
+def fverify_intermediate_code : Flag<["-"], "fverify-intermediate-code">,
+ Group<f_clang_Group>, Visibility<[ClangOption, CLOption, DXCOption]>,
+ HelpText<"Enable verification of LLVM IR">;
+def fno_verify_intermediate_code : Flag<["-"], "fno-verify-intermediate-code">,
+ Group<f_clang_Group>, Visibility<[ClangOption, CLOption, DXCOption]>,
+ HelpText<"Disable verification of LLVM IR">;
+def fdiscard_value_names : Flag<["-"], "fdiscard-value-names">,
+ Group<f_clang_Group>, Visibility<[ClangOption, DXCOption]>,
+ HelpText<"Discard value names in LLVM IR">;
+def fno_discard_value_names : Flag<["-"], "fno-discard-value-names">,
+ Group<f_clang_Group>, Visibility<[ClangOption, DXCOption]>,
+ HelpText<"Do not discard value names in LLVM IR">;
defm dollars_in_identifiers : BoolFOption<"dollars-in-identifiers",
LangOpts<"DollarIdents">, Default<!strconcat("!", asm_preprocessor.KeyPath)>,
- PosFlag<SetTrue, [], "Allow">, NegFlag<SetFalse, [], "Disallow">,
- BothFlags<[CC1Option], " '$' in identifiers">>;
+ PosFlag<SetTrue, [], [ClangOption], "Allow">,
+ NegFlag<SetFalse, [], [ClangOption], "Disallow">,
+ BothFlags<[], [ClangOption, CC1Option], " '$' in identifiers">>;
def fdwarf2_cfi_asm : Flag<["-"], "fdwarf2-cfi-asm">, Group<clang_ignored_f_Group>;
def fno_dwarf2_cfi_asm : Flag<["-"], "fno-dwarf2-cfi-asm">, Group<clang_ignored_f_Group>;
defm dwarf_directory_asm : BoolFOption<"dwarf-directory-asm",
CodeGenOpts<"NoDwarfDirectoryAsm">, DefaultFalse,
- NegFlag<SetTrue, [CC1Option]>, PosFlag<SetFalse>>;
+ NegFlag<SetTrue, [], [ClangOption, CC1Option]>,
+ PosFlag<SetFalse>>;
defm elide_constructors : BoolFOption<"elide-constructors",
LangOpts<"ElideConstructors">, DefaultTrue,
- NegFlag<SetFalse, [CC1Option], "Disable C++ copy constructor elision">,
+ NegFlag<SetFalse, [], [ClangOption, CC1Option],
+ "Disable C++ copy constructor elision">,
PosFlag<SetTrue>>;
def fno_elide_type : Flag<["-"], "fno-elide-type">, Group<f_Group>,
- Flags<[CC1Option]>,
+ Visibility<[ClangOption, CC1Option]>,
HelpText<"Do not elide types when printing diagnostics">,
MarshallingInfoNegativeFlag<DiagnosticOpts<"ElideType">>;
def feliminate_unused_debug_symbols : Flag<["-"], "feliminate-unused-debug-symbols">, Group<f_Group>;
-defm eliminate_unused_debug_types : OptOutFFlag<"eliminate-unused-debug-types",
+defm eliminate_unused_debug_types : OptOutCC1FFlag<"eliminate-unused-debug-types",
"Do not emit ", "Emit ", " debug info for defined but unused types">;
-def femit_all_decls : Flag<["-"], "femit-all-decls">, Group<f_Group>, Flags<[CC1Option]>,
+def femit_all_decls : Flag<["-"], "femit-all-decls">, Group<f_Group>,
+ Visibility<[ClangOption, CC1Option]>,
HelpText<"Emit all declarations, even if unused">,
MarshallingInfoFlag<LangOpts<"EmitAllDecls">>;
defm emulated_tls : BoolFOption<"emulated-tls",
CodeGenOpts<"EmulatedTLS">, DefaultFalse,
- PosFlag<SetTrue, [CC1Option], "Use emutls functions to access thread_local variables">,
- NegFlag<SetFalse>, BothFlags<[CC1Option]>>;
+ PosFlag<SetTrue, [], [ClangOption, CC1Option],
+ "Use emutls functions to access thread_local variables">,
+ NegFlag<SetFalse>>;
def fencoding_EQ : Joined<["-"], "fencoding=">, Group<f_Group>;
-def ferror_limit_EQ : Joined<["-"], "ferror-limit=">, Group<f_Group>, Flags<[CoreOption]>;
+def ferror_limit_EQ : Joined<["-"], "ferror-limit=">, Group<f_Group>,
+ Visibility<[ClangOption, CLOption, DXCOption]>;
defm exceptions : BoolFOption<"exceptions",
LangOpts<"Exceptions">, DefaultFalse,
- PosFlag<SetTrue, [CC1Option], "Enable">, NegFlag<SetFalse, [], "Disable">,
- BothFlags<[], " support for exception handling">>;
+ PosFlag<SetTrue, [], [ClangOption, CC1Option], "Enable">,
+ NegFlag<SetFalse, [], [ClangOption], "Disable">,
+ BothFlags<[], [ClangOption], " support for exception handling">>;
def fdwarf_exceptions : Flag<["-"], "fdwarf-exceptions">, Group<f_Group>,
HelpText<"Use DWARF style exceptions">;
def fsjlj_exceptions : Flag<["-"], "fsjlj-exceptions">, Group<f_Group>,
@@ -1413,97 +2054,160 @@ def fseh_exceptions : Flag<["-"], "fseh-exceptions">, Group<f_Group>,
def fwasm_exceptions : Flag<["-"], "fwasm-exceptions">, Group<f_Group>,
HelpText<"Use WebAssembly style exceptions">;
def exception_model : Separate<["-"], "exception-model">,
- Flags<[CC1Option, NoDriverOption]>, HelpText<"The exception model: dwarf|sjlj|seh|wasm">,
+ Visibility<[CC1Option]>, HelpText<"The exception model">,
Values<"dwarf,sjlj,seh,wasm">,
NormalizedValuesScope<"LangOptions::ExceptionHandlingKind">,
NormalizedValues<["DwarfCFI", "SjLj", "WinEH", "Wasm"]>,
MarshallingInfoEnum<LangOpts<"ExceptionHandling">, "None">;
def exception_model_EQ : Joined<["-"], "exception-model=">,
- Flags<[CC1Option, NoDriverOption]>, Alias<exception_model>;
-def fignore_exceptions : Flag<["-"], "fignore-exceptions">, Group<f_Group>, Flags<[CC1Option]>,
+ Visibility<[CC1Option]>, Alias<exception_model>;
+def fignore_exceptions : Flag<["-"], "fignore-exceptions">, Group<f_Group>,
+ Visibility<[ClangOption, CC1Option]>,
HelpText<"Enable support for ignoring exception handling constructs">,
MarshallingInfoFlag<LangOpts<"IgnoreExceptions">>;
-def fexcess_precision_EQ : Joined<["-"], "fexcess-precision=">,
- Group<clang_ignored_gcc_optimization_f_Group>;
+defm assume_nothrow_exception_dtor: BoolFOption<"assume-nothrow-exception-dtor",
+ LangOpts<"AssumeNothrowExceptionDtor">, DefaultFalse,
+ PosFlag<SetTrue, [], [ClangOption, CC1Option], "Assume that exception objects' destructors are non-throwing">,
+ NegFlag<SetFalse>>;
+def fexcess_precision_EQ : Joined<["-"], "fexcess-precision=">, Group<f_Group>,
+ Visibility<[ClangOption, CLOption]>,
+ HelpText<"Allows control over excess precision on targets where native "
+ "support for the precision types is not available. By default, excess "
+ "precision is used to calculate intermediate results following the "
+ "rules specified in ISO C99.">,
+ Values<"standard,fast,none">, NormalizedValuesScope<"LangOptions">,
+ NormalizedValues<["FPP_Standard", "FPP_Fast", "FPP_None"]>;
+def ffloat16_excess_precision_EQ : Joined<["-"], "ffloat16-excess-precision=">,
+ Group<f_Group>, Visibility<[CC1Option]>,
+ HelpText<"Allows control over excess precision on targets where native "
+ "support for Float16 precision types is not available. By default, excess "
+ "precision is used to calculate intermediate results following the "
+ "rules specified in ISO C99.">,
+ Values<"standard,fast,none">, NormalizedValuesScope<"LangOptions">,
+ NormalizedValues<["FPP_Standard", "FPP_Fast", "FPP_None"]>,
+ MarshallingInfoEnum<LangOpts<"Float16ExcessPrecision">, "FPP_Standard">;
+def fbfloat16_excess_precision_EQ : Joined<["-"], "fbfloat16-excess-precision=">,
+ Group<f_Group>, Visibility<[CC1Option]>,
+ HelpText<"Allows control over excess precision on targets where native "
+ "support for BFloat16 precision types is not available. By default, excess "
+ "precision is used to calculate intermediate results following the "
+ "rules specified in ISO C99.">,
+ Values<"standard,fast,none">, NormalizedValuesScope<"LangOptions">,
+ NormalizedValues<["FPP_Standard", "FPP_Fast", "FPP_None"]>,
+ MarshallingInfoEnum<LangOpts<"BFloat16ExcessPrecision">, "FPP_Standard">;
def : Flag<["-"], "fexpensive-optimizations">, Group<clang_ignored_gcc_optimization_f_Group>;
def : Flag<["-"], "fno-expensive-optimizations">, Group<clang_ignored_gcc_optimization_f_Group>;
def fextdirs_EQ : Joined<["-"], "fextdirs=">, Group<f_Group>;
def : Flag<["-"], "fdefer-pop">, Group<clang_ignored_gcc_optimization_f_Group>;
def : Flag<["-"], "fno-defer-pop">, Group<clang_ignored_gcc_optimization_f_Group>;
def : Flag<["-"], "fextended-identifiers">, Group<clang_ignored_f_Group>;
-def : Flag<["-"], "fno-extended-identifiers">, Group<f_Group>, Flags<[Unsupported]>;
+def : Flag<["-"], "fno-extended-identifiers">, Group<f_Group>,
+ Flags<[Unsupported]>;
def fhosted : Flag<["-"], "fhosted">, Group<f_Group>;
-def fdenormal_fp_math_EQ : Joined<["-"], "fdenormal-fp-math=">, Group<f_Group>, Flags<[CC1Option]>;
-def ffp_model_EQ : Joined<["-"], "ffp-model=">, Group<f_Group>, Flags<[NoXarchOption]>,
+def fdenormal_fp_math_EQ : Joined<["-"], "fdenormal-fp-math=">, Group<f_Group>,
+ Visibility<[ClangOption, CC1Option]>;
+def ffile_reproducible : Flag<["-"], "ffile-reproducible">, Group<f_Group>,
+ Visibility<[ClangOption, CLOption, CC1Option]>,
+ HelpText<"Use the target's platform-specific path separator character when "
+ "expanding the __FILE__ macro">;
+def fno_file_reproducible : Flag<["-"], "fno-file-reproducible">,
+ Group<f_Group>, Visibility<[ClangOption, CLOption, CC1Option]>,
+ HelpText<"Use the host's platform-specific path separator character when "
+ "expanding the __FILE__ macro">;
+def ffp_eval_method_EQ : Joined<["-"], "ffp-eval-method=">, Group<f_Group>,
+ Visibility<[ClangOption, CC1Option]>,
+ HelpText<"Specifies the evaluation method to use for floating-point arithmetic.">,
+ Values<"source,double,extended">, NormalizedValuesScope<"LangOptions">,
+ NormalizedValues<["FEM_Source", "FEM_Double", "FEM_Extended"]>,
+ MarshallingInfoEnum<LangOpts<"FPEvalMethod">, "FEM_UnsetOnCommandLine">;
+def ffp_model_EQ : Joined<["-"], "ffp-model=">, Group<f_Group>,
HelpText<"Controls the semantics of floating-point calculations.">;
-def ffp_exception_behavior_EQ : Joined<["-"], "ffp-exception-behavior=">, Group<f_Group>, Flags<[CC1Option]>,
+def ffp_exception_behavior_EQ : Joined<["-"], "ffp-exception-behavior=">, Group<f_Group>,
+ Visibility<[ClangOption, CC1Option]>,
HelpText<"Specifies the exception behavior of floating-point operations.">,
Values<"ignore,maytrap,strict">, NormalizedValuesScope<"LangOptions">,
NormalizedValues<["FPE_Ignore", "FPE_MayTrap", "FPE_Strict"]>,
- MarshallingInfoEnum<LangOpts<"FPExceptionMode">, "FPE_Ignore">;
+ MarshallingInfoEnum<LangOpts<"FPExceptionMode">, "FPE_Default">;
defm fast_math : BoolFOption<"fast-math",
LangOpts<"FastMath">, DefaultFalse,
- PosFlag<SetTrue, [CC1Option], "Allow aggressive, lossy floating-point optimizations",
+ PosFlag<SetTrue, [], [ClangOption, CC1Option, FC1Option, FlangOption],
+ "Allow aggressive, lossy floating-point optimizations",
[cl_fast_relaxed_math.KeyPath]>,
- NegFlag<SetFalse>>;
-def menable_unsafe_fp_math : Flag<["-"], "menable-unsafe-fp-math">, Flags<[CC1Option]>,
- HelpText<"Allow unsafe floating-point math optimizations which may decrease precision">,
- MarshallingInfoFlag<LangOpts<"UnsafeFPMath">>,
- ImpliedByAnyOf<[cl_unsafe_math_optimizations.KeyPath, ffast_math.KeyPath]>;
+ NegFlag<SetFalse, [], [ClangOption, CC1Option, FC1Option, FlangOption]>>;
defm math_errno : BoolFOption<"math-errno",
LangOpts<"MathErrno">, DefaultFalse,
- PosFlag<SetTrue, [CC1Option], "Require math functions to indicate errors by setting errno">,
+ PosFlag<SetTrue, [], [ClangOption, CC1Option],
+ "Require math functions to indicate errors by setting errno">,
NegFlag<SetFalse>>,
ShouldParseIf<!strconcat("!", open_cl.KeyPath)>;
def fextend_args_EQ : Joined<["-"], "fextend-arguments=">, Group<f_Group>,
- Flags<[CC1Option, NoArgumentUnused]>,
+ Flags<[NoArgumentUnused]>, Visibility<[ClangOption, CC1Option]>,
HelpText<"Controls how scalar integer arguments are extended in calls "
"to unprototyped and varargs functions">,
Values<"32,64">,
NormalizedValues<["ExtendTo32", "ExtendTo64"]>,
NormalizedValuesScope<"LangOptions::ExtendArgsKind">,
MarshallingInfoEnum<LangOpts<"ExtendIntArgs">,"ExtendTo32">;
-def fbracket_depth_EQ : Joined<["-"], "fbracket-depth=">, Group<f_Group>, Flags<[CoreOption]>;
+def fbracket_depth_EQ : Joined<["-"], "fbracket-depth=">, Group<f_Group>,
+ Visibility<[ClangOption, CLOption]>;
def fsignaling_math : Flag<["-"], "fsignaling-math">, Group<f_Group>;
def fno_signaling_math : Flag<["-"], "fno-signaling-math">, Group<f_Group>;
defm jump_tables : BoolFOption<"jump-tables",
CodeGenOpts<"NoUseJumpTables">, DefaultFalse,
- NegFlag<SetTrue, [CC1Option], "Do not use">, PosFlag<SetFalse, [], "Use">,
- BothFlags<[], " jump tables for lowering switches">>;
+ NegFlag<SetTrue, [], [ClangOption, CC1Option], "Do not use">,
+ PosFlag<SetFalse, [], [ClangOption], "Use">,
+ BothFlags<[], [ClangOption], " jump tables for lowering switches">>;
defm force_enable_int128 : BoolFOption<"force-enable-int128",
TargetOpts<"ForceEnableInt128">, DefaultFalse,
- PosFlag<SetTrue, [CC1Option], "Enable">, NegFlag<SetFalse, [], "Disable">,
- BothFlags<[], " support for int128_t type">>;
+ PosFlag<SetTrue, [], [ClangOption, CC1Option], "Enable">,
+ NegFlag<SetFalse, [], [ClangOption], "Disable">,
+ BothFlags<[], [ClangOption], " support for int128_t type">>;
defm keep_static_consts : BoolFOption<"keep-static-consts",
CodeGenOpts<"KeepStaticConsts">, DefaultFalse,
- PosFlag<SetTrue, [CC1Option], "Keep">, NegFlag<SetFalse, [], "Don't keep">,
- BothFlags<[NoXarchOption], " static const variables if unused">>;
+ PosFlag<SetTrue, [], [ClangOption, CC1Option], "Keep">,
+ NegFlag<SetFalse, [], [ClangOption], "Don't keep">,
+ BothFlags<[], [], " static const variables even if unused">>;
+defm keep_persistent_storage_variables : BoolFOption<"keep-persistent-storage-variables",
+ CodeGenOpts<"KeepPersistentStorageVariables">, DefaultFalse,
+ PosFlag<SetTrue, [], [ClangOption, CC1Option], "Enable">,
+ NegFlag<SetFalse, [], [ClangOption], "Disable">,
+ BothFlags<[], [],
+ " keeping all variables that have a persistent storage duration, including global, static and thread-local variables, to guarantee that they can be directly addressed">>;
defm fixed_point : BoolFOption<"fixed-point",
LangOpts<"FixedPoint">, DefaultFalse,
- PosFlag<SetTrue, [CC1Option], "Enable">, NegFlag<SetFalse, [], "Disable">,
- BothFlags<[], " fixed point types">>, ShouldParseIf<!strconcat("!", cplusplus.KeyPath)>;
+ PosFlag<SetTrue, [], [ClangOption, CC1Option], "Enable">,
+ NegFlag<SetFalse, [], [ClangOption], "Disable">,
+ BothFlags<[], [ClangOption], " fixed point types">>;
defm cxx_static_destructors : BoolFOption<"c++-static-destructors",
LangOpts<"RegisterStaticDestructors">, DefaultTrue,
- NegFlag<SetFalse, [CC1Option], "Disable C++ static destructor registration">,
+ NegFlag<SetFalse, [], [ClangOption, CC1Option],
+ "Disable C++ static destructor registration">,
PosFlag<SetTrue>>;
def fsymbol_partition_EQ : Joined<["-"], "fsymbol-partition=">, Group<f_Group>,
- Flags<[CC1Option]>, MarshallingInfoString<CodeGenOpts<"SymbolPartition">>;
+ Visibility<[ClangOption, CC1Option]>,
+ MarshallingInfoString<CodeGenOpts<"SymbolPartition">>;
-defm memory_profile : OptInFFlag<"memory-profile", "Enable", "Disable", " heap memory profiling">;
+defm memory_profile : OptInCC1FFlag<"memory-profile", "Enable", "Disable", " heap memory profiling">;
def fmemory_profile_EQ : Joined<["-"], "fmemory-profile=">,
- Group<f_Group>, Flags<[CC1Option]>, MetaVarName<"<directory>">,
+ Group<f_Group>, Visibility<[ClangOption, CC1Option]>,
+ MetaVarName<"<directory>">,
HelpText<"Enable heap memory profiling and dump results into <directory>">;
+def fmemory_profile_use_EQ : Joined<["-"], "fmemory-profile-use=">,
+ Group<f_Group>, Visibility<[ClangOption, CC1Option, CLOption]>,
+ MetaVarName<"<pathname>">,
+ HelpText<"Use memory profile for profile-guided memory optimization">,
+ MarshallingInfoString<CodeGenOpts<"MemoryProfileUsePath">>;
// Begin sanitizer flags. These should all be core options exposed in all driver
// modes.
-let Flags = [CC1Option, CoreOption] in {
+let Visibility = [ClangOption, CC1Option, CLOption] in {
def fsanitize_EQ : CommaJoined<["-"], "fsanitize=">, Group<f_clang_Group>,
MetaVarName<"<check>">,
HelpText<"Turn on runtime checks for various forms of undefined "
"or suspicious behavior. See user manual for available checks">;
def fno_sanitize_EQ : CommaJoined<["-"], "fno-sanitize=">, Group<f_clang_Group>,
- Flags<[CoreOption, NoXarchOption]>;
+ Visibility<[ClangOption, CLOption]>;
def fsanitize_ignorelist_EQ : Joined<["-"], "fsanitize-ignorelist=">,
Group<f_clang_Group>, HelpText<"Path to ignorelist file for sanitizers">;
@@ -1512,10 +2216,8 @@ def : Joined<["-"], "fsanitize-blacklist=">,
HelpText<"Alias for -fsanitize-ignorelist=">;
def fsanitize_system_ignorelist_EQ : Joined<["-"], "fsanitize-system-ignorelist=">,
- HelpText<"Path to system ignorelist file for sanitizers">, Flags<[CC1Option]>;
-def : Joined<["-"], "fsanitize-system-blacklist=">,
- HelpText<"Alias for -fsanitize-system-ignorelist=">,
- Flags<[CC1Option, HelpHidden]>, Alias<fsanitize_system_ignorelist_EQ>;
+ HelpText<"Path to system ignorelist file for sanitizers">,
+ Visibility<[ClangOption, CC1Option]>;
def fno_sanitize_ignorelist : Flag<["-"], "fno-sanitize-ignorelist">,
Group<f_clang_Group>, HelpText<"Don't use ignorelist file for sanitizers">;
@@ -1526,37 +2228,41 @@ def fsanitize_coverage : CommaJoined<["-"], "fsanitize-coverage=">,
Group<f_clang_Group>,
HelpText<"Specify the type of coverage instrumentation for Sanitizers">;
def fno_sanitize_coverage : CommaJoined<["-"], "fno-sanitize-coverage=">,
- Group<f_clang_Group>, Flags<[CoreOption, NoXarchOption]>,
+ Group<f_clang_Group>, Visibility<[ClangOption, CLOption]>,
HelpText<"Disable features of coverage instrumentation for Sanitizers">,
Values<"func,bb,edge,indirect-calls,trace-bb,trace-cmp,trace-div,trace-gep,"
"8bit-counters,trace-pc,trace-pc-guard,no-prune,inline-8bit-counters,"
"inline-bool-flag">;
def fsanitize_coverage_allowlist : Joined<["-"], "fsanitize-coverage-allowlist=">,
- Group<f_clang_Group>, Flags<[CoreOption, NoXarchOption]>,
+ Group<f_clang_Group>, Visibility<[ClangOption, CLOption]>,
HelpText<"Restrict sanitizer coverage instrumentation exclusively to modules and functions that match the provided special case list, except the blocked ones">,
MarshallingInfoStringVector<CodeGenOpts<"SanitizeCoverageAllowlistFiles">>;
-def : Joined<["-"], "fsanitize-coverage-whitelist=">,
- Group<f_clang_Group>, Flags<[CoreOption, HelpHidden]>, Alias<fsanitize_coverage_allowlist>,
- HelpText<"Deprecated, use -fsanitize-coverage-allowlist= instead">;
def fsanitize_coverage_ignorelist : Joined<["-"], "fsanitize-coverage-ignorelist=">,
- Group<f_clang_Group>, Flags<[CoreOption, NoXarchOption]>,
+ Group<f_clang_Group>, Visibility<[ClangOption, CLOption]>,
HelpText<"Disable sanitizer coverage instrumentation for modules and functions "
"that match the provided special case list, even the allowed ones">,
MarshallingInfoStringVector<CodeGenOpts<"SanitizeCoverageIgnorelistFiles">>;
-def : Joined<["-"], "fsanitize-coverage-blacklist=">,
- Group<f_clang_Group>, Flags<[CoreOption, HelpHidden]>,
- Alias<fsanitize_coverage_ignorelist>,
- HelpText<"Deprecated, use -fsanitize-coverage-ignorelist= instead">;
+def fexperimental_sanitize_metadata_EQ : CommaJoined<["-"], "fexperimental-sanitize-metadata=">,
+ Group<f_Group>,
+ HelpText<"Specify the type of metadata to emit for binary analysis sanitizers">;
+def fno_experimental_sanitize_metadata_EQ : CommaJoined<["-"], "fno-experimental-sanitize-metadata=">,
+ Group<f_Group>, Visibility<[ClangOption, CLOption]>,
+ HelpText<"Disable emitting metadata for binary analysis sanitizers">;
+def fexperimental_sanitize_metadata_ignorelist_EQ : Joined<["-"], "fexperimental-sanitize-metadata-ignorelist=">,
+ Group<f_Group>, Visibility<[ClangOption, CLOption]>,
+ HelpText<"Disable sanitizer metadata for modules and functions that match the provided special case list">,
+ MarshallingInfoStringVector<CodeGenOpts<"SanitizeMetadataIgnorelistFiles">>;
def fsanitize_memory_track_origins_EQ : Joined<["-"], "fsanitize-memory-track-origins=">,
Group<f_clang_Group>,
HelpText<"Enable origins tracking in MemorySanitizer">,
MarshallingInfoInt<CodeGenOpts<"SanitizeMemoryTrackOrigins">>;
def fsanitize_memory_track_origins : Flag<["-"], "fsanitize-memory-track-origins">,
Group<f_clang_Group>,
+ Alias<fsanitize_memory_track_origins_EQ>, AliasArgs<["2"]>,
HelpText<"Enable origins tracking in MemorySanitizer">;
def fno_sanitize_memory_track_origins : Flag<["-"], "fno-sanitize-memory-track-origins">,
Group<f_clang_Group>,
- Flags<[CoreOption, NoXarchOption]>,
+ Visibility<[ClangOption, CLOption]>,
HelpText<"Disable origins tracking in MemorySanitizer">;
def fsanitize_address_outline_instrumentation : Flag<["-"], "fsanitize-address-outline-instrumentation">,
Group<f_clang_Group>,
@@ -1564,18 +2270,27 @@ def fsanitize_address_outline_instrumentation : Flag<["-"], "fsanitize-address-o
def fno_sanitize_address_outline_instrumentation : Flag<["-"], "fno-sanitize-address-outline-instrumentation">,
Group<f_clang_Group>,
HelpText<"Use default code inlining logic for the address sanitizer">;
+defm sanitize_stable_abi
+ : OptInCC1FFlag<"sanitize-stable-abi", "Stable ", "Conventional ",
+ "ABI instrumentation for sanitizer runtime. Default: Conventional">;
+
+def fsanitize_memtag_mode_EQ : Joined<["-"], "fsanitize-memtag-mode=">,
+ Group<f_clang_Group>,
+ HelpText<"Set default MTE mode to 'sync' (default) or 'async'">;
def fsanitize_hwaddress_experimental_aliasing
: Flag<["-"], "fsanitize-hwaddress-experimental-aliasing">,
Group<f_clang_Group>,
HelpText<"Enable aliasing mode in HWAddressSanitizer">;
def fno_sanitize_hwaddress_experimental_aliasing
: Flag<["-"], "fno-sanitize-hwaddress-experimental-aliasing">,
- Group<f_clang_Group>, Flags<[CoreOption, NoXarchOption]>,
+ Group<f_clang_Group>,
+ Visibility<[ClangOption, CLOption]>,
HelpText<"Disable aliasing mode in HWAddressSanitizer">;
defm sanitize_memory_use_after_dtor : BoolOption<"f", "sanitize-memory-use-after-dtor",
CodeGenOpts<"SanitizeMemoryUseAfterDtor">, DefaultFalse,
- PosFlag<SetTrue, [CC1Option], "Enable">, NegFlag<SetFalse, [], "Disable">,
- BothFlags<[], " use-after-destroy detection in MemorySanitizer">>,
+ PosFlag<SetTrue, [], [ClangOption, CC1Option], "Enable">,
+ NegFlag<SetFalse, [], [ClangOption], "Disable">,
+ BothFlags<[], [ClangOption], " use-after-destroy detection in MemorySanitizer">>,
Group<f_clang_Group>;
def fsanitize_address_field_padding : Joined<["-"], "fsanitize-address-field-padding=">,
Group<f_clang_Group>,
@@ -1583,14 +2298,16 @@ def fsanitize_address_field_padding : Joined<["-"], "fsanitize-address-field-pad
MarshallingInfoInt<LangOpts<"SanitizeAddressFieldPadding">>;
defm sanitize_address_use_after_scope : BoolOption<"f", "sanitize-address-use-after-scope",
CodeGenOpts<"SanitizeAddressUseAfterScope">, DefaultFalse,
- PosFlag<SetTrue, [], "Enable">, NegFlag<SetFalse, [CoreOption, NoXarchOption], "Disable">,
- BothFlags<[], " use-after-scope detection in AddressSanitizer">>,
+ PosFlag<SetTrue, [], [ClangOption], "Enable">,
+ NegFlag<SetFalse, [], [ClangOption, CLOption],
+ "Disable">,
+ BothFlags<[], [ClangOption], " use-after-scope detection in AddressSanitizer">>,
Group<f_clang_Group>;
def sanitize_address_use_after_return_EQ
: Joined<["-"], "fsanitize-address-use-after-return=">,
MetaVarName<"<mode>">,
- Flags<[CC1Option]>,
- HelpText<"Select the mode of detecting stack use-after-return in AddressSanitizer: never | runtime (default) | always">,
+ Visibility<[ClangOption, CC1Option]>,
+ HelpText<"Select the mode of detecting stack use-after-return in AddressSanitizer">,
Group<f_clang_Group>,
Values<"never,runtime,always">,
NormalizedValuesScope<"llvm::AsanDetectStackUseAfterReturnMode">,
@@ -1598,28 +2315,52 @@ def sanitize_address_use_after_return_EQ
MarshallingInfoEnum<CodeGenOpts<"SanitizeAddressUseAfterReturn">, "Runtime">;
defm sanitize_address_poison_custom_array_cookie : BoolOption<"f", "sanitize-address-poison-custom-array-cookie",
CodeGenOpts<"SanitizeAddressPoisonCustomArrayCookie">, DefaultFalse,
- PosFlag<SetTrue, [], "Enable">, NegFlag<SetFalse, [], "Disable">,
- BothFlags<[], " poisoning array cookies when using custom operator new[] in AddressSanitizer">>,
+ PosFlag<SetTrue, [], [ClangOption], "Enable">,
+ NegFlag<SetFalse, [], [ClangOption], "Disable">,
+ BothFlags<[], [ClangOption], " poisoning array cookies when using custom operator new[] in AddressSanitizer">>,
+ DocBrief<[{Enable "poisoning" array cookies when allocating arrays with a
+custom operator new\[\] in Address Sanitizer, preventing accesses to the
+cookies from user code. An array cookie is a small implementation-defined
+header added to certain array allocations to record metadata such as the
+length of the array. Accesses to array cookies from user code are technically
+allowed by the standard but are more likely to be the result of an
+out-of-bounds array access.
+
+An operator new\[\] is "custom" if it is not one of the allocation functions
+provided by the C++ standard library. Array cookies from non-custom allocation
+functions are always poisoned.}]>,
+ Group<f_clang_Group>;
+defm sanitize_address_globals_dead_stripping : BoolOption<"f", "sanitize-address-globals-dead-stripping",
+ CodeGenOpts<"SanitizeAddressGlobalsDeadStripping">, DefaultFalse,
+ PosFlag<SetTrue, [], [ClangOption], "Enable linker dead stripping of globals in AddressSanitizer">,
+ NegFlag<SetFalse, [], [ClangOption], "Disable linker dead stripping of globals in AddressSanitizer">>,
Group<f_clang_Group>;
-def fsanitize_address_globals_dead_stripping : Flag<["-"], "fsanitize-address-globals-dead-stripping">,
- Group<f_clang_Group>, HelpText<"Enable linker dead stripping of globals in AddressSanitizer">,
- MarshallingInfoFlag<CodeGenOpts<"SanitizeAddressGlobalsDeadStripping">, "false">;
defm sanitize_address_use_odr_indicator : BoolOption<"f", "sanitize-address-use-odr-indicator",
- CodeGenOpts<"SanitizeAddressUseOdrIndicator">, DefaultFalse,
- PosFlag<SetTrue, [], "Enable ODR indicator globals to avoid false ODR violation"
+ CodeGenOpts<"SanitizeAddressUseOdrIndicator">, DefaultTrue,
+ PosFlag<SetTrue, [], [ClangOption], "Enable ODR indicator globals to avoid false ODR violation"
" reports in partially sanitized programs at the cost of an increase in binary size">,
- NegFlag<SetFalse, [], "Disable ODR indicator globals">>,
+ NegFlag<SetFalse, [], [ClangOption], "Disable ODR indicator globals">>,
Group<f_clang_Group>;
def sanitize_address_destructor_EQ
: Joined<["-"], "fsanitize-address-destructor=">,
- Flags<[CC1Option]>,
- HelpText<"Set destructor type used in ASan instrumentation">,
+ Visibility<[ClangOption, CC1Option]>,
+ HelpText<"Set the kind of module destructors emitted by "
+ "AddressSanitizer instrumentation. These destructors are "
+ "emitted to unregister instrumented global variables when "
+ "code is unloaded (e.g. via `dlclose()`).">,
Group<f_clang_Group>,
Values<"none,global">,
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">,
+ DefaultTrue,
+ PosFlag<SetTrue, [], [ClangOption, CC1Option], "Enable">,
+ NegFlag<SetFalse, [], [ClangOption], "Disable">,
+ BothFlags<[], [ClangOption], " 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
@@ -1633,24 +2374,26 @@ def fsanitize_recover_EQ : CommaJoined<["-"], "fsanitize-recover=">,
Group<f_clang_Group>,
HelpText<"Enable recovery for specified sanitizers">;
def fno_sanitize_recover_EQ : CommaJoined<["-"], "fno-sanitize-recover=">,
- Group<f_clang_Group>, Flags<[CoreOption, NoXarchOption]>,
+ Group<f_clang_Group>,
+ Visibility<[ClangOption, CLOption]>,
HelpText<"Disable recovery for specified sanitizers">;
def fsanitize_recover : Flag<["-"], "fsanitize-recover">, Group<f_clang_Group>,
Alias<fsanitize_recover_EQ>, AliasArgs<["all"]>;
def fno_sanitize_recover : Flag<["-"], "fno-sanitize-recover">,
- Flags<[CoreOption, NoXarchOption]>, Group<f_clang_Group>,
+ Visibility<[ClangOption, CLOption]>,
+ Group<f_clang_Group>,
Alias<fno_sanitize_recover_EQ>, AliasArgs<["all"]>;
def fsanitize_trap_EQ : CommaJoined<["-"], "fsanitize-trap=">, Group<f_clang_Group>,
HelpText<"Enable trapping for specified sanitizers">;
def fno_sanitize_trap_EQ : CommaJoined<["-"], "fno-sanitize-trap=">, Group<f_clang_Group>,
- Flags<[CoreOption, NoXarchOption]>,
+ Visibility<[ClangOption, CLOption]>,
HelpText<"Disable trapping for specified sanitizers">;
def fsanitize_trap : Flag<["-"], "fsanitize-trap">, Group<f_clang_Group>,
Alias<fsanitize_trap_EQ>, AliasArgs<["all"]>,
HelpText<"Enable trapping for all sanitizers">;
def fno_sanitize_trap : Flag<["-"], "fno-sanitize-trap">, Group<f_clang_Group>,
Alias<fno_sanitize_trap_EQ>, AliasArgs<["all"]>,
- Flags<[CoreOption, NoXarchOption]>,
+ Visibility<[ClangOption, CLOption]>,
HelpText<"Disable trapping for all sanitizers">;
def fsanitize_undefined_trap_on_error
: Flag<["-"], "fsanitize-undefined-trap-on-error">, Group<f_clang_Group>,
@@ -1660,7 +2403,8 @@ def fno_sanitize_undefined_trap_on_error
Alias<fno_sanitize_trap_EQ>, AliasArgs<["undefined"]>;
defm sanitize_minimal_runtime : BoolOption<"f", "sanitize-minimal-runtime",
CodeGenOpts<"SanitizeMinimalRuntime">, DefaultFalse,
- PosFlag<SetTrue>, NegFlag<SetFalse>>,
+ PosFlag<SetTrue>,
+ NegFlag<SetFalse>>,
Group<f_clang_Group>;
def fsanitize_link_runtime : Flag<["-"], "fsanitize-link-runtime">,
Group<f_clang_Group>;
@@ -1672,43 +2416,53 @@ def fno_sanitize_link_cxx_runtime : Flag<["-"], "fno-sanitize-link-c++-runtime">
Group<f_clang_Group>;
defm sanitize_cfi_cross_dso : BoolOption<"f", "sanitize-cfi-cross-dso",
CodeGenOpts<"SanitizeCfiCrossDso">, DefaultFalse,
- PosFlag<SetTrue, [], "Enable">, NegFlag<SetFalse, [CoreOption, NoXarchOption], "Disable">,
- BothFlags<[], " control flow integrity (CFI) checks for cross-DSO calls.">>,
+ PosFlag<SetTrue, [], [ClangOption], "Enable">,
+ NegFlag<SetFalse, [], [ClangOption, CLOption],
+ "Disable">,
+ BothFlags<[], [ClangOption], " control flow integrity (CFI) checks for cross-DSO calls.">>,
Group<f_clang_Group>;
def fsanitize_cfi_icall_generalize_pointers : Flag<["-"], "fsanitize-cfi-icall-generalize-pointers">,
Group<f_clang_Group>,
HelpText<"Generalize pointers in CFI indirect call type signature checks">,
MarshallingInfoFlag<CodeGenOpts<"SanitizeCfiICallGeneralizePointers">>;
+def fsanitize_cfi_icall_normalize_integers : Flag<["-"], "fsanitize-cfi-icall-experimental-normalize-integers">,
+ Group<f_clang_Group>,
+ HelpText<"Normalize integers in CFI indirect call type signature checks">,
+ MarshallingInfoFlag<CodeGenOpts<"SanitizeCfiICallNormalizeIntegers">>;
defm sanitize_cfi_canonical_jump_tables : BoolOption<"f", "sanitize-cfi-canonical-jump-tables",
CodeGenOpts<"SanitizeCfiCanonicalJumpTables">, DefaultFalse,
- PosFlag<SetTrue, [], "Make">, NegFlag<SetFalse, [CoreOption, NoXarchOption], "Do not make">,
- BothFlags<[], " the jump table addresses canonical in the symbol table">>,
+ PosFlag<SetTrue, [], [ClangOption], "Make">,
+ NegFlag<SetFalse, [], [ClangOption, CLOption],
+ "Do not make">,
+ BothFlags<[], [ClangOption], " the jump table addresses canonical in the symbol table">>,
Group<f_clang_Group>;
defm sanitize_stats : BoolOption<"f", "sanitize-stats",
CodeGenOpts<"SanitizeStats">, DefaultFalse,
- PosFlag<SetTrue, [], "Enable">, NegFlag<SetFalse, [CoreOption, NoXarchOption], "Disable">,
- BothFlags<[], " sanitizer statistics gathering.">>,
+ PosFlag<SetTrue, [], [ClangOption], "Enable">,
+ NegFlag<SetFalse, [], [ClangOption, CLOption],
+ "Disable">,
+ BothFlags<[], [ClangOption], " sanitizer statistics gathering.">>,
Group<f_clang_Group>;
def fsanitize_thread_memory_access : Flag<["-"], "fsanitize-thread-memory-access">,
Group<f_clang_Group>,
HelpText<"Enable memory access instrumentation in ThreadSanitizer (default)">;
def fno_sanitize_thread_memory_access : Flag<["-"], "fno-sanitize-thread-memory-access">,
Group<f_clang_Group>,
- Flags<[CoreOption, NoXarchOption]>,
+ Visibility<[ClangOption, CLOption]>,
HelpText<"Disable memory access instrumentation in ThreadSanitizer">;
def fsanitize_thread_func_entry_exit : Flag<["-"], "fsanitize-thread-func-entry-exit">,
Group<f_clang_Group>,
HelpText<"Enable function entry/exit instrumentation in ThreadSanitizer (default)">;
def fno_sanitize_thread_func_entry_exit : Flag<["-"], "fno-sanitize-thread-func-entry-exit">,
Group<f_clang_Group>,
- Flags<[CoreOption, NoXarchOption]>,
+ Visibility<[ClangOption, CLOption]>,
HelpText<"Disable function entry/exit instrumentation in ThreadSanitizer">;
def fsanitize_thread_atomics : Flag<["-"], "fsanitize-thread-atomics">,
Group<f_clang_Group>,
HelpText<"Enable atomic operations instrumentation in ThreadSanitizer (default)">;
def fno_sanitize_thread_atomics : Flag<["-"], "fno-sanitize-thread-atomics">,
Group<f_clang_Group>,
- Flags<[CoreOption, NoXarchOption]>,
+ Visibility<[ClangOption, CLOption]>,
HelpText<"Disable atomic operations instrumentation in ThreadSanitizer">;
def fsanitize_undefined_strip_path_components_EQ : Joined<["-"], "fsanitize-undefined-strip-path-components=">,
Group<f_clang_Group>, MetaVarName<"<number>">,
@@ -1719,58 +2473,83 @@ def fsanitize_undefined_strip_path_components_EQ : Joined<["-"], "fsanitize-unde
} // end -f[no-]sanitize* flags
def funsafe_math_optimizations : Flag<["-"], "funsafe-math-optimizations">,
- Group<f_Group>;
+ Group<f_Group>, Visibility<[ClangOption, CC1Option]>,
+ HelpText<"Allow unsafe floating-point math optimizations which may decrease precision">,
+ MarshallingInfoFlag<LangOpts<"UnsafeFPMath">>,
+ ImpliedByAnyOf<[cl_unsafe_math_optimizations.KeyPath, ffast_math.KeyPath]>;
def fno_unsafe_math_optimizations : Flag<["-"], "fno-unsafe-math-optimizations">,
Group<f_Group>;
-def fassociative_math : Flag<["-"], "fassociative-math">, Group<f_Group>;
-def fno_associative_math : Flag<["-"], "fno-associative-math">, Group<f_Group>;
+def fassociative_math : Flag<["-"], "fassociative-math">, Visibility<[ClangOption, FlangOption]>, Group<f_Group>;
+def fno_associative_math : Flag<["-"], "fno-associative-math">, Visibility<[ClangOption, FlangOption]>, Group<f_Group>;
defm reciprocal_math : BoolFOption<"reciprocal-math",
LangOpts<"AllowRecip">, DefaultFalse,
- PosFlag<SetTrue, [CC1Option], "Allow division operations to be reassociated",
- [menable_unsafe_fp_math.KeyPath]>,
- NegFlag<SetFalse>>;
-def fapprox_func : Flag<["-"], "fapprox-func">, Group<f_Group>, Flags<[CC1Option, NoDriverOption]>,
- MarshallingInfoFlag<LangOpts<"ApproxFunc">>, ImpliedByAnyOf<[menable_unsafe_fp_math.KeyPath]>;
+ PosFlag<SetTrue, [], [ClangOption, CC1Option, FC1Option, FlangOption],
+ "Allow division operations to be reassociated",
+ [funsafe_math_optimizations.KeyPath]>,
+ NegFlag<SetFalse, [], [ClangOption, CC1Option, FC1Option, FlangOption]>>;
+defm approx_func : BoolFOption<"approx-func", LangOpts<"ApproxFunc">, DefaultFalse,
+ PosFlag<SetTrue, [], [ClangOption, CC1Option, FC1Option, FlangOption],
+ "Allow certain math function calls to be replaced "
+ "with an approximately equivalent calculation",
+ [funsafe_math_optimizations.KeyPath]>,
+ NegFlag<SetFalse, [], [ClangOption, CC1Option, FC1Option, FlangOption]>>;
defm finite_math_only : BoolFOption<"finite-math-only",
LangOpts<"FiniteMathOnly">, DefaultFalse,
- PosFlag<SetTrue, [CC1Option], "", [cl_finite_math_only.KeyPath, ffast_math.KeyPath]>,
+ PosFlag<SetTrue, [], [ClangOption, CC1Option],
+ "Allow floating-point optimizations that "
+ "assume arguments and results are not NaNs or +-inf. This defines "
+ "the \\_\\_FINITE\\_MATH\\_ONLY\\_\\_ preprocessor macro.",
+ [cl_finite_math_only.KeyPath, ffast_math.KeyPath]>,
NegFlag<SetFalse>>;
defm signed_zeros : BoolFOption<"signed-zeros",
LangOpts<"NoSignedZero">, DefaultFalse,
- NegFlag<SetTrue, [CC1Option], "Allow optimizations that ignore the sign of floating point zeros",
- [cl_no_signed_zeros.KeyPath, menable_unsafe_fp_math.KeyPath]>,
- PosFlag<SetFalse>>;
-def fhonor_nans : Flag<["-"], "fhonor-nans">, Group<f_Group>;
-def fno_honor_nans : Flag<["-"], "fno-honor-nans">, Group<f_Group>;
-def fhonor_infinities : Flag<["-"], "fhonor-infinities">, Group<f_Group>;
-def fno_honor_infinities : Flag<["-"], "fno-honor-infinities">, Group<f_Group>;
+ NegFlag<SetTrue, [], [ClangOption, CC1Option, FC1Option, FlangOption],
+ "Allow optimizations that ignore the sign of floating point zeros",
+ [cl_no_signed_zeros.KeyPath, funsafe_math_optimizations.KeyPath]>,
+ PosFlag<SetFalse, [], [ClangOption, CC1Option, FC1Option, FlangOption]>>;
+def fhonor_nans : Flag<["-"], "fhonor-nans">, Group<f_Group>,
+ Visibility<[ClangOption, FlangOption]>,
+ HelpText<"Specify that floating-point optimizations are not allowed that "
+ "assume arguments and results are not NANs.">;
+def fno_honor_nans : Flag<["-"], "fno-honor-nans">, Visibility<[ClangOption, FlangOption]>, Group<f_Group>;
+def fhonor_infinities : Flag<["-"], "fhonor-infinities">,
+ Group<f_Group>, Visibility<[ClangOption, FlangOption]>,
+ HelpText<"Specify that floating-point optimizations are not allowed that "
+ "assume arguments and results are not +-inf.">;
+def fno_honor_infinities : Flag<["-"], "fno-honor-infinities">,
+ Visibility<[ClangOption, FlangOption]>, Group<f_Group>;
// This option was originally misspelt "infinites" [sic].
def : Flag<["-"], "fhonor-infinites">, Alias<fhonor_infinities>;
def : Flag<["-"], "fno-honor-infinites">, Alias<fno_honor_infinities>;
-def frounding_math : Flag<["-"], "frounding-math">, Group<f_Group>, Flags<[CC1Option]>,
- MarshallingInfoFlag<LangOpts<"FPRoundingMode">, "llvm::RoundingMode::NearestTiesToEven">,
+def frounding_math : Flag<["-"], "frounding-math">, Group<f_Group>,
+ Visibility<[ClangOption, CC1Option]>,
+ MarshallingInfoFlag<LangOpts<"RoundingMath">>,
Normalizer<"makeFlagToValueNormalizer(llvm::RoundingMode::Dynamic)">;
-def fno_rounding_math : Flag<["-"], "fno-rounding-math">, Group<f_Group>, Flags<[CC1Option]>;
+def fno_rounding_math : Flag<["-"], "fno-rounding-math">, Group<f_Group>,
+ Visibility<[ClangOption, CC1Option]>;
def ftrapping_math : Flag<["-"], "ftrapping-math">, Group<f_Group>;
def fno_trapping_math : Flag<["-"], "fno-trapping-math">, Group<f_Group>;
def ffp_contract : Joined<["-"], "ffp-contract=">, Group<f_Group>,
- Flags<[CC1Option]>, HelpText<"Form fused FP ops (e.g. FMAs):"
+ Visibility<[ClangOption, CC1Option, FC1Option, FlangOption]>,
+ DocBrief<"Form fused FP ops (e.g. FMAs):"
" fast (fuses across statements disregarding pragmas)"
" | on (only fuses in the same statement unless dictated by pragmas)"
" | off (never fuses)"
- " | fast-honor-pragmas (fuses across statements unless diectated by pragmas)."
+ " | fast-honor-pragmas (fuses across statements unless dictated by pragmas)."
" Default is 'fast' for CUDA, 'fast-honor-pragmas' for HIP, and 'on' otherwise.">,
+ HelpText<"Form fused FP ops (e.g. FMAs)">,
Values<"fast,on,off,fast-honor-pragmas">;
defm strict_float_cast_overflow : BoolFOption<"strict-float-cast-overflow",
CodeGenOpts<"StrictFloatCastOverflow">, DefaultTrue,
- NegFlag<SetFalse, [CC1Option], "Relax language rules and try to match the behavior"
+ NegFlag<SetFalse, [], [ClangOption, CC1Option],
+ "Relax language rules and try to match the behavior"
" of the target's native float-to-int conversion instructions">,
- PosFlag<SetTrue, [], "Assume that overflowing float-to-int casts are undefined (default)">>;
+ PosFlag<SetTrue, [], [ClangOption], "Assume that overflowing float-to-int casts are undefined (default)">>;
defm protect_parens : BoolFOption<"protect-parens",
LangOpts<"ProtectParens">, DefaultFalse,
- PosFlag<SetTrue, [CoreOption, CC1Option],
+ PosFlag<SetTrue, [], [ClangOption, CLOption, CC1Option],
"Determines whether the optimizer honors parentheses when "
"floating-point expressions are evaluated">,
NegFlag<SetFalse>>;
@@ -1780,32 +2559,61 @@ def fno_for_scope : Flag<["-"], "fno-for-scope">, Group<f_Group>;
defm rewrite_imports : BoolFOption<"rewrite-imports",
PreprocessorOutputOpts<"RewriteImports">, DefaultFalse,
- PosFlag<SetTrue, [CC1Option]>, NegFlag<SetFalse>>;
+ PosFlag<SetTrue, [], [ClangOption, CC1Option]>,
+ NegFlag<SetFalse>>;
defm rewrite_includes : BoolFOption<"rewrite-includes",
PreprocessorOutputOpts<"RewriteIncludes">, DefaultFalse,
- PosFlag<SetTrue, [CC1Option]>, NegFlag<SetFalse>>;
+ PosFlag<SetTrue, [], [ClangOption, CC1Option]>,
+ NegFlag<SetFalse>>;
+
+defm directives_only : OptInCC1FFlag<"directives-only", "">;
defm delete_null_pointer_checks : BoolFOption<"delete-null-pointer-checks",
CodeGenOpts<"NullPointerIsValid">, DefaultFalse,
- NegFlag<SetTrue, [CC1Option], "Do not treat usage of null pointers as undefined behavior">,
- PosFlag<SetFalse, [], "Treat usage of null pointers as undefined behavior (default)">,
- BothFlags<[CoreOption]>>;
-
-def frewrite_map_file_EQ : Joined<["-"], "frewrite-map-file=">,
- Group<f_Group>,
- Flags<[NoXarchOption, CC1Option]>,
- MarshallingInfoStringVector<CodeGenOpts<"RewriteMapFiles">>;
+ NegFlag<SetTrue, [], [ClangOption, CC1Option],
+ "Do not treat usage of null pointers as undefined behavior">,
+ PosFlag<SetFalse, [], [ClangOption], "Treat usage of null pointers as undefined behavior (default)">,
+ BothFlags<[], [ClangOption, CLOption]>>,
+ DocBrief<[{When enabled, treat null pointer dereference, creation of a reference to null,
+or passing a null pointer to a function parameter annotated with the "nonnull"
+attribute as undefined behavior. (And, thus the optimizer may assume that any
+pointer used in such a way must not have been null and optimize away the
+branches accordingly.) On by default.}]>;
defm use_line_directives : BoolFOption<"use-line-directives",
PreprocessorOutputOpts<"UseLineDirectives">, DefaultFalse,
- PosFlag<SetTrue, [CC1Option], "Use #line in preprocessed output">, NegFlag<SetFalse>>;
+ PosFlag<SetTrue, [], [ClangOption, CC1Option],
+ "Use #line in preprocessed output">,
+ NegFlag<SetFalse>>;
+defm minimize_whitespace : BoolFOption<"minimize-whitespace",
+ PreprocessorOutputOpts<"MinimizeWhitespace">, DefaultFalse,
+ PosFlag<SetTrue, [], [ClangOption, CC1Option],
+ "Ignore the whitespace from the input file "
+ "when emitting preprocessor output. It will only contain whitespace "
+ "when necessary, e.g. to keep two minus signs from merging into to "
+ "an increment operator. Useful with the -P option to normalize "
+ "whitespace such that two files with only formatting changes are "
+ "equal.\n\nOnly valid with -E on C-like inputs and incompatible "
+ "with -traditional-cpp.">, NegFlag<SetFalse>>;
+defm keep_system_includes : BoolFOption<"keep-system-includes",
+ PreprocessorOutputOpts<"KeepSystemIncludes">, DefaultFalse,
+ PosFlag<SetTrue, [], [ClangOption, CC1Option],
+ "Instead of expanding system headers when emitting preprocessor "
+ "output, preserve the #include directive. Useful when producing "
+ "preprocessed output for test case reduction. May produce incorrect "
+ "output if preprocessor symbols that control the included content "
+ "(e.g. _XOPEN_SOURCE) are defined in the including source file. The "
+ "portability of the resulting source to other compilation environments "
+ "is not guaranteed.\n\nOnly valid with -E.">,
+ NegFlag<SetFalse>>;
-def ffreestanding : Flag<["-"], "ffreestanding">, Group<f_Group>, Flags<[CC1Option]>,
+def ffreestanding : Flag<["-"], "ffreestanding">, Group<f_Group>,
+ Visibility<[ClangOption, CC1Option]>,
HelpText<"Assert that the compilation takes place in a freestanding environment">,
MarshallingInfoFlag<LangOpts<"Freestanding">>;
def fgnuc_version_EQ : Joined<["-"], "fgnuc-version=">, Group<f_Group>,
HelpText<"Sets various macros to claim compatibility with the given GCC version (default is 4.2.1)">,
- Flags<[CC1Option, CoreOption]>;
+ Visibility<[ClangOption, CC1Option, CLOption]>;
// We abuse '-f[no-]gnu-keywords' to force overriding all GNU-extension
// keywords. This behavior is provided by GCC's poorly named '-fasm' flag,
// while a subset (the non-C++ GNU keywords) is provided by GCC's
@@ -1813,164 +2621,193 @@ def fgnuc_version_EQ : Joined<["-"], "fgnuc-version=">, Group<f_Group>,
// name, as it doesn't seem a useful distinction.
defm gnu_keywords : BoolFOption<"gnu-keywords",
LangOpts<"GNUKeywords">, Default<gnu_mode.KeyPath>,
- PosFlag<SetTrue, [], "Allow GNU-extension keywords regardless of language standard">,
- NegFlag<SetFalse>, BothFlags<[CC1Option]>>;
+ PosFlag<SetTrue, [], [ClangOption], "Allow GNU-extension keywords regardless of language standard">,
+ NegFlag<SetFalse>, BothFlags<[], [ClangOption, CC1Option]>>;
defm gnu89_inline : BoolFOption<"gnu89-inline",
LangOpts<"GNUInline">, Default<!strconcat("!", c99.KeyPath, " && !", cplusplus.KeyPath)>,
- PosFlag<SetTrue, [CC1Option], "Use the gnu89 inline semantics">,
+ PosFlag<SetTrue, [], [ClangOption, CC1Option],
+ "Use the gnu89 inline semantics">,
NegFlag<SetFalse>>, ShouldParseIf<!strconcat("!", cplusplus.KeyPath)>;
def fgnu_runtime : Flag<["-"], "fgnu-runtime">, Group<f_Group>,
HelpText<"Generate output compatible with the standard GNU Objective-C runtime">;
-def fheinous_gnu_extensions : Flag<["-"], "fheinous-gnu-extensions">, Flags<[CC1Option]>,
+def fheinous_gnu_extensions : Flag<["-"], "fheinous-gnu-extensions">,
+ Visibility<[ClangOption, CC1Option]>,
MarshallingInfoFlag<LangOpts<"HeinousExtensions">>;
def filelist : Separate<["-"], "filelist">, Flags<[LinkerInput]>,
Group<Link_Group>;
def : Flag<["-"], "findirect-virtual-calls">, Alias<fapple_kext>;
-def finline_functions : Flag<["-"], "finline-functions">, Group<f_clang_Group>, Flags<[CC1Option]>,
+def finline_functions : Flag<["-"], "finline-functions">, Group<f_clang_Group>,
+ Visibility<[ClangOption, CC1Option]>,
HelpText<"Inline suitable functions">;
-def finline_hint_functions: Flag<["-"], "finline-hint-functions">, Group<f_clang_Group>, Flags<[CC1Option]>,
+def finline_hint_functions: Flag<["-"], "finline-hint-functions">, Group<f_clang_Group>,
+ Visibility<[ClangOption, CC1Option]>,
HelpText<"Inline functions which are (explicitly or implicitly) marked inline">;
def finline : Flag<["-"], "finline">, Group<clang_ignored_f_Group>;
+def finline_max_stacksize_EQ
+ : Joined<["-"], "finline-max-stacksize=">,
+ Group<f_Group>, Visibility<[ClangOption, CLOption, CC1Option]>,
+ HelpText<"Suppress inlining of functions whose stack size exceeds the given value">,
+ MarshallingInfoInt<CodeGenOpts<"InlineMaxStackSize">, "UINT_MAX">;
+defm jmc : BoolFOption<"jmc",
+ CodeGenOpts<"JMCInstrument">, DefaultFalse,
+ PosFlag<SetTrue, [], [ClangOption, CC1Option],
+ "Enable just-my-code debugging">,
+ NegFlag<SetFalse>>;
def fglobal_isel : Flag<["-"], "fglobal-isel">, Group<f_clang_Group>,
HelpText<"Enables the global instruction selector">;
def fexperimental_isel : Flag<["-"], "fexperimental-isel">, Group<f_clang_Group>,
Alias<fglobal_isel>;
-defm legacy_pass_manager : BoolOption<"f", "legacy-pass-manager",
- CodeGenOpts<"LegacyPassManager">, Default<"!static_cast<unsigned>(LLVM_ENABLE_NEW_PASS_MANAGER)">,
- PosFlag<SetTrue, [], "Use the legacy pass manager in LLVM">,
- NegFlag<SetFalse, [], "Use the new pass manager in LLVM">,
- BothFlags<[CC1Option]>>, Group<f_clang_Group>;
-def fexperimental_new_pass_manager : Flag<["-"], "fexperimental-new-pass-manager">,
- Group<f_clang_Group>, Flags<[CC1Option]>, Alias<fno_legacy_pass_manager>;
-def fno_experimental_new_pass_manager : Flag<["-"], "fno-experimental-new-pass-manager">,
- Group<f_clang_Group>, Flags<[CC1Option]>, Alias<flegacy_pass_manager>;
def fexperimental_strict_floating_point : Flag<["-"], "fexperimental-strict-floating-point">,
- Group<f_clang_Group>, Flags<[CC1Option]>,
- HelpText<"Enables experimental strict floating point in LLVM.">,
+ Group<f_clang_Group>, Visibility<[ClangOption, CC1Option]>,
+ HelpText<"Enables the use of non-default rounding modes and non-default exception handling on targets that are not currently ready.">,
MarshallingInfoFlag<LangOpts<"ExpStrictFP">>;
-def finput_charset_EQ : Joined<["-"], "finput-charset=">, Flags<[FlangOption, FC1Option]>, Group<f_Group>,
+def finput_charset_EQ : Joined<["-"], "finput-charset=">,
+ Visibility<[ClangOption, FlangOption, FC1Option]>, Group<f_Group>,
HelpText<"Specify the default character set for source files">;
def fexec_charset_EQ : Joined<["-"], "fexec-charset=">, Group<f_Group>;
-def finstrument_functions : Flag<["-"], "finstrument-functions">, Group<f_Group>, Flags<[CC1Option]>,
+def finstrument_functions : Flag<["-"], "finstrument-functions">, Group<f_Group>,
+ Visibility<[ClangOption, CC1Option]>,
HelpText<"Generate calls to instrument function entry and exit">,
MarshallingInfoFlag<CodeGenOpts<"InstrumentFunctions">>;
-def finstrument_functions_after_inlining : Flag<["-"], "finstrument-functions-after-inlining">, Group<f_Group>, Flags<[CC1Option]>,
+def finstrument_functions_after_inlining : Flag<["-"], "finstrument-functions-after-inlining">, Group<f_Group>,
+ Visibility<[ClangOption, CC1Option]>,
HelpText<"Like -finstrument-functions, but insert the calls after inlining">,
MarshallingInfoFlag<CodeGenOpts<"InstrumentFunctionsAfterInlining">>;
-def finstrument_function_entry_bare : Flag<["-"], "finstrument-function-entry-bare">, Group<f_Group>, Flags<[CC1Option]>,
+def finstrument_function_entry_bare : Flag<["-"], "finstrument-function-entry-bare">, Group<f_Group>,
+ Visibility<[ClangOption, CC1Option]>,
HelpText<"Instrument function entry only, after inlining, without arguments to the instrumentation call">,
MarshallingInfoFlag<CodeGenOpts<"InstrumentFunctionEntryBare">>;
-def fcf_protection_EQ : Joined<["-"], "fcf-protection=">, Flags<[CoreOption, CC1Option]>, Group<f_Group>,
- HelpText<"Instrument control-flow architecture protection. Options: return, branch, full, none.">, Values<"return,branch,full,none">;
-def fcf_protection : Flag<["-"], "fcf-protection">, Group<f_Group>, Flags<[CoreOption, CC1Option]>,
+def fcf_protection_EQ : Joined<["-"], "fcf-protection=">,
+ Visibility<[ClangOption, CLOption, CC1Option]>, Group<f_Group>,
+ HelpText<"Instrument control-flow architecture protection">, Values<"return,branch,full,none">;
+def fcf_protection : Flag<["-"], "fcf-protection">, Group<f_Group>,
+ Visibility<[ClangOption, CLOption, CC1Option]>,
Alias<fcf_protection_EQ>, AliasArgs<["full"]>,
HelpText<"Enable cf-protection in 'full' mode">;
+def mfunction_return_EQ : Joined<["-"], "mfunction-return=">,
+ Group<m_Group>, Visibility<[ClangOption, CLOption, CC1Option]>,
+ HelpText<"Replace returns with jumps to ``__x86_return_thunk`` (x86 only, error otherwise)">,
+ Values<"keep,thunk-extern">,
+ NormalizedValues<["Keep", "Extern"]>,
+ NormalizedValuesScope<"llvm::FunctionReturnThunksKind">,
+ MarshallingInfoEnum<CodeGenOpts<"FunctionReturnThunks">, "Keep">;
+def mindirect_branch_cs_prefix : Flag<["-"], "mindirect-branch-cs-prefix">,
+ Group<m_Group>, Visibility<[ClangOption, CLOption, CC1Option]>,
+ HelpText<"Add cs prefix to call and jmp to indirect thunk">,
+ MarshallingInfoFlag<CodeGenOpts<"IndirectBranchCSPrefix">>;
defm xray_instrument : BoolFOption<"xray-instrument",
LangOpts<"XRayInstrument">, DefaultFalse,
- PosFlag<SetTrue, [CC1Option], "Generate XRay instrumentation sleds on function entry and exit">,
+ PosFlag<SetTrue, [], [ClangOption, CC1Option],
+ "Generate XRay instrumentation sleds on function entry and exit">,
NegFlag<SetFalse>>;
def fxray_instruction_threshold_EQ :
- JoinedOrSeparate<["-"], "fxray-instruction-threshold=">,
- Group<f_Group>, Flags<[CC1Option]>,
+ Joined<["-"], "fxray-instruction-threshold=">,
+ Group<f_Group>, Visibility<[ClangOption, CC1Option]>,
HelpText<"Sets the minimum function size to instrument with XRay">,
MarshallingInfoInt<CodeGenOpts<"XRayInstructionThreshold">, "200">;
-def fxray_instruction_threshold_ :
- JoinedOrSeparate<["-"], "fxray-instruction-threshold">,
- Group<f_Group>, Flags<[CC1Option]>;
def fxray_always_instrument :
- JoinedOrSeparate<["-"], "fxray-always-instrument=">,
- Group<f_Group>, Flags<[CC1Option]>,
+ Joined<["-"], "fxray-always-instrument=">,
+ Group<f_Group>, Visibility<[ClangOption, CC1Option]>,
HelpText<"DEPRECATED: Filename defining the whitelist for imbuing the 'always instrument' XRay attribute.">,
MarshallingInfoStringVector<LangOpts<"XRayAlwaysInstrumentFiles">>;
def fxray_never_instrument :
- JoinedOrSeparate<["-"], "fxray-never-instrument=">,
- Group<f_Group>, Flags<[CC1Option]>,
+ Joined<["-"], "fxray-never-instrument=">,
+ Group<f_Group>, Visibility<[ClangOption, CC1Option]>,
HelpText<"DEPRECATED: Filename defining the whitelist for imbuing the 'never instrument' XRay attribute.">,
MarshallingInfoStringVector<LangOpts<"XRayNeverInstrumentFiles">>;
def fxray_attr_list :
- JoinedOrSeparate<["-"], "fxray-attr-list=">,
- Group<f_Group>, Flags<[CC1Option]>,
+ Joined<["-"], "fxray-attr-list=">,
+ Group<f_Group>, Visibility<[ClangOption, CC1Option]>,
HelpText<"Filename defining the list of functions/types for imbuing XRay attributes.">,
MarshallingInfoStringVector<LangOpts<"XRayAttrListFiles">>;
def fxray_modes :
- JoinedOrSeparate<["-"], "fxray-modes=">,
- Group<f_Group>, Flags<[CC1Option]>,
+ Joined<["-"], "fxray-modes=">,
+ Group<f_Group>, Visibility<[ClangOption, CC1Option]>,
HelpText<"List of modes to link in by default into XRay instrumented binaries.">;
defm xray_always_emit_customevents : BoolFOption<"xray-always-emit-customevents",
LangOpts<"XRayAlwaysEmitCustomEvents">, DefaultFalse,
- PosFlag<SetTrue, [CC1Option], "Always emit __xray_customevent(...) calls"
+ PosFlag<SetTrue, [], [ClangOption, CC1Option],
+ "Always emit __xray_customevent(...) calls"
" even if the containing function is not always instrumented">,
NegFlag<SetFalse>>;
defm xray_always_emit_typedevents : BoolFOption<"xray-always-emit-typedevents",
LangOpts<"XRayAlwaysEmitTypedEvents">, DefaultFalse,
- PosFlag<SetTrue, [CC1Option], "Always emit __xray_typedevent(...) calls"
+ PosFlag<SetTrue, [], [ClangOption, CC1Option],
+ "Always emit __xray_typedevent(...) calls"
" even if the containing function is not always instrumented">,
NegFlag<SetFalse>>;
defm xray_ignore_loops : BoolFOption<"xray-ignore-loops",
CodeGenOpts<"XRayIgnoreLoops">, DefaultFalse,
- PosFlag<SetTrue, [CC1Option], "Don't instrument functions with loops"
+ PosFlag<SetTrue, [], [ClangOption, CC1Option],
+ "Don't instrument functions with loops"
" unless they also meet the minimum function size">,
NegFlag<SetFalse>>;
defm xray_function_index : BoolFOption<"xray-function-index",
- CodeGenOpts<"XRayOmitFunctionIndex">, DefaultTrue,
- NegFlag<SetFalse, [CC1Option], "Omit function index section at the"
- " expense of single-function patching performance">,
- PosFlag<SetTrue>>;
+ CodeGenOpts<"XRayFunctionIndex">, DefaultTrue,
+ PosFlag<SetTrue, [], [ClangOption]>,
+ NegFlag<SetFalse, [], [ClangOption, CC1Option],
+ "Omit function index section at the"
+ " expense of single-function patching performance">>;
def fxray_link_deps : Flag<["-"], "fxray-link-deps">, Group<f_Group>,
- Flags<[CC1Option]>,
- HelpText<"Tells clang to add the link dependencies for XRay.">;
-def fnoxray_link_deps : Flag<["-"], "fnoxray-link-deps">, Group<f_Group>,
- Flags<[CC1Option]>;
+ HelpText<"Link XRay runtime library when -fxray-instrument is specified (default)">;
+def fno_xray_link_deps : Flag<["-"], "fno-xray-link-deps">, Group<f_Group>;
def fxray_instrumentation_bundle :
- JoinedOrSeparate<["-"], "fxray-instrumentation-bundle=">,
- Group<f_Group>, Flags<[CC1Option]>,
+ Joined<["-"], "fxray-instrumentation-bundle=">,
+ Group<f_Group>, Visibility<[ClangOption, CC1Option]>,
HelpText<"Select which XRay instrumentation points to emit. Options: all, none, function-entry, function-exit, function, custom. Default is 'all'. 'function' includes both 'function-entry' and 'function-exit'.">;
def fxray_function_groups :
Joined<["-"], "fxray-function-groups=">,
- Group<f_Group>, Flags<[CC1Option]>,
+ Group<f_Group>, Visibility<[ClangOption, CC1Option]>,
HelpText<"Only instrument 1 of N groups">,
MarshallingInfoInt<CodeGenOpts<"XRayTotalFunctionGroups">, "1">;
def fxray_selected_function_group :
Joined<["-"], "fxray-selected-function-group=">,
- Group<f_Group>, Flags<[CC1Option]>,
+ Group<f_Group>, Visibility<[ClangOption, CC1Option]>,
HelpText<"When using -fxray-function-groups, select which group of functions to instrument. Valid range is 0 to fxray-function-groups - 1">,
MarshallingInfoInt<CodeGenOpts<"XRaySelectedFunctionGroup">, "0">;
defm fine_grained_bitfield_accesses : BoolOption<"f", "fine-grained-bitfield-accesses",
CodeGenOpts<"FineGrainedBitfieldAccesses">, DefaultFalse,
- PosFlag<SetTrue, [], "Use separate accesses for consecutive bitfield runs with legal widths and alignments.">,
- NegFlag<SetFalse, [], "Use large-integer access for consecutive bitfield runs.">,
- BothFlags<[CC1Option]>>,
+ PosFlag<SetTrue, [], [ClangOption], "Use separate accesses for consecutive bitfield runs with legal widths and alignments.">,
+ NegFlag<SetFalse, [], [ClangOption], "Use large-integer access for consecutive bitfield runs.">,
+ BothFlags<[], [ClangOption, CC1Option]>>,
Group<f_clang_Group>;
def fexperimental_relative_cxx_abi_vtables :
Flag<["-"], "fexperimental-relative-c++-abi-vtables">,
- Group<f_clang_Group>, Flags<[CC1Option]>,
+ Group<f_clang_Group>, Visibility<[ClangOption, CC1Option]>,
HelpText<"Use the experimental C++ class ABI for classes with virtual tables">;
def fno_experimental_relative_cxx_abi_vtables :
Flag<["-"], "fno-experimental-relative-c++-abi-vtables">,
- Group<f_clang_Group>, Flags<[CC1Option]>,
+ Group<f_clang_Group>, Visibility<[ClangOption, CC1Option]>,
HelpText<"Do not use the experimental C++ class ABI for classes with virtual tables">;
+defm experimental_omit_vtable_rtti : BoolFOption<"experimental-omit-vtable-rtti",
+ LangOpts<"OmitVTableRTTI">, DefaultFalse,
+ PosFlag<SetTrue, [], [CC1Option], "Omit">,
+ NegFlag<SetFalse, [], [CC1Option], "Do not omit">,
+ BothFlags<[], [CC1Option], " the RTTI component from virtual tables">>;
+
def fcxx_abi_EQ : Joined<["-"], "fc++-abi=">,
- Group<f_clang_Group>, Flags<[CC1Option]>,
+ Group<f_clang_Group>, Visibility<[ClangOption, CC1Option]>,
HelpText<"C++ ABI to use. This will override the target C++ ABI.">;
def flat__namespace : Flag<["-"], "flat_namespace">;
def flax_vector_conversions_EQ : Joined<["-"], "flax-vector-conversions=">, Group<f_Group>,
- HelpText<"Enable implicit vector bit-casts">, Values<"none,integer,all">, Flags<[CC1Option]>,
+ HelpText<"Enable implicit vector bit-casts">, Values<"none,integer,all">,
+ Visibility<[ClangOption, CC1Option]>,
NormalizedValues<["LangOptions::LaxVectorConversionKind::None",
"LangOptions::LaxVectorConversionKind::Integer",
"LangOptions::LaxVectorConversionKind::All"]>,
@@ -1983,71 +2820,132 @@ def flax_vector_conversions : Flag<["-"], "flax-vector-conversions">, Group<f_Gr
def flimited_precision_EQ : Joined<["-"], "flimited-precision=">, Group<f_Group>;
def fapple_link_rtlib : Flag<["-"], "fapple-link-rtlib">, Group<f_Group>,
HelpText<"Force linking the clang builtins runtime library">;
-def flto_EQ : Joined<["-"], "flto=">, Flags<[CoreOption, CC1Option]>, Group<f_Group>,
- HelpText<"Set LTO mode to either 'full' or 'thin'">, Values<"thin,full">;
-def flto_EQ_jobserver : Flag<["-"], "flto=jobserver">, Group<f_Group>;
-def flto_EQ_auto : Flag<["-"], "flto=auto">, Group<f_Group>;
-def flto : Flag<["-"], "flto">, Flags<[CoreOption, CC1Option]>, Group<f_Group>,
- HelpText<"Enable LTO in 'full' mode">;
-def fno_lto : Flag<["-"], "fno-lto">, Flags<[CoreOption, CC1Option]>, Group<f_Group>,
+def flto_EQ : Joined<["-"], "flto=">,
+ Visibility<[ClangOption, CLOption, CC1Option, FC1Option, FlangOption]>,
+ Group<f_Group>,
+ HelpText<"Set LTO mode">, Values<"thin,full">;
+def flto_EQ_jobserver : Flag<["-"], "flto=jobserver">, Visibility<[ClangOption, FlangOption]>, Group<f_Group>,
+ Alias<flto_EQ>, AliasArgs<["full"]>, HelpText<"Enable LTO in 'full' mode">;
+def flto_EQ_auto : Flag<["-"], "flto=auto">, Visibility<[ClangOption, FlangOption]>, Group<f_Group>,
+ Alias<flto_EQ>, AliasArgs<["full"]>, HelpText<"Enable LTO in 'full' mode">;
+def flto : Flag<["-"], "flto">,
+ Visibility<[ClangOption, CLOption, CC1Option, FC1Option, FlangOption]>,
+ Group<f_Group>,
+ Alias<flto_EQ>, AliasArgs<["full"]>, HelpText<"Enable LTO in 'full' mode">;
+defm unified_lto : BoolFOption<"unified-lto",
+ CodeGenOpts<"UnifiedLTO">, DefaultFalse,
+ PosFlag<SetTrue, [], [ClangOption], "Use the unified LTO pipeline">,
+ NegFlag<SetFalse, [], [ClangOption], "Use distinct LTO pipelines">,
+ BothFlags<[], [ClangOption, CC1Option], "">>;
+def fno_lto : Flag<["-"], "fno-lto">,
+ Visibility<[ClangOption, CLOption, DXCOption, CC1Option, FlangOption]>, Group<f_Group>,
HelpText<"Disable LTO mode (default)">;
-def foffload_lto_EQ : Joined<["-"], "foffload-lto=">, Flags<[CoreOption]>, Group<f_Group>,
- HelpText<"Set LTO mode to either 'full' or 'thin' for offload compilation">, Values<"thin,full">;
-def foffload_lto : Flag<["-"], "foffload-lto">, Flags<[CoreOption]>, Group<f_Group>,
- HelpText<"Enable LTO in 'full' mode for offload compilation">;
-def fno_offload_lto : Flag<["-"], "fno-offload-lto">, Flags<[CoreOption]>, Group<f_Group>,
+def foffload_lto_EQ : Joined<["-"], "foffload-lto=">,
+ Visibility<[ClangOption, CLOption]>, Group<f_Group>,
+ HelpText<"Set LTO mode for offload compilation">, Values<"thin,full">;
+def foffload_lto : Flag<["-"], "foffload-lto">,
+ Visibility<[ClangOption, CLOption]>, Group<f_Group>,
+ Alias<foffload_lto_EQ>, AliasArgs<["full"]>, HelpText<"Enable LTO in 'full' mode for offload compilation">;
+def fno_offload_lto : Flag<["-"], "fno-offload-lto">,
+ Visibility<[ClangOption, CLOption]>, Group<f_Group>,
HelpText<"Disable LTO mode (default) for offload compilation">;
def flto_jobs_EQ : Joined<["-"], "flto-jobs=">,
- Flags<[CC1Option]>, Group<f_Group>,
+ Visibility<[ClangOption, CC1Option]>, Group<f_Group>,
HelpText<"Controls the backend parallelism of -flto=thin (default "
"of 0 means the number of threads will be derived from "
"the number of CPUs detected)">;
def fthinlto_index_EQ : Joined<["-"], "fthinlto-index=">,
- Flags<[CoreOption, CC1Option]>, Group<f_Group>,
+ Visibility<[ClangOption, CLOption, CC1Option]>, Group<f_Group>,
HelpText<"Perform ThinLTO importing using provided function summary index">;
def fthin_link_bitcode_EQ : Joined<["-"], "fthin-link-bitcode=">,
- Flags<[CoreOption, CC1Option]>, Group<f_Group>,
+ Visibility<[ClangOption, CLOption, CC1Option]>, Group<f_Group>,
HelpText<"Write minimized bitcode to <file> for the ThinLTO thin link only">,
MarshallingInfoString<CodeGenOpts<"ThinLinkBitcodeFile">>;
+defm fat_lto_objects : BoolFOption<"fat-lto-objects",
+ CodeGenOpts<"FatLTO">, DefaultFalse,
+ PosFlag<SetTrue, [], [ClangOption, CC1Option], "Enable">,
+ NegFlag<SetFalse, [], [ClangOption, CC1Option], "Disable">,
+ BothFlags<[], [ClangOption, CC1Option], " fat LTO object support">>;
def fmacro_backtrace_limit_EQ : Joined<["-"], "fmacro-backtrace-limit=">,
- Group<f_Group>, Flags<[NoXarchOption, CoreOption]>;
+ Group<f_Group>, Visibility<[ClangOption, CC1Option, CLOption]>,
+ HelpText<"Set the maximum number of entries to print in a macro expansion backtrace (0 = no limit)">,
+ MarshallingInfoInt<DiagnosticOpts<"MacroBacktraceLimit">, "DiagnosticOptions::DefaultMacroBacktraceLimit">;
+def fcaret_diagnostics_max_lines_EQ :
+ Joined<["-"], "fcaret-diagnostics-max-lines=">,
+ Group<f_Group>, Visibility<[ClangOption, CC1Option, CLOption, DXCOption]>,
+ HelpText<"Set the maximum number of source lines to show in a caret diagnostic (0 = no limit).">,
+ MarshallingInfoInt<DiagnosticOpts<"SnippetLineLimit">, "DiagnosticOptions::DefaultSnippetLineLimit">;
defm merge_all_constants : BoolFOption<"merge-all-constants",
CodeGenOpts<"MergeAllConstants">, DefaultFalse,
- PosFlag<SetTrue, [CC1Option, CoreOption], "Allow">, NegFlag<SetFalse, [], "Disallow">,
- BothFlags<[], " merging of constants">>;
-def fmessage_length_EQ : Joined<["-"], "fmessage-length=">, Group<f_Group>, Flags<[CC1Option]>,
+ PosFlag<SetTrue, [], [ClangOption, CC1Option, CLOption], "Allow">,
+ NegFlag<SetFalse, [], [ClangOption], "Disallow">,
+ BothFlags<[], [ClangOption], " merging of constants">>;
+def fmessage_length_EQ : Joined<["-"], "fmessage-length=">, Group<f_Group>,
+ Visibility<[ClangOption, CC1Option]>,
HelpText<"Format message diagnostics so that they fit within N columns">,
MarshallingInfoInt<DiagnosticOpts<"MessageLength">>;
-def fms_compatibility : Flag<["-"], "fms-compatibility">, Group<f_Group>, Flags<[CC1Option, CoreOption]>,
+def frandomize_layout_seed_EQ : Joined<["-"], "frandomize-layout-seed=">,
+ MetaVarName<"<seed>">, Group<f_clang_Group>,
+ Visibility<[ClangOption, CC1Option]>,
+ HelpText<"The seed used by the randomize structure layout feature">;
+def frandomize_layout_seed_file_EQ : Joined<["-"], "frandomize-layout-seed-file=">,
+ MetaVarName<"<file>">, Group<f_clang_Group>,
+ Visibility<[ClangOption, CC1Option]>,
+ HelpText<"File holding the seed used by the randomize structure layout feature">;
+def fms_compatibility : Flag<["-"], "fms-compatibility">, Group<f_Group>,
+ Visibility<[ClangOption, CC1Option, CLOption]>,
HelpText<"Enable full Microsoft Visual C++ compatibility">,
MarshallingInfoFlag<LangOpts<"MSVCCompat">>;
-def fms_extensions : Flag<["-"], "fms-extensions">, Group<f_Group>, Flags<[CC1Option, CoreOption]>,
+def fms_extensions : Flag<["-"], "fms-extensions">, Group<f_Group>,
+ Visibility<[ClangOption, CC1Option, CLOption]>,
HelpText<"Accept some non-standard constructs supported by the Microsoft compiler">,
MarshallingInfoFlag<LangOpts<"MicrosoftExt">>, ImpliedByAnyOf<[fms_compatibility.KeyPath]>;
defm asm_blocks : BoolFOption<"asm-blocks",
LangOpts<"AsmBlocks">, Default<fms_extensions.KeyPath>,
- PosFlag<SetTrue, [CC1Option]>, NegFlag<SetFalse>>;
-def fms_volatile : Flag<["-"], "fms-volatile">, Group<f_Group>, Flags<[CC1Option]>,
- MarshallingInfoFlag<CodeGenOpts<"MSVolatile">>;
-def fmsc_version : Joined<["-"], "fmsc-version=">, Group<f_Group>, Flags<[NoXarchOption, CoreOption]>,
+ PosFlag<SetTrue, [], [ClangOption, CC1Option]>,
+ NegFlag<SetFalse>>;
+defm ms_volatile : BoolFOption<"ms-volatile",
+ LangOpts<"MSVolatile">, DefaultFalse,
+ PosFlag<SetTrue, [], [ClangOption, CC1Option],
+ "Volatile loads and stores have acquire and release semantics">,
+ NegFlag<SetFalse>>;
+def fmsc_version : Joined<["-"], "fmsc-version=">, Group<f_Group>,
+ Visibility<[ClangOption, CLOption]>,
HelpText<"Microsoft compiler version number to report in _MSC_VER (0 = don't define it (default))">;
def fms_compatibility_version
: Joined<["-"], "fms-compatibility-version=">,
Group<f_Group>,
- Flags<[ CC1Option, CoreOption ]>,
+ Visibility<[ClangOption, CC1Option, CLOption]>,
HelpText<"Dot-separated value representing the Microsoft compiler "
"version number to report in _MSC_VER (0 = don't define it "
"(default))">;
+def fms_runtime_lib_EQ : Joined<["-"], "fms-runtime-lib=">, Group<f_Group>,
+ Flags<[]>, Visibility<[ClangOption, CLOption, FlangOption]>,
+ Values<"static,static_dbg,dll,dll_dbg">,
+ HelpText<"Select Windows run-time library">,
+ DocBrief<[{
+Specify Visual Studio C runtime library. "static" and "static_dbg" correspond
+to the cl flags /MT and /MTd which use the multithread, static version. "dll"
+and "dll_dbg" correspond to the cl flags /MD and /MDd which use the multithread,
+dll version.}]>;
+def fms_omit_default_lib : Joined<["-"], "fms-omit-default-lib">,
+ Group<f_Group>, Flags<[]>,
+ Visibility<[ClangOption, CLOption]>;
defm delayed_template_parsing : BoolFOption<"delayed-template-parsing",
LangOpts<"DelayedTemplateParsing">, DefaultFalse,
- PosFlag<SetTrue, [CC1Option], "Parse templated function definitions at the end of the translation unit">,
- NegFlag<SetFalse, [NoXarchOption], "Disable delayed template parsing">,
- BothFlags<[CoreOption]>>;
-def fms_memptr_rep_EQ : Joined<["-"], "fms-memptr-rep=">, Group<f_Group>, Flags<[CC1Option]>,
+ PosFlag<SetTrue, [], [ClangOption, CC1Option],
+ "Parse templated function definitions at the end of the translation unit">,
+ NegFlag<SetFalse, [], [], "Disable delayed template parsing">,
+ BothFlags<[], [ClangOption, CLOption]>>;
+def fms_memptr_rep_EQ : Joined<["-"], "fms-memptr-rep=">, Group<f_Group>,
+ Visibility<[ClangOption, CC1Option]>,
Values<"single,multiple,virtual">, NormalizedValuesScope<"LangOptions">,
NormalizedValues<["PPTMK_FullGeneralitySingleInheritance", "PPTMK_FullGeneralityMultipleInheritance",
"PPTMK_FullGeneralityVirtualInheritance"]>,
MarshallingInfoEnum<LangOpts<"MSPointerToMemberRepresentationMethod">, "PPTMK_BestCase">;
+def fms_kernel : Flag<["-"], "fms-kernel">, Group<f_Group>,
+ Visibility<[CC1Option]>,
+ MarshallingInfoFlag<LangOpts<"Kernel">>;
// __declspec is enabled by default for the PS4 by the driver, and also
// enabled for Microsoft Extensions or Borland Extensions, here.
//
@@ -2058,132 +2956,211 @@ def fms_memptr_rep_EQ : Joined<["-"], "fms-memptr-rep=">, Group<f_Group>, Flags<
// term here.
defm declspec : BoolOption<"f", "declspec",
LangOpts<"DeclSpecKeyword">, DefaultFalse,
- PosFlag<SetTrue, [], "Allow", [fms_extensions.KeyPath, fborland_extensions.KeyPath, cuda.KeyPath]>,
- NegFlag<SetFalse, [], "Disallow">,
- BothFlags<[CC1Option], " __declspec as a keyword">>, Group<f_clang_Group>;
+ PosFlag<SetTrue, [], [ClangOption], "Allow", [fms_extensions.KeyPath, fborland_extensions.KeyPath, cuda.KeyPath]>,
+ NegFlag<SetFalse, [], [ClangOption], "Disallow">,
+ BothFlags<[], [ClangOption, CC1Option],
+ " __declspec as a keyword">>, Group<f_clang_Group>;
def fmodules_cache_path : Joined<["-"], "fmodules-cache-path=">, Group<i_Group>,
- Flags<[NoXarchOption, CC1Option]>, MetaVarName<"<directory>">,
+ Flags<[]>, Visibility<[ClangOption, CC1Option]>,
+ MetaVarName<"<directory>">,
HelpText<"Specify the module cache path">;
def fmodules_user_build_path : Separate<["-"], "fmodules-user-build-path">, Group<i_Group>,
- Flags<[NoXarchOption, CC1Option]>, MetaVarName<"<directory>">,
+ Flags<[]>, Visibility<[ClangOption, CC1Option]>,
+ MetaVarName<"<directory>">,
HelpText<"Specify the module user build path">,
MarshallingInfoString<HeaderSearchOpts<"ModuleUserBuildPath">>;
def fprebuilt_module_path : Joined<["-"], "fprebuilt-module-path=">, Group<i_Group>,
- Flags<[NoXarchOption, CC1Option]>, MetaVarName<"<directory>">,
+ Flags<[]>, Visibility<[ClangOption, CC1Option]>,
+ MetaVarName<"<directory>">,
HelpText<"Specify the prebuilt module path">;
defm prebuilt_implicit_modules : BoolFOption<"prebuilt-implicit-modules",
HeaderSearchOpts<"EnablePrebuiltImplicitModules">, DefaultFalse,
- PosFlag<SetTrue, [], "Look up implicit modules in the prebuilt module path">,
- NegFlag<SetFalse>, BothFlags<[NoXarchOption, CC1Option]>>;
+ PosFlag<SetTrue, [], [ClangOption], "Look up implicit modules in the prebuilt module path">,
+ NegFlag<SetFalse>, BothFlags<[], [ClangOption, CC1Option]>>;
+
+def fmodule_output_EQ : Joined<["-"], "fmodule-output=">,
+ Flags<[NoXarchOption]>, Visibility<[ClangOption, CC1Option]>,
+ HelpText<"Save intermediate module file results when compiling a standard C++ module unit.">;
+def fmodule_output : Flag<["-"], "fmodule-output">, Flags<[NoXarchOption]>,
+ Visibility<[ClangOption, CC1Option]>,
+ HelpText<"Save intermediate module file results when compiling a standard C++ module unit.">;
+
+defm skip_odr_check_in_gmf : BoolOption<"f", "skip-odr-check-in-gmf",
+ LangOpts<"SkipODRCheckInGMF">, DefaultFalse,
+ PosFlag<SetTrue, [], [CC1Option],
+ "Skip ODR checks for decls in the global module fragment.">,
+ NegFlag<SetFalse, [], [CC1Option],
+ "Perform ODR checks for decls in the global module fragment.">>,
+ Group<f_Group>;
def fmodules_prune_interval : Joined<["-"], "fmodules-prune-interval=">, Group<i_Group>,
- Flags<[CC1Option]>, MetaVarName<"<seconds>">,
+ Visibility<[ClangOption, CC1Option]>, MetaVarName<"<seconds>">,
HelpText<"Specify the interval (in seconds) between attempts to prune the module cache">,
MarshallingInfoInt<HeaderSearchOpts<"ModuleCachePruneInterval">, "7 * 24 * 60 * 60">;
def fmodules_prune_after : Joined<["-"], "fmodules-prune-after=">, Group<i_Group>,
- Flags<[CC1Option]>, MetaVarName<"<seconds>">,
+ Visibility<[ClangOption, CC1Option]>, MetaVarName<"<seconds>">,
HelpText<"Specify the interval (in seconds) after which a module file will be considered unused">,
MarshallingInfoInt<HeaderSearchOpts<"ModuleCachePruneAfter">, "31 * 24 * 60 * 60">;
def fbuild_session_timestamp : Joined<["-"], "fbuild-session-timestamp=">,
- Group<i_Group>, Flags<[CC1Option]>, MetaVarName<"<time since Epoch in seconds>">,
+ Group<i_Group>, Visibility<[ClangOption, CC1Option]>,
+ MetaVarName<"<time since Epoch in seconds>">,
HelpText<"Time when the current build session started">,
MarshallingInfoInt<HeaderSearchOpts<"BuildSessionTimestamp">, "0", "uint64_t">;
def fbuild_session_file : Joined<["-"], "fbuild-session-file=">,
Group<i_Group>, MetaVarName<"<file>">,
HelpText<"Use the last modification time of <file> as the build session timestamp">;
def fmodules_validate_once_per_build_session : Flag<["-"], "fmodules-validate-once-per-build-session">,
- Group<i_Group>, Flags<[CC1Option]>,
+ Group<i_Group>, Visibility<[ClangOption, CC1Option]>,
HelpText<"Don't verify input files for the modules if the module has been "
"successfully validated or loaded during this build session">,
MarshallingInfoFlag<HeaderSearchOpts<"ModulesValidateOncePerBuildSession">>;
def fmodules_disable_diagnostic_validation : Flag<["-"], "fmodules-disable-diagnostic-validation">,
- Group<i_Group>, Flags<[CC1Option]>,
+ Group<i_Group>, Visibility<[ClangOption, CC1Option]>,
HelpText<"Disable validation of the diagnostic options when loading the module">,
MarshallingInfoNegativeFlag<HeaderSearchOpts<"ModulesValidateDiagnosticOptions">>;
defm modules_validate_system_headers : BoolOption<"f", "modules-validate-system-headers",
HeaderSearchOpts<"ModulesValidateSystemHeaders">, DefaultFalse,
- PosFlag<SetTrue, [CC1Option], "Validate the system headers that a module depends on when loading the module">,
- NegFlag<SetFalse, [NoXarchOption]>>, Group<i_Group>;
+ PosFlag<SetTrue, [], [ClangOption, CC1Option],
+ "Validate the system headers that a module depends on when loading the module">,
+ NegFlag<SetFalse, [], []>>, Group<i_Group>;
+def fno_modules_validate_textual_header_includes :
+ Flag<["-"], "fno-modules-validate-textual-header-includes">,
+ Group<f_Group>, Flags<[]>, Visibility<[ClangOption, CC1Option]>,
+ MarshallingInfoNegativeFlag<LangOpts<"ModulesValidateTextualHeaderIncludes">>,
+ HelpText<"Do not enforce -fmodules-decluse and private header restrictions for textual headers. "
+ "This flag will be removed in a future Clang release.">;
+defm modules_skip_diagnostic_options : BoolFOption<"modules-skip-diagnostic-options",
+ HeaderSearchOpts<"ModulesSkipDiagnosticOptions">, DefaultFalse,
+ PosFlag<SetTrue, [], [], "Disable writing diagnostic options">,
+ NegFlag<SetFalse>, BothFlags<[], [CC1Option]>>;
+defm modules_skip_header_search_paths : BoolFOption<"modules-skip-header-search-paths",
+ HeaderSearchOpts<"ModulesSkipHeaderSearchPaths">, DefaultFalse,
+ PosFlag<SetTrue, [], [], "Disable writing header search paths">,
+ NegFlag<SetFalse>, BothFlags<[], [CC1Option]>>;
+
+def fincremental_extensions :
+ Flag<["-"], "fincremental-extensions">,
+ Group<f_Group>, Visibility<[ClangOption, CC1Option]>,
+ HelpText<"Enable incremental processing extensions such as processing"
+ "statements on the global scope.">,
+ MarshallingInfoFlag<LangOpts<"IncrementalExtensions">>;
def fvalidate_ast_input_files_content:
Flag <["-"], "fvalidate-ast-input-files-content">,
- Group<f_Group>, Flags<[CC1Option]>,
+ Group<f_Group>, Visibility<[ClangOption, CC1Option]>,
HelpText<"Compute and store the hash of input files used to build an AST."
" Files with mismatching mtime's are considered valid"
" if both contents is identical">,
MarshallingInfoFlag<HeaderSearchOpts<"ValidateASTInputFilesContent">>;
+def fforce_check_cxx20_modules_input_files:
+ Flag <["-"], "fforce-check-cxx20-modules-input-files">,
+ Group<f_Group>, Visibility<[ClangOption, CC1Option]>,
+ HelpText<"Check the input source files from C++20 modules explicitly">,
+ MarshallingInfoFlag<HeaderSearchOpts<"ForceCheckCXX20ModulesInputFiles">>;
def fmodules_validate_input_files_content:
Flag <["-"], "fmodules-validate-input-files-content">,
- Group<f_Group>, Flags<[NoXarchOption]>,
+ Group<f_Group>,
HelpText<"Validate PCM input files based on content if mtime differs">;
def fno_modules_validate_input_files_content:
Flag <["-"], "fno_modules-validate-input-files-content">,
- Group<f_Group>, Flags<[NoXarchOption]>;
+ Group<f_Group>;
def fpch_validate_input_files_content:
Flag <["-"], "fpch-validate-input-files-content">,
- Group<f_Group>, Flags<[NoXarchOption]>,
+ Group<f_Group>,
HelpText<"Validate PCH input files based on content if mtime differs">;
def fno_pch_validate_input_files_content:
Flag <["-"], "fno_pch-validate-input-files-content">,
- Group<f_Group>, Flags<[NoXarchOption]>;
+ Group<f_Group>;
defm pch_instantiate_templates : BoolFOption<"pch-instantiate-templates",
LangOpts<"PCHInstantiateTemplates">, DefaultFalse,
- PosFlag<SetTrue, [], "Instantiate templates already while building a PCH">,
- NegFlag<SetFalse>, BothFlags<[CC1Option, CoreOption]>>;
-defm pch_codegen: OptInFFlag<"pch-codegen", "Generate ", "Do not generate ",
+ PosFlag<SetTrue, [], [ClangOption], "Instantiate templates already while building a PCH">,
+ NegFlag<SetFalse>, BothFlags<[], [ClangOption, CC1Option, CLOption]
+ >>;
+defm pch_codegen: OptInCC1FFlag<"pch-codegen", "Generate ", "Do not generate ",
"code for uses of this PCH that assumes an explicit object file will be built for the PCH">;
-defm pch_debuginfo: OptInFFlag<"pch-debuginfo", "Generate ", "Do not generate ",
+defm pch_debuginfo: OptInCC1FFlag<"pch-debuginfo", "Generate ", "Do not generate ",
"debug info for types in an object file built from this PCH and do not generate them elsewhere">;
def fimplicit_module_maps : Flag <["-"], "fimplicit-module-maps">, Group<f_Group>,
- Flags<[NoXarchOption, CC1Option, CoreOption]>,
+ Visibility<[ClangOption, CC1Option, CLOption]>,
HelpText<"Implicitly search the file system for module map files.">,
MarshallingInfoFlag<HeaderSearchOpts<"ImplicitModuleMaps">>;
-def fmodules_ts : Flag <["-"], "fmodules-ts">, Group<f_Group>,
- Flags<[CC1Option]>, HelpText<"Enable support for the C++ Modules TS">,
- MarshallingInfoFlag<LangOpts<"ModulesTS">>;
defm modules : BoolFOption<"modules",
- LangOpts<"Modules">, Default<!strconcat(fmodules_ts.KeyPath, "||", cpp_modules.KeyPath)>,
- PosFlag<SetTrue, [CC1Option], "Enable the 'modules' language feature">,
- NegFlag<SetFalse>, BothFlags<[NoXarchOption, CoreOption]>>;
-def fmodule_maps : Flag <["-"], "fmodule-maps">, Flags<[CoreOption]>, Alias<fimplicit_module_maps>;
+ LangOpts<"Modules">, Default<fcxx_modules.KeyPath>,
+ PosFlag<SetTrue, [], [ClangOption, CC1Option],
+ "Enable the 'modules' language feature">,
+ NegFlag<SetFalse>, BothFlags<
+ [NoXarchOption], [ClangOption, CLOption]>>;
+def fbuiltin_headers_in_system_modules : Flag <["-"], "fbuiltin-headers-in-system-modules">,
+ Group<f_Group>,
+ Visibility<[CC1Option]>,
+ ShouldParseIf<fmodules.KeyPath>,
+ HelpText<"builtin headers belong to system modules, and _Builtin_ modules are ignored for cstdlib headers">,
+ MarshallingInfoFlag<LangOpts<"BuiltinHeadersInSystemModules">>;
+def fmodule_maps : Flag <["-"], "fmodule-maps">,
+ Visibility<[ClangOption, CLOption]>, Alias<fimplicit_module_maps>;
def fmodule_name_EQ : Joined<["-"], "fmodule-name=">, Group<f_Group>,
- Flags<[NoXarchOption,CC1Option,CoreOption]>, MetaVarName<"<name>">,
+ Visibility<[ClangOption, CC1Option, CLOption]>,
+ MetaVarName<"<name>">,
HelpText<"Specify the name of the module to build">,
MarshallingInfoString<LangOpts<"ModuleName">>;
def fmodule_implementation_of : Separate<["-"], "fmodule-implementation-of">,
- Flags<[CC1Option,CoreOption]>, Alias<fmodule_name_EQ>;
-def fsystem_module : Flag<["-"], "fsystem-module">, Flags<[CC1Option,CoreOption]>,
+ Visibility<[ClangOption, CC1Option, CLOption]>,
+ Alias<fmodule_name_EQ>;
+def fsystem_module : Flag<["-"], "fsystem-module">,
+ Visibility<[ClangOption, CC1Option, CLOption]>,
HelpText<"Build this module as a system module. Only used with -emit-module">,
MarshallingInfoFlag<FrontendOpts<"IsSystemModule">>;
def fmodule_map_file : Joined<["-"], "fmodule-map-file=">,
- Group<f_Group>, Flags<[NoXarchOption,CC1Option,CoreOption]>, MetaVarName<"<file>">,
+ Group<f_Group>,
+ Visibility<[ClangOption, CC1Option, CLOption]>,
+ MetaVarName<"<file>">,
HelpText<"Load this module map file">,
MarshallingInfoStringVector<FrontendOpts<"ModuleMapFiles">>;
def fmodule_file : Joined<["-"], "fmodule-file=">,
- Group<i_Group>, Flags<[NoXarchOption,CC1Option,CoreOption]>, MetaVarName<"[<name>=]<file>">,
+ Group<i_Group>,
+ Visibility<[ClangOption, CC1Option, CLOption]>,
+ MetaVarName<"[<name>=]<file>">,
HelpText<"Specify the mapping of module name to precompiled module file, or load a module file if name is omitted.">;
def fmodules_ignore_macro : Joined<["-"], "fmodules-ignore-macro=">, Group<f_Group>,
- Flags<[CC1Option,CoreOption]>,
+ Visibility<[ClangOption, CC1Option, CLOption]>,
HelpText<"Ignore the definition of the given macro when building and loading modules">;
def fmodules_strict_decluse : Flag <["-"], "fmodules-strict-decluse">, Group<f_Group>,
- Flags<[NoXarchOption,CC1Option,CoreOption]>,
+ Visibility<[ClangOption, CC1Option, CLOption]>,
HelpText<"Like -fmodules-decluse but requires all headers to be in modules">,
MarshallingInfoFlag<LangOpts<"ModulesStrictDeclUse">>;
defm modules_decluse : BoolFOption<"modules-decluse",
LangOpts<"ModulesDeclUse">, Default<fmodules_strict_decluse.KeyPath>,
- PosFlag<SetTrue, [CC1Option], "Require declaration of modules used within a module">,
- NegFlag<SetFalse>, BothFlags<[NoXarchOption,CoreOption]>>;
+ PosFlag<SetTrue, [], [ClangOption, CC1Option],
+ "Require declaration of modules used within a module">,
+ NegFlag<SetFalse>, BothFlags<[], [ClangOption, CLOption]>>;
defm modules_search_all : BoolFOption<"modules-search-all",
LangOpts<"ModulesSearchAll">, DefaultFalse,
- PosFlag<SetTrue, [], "Search even non-imported modules to resolve references">,
- NegFlag<SetFalse>, BothFlags<[NoXarchOption, CC1Option,CoreOption]>>,
+ PosFlag<SetTrue, [], [ClangOption], "Search even non-imported modules to resolve references">,
+ NegFlag<SetFalse>, BothFlags<[], [ClangOption, CC1Option, CLOption]>>,
ShouldParseIf<fmodules.KeyPath>;
defm implicit_modules : BoolFOption<"implicit-modules",
LangOpts<"ImplicitModules">, DefaultTrue,
- NegFlag<SetFalse, [CC1Option]>, PosFlag<SetTrue>, BothFlags<[NoXarchOption,CoreOption]>>;
-def fretain_comments_from_system_headers : Flag<["-"], "fretain-comments-from-system-headers">, Group<f_Group>, Flags<[CC1Option]>,
+ NegFlag<SetFalse, [], [ClangOption, CC1Option]>,
+ PosFlag<SetTrue>, BothFlags<
+ [NoXarchOption], [ClangOption, CLOption]>>;
+def fno_modules_check_relocated : Joined<["-"], "fno-modules-check-relocated">,
+ Group<f_Group>, Visibility<[ClangOption, CC1Option]>,
+ HelpText<"Skip checks for relocated modules when loading PCM files">,
+ MarshallingInfoNegativeFlag<PreprocessorOpts<"ModulesCheckRelocated">>;
+def fretain_comments_from_system_headers : Flag<["-"], "fretain-comments-from-system-headers">, Group<f_Group>,
+ Visibility<[ClangOption, CC1Option]>,
MarshallingInfoFlag<LangOpts<"RetainCommentsFromSystemHeaders">>;
+def fmodule_header : Flag <["-"], "fmodule-header">, Group<f_Group>,
+ HelpText<"Build a C++20 Header Unit from a header">;
+def fmodule_header_EQ : Joined<["-"], "fmodule-header=">, Group<f_Group>,
+ MetaVarName<"<kind>">,
+ HelpText<"Build a C++20 Header Unit from a header that should be found in the user (fmodule-header=user) or system (fmodule-header=system) search path.">;
+
+def fno_knr_functions : Flag<["-"], "fno-knr-functions">, Group<f_Group>,
+ MarshallingInfoFlag<LangOpts<"DisableKNRFunctions">>,
+ HelpText<"Disable support for K&R C function declarations">,
+ Visibility<[ClangOption, CC1Option, CLOption]>;
def fmudflapth : Flag<["-"], "fmudflapth">, Group<f_Group>;
def fmudflap : Flag<["-"], "fmudflap">, Group<f_Group>;
@@ -2193,121 +3170,140 @@ def fno_asm : Flag<["-"], "fno-asm">, Group<f_Group>;
def fno_asynchronous_unwind_tables : Flag<["-"], "fno-asynchronous-unwind-tables">, Group<f_Group>;
def fno_assume_sane_operator_new : Flag<["-"], "fno-assume-sane-operator-new">, Group<f_Group>,
HelpText<"Don't assume that C++'s global operator new can't alias any pointer">,
- Flags<[CC1Option]>, MarshallingInfoNegativeFlag<CodeGenOpts<"AssumeSaneOperatorNew">>;
-def fno_builtin : Flag<["-"], "fno-builtin">, Group<f_Group>, Flags<[CC1Option, CoreOption]>,
+ Visibility<[ClangOption, CC1Option]>,
+ MarshallingInfoNegativeFlag<CodeGenOpts<"AssumeSaneOperatorNew">>;
+def fno_builtin : Flag<["-"], "fno-builtin">, Group<f_Group>,
+ Visibility<[ClangOption, CC1Option, CLOption, DXCOption]>,
HelpText<"Disable implicit builtin knowledge of functions">;
-def fno_builtin_ : Joined<["-"], "fno-builtin-">, Group<f_Group>, Flags<[CC1Option, CoreOption]>,
+def fno_builtin_ : Joined<["-"], "fno-builtin-">, Group<f_Group>,
+ Visibility<[ClangOption, CC1Option, CLOption, DXCOption]>,
HelpText<"Disable implicit builtin knowledge of a specific function">;
-def fno_diagnostics_color : Flag<["-"], "fno-diagnostics-color">, Group<f_Group>,
- Flags<[CoreOption, NoXarchOption]>;
-def fno_common : Flag<["-"], "fno-common">, Group<f_Group>, Flags<[CC1Option]>,
+def fno_common : Flag<["-"], "fno-common">, Group<f_Group>,
+ Visibility<[ClangOption, CC1Option]>,
HelpText<"Compile common globals like normal definitions">;
-def fno_cxx_modules : Flag <["-"], "fno-cxx-modules">, Group<f_Group>,
- Flags<[NoXarchOption]>;
defm digraphs : BoolFOption<"digraphs",
LangOpts<"Digraphs">, Default<std#".hasDigraphs()">,
- PosFlag<SetTrue, [], "Enable alternative token representations '<:', ':>', '<%', '%>', '%:', '%:%:' (default)">,
- NegFlag<SetFalse, [], "Disallow alternative token representations '<:', ':>', '<%', '%>', '%:', '%:%:'">,
- BothFlags<[CC1Option]>>;
+ PosFlag<SetTrue, [], [ClangOption], "Enable alternative token representations '<:', ':>', '<%', '%>', '%:', '%:%:' (default)">,
+ NegFlag<SetFalse, [], [ClangOption], "Disallow alternative token representations '<:', ':>', '<%', '%>', '%:', '%:%:'">,
+ BothFlags<[], [ClangOption, CC1Option]>>;
def fno_eliminate_unused_debug_symbols : Flag<["-"], "fno-eliminate-unused-debug-symbols">, Group<f_Group>;
-def fno_inline_functions : Flag<["-"], "fno-inline-functions">, Group<f_clang_Group>, Flags<[CC1Option]>;
-def fno_inline : Flag<["-"], "fno-inline">, Group<f_clang_Group>, Flags<[CC1Option]>;
+def fno_inline_functions : Flag<["-"], "fno-inline-functions">, Group<f_clang_Group>,
+ Visibility<[ClangOption, CC1Option]>;
+def fno_inline : Flag<["-"], "fno-inline">, Group<f_clang_Group>,
+ Visibility<[ClangOption, CC1Option]>;
def fno_global_isel : Flag<["-"], "fno-global-isel">, Group<f_clang_Group>,
HelpText<"Disables the global instruction selector">;
def fno_experimental_isel : Flag<["-"], "fno-experimental-isel">, Group<f_clang_Group>,
Alias<fno_global_isel>;
-def fveclib : Joined<["-"], "fveclib=">, Group<f_Group>, Flags<[CC1Option]>,
+def fveclib : Joined<["-"], "fveclib=">, Group<f_Group>,
+ Visibility<[ClangOption, CC1Option, FlangOption, FC1Option]>,
HelpText<"Use the given vector functions library">,
- Values<"Accelerate,libmvec,MASSV,SVML,Darwin_libsystem_m,none">,
- NormalizedValuesScope<"CodeGenOptions">,
- NormalizedValues<["Accelerate", "LIBMVEC", "MASSV", "SVML",
- "Darwin_libsystem_m", "NoLibrary"]>,
+ Values<"Accelerate,libmvec,MASSV,SVML,SLEEF,Darwin_libsystem_m,ArmPL,none">,
+ NormalizedValuesScope<"llvm::driver::VectorLibrary">,
+ NormalizedValues<["Accelerate", "LIBMVEC", "MASSV", "SVML", "SLEEF",
+ "Darwin_libsystem_m", "ArmPL", "NoLibrary"]>,
MarshallingInfoEnum<CodeGenOpts<"VecLib">, "NoLibrary">;
def fno_lax_vector_conversions : Flag<["-"], "fno-lax-vector-conversions">, Group<f_Group>,
Alias<flax_vector_conversions_EQ>, AliasArgs<["none"]>;
-def fno_implicit_module_maps : Flag <["-"], "fno-implicit-module-maps">, Group<f_Group>,
- Flags<[NoXarchOption]>;
+def fno_implicit_module_maps : Flag <["-"], "fno-implicit-module-maps">, Group<f_Group>;
def fno_module_maps : Flag <["-"], "fno-module-maps">, Alias<fno_implicit_module_maps>;
-def fno_modules_strict_decluse : Flag <["-"], "fno-strict-modules-decluse">, Group<f_Group>,
- Flags<[NoXarchOption]>;
-def fmodule_file_deps : Flag <["-"], "fmodule-file-deps">, Group<f_Group>,
- Flags<[NoXarchOption]>;
-def fno_module_file_deps : Flag <["-"], "fno-module-file-deps">, Group<f_Group>,
- Flags<[NoXarchOption]>;
+def fno_modules_strict_decluse : Flag <["-"], "fno-strict-modules-decluse">, Group<f_Group>;
+def fmodule_file_deps : Flag <["-"], "fmodule-file-deps">, Group<f_Group>;
+def fno_module_file_deps : Flag <["-"], "fno-module-file-deps">, Group<f_Group>;
def fno_ms_extensions : Flag<["-"], "fno-ms-extensions">, Group<f_Group>,
- Flags<[CoreOption]>;
+ Visibility<[ClangOption, CLOption]>;
def fno_ms_compatibility : Flag<["-"], "fno-ms-compatibility">, Group<f_Group>,
- Flags<[CoreOption]>;
+ Visibility<[ClangOption, CLOption]>;
def fno_objc_legacy_dispatch : Flag<["-"], "fno-objc-legacy-dispatch">, Group<f_Group>;
-def fno_objc_weak : Flag<["-"], "fno-objc-weak">, Group<f_Group>, Flags<[CC1Option]>;
-def fno_omit_frame_pointer : Flag<["-"], "fno-omit-frame-pointer">, Group<f_Group>;
+def fno_objc_weak : Flag<["-"], "fno-objc-weak">, Group<f_Group>,
+ Visibility<[ClangOption, CC1Option]>;
+def fno_omit_frame_pointer : Flag<["-"], "fno-omit-frame-pointer">, Group<f_Group>,
+ Visibility<[ClangOption, FlangOption]>;
defm operator_names : BoolFOption<"operator-names",
LangOpts<"CXXOperatorNames">, Default<cplusplus.KeyPath>,
- NegFlag<SetFalse, [CC1Option], "Do not treat C++ operator name keywords as synonyms for operators">,
+ NegFlag<SetFalse, [], [ClangOption, CC1Option],
+ "Do not treat C++ operator name keywords as synonyms for operators">,
PosFlag<SetTrue>>;
def fdiagnostics_absolute_paths : Flag<["-"], "fdiagnostics-absolute-paths">, Group<f_Group>,
- Flags<[CC1Option, CoreOption]>, HelpText<"Print absolute paths in diagnostics">,
+ Visibility<[ClangOption, CC1Option, CLOption, DXCOption]>,
+ HelpText<"Print absolute paths in diagnostics">,
MarshallingInfoFlag<DiagnosticOpts<"AbsolutePath">>;
+defm diagnostics_show_line_numbers : BoolFOption<"diagnostics-show-line-numbers",
+ DiagnosticOpts<"ShowLineNumbers">, DefaultTrue,
+ NegFlag<SetFalse, [], [ClangOption, CC1Option],
+ "Show line numbers in diagnostic code snippets">,
+ PosFlag<SetTrue>>;
def fno_stack_protector : Flag<["-"], "fno-stack-protector">, Group<f_Group>,
HelpText<"Disable the use of stack protectors">;
def fno_strict_aliasing : Flag<["-"], "fno-strict-aliasing">, Group<f_Group>,
- Flags<[NoXarchOption, CoreOption]>;
+ Visibility<[ClangOption, CLOption, DXCOption]>,
+ HelpText<"Disable optimizations based on strict aliasing rules">;
def fstruct_path_tbaa : Flag<["-"], "fstruct-path-tbaa">, Group<f_Group>;
def fno_struct_path_tbaa : Flag<["-"], "fno-struct-path-tbaa">, Group<f_Group>;
def fno_strict_enums : Flag<["-"], "fno-strict-enums">, Group<f_Group>;
def fno_strict_overflow : Flag<["-"], "fno-strict-overflow">, Group<f_Group>;
def fno_temp_file : Flag<["-"], "fno-temp-file">, Group<f_Group>,
- Flags<[CC1Option, CoreOption]>, HelpText<
+ Visibility<[ClangOption, CC1Option, CLOption, DXCOption]>, HelpText<
"Directly create compilation output files. This may lead to incorrect incremental builds if the compiler crashes">,
MarshallingInfoNegativeFlag<FrontendOpts<"UseTemporary">>;
defm use_cxa_atexit : BoolFOption<"use-cxa-atexit",
CodeGenOpts<"CXAAtExit">, DefaultTrue,
- NegFlag<SetFalse, [CC1Option], "Don't use __cxa_atexit for calling destructors">,
+ NegFlag<SetFalse, [], [ClangOption, CC1Option],
+ "Don't use __cxa_atexit for calling destructors">,
PosFlag<SetTrue>>;
-def fno_unit_at_a_time : Flag<["-"], "fno-unit-at-a-time">, Group<f_Group>;
def fno_unwind_tables : Flag<["-"], "fno-unwind-tables">, Group<f_Group>;
-def fno_verbose_asm : Flag<["-"], "fno-verbose-asm">, Group<f_Group>, Flags<[CC1Option]>,
+def fno_verbose_asm : Flag<["-"], "fno-verbose-asm">, Group<f_Group>,
+ Visibility<[ClangOption, CC1Option]>,
MarshallingInfoNegativeFlag<CodeGenOpts<"AsmVerbose">>;
def fno_working_directory : Flag<["-"], "fno-working-directory">, Group<f_Group>;
def fno_wrapv : Flag<["-"], "fno-wrapv">, Group<f_Group>;
-def fobjc_arc : Flag<["-"], "fobjc-arc">, Group<f_Group>, Flags<[CC1Option]>,
+def fobjc_arc : Flag<["-"], "fobjc-arc">, Group<f_Group>,
+ Visibility<[ClangOption, CC1Option]>,
HelpText<"Synthesize retain and release calls for Objective-C pointers">;
def fno_objc_arc : Flag<["-"], "fno-objc-arc">, Group<f_Group>;
defm objc_encode_cxx_class_template_spec : BoolFOption<"objc-encode-cxx-class-template-spec",
LangOpts<"EncodeCXXClassTemplateSpec">, DefaultFalse,
- PosFlag<SetTrue, [CC1Option], "Fully encode c++ class template specialization">,
+ PosFlag<SetTrue, [], [ClangOption, CC1Option],
+ "Fully encode c++ class template specialization">,
NegFlag<SetFalse>>;
defm objc_convert_messages_to_runtime_calls : BoolFOption<"objc-convert-messages-to-runtime-calls",
CodeGenOpts<"ObjCConvertMessagesToRuntimeCalls">, DefaultTrue,
- NegFlag<SetFalse, [CC1Option]>, PosFlag<SetTrue>>;
+ NegFlag<SetFalse, [], [ClangOption, CC1Option]>,
+ PosFlag<SetTrue>>;
defm objc_arc_exceptions : BoolFOption<"objc-arc-exceptions",
CodeGenOpts<"ObjCAutoRefCountExceptions">, DefaultFalse,
- PosFlag<SetTrue, [CC1Option], "Use EH-safe code when synthesizing retains and releases in -fobjc-arc">,
+ PosFlag<SetTrue, [], [ClangOption, CC1Option],
+ "Use EH-safe code when synthesizing retains and releases in -fobjc-arc">,
NegFlag<SetFalse>>;
def fobjc_atdefs : Flag<["-"], "fobjc-atdefs">, Group<clang_ignored_f_Group>;
def fobjc_call_cxx_cdtors : Flag<["-"], "fobjc-call-cxx-cdtors">, Group<clang_ignored_f_Group>;
defm objc_exceptions : BoolFOption<"objc-exceptions",
LangOpts<"ObjCExceptions">, DefaultFalse,
- PosFlag<SetTrue, [CC1Option], "Enable Objective-C exceptions">, NegFlag<SetFalse>>;
+ PosFlag<SetTrue, [], [ClangOption, CC1Option],
+ "Enable Objective-C exceptions">,
+ NegFlag<SetFalse>>;
defm application_extension : BoolFOption<"application-extension",
LangOpts<"AppExt">, DefaultFalse,
- PosFlag<SetTrue, [CC1Option], "Restrict code to those available for App Extensions">,
+ PosFlag<SetTrue, [], [ClangOption, CC1Option],
+ "Restrict code to those available for App Extensions">,
NegFlag<SetFalse>>;
defm relaxed_template_template_args : BoolFOption<"relaxed-template-template-args",
LangOpts<"RelaxedTemplateTemplateArgs">, DefaultFalse,
- PosFlag<SetTrue, [CC1Option], "Enable C++17 relaxed template template argument matching">,
+ PosFlag<SetTrue, [], [ClangOption, CC1Option],
+ "Enable C++17 relaxed template template argument matching">,
NegFlag<SetFalse>>;
defm sized_deallocation : BoolFOption<"sized-deallocation",
LangOpts<"SizedDeallocation">, DefaultFalse,
- PosFlag<SetTrue, [CC1Option], "Enable C++14 sized global deallocation functions">,
+ PosFlag<SetTrue, [], [ClangOption, CC1Option],
+ "Enable C++14 sized global deallocation functions">,
NegFlag<SetFalse>>;
defm aligned_allocation : BoolFOption<"aligned-allocation",
LangOpts<"AlignedAllocation">, Default<cpp17.KeyPath>,
- PosFlag<SetTrue, [], "Enable C++17 aligned allocation functions">,
- NegFlag<SetFalse>, BothFlags<[CC1Option]>>;
+ PosFlag<SetTrue, [], [ClangOption], "Enable C++17 aligned allocation functions">,
+ NegFlag<SetFalse>, BothFlags<[], [ClangOption, CC1Option]>>;
def fnew_alignment_EQ : Joined<["-"], "fnew-alignment=">,
HelpText<"Specifies the largest alignment guaranteed by '::operator new(size_t)'">,
- MetaVarName<"<align>">, Group<f_Group>, Flags<[CC1Option]>,
+ MetaVarName<"<align>">, Group<f_Group>, Visibility<[ClangOption, CC1Option]>,
MarshallingInfoInt<LangOpts<"NewAlignOverride">>;
def : Separate<["-"], "fnew-alignment">, Alias<fnew_alignment_EQ>;
def : Flag<["-"], "faligned-new">, Alias<faligned_allocation>;
@@ -2318,14 +3314,17 @@ def fobjc_legacy_dispatch : Flag<["-"], "fobjc-legacy-dispatch">, Group<f_Group>
def fobjc_new_property : Flag<["-"], "fobjc-new-property">, Group<clang_ignored_f_Group>;
defm objc_infer_related_result_type : BoolFOption<"objc-infer-related-result-type",
LangOpts<"ObjCInferRelatedResultType">, DefaultTrue,
- NegFlag<SetFalse, [CC1Option], "do not infer Objective-C related result type based on method family">,
+ NegFlag<SetFalse, [], [ClangOption, CC1Option],
+ "do not infer Objective-C related result type based on method family">,
PosFlag<SetTrue>>;
def fobjc_link_runtime: Flag<["-"], "fobjc-link-runtime">, Group<f_Group>;
-def fobjc_weak : Flag<["-"], "fobjc-weak">, Group<f_Group>, Flags<[CC1Option]>,
+def fobjc_weak : Flag<["-"], "fobjc-weak">, Group<f_Group>,
+ Visibility<[ClangOption, CC1Option]>,
HelpText<"Enable ARC-style weak references in Objective-C">;
// Objective-C ABI options.
-def fobjc_runtime_EQ : Joined<["-"], "fobjc-runtime=">, Group<f_Group>, Flags<[CC1Option, CoreOption]>,
+def fobjc_runtime_EQ : Joined<["-"], "fobjc-runtime=">, Group<f_Group>,
+ Visibility<[ClangOption, CC1Option, CLOption]>,
HelpText<"Specify the target Objective-C runtime kind and version">;
def fobjc_abi_version_EQ : Joined<["-"], "fobjc-abi-version=">, Group<f_Group>;
def fobjc_nonfragile_abi_version_EQ : Joined<["-"], "fobjc-nonfragile-abi-version=">, Group<f_Group>;
@@ -2335,59 +3334,173 @@ def fno_objc_nonfragile_abi : Flag<["-"], "fno-objc-nonfragile-abi">, Group<f_Gr
def fobjc_sender_dependent_dispatch : Flag<["-"], "fobjc-sender-dependent-dispatch">, Group<f_Group>;
def fobjc_disable_direct_methods_for_testing :
Flag<["-"], "fobjc-disable-direct-methods-for-testing">,
- Group<f_Group>, Flags<[CC1Option]>,
+ Group<f_Group>, Visibility<[ClangOption, CC1Option]>,
HelpText<"Ignore attribute objc_direct so that direct methods can be tested">,
MarshallingInfoFlag<LangOpts<"ObjCDisableDirectMethodsForTesting">>;
-
-def fomit_frame_pointer : Flag<["-"], "fomit-frame-pointer">, Group<f_Group>;
-def fopenmp : Flag<["-"], "fopenmp">, Group<f_Group>, Flags<[CC1Option, NoArgumentUnused, FlangOption, FC1Option]>,
+defm objc_avoid_heapify_local_blocks : BoolFOption<"objc-avoid-heapify-local-blocks",
+ CodeGenOpts<"ObjCAvoidHeapifyLocalBlocks">, DefaultFalse,
+ PosFlag<SetTrue, [], [ClangOption], "Try">,
+ NegFlag<SetFalse, [], [ClangOption], "Don't try">,
+ BothFlags<[], [CC1Option], " to avoid heapifying local blocks">>;
+
+def fomit_frame_pointer : Flag<["-"], "fomit-frame-pointer">, Group<f_Group>,
+ Visibility<[ClangOption, FlangOption]>,
+ HelpText<"Omit the frame pointer from functions that don't need it. "
+ "Some stack unwinding cases, such as profilers and sanitizers, may prefer specifying -fno-omit-frame-pointer. "
+ "On many targets, -O1 and higher omit the frame pointer by default. "
+ "-m[no-]omit-leaf-frame-pointer takes precedence for leaf functions">;
+def fopenmp : Flag<["-"], "fopenmp">, Group<f_Group>,
+ Flags<[NoArgumentUnused]>,
+ Visibility<[ClangOption, CC1Option, FlangOption, FC1Option]>,
HelpText<"Parse OpenMP pragmas and generate parallel code.">;
-def fno_openmp : Flag<["-"], "fno-openmp">, Group<f_Group>, Flags<[NoArgumentUnused]>;
-def fopenmp_version_EQ : Joined<["-"], "fopenmp-version=">, Group<f_Group>, Flags<[CC1Option, NoArgumentUnused]>;
+def fno_openmp : Flag<["-"], "fno-openmp">, Group<f_Group>,
+ Flags<[NoArgumentUnused]>;
+def fopenmp_version_EQ : Joined<["-"], "fopenmp-version=">, Group<f_Group>,
+ Flags<[NoArgumentUnused]>,
+ Visibility<[ClangOption, CC1Option, FlangOption, FC1Option]>,
+ HelpText<"Set OpenMP version (e.g. 45 for OpenMP 4.5, 51 for OpenMP 5.1). Default value is 51 for Clang">;
+defm openmp_extensions: BoolFOption<"openmp-extensions",
+ LangOpts<"OpenMPExtensions">, DefaultTrue,
+ PosFlag<SetTrue, [NoArgumentUnused], [ClangOption, CC1Option],
+ "Enable all Clang extensions for OpenMP directives and clauses">,
+ NegFlag<SetFalse, [NoArgumentUnused], [ClangOption, CC1Option],
+ "Disable all Clang extensions for OpenMP directives and clauses">>;
def fopenmp_EQ : Joined<["-"], "fopenmp=">, Group<f_Group>;
def fopenmp_use_tls : Flag<["-"], "fopenmp-use-tls">, Group<f_Group>,
Flags<[NoArgumentUnused, HelpHidden]>;
def fnoopenmp_use_tls : Flag<["-"], "fnoopenmp-use-tls">, Group<f_Group>,
- Flags<[CC1Option, NoArgumentUnused, HelpHidden]>;
-def fopenmp_targets_EQ : CommaJoined<["-"], "fopenmp-targets=">, Flags<[NoXarchOption, CC1Option]>,
+ Flags<[NoArgumentUnused, HelpHidden]>, Visibility<[ClangOption, CC1Option]>;
+def fopenmp_targets_EQ : CommaJoined<["-"], "fopenmp-targets=">,
+ Flags<[NoXarchOption]>, Visibility<[ClangOption, CC1Option, FlangOption]>,
HelpText<"Specify comma-separated list of triples OpenMP offloading targets to be supported">;
def fopenmp_relocatable_target : Flag<["-"], "fopenmp-relocatable-target">,
- Group<f_Group>, Flags<[CC1Option, NoArgumentUnused, HelpHidden]>;
+ Group<f_Group>, Flags<[NoArgumentUnused, HelpHidden]>,
+ Visibility<[ClangOption, CC1Option]>;
def fnoopenmp_relocatable_target : Flag<["-"], "fnoopenmp-relocatable-target">,
- Group<f_Group>, Flags<[CC1Option, NoArgumentUnused, HelpHidden]>;
-def fopenmp_simd : Flag<["-"], "fopenmp-simd">, Group<f_Group>, Flags<[CC1Option, NoArgumentUnused]>,
+ Group<f_Group>, Flags<[NoArgumentUnused, HelpHidden]>,
+ Visibility<[ClangOption, CC1Option]>;
+def fopenmp_simd : Flag<["-"], "fopenmp-simd">, Group<f_Group>,
+ Flags<[NoArgumentUnused]>, Visibility<[ClangOption, CC1Option]>,
HelpText<"Emit OpenMP code only for SIMD-based constructs.">;
-def fopenmp_enable_irbuilder : Flag<["-"], "fopenmp-enable-irbuilder">, Group<f_Group>, Flags<[CC1Option, NoArgumentUnused, HelpHidden]>,
+def fopenmp_enable_irbuilder : Flag<["-"], "fopenmp-enable-irbuilder">, Group<f_Group>,
+ Flags<[NoArgumentUnused, HelpHidden]>, Visibility<[ClangOption, CC1Option]>,
HelpText<"Use the experimental OpenMP-IR-Builder codegen path.">;
-def fno_openmp_simd : Flag<["-"], "fno-openmp-simd">, Group<f_Group>, Flags<[CC1Option, NoArgumentUnused]>;
+def fno_openmp_simd : Flag<["-"], "fno-openmp-simd">, Group<f_Group>,
+ Flags<[NoArgumentUnused]>, Visibility<[ClangOption, CC1Option]>;
def fopenmp_cuda_mode : Flag<["-"], "fopenmp-cuda-mode">, Group<f_Group>,
- Flags<[CC1Option, NoArgumentUnused, HelpHidden]>;
+ Flags<[NoArgumentUnused, HelpHidden]>, Visibility<[ClangOption, CC1Option]>;
def fno_openmp_cuda_mode : Flag<["-"], "fno-openmp-cuda-mode">, Group<f_Group>,
Flags<[NoArgumentUnused, HelpHidden]>;
-def fopenmp_cuda_force_full_runtime : Flag<["-"], "fopenmp-cuda-force-full-runtime">, Group<f_Group>,
- Flags<[CC1Option, NoArgumentUnused, HelpHidden]>;
-def fno_openmp_cuda_force_full_runtime : Flag<["-"], "fno-openmp-cuda-force-full-runtime">, Group<f_Group>,
- Flags<[NoArgumentUnused, HelpHidden]>;
def fopenmp_cuda_number_of_sm_EQ : Joined<["-"], "fopenmp-cuda-number-of-sm=">, Group<f_Group>,
- Flags<[CC1Option, NoArgumentUnused, HelpHidden]>;
+ Flags<[NoArgumentUnused, HelpHidden]>, Visibility<[ClangOption, CC1Option]>;
def fopenmp_cuda_blocks_per_sm_EQ : Joined<["-"], "fopenmp-cuda-blocks-per-sm=">, Group<f_Group>,
- Flags<[CC1Option, NoArgumentUnused, HelpHidden]>;
+ Flags<[NoArgumentUnused, HelpHidden]>, Visibility<[ClangOption, CC1Option]>;
def fopenmp_cuda_teams_reduction_recs_num_EQ : Joined<["-"], "fopenmp-cuda-teams-reduction-recs-num=">, Group<f_Group>,
- Flags<[CC1Option, NoArgumentUnused, HelpHidden]>;
-defm openmp_target_new_runtime: BoolFOption<"openmp-target-new-runtime",
- LangOpts<"OpenMPTargetNewRuntime">, DefaultFalse,
- PosFlag<SetTrue, [CC1Option], "Use the new bitcode library for OpenMP offloading">,
- NegFlag<SetFalse>>;
+ Flags<[NoArgumentUnused, HelpHidden]>, Visibility<[ClangOption, CC1Option]>;
+
+//===----------------------------------------------------------------------===//
+// Shared cc1 + fc1 OpenMP Target Options
+//===----------------------------------------------------------------------===//
+
+let Flags = [NoArgumentUnused] in {
+let Visibility = [ClangOption, CC1Option, FC1Option, FlangOption] in {
+let Group = f_Group in {
+
+def fopenmp_target_debug : Flag<["-"], "fopenmp-target-debug">,
+ HelpText<"Enable debugging in the OpenMP offloading device RTL">;
+def fno_openmp_target_debug : Flag<["-"], "fno-openmp-target-debug">;
+
+} // let Group = f_Group
+} // let Visibility = [ClangOption, CC1Option, FC1Option]
+} // let Flags = [NoArgumentUnused]
+
+//===----------------------------------------------------------------------===//
+// FlangOption + FC1 + ClangOption + CC1Option
+//===----------------------------------------------------------------------===//
+let Visibility = [FC1Option, FlangOption, CC1Option, ClangOption] in {
+def fopenacc : Flag<["-"], "fopenacc">, Group<f_Group>,
+ HelpText<"Enable OpenACC">;
+} // let Visibility = [FC1Option, FlangOption, CC1Option, ClangOption]
+
+//===----------------------------------------------------------------------===//
+// Optimisation remark options
+//===----------------------------------------------------------------------===//
+
+let Visibility = [ClangOption, CC1Option, FC1Option, FlangOption] in {
+
+def Rpass_EQ : Joined<["-"], "Rpass=">, Group<R_value_Group>,
+ HelpText<"Report transformations performed by optimization passes whose "
+ "name matches the given POSIX regular expression">;
+def Rpass_missed_EQ : Joined<["-"], "Rpass-missed=">, Group<R_value_Group>,
+ HelpText<"Report missed transformations by optimization passes whose "
+ "name matches the given POSIX regular expression">;
+def Rpass_analysis_EQ : Joined<["-"], "Rpass-analysis=">, Group<R_value_Group>,
+ HelpText<"Report transformation analysis from optimization passes whose "
+ "name matches the given POSIX regular expression">;
+def R_Joined : Joined<["-"], "R">, Group<R_Group>,
+ Visibility<[ClangOption, CLOption, DXCOption]>,
+ MetaVarName<"<remark>">, HelpText<"Enable the specified remark">;
+
+} // let Visibility = [ClangOption, CC1Option, FC1Option, FlangOption]
+
+let Flags = [NoArgumentUnused, HelpHidden] in {
+let Visibility = [ClangOption, CC1Option, FC1Option, FlangOption] in {
+let Group = f_Group in {
+
+def fopenmp_target_debug_EQ : Joined<["-"], "fopenmp-target-debug=">;
+def fopenmp_assume_teams_oversubscription : Flag<["-"], "fopenmp-assume-teams-oversubscription">;
+def fopenmp_assume_threads_oversubscription : Flag<["-"], "fopenmp-assume-threads-oversubscription">;
+def fno_openmp_assume_teams_oversubscription : Flag<["-"], "fno-openmp-assume-teams-oversubscription">;
+def fno_openmp_assume_threads_oversubscription : Flag<["-"], "fno-openmp-assume-threads-oversubscription">;
+def fopenmp_assume_no_thread_state : Flag<["-"], "fopenmp-assume-no-thread-state">,
+ HelpText<"Assert no thread in a parallel region modifies an ICV">,
+ MarshallingInfoFlag<LangOpts<"OpenMPNoThreadState">>;
+def fopenmp_assume_no_nested_parallelism : Flag<["-"], "fopenmp-assume-no-nested-parallelism">,
+ HelpText<"Assert no nested parallel regions in the GPU">,
+ MarshallingInfoFlag<LangOpts<"OpenMPNoNestedParallelism">>;
+
+} // let Group = f_Group
+} // let Visibility = [ClangOption, CC1Option, FC1Option]
+} // let Flags = [NoArgumentUnused, HelpHidden]
+
+def fopenmp_offload_mandatory : Flag<["-"], "fopenmp-offload-mandatory">, Group<f_Group>,
+ Flags<[NoArgumentUnused]>, Visibility<[ClangOption, CC1Option]>,
+ HelpText<"Do not create a host fallback if offloading to the device fails.">,
+ MarshallingInfoFlag<LangOpts<"OpenMPOffloadMandatory">>;
+def fopenmp_force_usm : Flag<["-"], "fopenmp-force-usm">, Group<f_Group>,
+ Flags<[NoArgumentUnused]>, Visibility<[ClangOption, CC1Option]>,
+ HelpText<"Force behvaior as if the user specified pragma omp requires unified_shared_memory.">,
+ MarshallingInfoFlag<LangOpts<"OpenMPForceUSM">>;
+def fopenmp_target_jit : Flag<["-"], "fopenmp-target-jit">, Group<f_Group>,
+ Flags<[NoArgumentUnused]>, Visibility<[ClangOption, CLOption]>,
+ HelpText<"Emit code that can be JIT compiled for OpenMP offloading. Implies -foffload-lto=full">;
+def fno_openmp_target_jit : Flag<["-"], "fno-openmp-target-jit">, Group<f_Group>,
+ Flags<[NoArgumentUnused, HelpHidden]>,
+ Visibility<[ClangOption, CLOption]>;
+def fopenmp_target_new_runtime : Flag<["-"], "fopenmp-target-new-runtime">,
+ Group<f_Group>, Flags<[HelpHidden]>, Visibility<[ClangOption, CC1Option]>;
+def fno_openmp_target_new_runtime : Flag<["-"], "fno-openmp-target-new-runtime">,
+ Group<f_Group>, Flags<[HelpHidden]>, Visibility<[ClangOption, CC1Option]>;
defm openmp_optimistic_collapse : BoolFOption<"openmp-optimistic-collapse",
LangOpts<"OpenMPOptimisticCollapse">, DefaultFalse,
- PosFlag<SetTrue, [CC1Option]>, NegFlag<SetFalse>, BothFlags<[NoArgumentUnused, HelpHidden]>>;
+ PosFlag<SetTrue, [], [ClangOption, CC1Option]>,
+ NegFlag<SetFalse>, BothFlags<[NoArgumentUnused, HelpHidden], []>>;
def static_openmp: Flag<["-"], "static-openmp">,
HelpText<"Use the static host OpenMP runtime while linking.">;
-def fno_optimize_sibling_calls : Flag<["-"], "fno-optimize-sibling-calls">, Group<f_Group>;
+def fopenmp_new_driver : Flag<["-"], "fopenmp-new-driver">, Flags<[HelpHidden]>,
+ HelpText<"Use the new driver for OpenMP offloading.">;
+def fno_openmp_new_driver : Flag<["-"], "fno-openmp-new-driver">,
+ Flags<[HelpHidden]>,
+ HelpText<"Don't use the new driver for OpenMP offloading.">;
+def fno_optimize_sibling_calls : Flag<["-"], "fno-optimize-sibling-calls">, Group<f_Group>,
+ Visibility<[ClangOption, CC1Option]>,
+ HelpText<"Disable tail call optimization, keeping the call stack accurate">,
+ MarshallingInfoFlag<CodeGenOpts<"DisableTailCalls">>;
def foptimize_sibling_calls : Flag<["-"], "foptimize-sibling-calls">, Group<f_Group>;
defm escaping_block_tail_calls : BoolFOption<"escaping-block-tail-calls",
CodeGenOpts<"NoEscapingBlockTailCalls">, DefaultFalse,
- NegFlag<SetTrue, [CC1Option]>, PosFlag<SetFalse>>;
+ NegFlag<SetTrue, [], [ClangOption, CC1Option]>,
+ PosFlag<SetFalse>>;
def force__cpusubtype__ALL : Flag<["-"], "force_cpusubtype_ALL">;
def force__flat__namespace : Flag<["-"], "force_flat_namespace">;
def force__load : Separate<["-"], "force_load">;
@@ -2395,114 +3508,147 @@ def force_addr : Joined<["-"], "fforce-addr">, Group<clang_ignored_f_Group>;
def foutput_class_dir_EQ : Joined<["-"], "foutput-class-dir=">, Group<f_Group>;
def fpack_struct : Flag<["-"], "fpack-struct">, Group<f_Group>;
def fno_pack_struct : Flag<["-"], "fno-pack-struct">, Group<f_Group>;
-def fpack_struct_EQ : Joined<["-"], "fpack-struct=">, Group<f_Group>, Flags<[CC1Option]>,
+def fpack_struct_EQ : Joined<["-"], "fpack-struct=">, Group<f_Group>,
+ Visibility<[ClangOption, CC1Option]>,
HelpText<"Specify the default maximum struct packing alignment">,
MarshallingInfoInt<LangOpts<"PackStruct">>;
-def fmax_type_align_EQ : Joined<["-"], "fmax-type-align=">, Group<f_Group>, Flags<[CC1Option]>,
+def fmax_type_align_EQ : Joined<["-"], "fmax-type-align=">, Group<f_Group>,
+ Visibility<[ClangOption, CC1Option]>,
HelpText<"Specify the maximum alignment to enforce on pointers lacking an explicit alignment">,
MarshallingInfoInt<LangOpts<"MaxTypeAlign">>;
def fno_max_type_align : Flag<["-"], "fno-max-type-align">, Group<f_Group>;
defm pascal_strings : BoolFOption<"pascal-strings",
LangOpts<"PascalStrings">, DefaultFalse,
- PosFlag<SetTrue, [CC1Option], "Recognize and construct Pascal-style string literals">,
+ PosFlag<SetTrue, [], [ClangOption, CC1Option],
+ "Recognize and construct Pascal-style string literals">,
NegFlag<SetFalse>>;
// Note: This flag has different semantics in the driver and in -cc1. The driver accepts -fpatchable-function-entry=M,N
// and forwards it to -cc1 as -fpatchable-function-entry=M and -fpatchable-function-entry-offset=N. In -cc1, both flags
// are treated as a single integer.
-def fpatchable_function_entry_EQ : Joined<["-"], "fpatchable-function-entry=">, Group<f_Group>, Flags<[CC1Option]>,
+def fpatchable_function_entry_EQ : Joined<["-"], "fpatchable-function-entry=">, Group<f_Group>,
+ Visibility<[ClangOption, CC1Option]>,
MetaVarName<"<N,M>">, HelpText<"Generate M NOPs before function entry and N-M NOPs after function entry">,
MarshallingInfoInt<CodeGenOpts<"PatchableFunctionEntryCount">>;
-def fpcc_struct_return : Flag<["-"], "fpcc-struct-return">, Group<f_Group>, Flags<[CC1Option]>,
+def fms_hotpatch : Flag<["-"], "fms-hotpatch">, Group<f_Group>,
+ Visibility<[ClangOption, CC1Option, CLOption]>,
+ HelpText<"Ensure that all functions can be hotpatched at runtime">,
+ MarshallingInfoFlag<CodeGenOpts<"HotPatch">>;
+def fpcc_struct_return : Flag<["-"], "fpcc-struct-return">, Group<f_Group>,
+ Visibility<[ClangOption, CC1Option]>,
HelpText<"Override the default ABI to return all structs on the stack">;
def fpch_preprocess : Flag<["-"], "fpch-preprocess">, Group<f_Group>;
-def fpic : Flag<["-"], "fpic">, Group<f_Group>;
-def fno_pic : Flag<["-"], "fno-pic">, Group<f_Group>;
-def fpie : Flag<["-"], "fpie">, Group<f_Group>;
-def fno_pie : Flag<["-"], "fno-pie">, Group<f_Group>;
-def fdirect_access_external_data : Flag<["-"], "fdirect-access-external-data">, Group<f_Group>, Flags<[CC1Option]>,
+defm pic_data_is_text_relative : SimpleMFlag<"pic-data-is-text-relative",
+ "Assume", "Don't assume", " data segments are relative to text segment">;
+def fdirect_access_external_data : Flag<["-"], "fdirect-access-external-data">, Group<f_Group>,
+ Visibility<[ClangOption, CC1Option]>,
HelpText<"Don't use GOT indirection to reference external data symbols">;
-def fno_direct_access_external_data : Flag<["-"], "fno-direct-access-external-data">, Group<f_Group>, Flags<[CC1Option]>,
+def fno_direct_access_external_data : Flag<["-"], "fno-direct-access-external-data">, Group<f_Group>,
+ Visibility<[ClangOption, CC1Option]>,
HelpText<"Use GOT indirection to reference external data symbols">;
defm plt : BoolFOption<"plt",
CodeGenOpts<"NoPLT">, DefaultFalse,
- NegFlag<SetTrue, [CC1Option], "Use GOT indirection instead of PLT to make external function calls (x86 only)">,
+ NegFlag<SetTrue, [], [ClangOption, CC1Option],
+ "Use GOT indirection instead of PLT to make external function calls (x86 only)">,
PosFlag<SetFalse>>;
defm ropi : BoolFOption<"ropi",
LangOpts<"ROPI">, DefaultFalse,
- PosFlag<SetTrue, [CC1Option], "Generate read-only position independent code (ARM only)">,
- NegFlag<SetFalse>>;
+ PosFlag<SetTrue, [], [ClangOption, FlangOption, CC1Option],
+ "Generate read-only position independent code (ARM only)">,
+ NegFlag<SetFalse, [], [ClangOption, FlangOption, CC1Option]>>;
defm rwpi : BoolFOption<"rwpi",
LangOpts<"RWPI">, DefaultFalse,
- PosFlag<SetTrue, [CC1Option], "Generate read-write position independent code (ARM only)">,
- NegFlag<SetFalse>>;
-def fplugin_EQ : Joined<["-"], "fplugin=">, Group<f_Group>, Flags<[NoXarchOption]>, MetaVarName<"<dsopath>">,
+ PosFlag<SetTrue, [], [ClangOption, FlangOption, CC1Option],
+ "Generate read-write position independent code (ARM only)">,
+ NegFlag<SetFalse, [], [ClangOption, FlangOption, CC1Option]>>;
+def fplugin_EQ : Joined<["-"], "fplugin=">, Group<f_Group>,
+ Flags<[NoXarchOption]>, MetaVarName<"<dsopath>">,
HelpText<"Load the named plugin (dynamic shared object)">;
+def fplugin_arg : Joined<["-"], "fplugin-arg-">,
+ MetaVarName<"<name>-<arg>">,
+ HelpText<"Pass <arg> to plugin <name>">;
def fpass_plugin_EQ : Joined<["-"], "fpass-plugin=">,
- Group<f_Group>, Flags<[CC1Option]>, MetaVarName<"<dsopath>">,
+ Group<f_Group>, Visibility<[ClangOption, CC1Option, FlangOption, FC1Option]>,
+ MetaVarName<"<dsopath>">,
HelpText<"Load pass plugin from a dynamic shared object file (only with new pass manager).">,
MarshallingInfoStringVector<CodeGenOpts<"PassPlugins">>;
defm preserve_as_comments : BoolFOption<"preserve-as-comments",
CodeGenOpts<"PreserveAsmComments">, DefaultTrue,
- NegFlag<SetFalse, [CC1Option], "Do not preserve comments in inline assembly">,
+ NegFlag<SetFalse, [], [ClangOption, CC1Option],
+ "Do not preserve comments in inline assembly">,
PosFlag<SetTrue>>;
def framework : Separate<["-"], "framework">, Flags<[LinkerInput]>;
def frandom_seed_EQ : Joined<["-"], "frandom-seed=">, Group<clang_ignored_f_Group>;
-def freg_struct_return : Flag<["-"], "freg-struct-return">, Group<f_Group>, Flags<[CC1Option]>,
+def freg_struct_return : Flag<["-"], "freg-struct-return">, Group<f_Group>,
+ Visibility<[ClangOption, CC1Option]>,
HelpText<"Override the default ABI to return small structs in registers">;
defm rtti : BoolFOption<"rtti",
LangOpts<"RTTI">, Default<cplusplus.KeyPath>,
- NegFlag<SetFalse, [CC1Option], "Disable generation of rtti information">,
+ NegFlag<SetFalse, [], [ClangOption, CC1Option],
+ "Disable generation of rtti information">,
PosFlag<SetTrue>>, ShouldParseIf<cplusplus.KeyPath>;
defm rtti_data : BoolFOption<"rtti-data",
LangOpts<"RTTIData">, Default<frtti.KeyPath>,
- NegFlag<SetFalse, [CC1Option], "Disable generation of RTTI data">,
+ NegFlag<SetFalse, [], [ClangOption, CC1Option],
+ "Disable generation of RTTI data">,
PosFlag<SetTrue>>, ShouldParseIf<frtti.KeyPath>;
def : Flag<["-"], "fsched-interblock">, Group<clang_ignored_f_Group>;
defm short_enums : BoolFOption<"short-enums",
LangOpts<"ShortEnums">, DefaultFalse,
- PosFlag<SetTrue, [CC1Option], "Allocate to an enum type only as many bytes as it"
+ PosFlag<SetTrue, [], [ClangOption, CC1Option],
+ "Allocate to an enum type only as many bytes as it"
" needs for the declared range of possible values">,
NegFlag<SetFalse>>;
defm char8__t : BoolFOption<"char8_t",
LangOpts<"Char8">, Default<cpp20.KeyPath>,
- PosFlag<SetTrue, [], "Enable">, NegFlag<SetFalse, [], "Disable">,
- BothFlags<[CC1Option], " C++ builtin type char8_t">>;
+ PosFlag<SetTrue, [], [ClangOption], "Enable">,
+ NegFlag<SetFalse, [], [ClangOption], "Disable">,
+ BothFlags<[], [ClangOption, CC1Option], " C++ builtin type char8_t">>;
def fshort_wchar : Flag<["-"], "fshort-wchar">, Group<f_Group>,
HelpText<"Force wchar_t to be a short unsigned int">;
def fno_short_wchar : Flag<["-"], "fno-short-wchar">, Group<f_Group>,
HelpText<"Force wchar_t to be an unsigned int">;
-def fshow_overloads_EQ : Joined<["-"], "fshow-overloads=">, Group<f_Group>, Flags<[CC1Option]>,
- HelpText<"Which overload candidates to show when overload resolution fails: "
- "best|all; defaults to all">, Values<"best,all">,
+def fshow_overloads_EQ : Joined<["-"], "fshow-overloads=">, Group<f_Group>,
+ Visibility<[ClangOption, CC1Option]>,
+ HelpText<"Which overload candidates to show when overload resolution fails. Defaults to 'all'">,
+ Values<"best,all">,
NormalizedValues<["Ovl_Best", "Ovl_All"]>,
MarshallingInfoEnum<DiagnosticOpts<"ShowOverloads">, "Ovl_All">;
defm show_column : BoolFOption<"show-column",
DiagnosticOpts<"ShowColumn">, DefaultTrue,
- NegFlag<SetFalse, [CC1Option], "Do not include column number on diagnostics">,
+ NegFlag<SetFalse, [], [ClangOption, CC1Option],
+ "Do not include column number on diagnostics">,
PosFlag<SetTrue>>;
defm show_source_location : BoolFOption<"show-source-location",
DiagnosticOpts<"ShowLocation">, DefaultTrue,
- NegFlag<SetFalse, [CC1Option], "Do not include source location information with diagnostics">,
+ NegFlag<SetFalse, [], [ClangOption, CC1Option],
+ "Do not include source location information with diagnostics">,
PosFlag<SetTrue>>;
defm spell_checking : BoolFOption<"spell-checking",
LangOpts<"SpellChecking">, DefaultTrue,
- NegFlag<SetFalse, [CC1Option], "Disable spell-checking">, PosFlag<SetTrue>>;
-def fspell_checking_limit_EQ : Joined<["-"], "fspell-checking-limit=">, Group<f_Group>;
+ NegFlag<SetFalse, [], [ClangOption, CC1Option], "Disable spell-checking">,
+ PosFlag<SetTrue>>;
+def fspell_checking_limit_EQ : Joined<["-"], "fspell-checking-limit=">, Group<f_Group>,
+ Visibility<[ClangOption, CC1Option]>,
+ HelpText<"Set the maximum number of times to perform spell checking on unrecognized identifiers (0 = no limit)">,
+ MarshallingInfoInt<DiagnosticOpts<"SpellCheckingLimit">, "DiagnosticOptions::DefaultSpellCheckingLimit">;
def fsigned_bitfields : Flag<["-"], "fsigned-bitfields">, Group<f_Group>;
defm signed_char : BoolFOption<"signed-char",
LangOpts<"CharIsSigned">, DefaultTrue,
- NegFlag<SetFalse, [CC1Option], "char is unsigned">, PosFlag<SetTrue, [], "char is signed">>,
+ NegFlag<SetFalse, [], [ClangOption, CC1Option], "char is unsigned">,
+ PosFlag<SetTrue, [], [ClangOption], "char is signed">>,
ShouldParseIf<!strconcat("!", open_cl.KeyPath)>;
defm split_stack : BoolFOption<"split-stack",
CodeGenOpts<"EnableSegmentedStacks">, DefaultFalse,
- NegFlag<SetFalse, [], "Wouldn't use segmented stack">,
- PosFlag<SetTrue, [CC1Option], "Use segmented stack">>;
+ NegFlag<SetFalse, [], [ClangOption], "Wouldn't use segmented stack">,
+ PosFlag<SetTrue, [], [ClangOption, CC1Option], "Use segmented stack">>;
def fstack_protector_all : Flag<["-"], "fstack-protector-all">, Group<f_Group>,
HelpText<"Enable stack protectors for all functions">;
defm stack_clash_protection : BoolFOption<"stack-clash-protection",
CodeGenOpts<"StackClashProtector">, DefaultFalse,
- PosFlag<SetTrue, [CC1Option], "Enable">, NegFlag<SetFalse, [], "Disable">,
- BothFlags<[], " stack clash protection">>;
+ PosFlag<SetTrue, [], [ClangOption, CC1Option], "Enable">,
+ NegFlag<SetFalse, [], [ClangOption], "Disable">,
+ BothFlags<[], [ClangOption], " stack clash protection">>,
+ DocBrief<"Instrument stack allocation to prevent stack clash attacks">;
def fstack_protector_strong : Flag<["-"], "fstack-protector-strong">, Group<f_Group>,
HelpText<"Enable stack protectors for some functions vulnerable to stack smashing. "
"Compared to -fstack-protector, this uses a stronger heuristic "
@@ -2520,61 +3666,91 @@ def fstack_protector : Flag<["-"], "fstack-protector">, Group<f_Group>,
"overwrite the guard value before overwriting the function's return "
"address. The reference stack guard value is stored in a global variable.">;
def ftrivial_auto_var_init : Joined<["-"], "ftrivial-auto-var-init=">, Group<f_Group>,
- Flags<[CC1Option, CoreOption]>, HelpText<"Initialize trivial automatic stack variables: uninitialized (default)"
- " | pattern">, Values<"uninitialized,zero,pattern">,
+ Visibility<[ClangOption, CC1Option, CLOption, DXCOption]>,
+ HelpText<"Initialize trivial automatic stack variables. Defaults to 'uninitialized'">,
+ Values<"uninitialized,zero,pattern">,
NormalizedValuesScope<"LangOptions::TrivialAutoVarInitKind">,
NormalizedValues<["Uninitialized", "Zero", "Pattern"]>,
MarshallingInfoEnum<LangOpts<"TrivialAutoVarInit">, "Uninitialized">;
-def enable_trivial_var_init_zero : Flag<["-"], "enable-trivial-auto-var-init-zero-knowing-it-will-be-removed-from-clang">,
- Flags<[CC1Option, CoreOption]>,
- HelpText<"Trivial automatic variable initialization to zero is only here for benchmarks, it'll eventually be removed, and I'm OK with that because I'm only using it to benchmark">;
def ftrivial_auto_var_init_stop_after : Joined<["-"], "ftrivial-auto-var-init-stop-after=">, Group<f_Group>,
- Flags<[CC1Option, CoreOption]>, HelpText<"Stop initializing trivial automatic stack variables after the specified number of instances">,
+ Visibility<[ClangOption, CC1Option, CLOption, DXCOption]>,
+ HelpText<"Stop initializing trivial automatic stack variables after the specified number of instances">,
MarshallingInfoInt<LangOpts<"TrivialAutoVarInitStopAfter">>;
-def fstandalone_debug : Flag<["-"], "fstandalone-debug">, Group<f_Group>, Flags<[CoreOption]>,
+def ftrivial_auto_var_init_max_size : Joined<["-"], "ftrivial-auto-var-init-max-size=">, Group<f_Group>,
+ Visibility<[ClangOption, CC1Option, CLOption, DXCOption]>,
+ HelpText<"Stop initializing trivial automatic stack variables if var size exceeds the specified number of instances (in bytes)">,
+ MarshallingInfoInt<LangOpts<"TrivialAutoVarInitMaxSize">>;
+def fstandalone_debug : Flag<["-"], "fstandalone-debug">, Group<f_Group>,
+ Visibility<[ClangOption, CLOption, DXCOption]>,
HelpText<"Emit full debug info for all types used by the program">;
-def fno_standalone_debug : Flag<["-"], "fno-standalone-debug">, Group<f_Group>, Flags<[CoreOption]>,
+def fno_standalone_debug : Flag<["-"], "fno-standalone-debug">, Group<f_Group>,
+ Visibility<[ClangOption, CLOption, DXCOption]>,
HelpText<"Limit debug information produced to reduce size of debug binary">;
-def flimit_debug_info : Flag<["-"], "flimit-debug-info">, Flags<[CoreOption]>, Alias<fno_standalone_debug>;
-def fno_limit_debug_info : Flag<["-"], "fno-limit-debug-info">, Flags<[CoreOption]>, Alias<fstandalone_debug>;
-def fdebug_macro : Flag<["-"], "fdebug-macro">, Group<f_Group>, Flags<[CoreOption]>,
+def flimit_debug_info : Flag<["-"], "flimit-debug-info">,
+ Visibility<[ClangOption, CLOption, DXCOption]>, Alias<fno_standalone_debug>;
+def fno_limit_debug_info : Flag<["-"], "fno-limit-debug-info">,
+ Visibility<[ClangOption, CLOption, DXCOption]>, Alias<fstandalone_debug>;
+def fdebug_macro : Flag<["-"], "fdebug-macro">, Group<f_Group>,
+ Visibility<[ClangOption, CLOption, DXCOption]>,
HelpText<"Emit macro debug information">;
-def fno_debug_macro : Flag<["-"], "fno-debug-macro">, Group<f_Group>, Flags<[CoreOption]>,
+def fno_debug_macro : Flag<["-"], "fno-debug-macro">, Group<f_Group>,
+ Visibility<[ClangOption, CLOption, DXCOption]>,
HelpText<"Do not emit macro debug information">;
def fstrict_aliasing : Flag<["-"], "fstrict-aliasing">, Group<f_Group>,
- Flags<[NoXarchOption, CoreOption]>;
-def fstrict_enums : Flag<["-"], "fstrict-enums">, Group<f_Group>, Flags<[CC1Option]>,
+ Visibility<[ClangOption, CLOption, DXCOption]>,
+ HelpText<"Enable optimizations based on strict aliasing rules">;
+def fstrict_enums : Flag<["-"], "fstrict-enums">, Group<f_Group>,
+ Visibility<[ClangOption, CC1Option]>,
HelpText<"Enable optimizations based on the strict definition of an enum's "
"value range">,
MarshallingInfoFlag<CodeGenOpts<"StrictEnums">>;
defm strict_vtable_pointers : BoolFOption<"strict-vtable-pointers",
CodeGenOpts<"StrictVTablePointers">, DefaultFalse,
- PosFlag<SetTrue, [CC1Option], "Enable optimizations based on the strict rules for"
+ PosFlag<SetTrue, [], [ClangOption, CC1Option],
+ "Enable optimizations based on the strict rules for"
" overwriting polymorphic C++ objects">,
NegFlag<SetFalse>>;
def fstrict_overflow : Flag<["-"], "fstrict-overflow">, Group<f_Group>;
+def fdriver_only : Flag<["-"], "fdriver-only">, Flags<[NoXarchOption]>,
+ Visibility<[ClangOption, CLOption, DXCOption]>,
+ Group<Action_Group>, HelpText<"Only run the driver.">;
def fsyntax_only : Flag<["-"], "fsyntax-only">,
- Flags<[NoXarchOption,CoreOption,CC1Option,FC1Option]>, Group<Action_Group>;
+ Flags<[NoXarchOption]>,
+ Visibility<[ClangOption, CLOption, DXCOption, CC1Option, FC1Option, FlangOption]>,
+ Group<Action_Group>,
+ HelpText<"Run the preprocessor, parser and semantic analysis stages">;
def ftabstop_EQ : Joined<["-"], "ftabstop=">, Group<f_Group>;
-def ftemplate_depth_EQ : Joined<["-"], "ftemplate-depth=">, Group<f_Group>;
-def ftemplate_depth_ : Joined<["-"], "ftemplate-depth-">, Group<f_Group>;
-def ftemplate_backtrace_limit_EQ : Joined<["-"], "ftemplate-backtrace-limit=">,
- Group<f_Group>;
-def foperator_arrow_depth_EQ : Joined<["-"], "foperator-arrow-depth=">,
- Group<f_Group>;
+def ftemplate_depth_EQ : Joined<["-"], "ftemplate-depth=">, Group<f_Group>,
+ Visibility<[ClangOption, CC1Option]>,
+ HelpText<"Set the maximum depth of recursive template instantiation">,
+ MarshallingInfoInt<LangOpts<"InstantiationDepth">, "1024">;
+def : Joined<["-"], "ftemplate-depth-">, Group<f_Group>, Alias<ftemplate_depth_EQ>;
+def ftemplate_backtrace_limit_EQ : Joined<["-"], "ftemplate-backtrace-limit=">, Group<f_Group>,
+ Visibility<[ClangOption, CC1Option]>,
+ HelpText<"Set the maximum number of entries to print in a template instantiation backtrace (0 = no limit)">,
+ MarshallingInfoInt<DiagnosticOpts<"TemplateBacktraceLimit">, "DiagnosticOptions::DefaultTemplateBacktraceLimit">;
+def foperator_arrow_depth_EQ : Joined<["-"], "foperator-arrow-depth=">, Group<f_Group>,
+ Visibility<[ClangOption, CC1Option]>,
+ HelpText<"Maximum number of 'operator->'s to call for a member access">,
+ MarshallingInfoInt<LangOpts<"ArrowDepth">, "256">;
def fsave_optimization_record : Flag<["-"], "fsave-optimization-record">,
+ Visibility<[ClangOption, FlangOption]>,
Group<f_Group>, HelpText<"Generate a YAML optimization record file">;
def fsave_optimization_record_EQ : Joined<["-"], "fsave-optimization-record=">,
+ Visibility<[ClangOption, FlangOption]>,
Group<f_Group>, HelpText<"Generate an optimization record file in a specific format">,
MetaVarName<"<format>">;
def fno_save_optimization_record : Flag<["-"], "fno-save-optimization-record">,
- Group<f_Group>, Flags<[NoArgumentUnused]>;
+ Group<f_Group>, Flags<[NoArgumentUnused]>,
+ Visibility<[ClangOption, FlangOption]>;
def foptimization_record_file_EQ : Joined<["-"], "foptimization-record-file=">,
+ Visibility<[ClangOption, FlangOption]>,
Group<f_Group>,
HelpText<"Specify the output name of the file containing the optimization remarks. Implies -fsave-optimization-record. On Darwin platforms, this cannot be used with multiple -arch <arch> options.">,
MetaVarName<"<file>">;
def foptimization_record_passes_EQ : Joined<["-"], "foptimization-record-passes=">,
+ Visibility<[ClangOption, FlangOption]>,
Group<f_Group>,
HelpText<"Only include passes which match a specified regular expression in the generated optimization record (by default, include all passes)">,
MetaVarName<"<regex>">;
@@ -2592,7 +3768,8 @@ def : Flag<["-"], "fno-tree-slp-vectorize">, Alias<fno_slp_vectorize>;
def Wlarge_by_value_copy_def : Flag<["-"], "Wlarge-by-value-copy">,
HelpText<"Warn if a function definition returns or accepts an object larger "
"in bytes than a given value">, Flags<[HelpHidden]>;
-def Wlarge_by_value_copy_EQ : Joined<["-"], "Wlarge-by-value-copy=">, Flags<[CC1Option]>,
+def Wlarge_by_value_copy_EQ : Joined<["-"], "Wlarge-by-value-copy=">,
+ Visibility<[ClangOption, CC1Option]>,
MarshallingInfoInt<LangOpts<"NumLargeByValueCopy">>;
// These "special" warning flags are effectively processed as f_Group flags by the driver:
@@ -2603,79 +3780,92 @@ def Wlarger_than_ : Joined<["-"], "Wlarger-than-">, Alias<Wlarger_than_EQ>;
// This is converted to -fwarn-stack-size=N and also passed through by the driver.
// FIXME: The driver should strip out the =<value> when passing W_value_Group through.
def Wframe_larger_than_EQ : Joined<["-"], "Wframe-larger-than=">, Group<W_value_Group>,
- Flags<[NoXarchOption, CC1Option]>;
+ Visibility<[ClangOption, CC1Option]>;
def Wframe_larger_than : Flag<["-"], "Wframe-larger-than">, Alias<Wframe_larger_than_EQ>;
def : Flag<["-"], "fterminated-vtables">, Alias<fapple_kext>;
defm threadsafe_statics : BoolFOption<"threadsafe-statics",
LangOpts<"ThreadsafeStatics">, DefaultTrue,
- NegFlag<SetFalse, [CC1Option], "Do not emit code to make initialization of local statics thread safe">,
+ NegFlag<SetFalse, [], [ClangOption, CC1Option],
+ "Do not emit code to make initialization of local statics thread safe">,
PosFlag<SetTrue>>;
-def ftime_report : Flag<["-"], "ftime-report">, Group<f_Group>, Flags<[CC1Option]>,
+def ftime_report : Flag<["-"], "ftime-report">, Group<f_Group>,
+ Visibility<[ClangOption, CC1Option]>,
MarshallingInfoFlag<CodeGenOpts<"TimePasses">>;
def ftime_report_EQ: Joined<["-"], "ftime-report=">, Group<f_Group>,
- Flags<[CC1Option]>, Values<"per-pass,per-pass-run">,
+ Visibility<[ClangOption, CC1Option]>, Values<"per-pass,per-pass-run">,
MarshallingInfoFlag<CodeGenOpts<"TimePassesPerRun">>,
- HelpText<"(For new pass manager) \"per-pass\": one report for each pass; "
- "\"per-pass-run\": one report for each pass invocation">;
+ HelpText<"(For new pass manager) 'per-pass': one report for each pass; "
+ "'per-pass-run': one report for each pass invocation">;
def ftime_trace : Flag<["-"], "ftime-trace">, Group<f_Group>,
HelpText<"Turn on time profiler. Generates JSON file based on output filename.">,
DocBrief<[{
Turn on time profiler. Generates JSON file based on output filename. Results
can be analyzed with chrome://tracing or `Speedscope App
<https://www.speedscope.app>`_ for flamegraph visualization.}]>,
- Flags<[CC1Option, CoreOption]>,
- MarshallingInfoFlag<FrontendOpts<"TimeTrace">>;
+ Visibility<[ClangOption, CLOption, DXCOption]>;
def ftime_trace_granularity_EQ : Joined<["-"], "ftime-trace-granularity=">, Group<f_Group>,
HelpText<"Minimum time granularity (in microseconds) traced by time profiler">,
- Flags<[CC1Option, CoreOption]>,
+ Visibility<[ClangOption, CC1Option, CLOption, DXCOption]>,
MarshallingInfoInt<FrontendOpts<"TimeTraceGranularity">, "500u">;
+def ftime_trace_EQ : Joined<["-"], "ftime-trace=">, Group<f_Group>,
+ HelpText<"Similar to -ftime-trace. Specify the JSON file or a directory which will contain the JSON file">,
+ Visibility<[ClangOption, CC1Option, CLOption, DXCOption]>,
+ MarshallingInfoString<FrontendOpts<"TimeTracePath">>;
def fproc_stat_report : Joined<["-"], "fproc-stat-report">, Group<f_Group>,
HelpText<"Print subprocess statistics">;
def fproc_stat_report_EQ : Joined<["-"], "fproc-stat-report=">, Group<f_Group>,
HelpText<"Save subprocess statistics to the given file">;
-def ftlsmodel_EQ : Joined<["-"], "ftls-model=">, Group<f_Group>, Flags<[CC1Option]>,
+def ftlsmodel_EQ : Joined<["-"], "ftls-model=">, Group<f_Group>,
+ Visibility<[ClangOption, CC1Option]>,
Values<"global-dynamic,local-dynamic,initial-exec,local-exec">,
NormalizedValuesScope<"CodeGenOptions">,
NormalizedValues<["GeneralDynamicTLSModel", "LocalDynamicTLSModel", "InitialExecTLSModel", "LocalExecTLSModel"]>,
MarshallingInfoEnum<CodeGenOpts<"DefaultTLSModel">, "GeneralDynamicTLSModel">;
-def ftrapv : Flag<["-"], "ftrapv">, Group<f_Group>, Flags<[CC1Option]>,
+def ftrapv : Flag<["-"], "ftrapv">, Group<f_Group>,
+ Visibility<[ClangOption, CC1Option]>,
HelpText<"Trap on integer overflow">;
def ftrapv_handler_EQ : Joined<["-"], "ftrapv-handler=">, Group<f_Group>,
MetaVarName<"<function name>">,
HelpText<"Specify the function to be called on overflow">;
-def ftrapv_handler : Separate<["-"], "ftrapv-handler">, Group<f_Group>, Flags<[CC1Option]>;
-def ftrap_function_EQ : Joined<["-"], "ftrap-function=">, Group<f_Group>, Flags<[CC1Option]>,
+def ftrapv_handler : Separate<["-"], "ftrapv-handler">, Group<f_Group>,
+ Visibility<[ClangOption, CC1Option]>;
+def ftrap_function_EQ : Joined<["-"], "ftrap-function=">, Group<f_Group>,
+ Visibility<[ClangOption, CC1Option]>,
HelpText<"Issue call to specified function rather than a trap instruction">,
MarshallingInfoString<CodeGenOpts<"TrapFuncName">>;
-def funit_at_a_time : Flag<["-"], "funit-at-a-time">, Group<f_Group>;
def funroll_loops : Flag<["-"], "funroll-loops">, Group<f_Group>,
- HelpText<"Turn on loop unroller">, Flags<[CC1Option]>;
+ HelpText<"Turn on loop unroller">, Visibility<[ClangOption, CC1Option]>;
def fno_unroll_loops : Flag<["-"], "fno-unroll-loops">, Group<f_Group>,
- HelpText<"Turn off loop unroller">, Flags<[CC1Option]>;
+ HelpText<"Turn off loop unroller">, Visibility<[ClangOption, CC1Option]>;
defm reroll_loops : BoolFOption<"reroll-loops",
CodeGenOpts<"RerollLoops">, DefaultFalse,
- PosFlag<SetTrue, [CC1Option], "Turn on loop reroller">, NegFlag<SetFalse>>;
+ PosFlag<SetTrue, [], [ClangOption, CC1Option], "Turn on loop reroller">,
+ NegFlag<SetFalse>>;
def ffinite_loops: Flag<["-"], "ffinite-loops">, Group<f_Group>,
- HelpText<"Assume all loops are finite.">, Flags<[CC1Option]>;
+ HelpText<"Assume all loops are finite.">, Visibility<[ClangOption, CC1Option]>;
def fno_finite_loops: Flag<["-"], "fno-finite-loops">, Group<f_Group>,
- HelpText<"Do not assume that any loop is finite.">, Flags<[CC1Option]>;
+ HelpText<"Do not assume that any loop is finite.">,
+ Visibility<[ClangOption, CC1Option]>;
def ftrigraphs : Flag<["-"], "ftrigraphs">, Group<f_Group>,
- HelpText<"Process trigraph sequences">, Flags<[CC1Option]>;
+ HelpText<"Process trigraph sequences">, Visibility<[ClangOption, CC1Option]>;
def fno_trigraphs : Flag<["-"], "fno-trigraphs">, Group<f_Group>,
- HelpText<"Do not process trigraph sequences">, Flags<[CC1Option]>;
+ HelpText<"Do not process trigraph sequences">,
+ Visibility<[ClangOption, CC1Option]>;
def funsigned_bitfields : Flag<["-"], "funsigned-bitfields">, Group<f_Group>;
def funsigned_char : Flag<["-"], "funsigned-char">, Group<f_Group>;
def fno_unsigned_char : Flag<["-"], "fno-unsigned-char">;
def funwind_tables : Flag<["-"], "funwind-tables">, Group<f_Group>;
defm register_global_dtors_with_atexit : BoolFOption<"register-global-dtors-with-atexit",
CodeGenOpts<"RegisterGlobalDtorsWithAtExit">, DefaultFalse,
- PosFlag<SetTrue, [CC1Option], "Use">, NegFlag<SetFalse, [], "Don't use">,
- BothFlags<[], " atexit or __cxa_atexit to register global destructors">>;
+ PosFlag<SetTrue, [], [ClangOption, CC1Option], "Use">,
+ NegFlag<SetFalse, [], [ClangOption], "Don't use">,
+ BothFlags<[], [ClangOption], " atexit or __cxa_atexit to register global destructors">>;
defm use_init_array : BoolFOption<"use-init-array",
CodeGenOpts<"UseInitArray">, DefaultTrue,
- NegFlag<SetFalse, [CC1Option], "Use .ctors/.dtors instead of .init_array/.fini_array">,
+ NegFlag<SetFalse, [], [ClangOption, CC1Option],
+ "Use .ctors/.dtors instead of .init_array/.fini_array">,
PosFlag<SetTrue>>;
def fno_var_tracking : Flag<["-"], "fno-var-tracking">, Group<clang_ignored_f_Group>;
def fverbose_asm : Flag<["-"], "fverbose-asm">, Group<f_Group>,
@@ -2683,166 +3873,256 @@ def fverbose_asm : Flag<["-"], "fverbose-asm">, Group<f_Group>,
def dA : Flag<["-"], "dA">, Alias<fverbose_asm>;
defm visibility_from_dllstorageclass : BoolFOption<"visibility-from-dllstorageclass",
LangOpts<"VisibilityFromDLLStorageClass">, DefaultFalse,
- PosFlag<SetTrue, [CC1Option], "Set the visiblity of symbols in the generated code from their DLL storage class">,
+ PosFlag<SetTrue, [], [ClangOption, CC1Option],
+ "Override the visibility of globals based on their final DLL storage class.">,
NegFlag<SetFalse>>;
-def fvisibility_dllexport_EQ : Joined<["-"], "fvisibility-dllexport=">, Group<f_Group>, Flags<[CC1Option]>,
- HelpText<"The visibility for dllexport defintions [-fvisibility-from-dllstorageclass]">,
- MarshallingInfoVisibility<LangOpts<"DLLExportVisibility">, "DefaultVisibility">,
+class MarshallingInfoVisibilityFromDLLStorage<KeyPathAndMacro kpm, code default>
+ : MarshallingInfoEnum<kpm, default>,
+ Values<"keep,hidden,protected,default">,
+ NormalizedValuesScope<"LangOptions::VisibilityFromDLLStorageClassKinds">,
+ NormalizedValues<["Keep", "Hidden", "Protected", "Default"]> {}
+def fvisibility_dllexport_EQ : Joined<["-"], "fvisibility-dllexport=">, Group<f_Group>,
+ Visibility<[ClangOption, CC1Option]>,
+ HelpText<"The visibility for dllexport definitions. If Keep is specified the visibility is not adjusted [-fvisibility-from-dllstorageclass]">,
+ MarshallingInfoVisibilityFromDLLStorage<LangOpts<"DLLExportVisibility">, "Default">,
ShouldParseIf<fvisibility_from_dllstorageclass.KeyPath>;
-def fvisibility_nodllstorageclass_EQ : Joined<["-"], "fvisibility-nodllstorageclass=">, Group<f_Group>, Flags<[CC1Option]>,
- HelpText<"The visibility for defintiions without an explicit DLL export class [-fvisibility-from-dllstorageclass]">,
- MarshallingInfoVisibility<LangOpts<"NoDLLStorageClassVisibility">, "HiddenVisibility">,
+def fvisibility_nodllstorageclass_EQ : Joined<["-"], "fvisibility-nodllstorageclass=">, Group<f_Group>,
+ Visibility<[ClangOption, CC1Option]>,
+ HelpText<"The visibility for definitions without an explicit DLL storage class. If Keep is specified the visibility is not adjusted [-fvisibility-from-dllstorageclass]">,
+ MarshallingInfoVisibilityFromDLLStorage<LangOpts<"NoDLLStorageClassVisibility">, "Hidden">,
ShouldParseIf<fvisibility_from_dllstorageclass.KeyPath>;
-def fvisibility_externs_dllimport_EQ : Joined<["-"], "fvisibility-externs-dllimport=">, Group<f_Group>, Flags<[CC1Option]>,
- HelpText<"The visibility for dllimport external declarations [-fvisibility-from-dllstorageclass]">,
- MarshallingInfoVisibility<LangOpts<"ExternDeclDLLImportVisibility">, "DefaultVisibility">,
+def fvisibility_externs_dllimport_EQ : Joined<["-"], "fvisibility-externs-dllimport=">, Group<f_Group>,
+ Visibility<[ClangOption, CC1Option]>,
+ HelpText<"The visibility for dllimport external declarations. If Keep is specified the visibility is not adjusted [-fvisibility-from-dllstorageclass]">,
+ MarshallingInfoVisibilityFromDLLStorage<LangOpts<"ExternDeclDLLImportVisibility">, "Default">,
ShouldParseIf<fvisibility_from_dllstorageclass.KeyPath>;
-def fvisibility_externs_nodllstorageclass_EQ : Joined<["-"], "fvisibility-externs-nodllstorageclass=">, Group<f_Group>, Flags<[CC1Option]>,
- HelpText<"The visibility for external declarations without an explicit DLL dllstorageclass [-fvisibility-from-dllstorageclass]">,
- MarshallingInfoVisibility<LangOpts<"ExternDeclNoDLLStorageClassVisibility">, "HiddenVisibility">,
+def fvisibility_externs_nodllstorageclass_EQ : Joined<["-"], "fvisibility-externs-nodllstorageclass=">, Group<f_Group>,
+ Visibility<[ClangOption, CC1Option]>,
+ HelpText<"The visibility for external declarations without an explicit DLL storage class. If Keep is specified the visibility is not adjusted [-fvisibility-from-dllstorageclass]">,
+ MarshallingInfoVisibilityFromDLLStorage<LangOpts<"ExternDeclNoDLLStorageClassVisibility">, "Hidden">,
ShouldParseIf<fvisibility_from_dllstorageclass.KeyPath>;
def fvisibility_EQ : Joined<["-"], "fvisibility=">, Group<f_Group>,
- HelpText<"Set the default symbol visibility for all global declarations">, Values<"hidden,default">;
+ Visibility<[ClangOption, CC1Option]>,
+ HelpText<"Set the default symbol visibility for all global definitions">,
+ MarshallingInfoVisibility<LangOpts<"ValueVisibilityMode">, "DefaultVisibility">;
defm visibility_inlines_hidden : BoolFOption<"visibility-inlines-hidden",
LangOpts<"InlineVisibilityHidden">, DefaultFalse,
- PosFlag<SetTrue, [CC1Option], "Give inline C++ member functions hidden visibility by default">,
+ PosFlag<SetTrue, [], [ClangOption, CC1Option],
+ "Give inline C++ member functions hidden visibility by default">,
NegFlag<SetFalse>>;
defm visibility_inlines_hidden_static_local_var : BoolFOption<"visibility-inlines-hidden-static-local-var",
LangOpts<"VisibilityInlinesHiddenStaticLocalVar">, DefaultFalse,
- PosFlag<SetTrue, [CC1Option], "When -fvisibility-inlines-hidden is enabled, static variables in"
+ PosFlag<SetTrue, [], [ClangOption, CC1Option],
+ "When -fvisibility-inlines-hidden is enabled, static variables in"
" inline C++ member functions will also be given hidden visibility by default">,
- NegFlag<SetFalse, [], "Disables -fvisibility-inlines-hidden-static-local-var"
- " (this is the default on non-darwin targets)">, BothFlags<[CC1Option]>>;
+ NegFlag<SetFalse, [], [ClangOption], "Disables -fvisibility-inlines-hidden-static-local-var"
+ " (this is the default on non-darwin targets)">, BothFlags<
+ [], [ClangOption, CC1Option]>>;
def fvisibility_ms_compat : Flag<["-"], "fvisibility-ms-compat">, Group<f_Group>,
HelpText<"Give global types 'default' visibility and global functions and "
"variables 'hidden' visibility by default">;
def fvisibility_global_new_delete_hidden : Flag<["-"], "fvisibility-global-new-delete-hidden">, Group<f_Group>,
- HelpText<"Give global C++ operator new and delete declarations hidden visibility">, Flags<[CC1Option]>,
- MarshallingInfoFlag<LangOpts<"GlobalAllocationFunctionVisibilityHidden">>;
+ HelpText<"Give global C++ operator new and delete declarations hidden visibility">;
+class MarshallingInfoVisibilityGlobalNewDelete<KeyPathAndMacro kpm, code default>
+ : MarshallingInfoEnum<kpm, default>,
+ Values<"force-default,force-protected,force-hidden,source">,
+ NormalizedValuesScope<"LangOptions::VisibilityForcedKinds">,
+ NormalizedValues<["ForceDefault", "ForceProtected", "ForceHidden", "Source"]> {}
+def fvisibility_global_new_delete_EQ : Joined<["-"], "fvisibility-global-new-delete=">, Group<f_Group>,
+ Visibility<[ClangOption, CC1Option]>,
+ HelpText<"The visibility for global C++ operator new and delete declarations. If 'source' is specified the visibility is not adjusted">,
+ MarshallingInfoVisibilityGlobalNewDelete<LangOpts<"GlobalAllocationFunctionVisibility">, "ForceDefault">;
+def mdefault_visibility_export_mapping_EQ : Joined<["-"], "mdefault-visibility-export-mapping=">,
+ Values<"none,explicit,all">,
+ NormalizedValuesScope<"LangOptions::DefaultVisiblityExportMapping">,
+ NormalizedValues<["None", "Explicit", "All"]>,
+ HelpText<"Mapping between default visibility and export">,
+ Group<m_Group>, Flags<[TargetSpecific]>,
+ Visibility<[ClangOption, CC1Option]>,
+ MarshallingInfoEnum<LangOpts<"DefaultVisibilityExportMapping">,"None">;
+defm new_infallible : BoolFOption<"new-infallible",
+ LangOpts<"NewInfallible">, DefaultFalse,
+ PosFlag<SetTrue, [], [ClangOption], "Enable">,
+ NegFlag<SetFalse, [], [ClangOption], "Disable">,
+ BothFlags<[], [ClangOption, CC1Option],
+ " treating throwing global C++ operator new as always returning valid memory "
+ "(annotates with __attribute__((returns_nonnull)) and throw()). This is detectable in source.">>;
defm whole_program_vtables : BoolFOption<"whole-program-vtables",
CodeGenOpts<"WholeProgramVTables">, DefaultFalse,
- PosFlag<SetTrue, [CC1Option], "Enables whole-program vtable optimization. Requires -flto">,
- NegFlag<SetFalse>, BothFlags<[CoreOption]>>;
+ PosFlag<SetTrue, [], [ClangOption, CC1Option],
+ "Enables whole-program vtable optimization. Requires -flto">,
+ NegFlag<SetFalse>, BothFlags<[], [ClangOption, CLOption]>>;
defm split_lto_unit : BoolFOption<"split-lto-unit",
CodeGenOpts<"EnableSplitLTOUnit">, DefaultFalse,
- PosFlag<SetTrue, [CC1Option], "Enables splitting of the LTO unit">,
- NegFlag<SetFalse>, BothFlags<[CoreOption]>>;
+ PosFlag<SetTrue, [], [ClangOption, CC1Option],
+ "Enables splitting of the LTO unit">,
+ NegFlag<SetFalse>, BothFlags<[], [ClangOption, CLOption]>>;
defm force_emit_vtables : BoolFOption<"force-emit-vtables",
CodeGenOpts<"ForceEmitVTables">, DefaultFalse,
- PosFlag<SetTrue, [CC1Option], "Emits more virtual tables to improve devirtualization">,
- NegFlag<SetFalse>, BothFlags<[CoreOption]>>;
+ PosFlag<SetTrue, [], [ClangOption, CC1Option],
+ "Emits more virtual tables to improve devirtualization">,
+ NegFlag<SetFalse>, BothFlags<[], [ClangOption, CLOption]>>,
+ DocBrief<[{In order to improve devirtualization, forces emitting of vtables even in
+modules where it isn't necessary. It causes more inline virtual functions
+to be emitted.}]>;
defm virtual_function_elimination : BoolFOption<"virtual-function-elimination",
CodeGenOpts<"VirtualFunctionElimination">, DefaultFalse,
- PosFlag<SetTrue, [CC1Option], "Enables dead virtual function elimination optimization. Requires -flto=full">,
- NegFlag<SetFalse>, BothFlags<[CoreOption]>>;
+ PosFlag<SetTrue, [], [ClangOption, CC1Option],
+ "Enables dead virtual function elimination optimization. Requires -flto=full">,
+ NegFlag<SetFalse>, BothFlags<[], [ClangOption, CLOption]>>;
-def fwrapv : Flag<["-"], "fwrapv">, Group<f_Group>, Flags<[CC1Option]>,
+def fwrapv : Flag<["-"], "fwrapv">, Group<f_Group>,
+ Visibility<[ClangOption, CC1Option]>,
HelpText<"Treat signed integer overflow as two's complement">;
-def fwritable_strings : Flag<["-"], "fwritable-strings">, Group<f_Group>, Flags<[CC1Option]>,
+def fwritable_strings : Flag<["-"], "fwritable-strings">, Group<f_Group>,
+ Visibility<[ClangOption, CC1Option]>,
HelpText<"Store string literals as writable data">,
MarshallingInfoFlag<LangOpts<"WritableStrings">>;
defm zero_initialized_in_bss : BoolFOption<"zero-initialized-in-bss",
CodeGenOpts<"NoZeroInitializedInBSS">, DefaultFalse,
- NegFlag<SetTrue, [CC1Option], "Don't place zero initialized data in BSS">,
+ NegFlag<SetTrue, [], [ClangOption, CC1Option],
+ "Don't place zero initialized data in BSS">,
PosFlag<SetFalse>>;
defm function_sections : BoolFOption<"function-sections",
CodeGenOpts<"FunctionSections">, DefaultFalse,
- PosFlag<SetTrue, [CC1Option], "Place each function in its own section">,
+ PosFlag<SetTrue, [], [ClangOption, CC1Option],
+ "Place each function in its own section">,
NegFlag<SetFalse>>;
def fbasic_block_sections_EQ : Joined<["-"], "fbasic-block-sections=">, Group<f_Group>,
- Flags<[CC1Option, CC1AsOption]>,
- HelpText<"Place each function's basic blocks in unique sections (ELF Only) : all | labels | none | list=<file>">,
+ Visibility<[ClangOption, CC1Option, CC1AsOption]>,
+ HelpText<"Place each function's basic blocks in unique sections (ELF Only)">,
DocBrief<[{Generate labels for each basic block or place each basic block or a subset of basic blocks in its own section.}]>,
Values<"all,labels,none,list=">,
MarshallingInfoString<CodeGenOpts<"BBSections">, [{"none"}]>;
defm data_sections : BoolFOption<"data-sections",
CodeGenOpts<"DataSections">, DefaultFalse,
- PosFlag<SetTrue, [CC1Option], "Place each data in its own section">, NegFlag<SetFalse>>;
+ PosFlag<SetTrue, [], [ClangOption, CC1Option],
+ "Place each data in its own section">,
+ NegFlag<SetFalse>>;
defm stack_size_section : BoolFOption<"stack-size-section",
CodeGenOpts<"StackSizeSection">, DefaultFalse,
- PosFlag<SetTrue, [CC1Option], "Emit section containing metadata on function stack sizes">,
+ PosFlag<SetTrue, [], [ClangOption, CC1Option],
+ "Emit section containing metadata on function stack sizes">,
NegFlag<SetFalse>>;
def fstack_usage : Flag<["-"], "fstack-usage">, Group<f_Group>,
HelpText<"Emit .su file containing information on function stack sizes">;
def stack_usage_file : Separate<["-"], "stack-usage-file">,
- Flags<[CC1Option, NoDriverOption]>,
+ Visibility<[CC1Option]>,
HelpText<"Filename (or -) to write stack usage output to">,
MarshallingInfoString<CodeGenOpts<"StackUsageOutput">>;
defm unique_basic_block_section_names : BoolFOption<"unique-basic-block-section-names",
CodeGenOpts<"UniqueBasicBlockSectionNames">, DefaultFalse,
- PosFlag<SetTrue, [CC1Option], "Use unique names for basic block sections (ELF Only)">,
+ PosFlag<SetTrue, [], [ClangOption, CC1Option],
+ "Use unique names for basic block sections (ELF Only)">,
NegFlag<SetFalse>>;
defm unique_internal_linkage_names : BoolFOption<"unique-internal-linkage-names",
CodeGenOpts<"UniqueInternalLinkageNames">, DefaultFalse,
- PosFlag<SetTrue, [CC1Option], "Uniqueify Internal Linkage Symbol Names by appending"
+ PosFlag<SetTrue, [], [ClangOption, CC1Option],
+ "Uniqueify Internal Linkage Symbol Names by appending"
" the MD5 hash of the module path">,
NegFlag<SetFalse>>;
defm unique_section_names : BoolFOption<"unique-section-names",
CodeGenOpts<"UniqueSectionNames">, DefaultTrue,
- NegFlag<SetFalse, [CC1Option], "Don't use unique names for text and data sections">,
+ NegFlag<SetFalse, [], [ClangOption, CC1Option],
+ "Don't use unique names for text and data sections">,
PosFlag<SetTrue>>;
defm split_machine_functions: BoolFOption<"split-machine-functions",
CodeGenOpts<"SplitMachineFunctions">, DefaultFalse,
- PosFlag<SetTrue, [CC1Option], "Enable">, NegFlag<SetFalse, [], "Disable">,
- BothFlags<[], " late function splitting using profile information (x86 ELF)">>;
+ PosFlag<SetTrue, [], [ClangOption, CC1Option], "Enable">,
+ NegFlag<SetFalse, [], [ClangOption], "Disable">,
+ BothFlags<[], [ClangOption], " late function splitting using profile information (x86 ELF)">>;
defm strict_return : BoolFOption<"strict-return",
CodeGenOpts<"StrictReturn">, DefaultTrue,
- NegFlag<SetFalse, [CC1Option], "Don't treat control flow paths that fall off the end"
+ NegFlag<SetFalse, [], [ClangOption, CC1Option],
+ "Don't treat control flow paths that fall off the end"
" of a non-void function as unreachable">,
PosFlag<SetTrue>>;
def fenable_matrix : Flag<["-"], "fenable-matrix">, Group<f_Group>,
- Flags<[CC1Option]>,
+ Visibility<[ClangOption, CC1Option]>,
HelpText<"Enable matrix data type and related builtin functions">,
MarshallingInfoFlag<LangOpts<"MatrixTypes">>;
+def fzero_call_used_regs_EQ
+ : Joined<["-"], "fzero-call-used-regs=">, Group<f_Group>,
+ Visibility<[ClangOption, CC1Option]>,
+ HelpText<"Clear call-used registers upon function return (AArch64/x86 only)">,
+ Values<"skip,used-gpr-arg,used-gpr,used-arg,used,all-gpr-arg,all-gpr,all-arg,all">,
+ NormalizedValues<["Skip", "UsedGPRArg", "UsedGPR", "UsedArg", "Used",
+ "AllGPRArg", "AllGPR", "AllArg", "All"]>,
+ NormalizedValuesScope<"llvm::ZeroCallUsedRegs::ZeroCallUsedRegsKind">,
+ MarshallingInfoEnum<CodeGenOpts<"ZeroCallUsedRegs">, "Skip">;
def fdebug_types_section: Flag <["-"], "fdebug-types-section">, Group<f_Group>,
HelpText<"Place debug types in their own section (ELF Only)">;
def fno_debug_types_section: Flag<["-"], "fno-debug-types-section">, Group<f_Group>;
defm debug_ranges_base_address : BoolFOption<"debug-ranges-base-address",
CodeGenOpts<"DebugRangesBaseAddress">, DefaultFalse,
- PosFlag<SetTrue, [CC1Option], "Use DWARF base address selection entries in .debug_ranges">,
+ PosFlag<SetTrue, [], [ClangOption, CC1Option],
+ "Use DWARF base address selection entries in .debug_ranges">,
NegFlag<SetFalse>>;
defm split_dwarf_inlining : BoolFOption<"split-dwarf-inlining",
CodeGenOpts<"SplitDwarfInlining">, DefaultFalse,
- NegFlag<SetFalse, []>,
- PosFlag<SetTrue, [CC1Option], "Provide minimal debug info in the object/executable"
+ NegFlag<SetFalse, [], [ClangOption]>,
+ PosFlag<SetTrue, [], [ClangOption, CC1Option],
+ "Provide minimal debug info in the object/executable"
" to facilitate online symbolication/stack traces in the absence of"
" .dwo/.dwp files when using Split DWARF">>;
def fdebug_default_version: Joined<["-"], "fdebug-default-version=">, Group<f_Group>,
HelpText<"Default DWARF version to use, if a -g option caused DWARF debug info to be produced">;
def fdebug_prefix_map_EQ
: Joined<["-"], "fdebug-prefix-map=">, Group<f_Group>,
- Flags<[CC1Option,CC1AsOption]>,
- HelpText<"remap file source paths in debug info">;
+ Visibility<[ClangOption, CC1Option, CC1AsOption]>,
+ MetaVarName<"<old>=<new>">,
+ HelpText<"For paths in debug info, remap directory <old> to <new>. If multiple options match a path, the last option wins">;
def fcoverage_prefix_map_EQ
: Joined<["-"], "fcoverage-prefix-map=">, Group<f_Group>,
- Flags<[CC1Option]>,
- HelpText<"remap file source paths in coverage mapping">;
+ Visibility<[ClangOption, CC1Option]>,
+ MetaVarName<"<old>=<new>">,
+ HelpText<"remap file source paths <old> to <new> in coverage mapping. If there are multiple options, prefix replacement is applied in reverse order starting from the last one">;
def ffile_prefix_map_EQ
: Joined<["-"], "ffile-prefix-map=">, Group<f_Group>,
- HelpText<"remap file source paths in debug info, predefined preprocessor macros and __builtin_FILE()">;
+ HelpText<"remap file source paths in debug info, predefined preprocessor "
+ "macros and __builtin_FILE(). Implies -ffile-reproducible.">;
def fmacro_prefix_map_EQ
- : Joined<["-"], "fmacro-prefix-map=">, Group<f_Group>, Flags<[CC1Option]>,
- HelpText<"remap file source paths in predefined preprocessor macros and __builtin_FILE()">;
+ : Joined<["-"], "fmacro-prefix-map=">, Group<f_Group>,
+ Visibility<[ClangOption, CC1Option]>,
+ HelpText<"remap file source paths in predefined preprocessor macros and "
+ "__builtin_FILE(). Implies -ffile-reproducible.">;
defm force_dwarf_frame : BoolFOption<"force-dwarf-frame",
CodeGenOpts<"ForceDwarfFrameSection">, DefaultFalse,
- PosFlag<SetTrue, [CC1Option], "Always emit a debug frame section">, NegFlag<SetFalse>>;
+ PosFlag<SetTrue, [], [ClangOption, CC1Option],
+ "Always emit a debug frame section">,
+ NegFlag<SetFalse>>;
+def femit_dwarf_unwind_EQ : Joined<["-"], "femit-dwarf-unwind=">,
+ Group<f_Group>, Visibility<[ClangOption, CC1Option, CC1AsOption]>,
+ HelpText<"When to emit DWARF unwind (EH frame) info">,
+ Values<"always,no-compact-unwind,default">,
+ NormalizedValues<["Always", "NoCompactUnwind", "Default"]>,
+ NormalizedValuesScope<"llvm::EmitDwarfUnwindType">,
+ MarshallingInfoEnum<CodeGenOpts<"EmitDwarfUnwind">, "Default">;
+defm emit_compact_unwind_non_canonical : BoolFOption<"emit-compact-unwind-non-canonical",
+ CodeGenOpts<"EmitCompactUnwindNonCanonical">, DefaultFalse,
+ PosFlag<SetTrue, [], [ClangOption, CC1Option, CC1AsOption],
+ "Try emitting Compact-Unwind for non-canonical entries. Maybe overriden by other constraints">,
+ NegFlag<SetFalse>>;
def g_Flag : Flag<["-"], "g">, Group<g_Group>,
- HelpText<"Generate source-level debug information">;
+ Visibility<[ClangOption, CLOption, DXCOption, FlangOption]>,
+ HelpText<"Generate source-level debug information">;
def gline_tables_only : Flag<["-"], "gline-tables-only">, Group<gN_Group>,
- Flags<[CoreOption]>, HelpText<"Emit debug line number tables only">;
+ Visibility<[ClangOption, CLOption, DXCOption, FlangOption]>,
+ HelpText<"Emit debug line number tables only">;
def gline_directives_only : Flag<["-"], "gline-directives-only">, Group<gN_Group>,
- Flags<[CoreOption]>, HelpText<"Emit debug line info directives only">;
+ Visibility<[ClangOption, CLOption, DXCOption, FlangOption]>,
+ HelpText<"Emit debug line info directives only">;
def gmlt : Flag<["-"], "gmlt">, Alias<gline_tables_only>;
-def g0 : Flag<["-"], "g0">, Group<gN_Group>;
-def g1 : Flag<["-"], "g1">, Group<gN_Group>, Alias<gline_tables_only>;
-def g2 : Flag<["-"], "g2">, Group<gN_Group>;
-def g3 : Flag<["-"], "g3">, Group<gN_Group>;
+def g0 : Flag<["-"], "g0">, Group<gN_Group>, Visibility<[ClangOption, FlangOption]>;
+def g1 : Flag<["-"], "g1">, Group<gN_Group>, Visibility<[ClangOption, FlangOption]>, Alias<gline_tables_only>;
+def g2 : Flag<["-"], "g2">, Group<gN_Group>, Visibility<[ClangOption, FlangOption]>;
+def g3 : Flag<["-"], "g3">, Group<gN_Group>, Visibility<[ClangOption, FlangOption]>;
def ggdb : Flag<["-"], "ggdb">, Group<gTune_Group>;
def ggdb0 : Flag<["-"], "ggdb0">, Group<ggdbN_Group>;
def ggdb1 : Flag<["-"], "ggdb1">, Group<ggdbN_Group>;
@@ -2853,7 +4133,8 @@ def gsce : Flag<["-"], "gsce">, Group<gTune_Group>;
def gdbx : Flag<["-"], "gdbx">, Group<gTune_Group>;
// Equivalent to our default dwarf version. Forces usual dwarf emission when
// CodeView is enabled.
-def gdwarf : Flag<["-"], "gdwarf">, Group<g_Group>, Flags<[CoreOption]>,
+def gdwarf : Flag<["-"], "gdwarf">, Group<g_Group>,
+ Visibility<[ClangOption, CLOption, DXCOption]>,
HelpText<"Generate source-level debug information with the default dwarf version">;
def gdwarf_2 : Flag<["-"], "gdwarf-2">, Group<g_Group>,
HelpText<"Generate source-level debug information with dwarf version 2">;
@@ -2864,25 +4145,32 @@ def gdwarf_4 : Flag<["-"], "gdwarf-4">, Group<g_Group>,
def gdwarf_5 : Flag<["-"], "gdwarf-5">, Group<g_Group>,
HelpText<"Generate source-level debug information with dwarf version 5">;
def gdwarf64 : Flag<["-"], "gdwarf64">, Group<g_Group>,
- Flags<[CC1Option, CC1AsOption]>,
+ Visibility<[ClangOption, CC1Option, CC1AsOption]>,
HelpText<"Enables DWARF64 format for ELF binaries, if debug information emission is enabled.">,
MarshallingInfoFlag<CodeGenOpts<"Dwarf64">>;
def gdwarf32 : Flag<["-"], "gdwarf32">, Group<g_Group>,
- Flags<[CC1Option, CC1AsOption]>,
+ Visibility<[ClangOption, CC1Option, CC1AsOption]>,
HelpText<"Enables DWARF32 format for ELF binaries, if debug information emission is enabled.">;
def gcodeview : Flag<["-"], "gcodeview">,
HelpText<"Generate CodeView debug information">,
- Flags<[CC1Option, CC1AsOption, CoreOption]>,
+ Visibility<[ClangOption, CC1Option, CC1AsOption, CLOption, DXCOption]>,
MarshallingInfoFlag<CodeGenOpts<"EmitCodeView">>;
defm codeview_ghash : BoolOption<"g", "codeview-ghash",
CodeGenOpts<"CodeViewGHash">, DefaultFalse,
- PosFlag<SetTrue, [CC1Option], "Emit type record hashes in a .debug$H section">,
- NegFlag<SetFalse>, BothFlags<[CoreOption]>>;
+ PosFlag<SetTrue, [], [ClangOption, CC1Option],
+ "Emit type record hashes in a .debug$H section">,
+ NegFlag<SetFalse>, BothFlags<[], [ClangOption, CLOption, DXCOption]>>;
+defm codeview_command_line : BoolOption<"g", "codeview-command-line",
+ CodeGenOpts<"CodeViewCommandLine">, DefaultTrue,
+ PosFlag<SetTrue, [], [ClangOption], "Emit compiler path and command line into CodeView debug information">,
+ NegFlag<SetFalse, [], [ClangOption], "Don't emit compiler path and command line into CodeView debug information">,
+ BothFlags<[], [ClangOption, CLOption, DXCOption, CC1Option]>>;
defm inline_line_tables : BoolGOption<"inline-line-tables",
CodeGenOpts<"NoInlineLineTables">, DefaultFalse,
- NegFlag<SetTrue, [CC1Option], "Don't emit inline line tables.">,
- PosFlag<SetFalse>, BothFlags<[CoreOption]>>;
+ NegFlag<SetTrue, [], [ClangOption, CC1Option],
+ "Don't emit inline line tables.">,
+ PosFlag<SetFalse>, BothFlags<[], [ClangOption, CLOption, DXCOption]>>;
def gfull : Flag<["-"], "gfull">, Group<g_Group>;
def gused : Flag<["-"], "gused">, Group<g_Group>;
@@ -2899,148 +4187,216 @@ def : Flag<["-"], "grecord-gcc-switches">, Alias<grecord_command_line>;
def : Flag<["-"], "gno-record-gcc-switches">, Alias<gno_record_command_line>;
defm strict_dwarf : BoolOption<"g", "strict-dwarf",
CodeGenOpts<"DebugStrictDwarf">, DefaultFalse,
- PosFlag<SetTrue, [CC1Option]>, NegFlag<SetFalse>, BothFlags<[CoreOption]>>,
+ PosFlag<SetTrue, [], [ClangOption, CC1Option],
+ "Restrict DWARF features to those defined in "
+ "the specified version, avoiding features from later versions.">,
+ NegFlag<SetFalse>, BothFlags<[], [ClangOption, CLOption, DXCOption]>>,
Group<g_flags_Group>;
defm column_info : BoolOption<"g", "column-info",
CodeGenOpts<"DebugColumnInfo">, DefaultTrue,
- NegFlag<SetFalse, [CC1Option]>, PosFlag<SetTrue>, BothFlags<[CoreOption]>>,
+ NegFlag<SetFalse, [], [ClangOption, CC1Option]>,
+ PosFlag<SetTrue>, BothFlags<[], [ClangOption, CLOption, DXCOption]>>,
Group<g_flags_Group>;
-def gsplit_dwarf : Flag<["-"], "gsplit-dwarf">, Group<g_flags_Group>;
+def gsplit_dwarf : Flag<["-"], "gsplit-dwarf">, Group<g_flags_Group>,
+ Visibility<[ClangOption, CLOption, DXCOption]>;
def gsplit_dwarf_EQ : Joined<["-"], "gsplit-dwarf=">, Group<g_flags_Group>,
- HelpText<"Set DWARF fission mode to either 'split' or 'single'">,
+ Visibility<[ClangOption, CLOption, DXCOption]>,
+ HelpText<"Set DWARF fission mode">,
Values<"split,single">;
-def gno_split_dwarf : Flag<["-"], "gno-split-dwarf">, Group<g_flags_Group>;
-def ggnu_pubnames : Flag<["-"], "ggnu-pubnames">, Group<g_flags_Group>, Flags<[CC1Option]>;
+def gno_split_dwarf : Flag<["-"], "gno-split-dwarf">, Group<g_flags_Group>,
+ Visibility<[ClangOption, CLOption, DXCOption]>;
+def gsimple_template_names : Flag<["-"], "gsimple-template-names">, Group<g_flags_Group>;
+def gsimple_template_names_EQ
+ : Joined<["-"], "gsimple-template-names=">,
+ HelpText<"Use simple template names in DWARF, or include the full "
+ "template name with a modified prefix for validation">,
+ Values<"simple,mangled">, Visibility<[CC1Option]>;
+def gsrc_hash_EQ : Joined<["-"], "gsrc-hash=">,
+ Group<g_flags_Group>, Visibility<[CC1Option]>,
+ Values<"md5,sha1,sha256">,
+ NormalizedValues<["DSH_MD5", "DSH_SHA1", "DSH_SHA256"]>,
+ NormalizedValuesScope<"CodeGenOptions">,
+ MarshallingInfoEnum<CodeGenOpts<"DebugSrcHash">, "DSH_MD5">;
+def gno_simple_template_names : Flag<["-"], "gno-simple-template-names">,
+ Group<g_flags_Group>;
+def ggnu_pubnames : Flag<["-"], "ggnu-pubnames">, Group<g_flags_Group>,
+ Visibility<[ClangOption, CC1Option]>;
def gno_gnu_pubnames : Flag<["-"], "gno-gnu-pubnames">, Group<g_flags_Group>;
-def gpubnames : Flag<["-"], "gpubnames">, Group<g_flags_Group>, Flags<[CC1Option]>;
+def gpubnames : Flag<["-"], "gpubnames">, Group<g_flags_Group>,
+ Visibility<[ClangOption, CC1Option]>;
def gno_pubnames : Flag<["-"], "gno-pubnames">, Group<g_flags_Group>;
def gdwarf_aranges : Flag<["-"], "gdwarf-aranges">, Group<g_flags_Group>;
def gmodules : Flag <["-"], "gmodules">, Group<gN_Group>,
HelpText<"Generate debug info with external references to clang modules"
" or precompiled headers">;
+def gno_modules : Flag <["-"], "gno-modules">, Group<g_flags_Group>;
def gz_EQ : Joined<["-"], "gz=">, Group<g_flags_Group>,
HelpText<"DWARF debug sections compression type">;
def gz : Flag<["-"], "gz">, Alias<gz_EQ>, AliasArgs<["zlib"]>, Group<g_flags_Group>;
-def gembed_source : Flag<["-"], "gembed-source">, Group<g_flags_Group>, Flags<[CC1Option]>,
+def gembed_source : Flag<["-"], "gembed-source">, Group<g_flags_Group>,
+ Visibility<[ClangOption, CC1Option]>,
HelpText<"Embed source text in DWARF debug sections">,
MarshallingInfoFlag<CodeGenOpts<"EmbedSource">>;
def gno_embed_source : Flag<["-"], "gno-embed-source">, Group<g_flags_Group>,
Flags<[NoXarchOption]>,
HelpText<"Restore the default behavior of not embedding source text in DWARF debug sections">;
def headerpad__max__install__names : Joined<["-"], "headerpad_max_install_names">;
-def help : Flag<["-", "--"], "help">, Flags<[CC1Option,CC1AsOption, FC1Option,
- FlangOption]>, HelpText<"Display available options">,
+def help : Flag<["-", "--"], "help">,
+ Visibility<[ClangOption, CC1Option, CC1AsOption,
+ FC1Option, FlangOption, DXCOption]>,
+ HelpText<"Display available options">,
MarshallingInfoFlag<FrontendOpts<"ShowHelp">>;
-def ibuiltininc : Flag<["-"], "ibuiltininc">,
+def ibuiltininc : Flag<["-"], "ibuiltininc">, Group<clang_i_Group>,
HelpText<"Enable builtin #include directories even when -nostdinc is used "
"before or after -ibuiltininc. "
"Using -nobuiltininc after the option disables it">;
-def index_header_map : Flag<["-"], "index-header-map">, Flags<[CC1Option]>,
+def index_header_map : Flag<["-"], "index-header-map">,
+ Visibility<[ClangOption, CC1Option]>,
HelpText<"Make the next included directory (-I or -F) an indexer header map">;
-def idirafter : JoinedOrSeparate<["-"], "idirafter">, Group<clang_i_Group>, Flags<[CC1Option]>,
+def iapinotes_modules : JoinedOrSeparate<["-"], "iapinotes-modules">, Group<clang_i_Group>,
+ Visibility<[ClangOption, CC1Option]>,
+ HelpText<"Add directory to the API notes search path referenced by module name">, MetaVarName<"<directory>">;
+def idirafter : JoinedOrSeparate<["-"], "idirafter">, Group<clang_i_Group>,
+ Visibility<[ClangOption, CC1Option]>,
HelpText<"Add directory to AFTER include search path">;
-def iframework : JoinedOrSeparate<["-"], "iframework">, Group<clang_i_Group>, Flags<[CC1Option]>,
+def iframework : JoinedOrSeparate<["-"], "iframework">, Group<clang_i_Group>,
+ Visibility<[ClangOption, CC1Option]>,
HelpText<"Add directory to SYSTEM framework search path">;
def iframeworkwithsysroot : JoinedOrSeparate<["-"], "iframeworkwithsysroot">,
Group<clang_i_Group>,
HelpText<"Add directory to SYSTEM framework search path, "
"absolute paths are relative to -isysroot">,
- MetaVarName<"<directory>">, Flags<[CC1Option]>;
-def imacros : JoinedOrSeparate<["-", "--"], "imacros">, Group<clang_i_Group>, Flags<[CC1Option]>,
+ MetaVarName<"<directory>">, Visibility<[ClangOption, CC1Option]>;
+def imacros : JoinedOrSeparate<["-", "--"], "imacros">, Group<clang_i_Group>,
+ Visibility<[ClangOption, CC1Option]>,
HelpText<"Include macros from file before parsing">, MetaVarName<"<file>">,
MarshallingInfoStringVector<PreprocessorOpts<"MacroIncludes">>;
def image__base : Separate<["-"], "image_base">;
def include_ : JoinedOrSeparate<["-", "--"], "include">, Group<clang_i_Group>, EnumName<"include">,
- MetaVarName<"<file>">, HelpText<"Include file before parsing">, Flags<[CC1Option]>;
-def include_pch : Separate<["-"], "include-pch">, Group<clang_i_Group>, Flags<[CC1Option]>,
+ MetaVarName<"<file>">, HelpText<"Include file before parsing">,
+ Visibility<[ClangOption, CC1Option]>;
+def include_pch : Separate<["-"], "include-pch">, Group<clang_i_Group>,
+ Visibility<[ClangOption, CC1Option]>,
HelpText<"Include precompiled header file">, MetaVarName<"<file>">,
MarshallingInfoString<PreprocessorOpts<"ImplicitPCHInclude">>;
-def relocatable_pch : Flag<["-", "--"], "relocatable-pch">, Flags<[CC1Option]>,
+def relocatable_pch : Flag<["-", "--"], "relocatable-pch">,
+ Visibility<[ClangOption, CC1Option]>,
HelpText<"Whether to build a relocatable precompiled header">,
MarshallingInfoFlag<FrontendOpts<"RelocatablePCH">>;
-def verify_pch : Flag<["-"], "verify-pch">, Group<Action_Group>, Flags<[CC1Option]>,
+def verify_pch : Flag<["-"], "verify-pch">, Group<Action_Group>,
+ Visibility<[ClangOption, CC1Option]>,
HelpText<"Load and verify that a pre-compiled header file is not stale">;
def init : Separate<["-"], "init">;
def install__name : Separate<["-"], "install_name">;
-def iprefix : JoinedOrSeparate<["-"], "iprefix">, Group<clang_i_Group>, Flags<[CC1Option]>,
+def iprefix : JoinedOrSeparate<["-"], "iprefix">, Group<clang_i_Group>,
+ Visibility<[ClangOption, CC1Option]>,
HelpText<"Set the -iwithprefix/-iwithprefixbefore prefix">, MetaVarName<"<dir>">;
-def iquote : JoinedOrSeparate<["-"], "iquote">, Group<clang_i_Group>, Flags<[CC1Option]>,
+def iquote : JoinedOrSeparate<["-"], "iquote">, Group<clang_i_Group>,
+ Visibility<[ClangOption, CC1Option]>,
HelpText<"Add directory to QUOTE include search path">, MetaVarName<"<directory>">;
-def isysroot : JoinedOrSeparate<["-"], "isysroot">, Group<clang_i_Group>, Flags<[CC1Option]>,
+def isysroot : JoinedOrSeparate<["-"], "isysroot">, Group<clang_i_Group>,
+ Visibility<[ClangOption, CC1Option, FlangOption]>,
HelpText<"Set the system root directory (usually /)">, MetaVarName<"<dir>">,
MarshallingInfoString<HeaderSearchOpts<"Sysroot">, [{"/"}]>;
def isystem : JoinedOrSeparate<["-"], "isystem">, Group<clang_i_Group>,
- Flags<[CC1Option]>,
+ Visibility<[ClangOption, CC1Option]>,
HelpText<"Add directory to SYSTEM include search path">, MetaVarName<"<directory>">;
def isystem_after : JoinedOrSeparate<["-"], "isystem-after">,
Group<clang_i_Group>, Flags<[NoXarchOption]>, MetaVarName<"<directory>">,
HelpText<"Add directory to end of the SYSTEM include search path">;
def iwithprefixbefore : JoinedOrSeparate<["-"], "iwithprefixbefore">, Group<clang_i_Group>,
HelpText<"Set directory to include search path with prefix">, MetaVarName<"<dir>">,
- Flags<[CC1Option]>;
-def iwithprefix : JoinedOrSeparate<["-"], "iwithprefix">, Group<clang_i_Group>, Flags<[CC1Option]>,
+ Visibility<[ClangOption, CC1Option]>;
+def iwithprefix : JoinedOrSeparate<["-"], "iwithprefix">, Group<clang_i_Group>,
+ Visibility<[ClangOption, CC1Option]>,
HelpText<"Set directory to SYSTEM include search path with prefix">, MetaVarName<"<dir>">;
def iwithsysroot : JoinedOrSeparate<["-"], "iwithsysroot">, Group<clang_i_Group>,
HelpText<"Add directory to SYSTEM include search path, "
"absolute paths are relative to -isysroot">, MetaVarName<"<directory>">,
- Flags<[CC1Option]>;
-def ivfsoverlay : JoinedOrSeparate<["-"], "ivfsoverlay">, Group<clang_i_Group>, Flags<[CC1Option]>,
+ Visibility<[ClangOption, CC1Option]>;
+def ivfsoverlay : JoinedOrSeparate<["-"], "ivfsoverlay">, Group<clang_i_Group>,
+ Visibility<[ClangOption, CC1Option]>,
HelpText<"Overlay the virtual filesystem described by file over the real file system">;
+def vfsoverlay : JoinedOrSeparate<["-", "--"], "vfsoverlay">,
+ Visibility<[ClangOption, CC1Option, CLOption, DXCOption]>,
+ HelpText<"Overlay the virtual filesystem described by file over the real file system. "
+ "Additionally, pass this overlay file to the linker if it supports it">;
def imultilib : Separate<["-"], "imultilib">, Group<gfortran_Group>;
+def K : Flag<["-"], "K">, Flags<[LinkerInput]>;
def keep__private__externs : Flag<["-"], "keep_private_externs">;
def l : JoinedOrSeparate<["-"], "l">, Flags<[LinkerInput, RenderJoined]>,
- Group<Link_Group>;
+ Visibility<[ClangOption, FlangOption]>, Group<Link_Group>;
def lazy__framework : Separate<["-"], "lazy_framework">, Flags<[LinkerInput]>;
def lazy__library : Separate<["-"], "lazy_library">, Flags<[LinkerInput]>;
-def mlittle_endian : Flag<["-"], "mlittle-endian">, Flags<[NoXarchOption]>;
+def mlittle_endian : Flag<["-"], "mlittle-endian">, Group<m_Group>,
+ Flags<[NoXarchOption, TargetSpecific]>;
def EL : Flag<["-"], "EL">, Alias<mlittle_endian>;
-def mbig_endian : Flag<["-"], "mbig-endian">, Flags<[NoXarchOption]>;
+def mbig_endian : Flag<["-"], "mbig-endian">, Group<m_Group>,
+ Flags<[NoXarchOption, TargetSpecific]>;
def EB : Flag<["-"], "EB">, Alias<mbig_endian>;
-def m16 : Flag<["-"], "m16">, Group<m_Group>, Flags<[NoXarchOption, CoreOption]>;
-def m32 : Flag<["-"], "m32">, Group<m_Group>, Flags<[NoXarchOption, CoreOption]>;
-def mqdsp6_compat : Flag<["-"], "mqdsp6-compat">, Group<m_Group>, Flags<[NoXarchOption,CC1Option]>,
+def m16 : Flag<["-"], "m16">, Group<m_Group>, Flags<[NoXarchOption]>,
+ Visibility<[ClangOption, CLOption, DXCOption]>;
+def m32 : Flag<["-"], "m32">, Group<m_Group>, Flags<[NoXarchOption]>,
+ Visibility<[ClangOption, CLOption, DXCOption]>;
+def maix32 : Flag<["-"], "maix32">, Group<m_Group>, Flags<[NoXarchOption]>;
+def mqdsp6_compat : Flag<["-"], "mqdsp6-compat">, Group<m_Group>,
+ Flags<[NoXarchOption]>, Visibility<[ClangOption, CC1Option]>,
HelpText<"Enable hexagon-qdsp6 backward compatibility">,
MarshallingInfoFlag<LangOpts<"HexagonQdsp6Compat">>;
-def m64 : Flag<["-"], "m64">, Group<m_Group>, Flags<[NoXarchOption, CoreOption]>;
-def mx32 : Flag<["-"], "mx32">, Group<m_Group>, Flags<[NoXarchOption, CoreOption]>;
-def mabi_EQ : Joined<["-"], "mabi=">, Group<m_Group>;
-def miamcu : Flag<["-"], "miamcu">, Group<m_Group>, Flags<[NoXarchOption, CoreOption]>,
+def m64 : Flag<["-"], "m64">, Group<m_Group>, Flags<[NoXarchOption]>,
+ Visibility<[ClangOption, CLOption, DXCOption]>;
+def maix64 : Flag<["-"], "maix64">, Group<m_Group>, Flags<[NoXarchOption]>;
+def mx32 : Flag<["-"], "mx32">, Group<m_Group>, Flags<[NoXarchOption]>,
+ Visibility<[ClangOption, CLOption, DXCOption]>;
+def miamcu : Flag<["-"], "miamcu">, Group<m_Group>, Flags<[NoXarchOption]>,
+ Visibility<[ClangOption, CLOption]>,
HelpText<"Use Intel MCU ABI">;
-def mno_iamcu : Flag<["-"], "mno-iamcu">, Group<m_Group>, Flags<[NoXarchOption, CoreOption]>;
+def mno_iamcu : Flag<["-"], "mno-iamcu">, Group<m_Group>,
+ Flags<[NoXarchOption]>, Visibility<[ClangOption, CLOption]>;
def malign_functions_EQ : Joined<["-"], "malign-functions=">, Group<clang_ignored_m_Group>;
def malign_loops_EQ : Joined<["-"], "malign-loops=">, Group<clang_ignored_m_Group>;
def malign_jumps_EQ : Joined<["-"], "malign-jumps=">, Group<clang_ignored_m_Group>;
-def malign_branch_EQ : CommaJoined<["-"], "malign-branch=">, Group<m_Group>, Flags<[NoXarchOption]>,
+
+let Flags = [TargetSpecific] in {
+def mabi_EQ : Joined<["-"], "mabi=">, Group<m_Group>;
+def malign_branch_EQ : CommaJoined<["-"], "malign-branch=">, Group<m_Group>,
HelpText<"Specify types of branches to align">;
-def malign_branch_boundary_EQ : Joined<["-"], "malign-branch-boundary=">, Group<m_Group>, Flags<[NoXarchOption]>,
+def malign_branch_boundary_EQ : Joined<["-"], "malign-branch-boundary=">, Group<m_Group>,
HelpText<"Specify the boundary's size to align branches">;
-def mpad_max_prefix_size_EQ : Joined<["-"], "mpad-max-prefix-size=">, Group<m_Group>, Flags<[NoXarchOption]>,
+def mpad_max_prefix_size_EQ : Joined<["-"], "mpad-max-prefix-size=">, Group<m_Group>,
HelpText<"Specify maximum number of prefixes to use for padding">;
-def mbranches_within_32B_boundaries : Flag<["-"], "mbranches-within-32B-boundaries">, Flags<[NoXarchOption]>, Group<m_Group>,
+def mbranches_within_32B_boundaries : Flag<["-"], "mbranches-within-32B-boundaries">, Group<m_Group>,
HelpText<"Align selected branches (fused, jcc, jmp) within 32-byte boundary">;
def mfancy_math_387 : Flag<["-"], "mfancy-math-387">, Group<clang_ignored_m_Group>;
def mlong_calls : Flag<["-"], "mlong-calls">, Group<m_Group>,
HelpText<"Generate branches with extended addressability, usually via indirect jumps.">;
-def mdouble_EQ : Joined<["-"], "mdouble=">, Group<m_Group>, Values<"32,64">, Flags<[CC1Option]>,
- HelpText<"Force double to be 32 bits or 64 bits">,
+} // let Flags = [TargetSpecific]
+def mdouble_EQ : Joined<["-"], "mdouble=">, Group<m_Group>,
+ MetaVarName<"<n">, Values<"32,64">, Visibility<[ClangOption, CC1Option]>,
+ HelpText<"Force double to be <n> bits">,
MarshallingInfoInt<LangOpts<"DoubleSize">, "0">;
-def LongDouble_Group : OptionGroup<"<LongDouble group>">, Group<m_Group>,
- DocName<"Long double flags">,
- DocBrief<[{Selects the long double implementation}]>;
-def mlong_double_64 : Flag<["-"], "mlong-double-64">, Group<LongDouble_Group>, Flags<[CC1Option]>,
+def mlong_double_64 : Flag<["-"], "mlong-double-64">, Group<LongDouble_Group>,
+ Visibility<[ClangOption, CC1Option]>,
HelpText<"Force long double to be 64 bits">;
-def mlong_double_80 : Flag<["-"], "mlong-double-80">, Group<LongDouble_Group>, Flags<[CC1Option]>,
+def mlong_double_80 : Flag<["-"], "mlong-double-80">, Group<LongDouble_Group>,
+ Visibility<[ClangOption, CC1Option]>,
HelpText<"Force long double to be 80 bits, padded to 128 bits for storage">;
-def mlong_double_128 : Flag<["-"], "mlong-double-128">, Group<LongDouble_Group>, Flags<[CC1Option]>,
+def mlong_double_128 : Flag<["-"], "mlong-double-128">, Group<LongDouble_Group>,
+ Visibility<[ClangOption, CC1Option]>,
HelpText<"Force long double to be 128 bits">;
+let Flags = [TargetSpecific] in {
def mno_long_calls : Flag<["-"], "mno-long-calls">, Group<m_Group>,
HelpText<"Restore the default behaviour of not generating long calls">;
+} // let Flags = [TargetSpecific]
def mexecute_only : Flag<["-"], "mexecute-only">, Group<m_arm_Features_Group>,
HelpText<"Disallow generation of data access to code sections (ARM only)">;
def mno_execute_only : Flag<["-"], "mno-execute-only">, Group<m_arm_Features_Group>,
HelpText<"Allow generation of data access to code sections (ARM only)">;
-def mtp_mode_EQ : Joined<["-"], "mtp=">, Group<m_arm_Features_Group>, Values<"soft,cp15,el0,el1,el2,el3">,
- HelpText<"Thread pointer access method (AArch32/AArch64 only)">;
+let Flags = [TargetSpecific] in {
+def mtp_mode_EQ : Joined<["-"], "mtp=">, Group<m_arm_Features_Group>, Values<"soft,cp15,tpidrurw,tpidruro,tpidrprw,el0,el1,el2,el3,tpidr_el0,tpidr_el1,tpidr_el2,tpidr_el3,tpidrro_el0">,
+ HelpText<"Thread pointer access method. "
+ "For AArch32: 'soft' uses a function call, or 'tpidrurw', 'tpidruro' or 'tpidrprw' use the three CP15 registers. 'cp15' is an alias for 'tpidruro'. "
+ "For AArch64: 'tpidr_el0', 'tpidr_el1', 'tpidr_el2', 'tpidr_el3' or 'tpidrro_el0' use the five system registers. 'elN' is an alias for 'tpidr_elN'.">;
def mpure_code : Flag<["-"], "mpure-code">, Alias<mexecute_only>; // Alias for GCC compatibility
def mno_pure_code : Flag<["-"], "mno-pure-code">, Alias<mno_execute_only>;
def mtvos_version_min_EQ : Joined<["-"], "mtvos-version-min=">, Group<m_Group>;
@@ -3048,124 +4404,198 @@ def mappletvos_version_min_EQ : Joined<["-"], "mappletvos-version-min=">, Alias<
def mtvos_simulator_version_min_EQ : Joined<["-"], "mtvos-simulator-version-min=">;
def mappletvsimulator_version_min_EQ : Joined<["-"], "mappletvsimulator-version-min=">, Alias<mtvos_simulator_version_min_EQ>;
def mwatchos_version_min_EQ : Joined<["-"], "mwatchos-version-min=">, Group<m_Group>;
-def mwatchos_simulator_version_min_EQ : Joined<["-"], "mwatchos-simulator-version-min=">;
+def mwatchos_simulator_version_min_EQ : Joined<["-"], "mwatchos-simulator-version-min=">, Group<m_Group>;
def mwatchsimulator_version_min_EQ : Joined<["-"], "mwatchsimulator-version-min=">, Alias<mwatchos_simulator_version_min_EQ>;
-def march_EQ : Joined<["-"], "march=">, Group<m_Group>, Flags<[CoreOption]>;
-def masm_EQ : Joined<["-"], "masm=">, Group<m_Group>, Flags<[NoXarchOption]>;
-def mcmodel_EQ : Joined<["-"], "mcmodel=">, Group<m_Group>, Flags<[CC1Option]>,
+} // let Flags = [TargetSpecific]
+def march_EQ : Joined<["-"], "march=">, Group<m_Group>,
+ Flags<[TargetSpecific]>, Visibility<[ClangOption, CLOption, DXCOption, FlangOption]>,
+ HelpText<"For a list of available architectures for the target use '-mcpu=help'">;
+def masm_EQ : Joined<["-"], "masm=">, Group<m_Group>;
+def inline_asm_EQ : Joined<["-"], "inline-asm=">, Group<m_Group>,
+ Visibility<[ClangOption, CC1Option]>,
+ Values<"att,intel">,
+ NormalizedValuesScope<"CodeGenOptions">, NormalizedValues<["IAD_ATT", "IAD_Intel"]>,
+ MarshallingInfoEnum<CodeGenOpts<"InlineAsmDialect">, "IAD_ATT">;
+def mcmodel_EQ : Joined<["-"], "mcmodel=">, Group<m_Group>,
+ Visibility<[ClangOption, CC1Option]>,
MarshallingInfoString<TargetOpts<"CodeModel">, [{"default"}]>;
-def mtls_size_EQ : Joined<["-"], "mtls-size=">, Group<m_Group>, Flags<[NoXarchOption, CC1Option]>,
+def mlarge_data_threshold_EQ : Joined<["-"], "mlarge-data-threshold=">, Group<m_Group>,
+ Flags<[TargetSpecific]>, Visibility<[ClangOption, CC1Option]>,
+ MarshallingInfoInt<TargetOpts<"LargeDataThreshold">, "0">;
+def mtls_size_EQ : Joined<["-"], "mtls-size=">, Group<m_Group>,
+ Visibility<[ClangOption, CC1Option]>,
HelpText<"Specify bit size of immediate TLS offsets (AArch64 ELF only): "
"12 (for 4KB) | 24 (for 16MB, default) | 32 (for 4GB) | 48 (for 256TB, needs -mcmodel=large)">,
MarshallingInfoInt<CodeGenOpts<"TLSSize">>;
+def mtls_dialect_EQ : Joined<["-"], "mtls-dialect=">, Group<m_Group>,
+ Flags<[TargetSpecific]>, HelpText<"Which thread-local storage dialect to use for dynamic accesses of TLS variables">;
def mimplicit_it_EQ : Joined<["-"], "mimplicit-it=">, Group<m_Group>;
def mdefault_build_attributes : Joined<["-"], "mdefault-build-attributes">, Group<m_Group>;
def mno_default_build_attributes : Joined<["-"], "mno-default-build-attributes">, Group<m_Group>;
+let Flags = [TargetSpecific] in {
def mconstant_cfstrings : Flag<["-"], "mconstant-cfstrings">, Group<clang_ignored_m_Group>;
-def mconsole : Joined<["-"], "mconsole">, Group<m_Group>, Flags<[NoXarchOption]>;
-def mwindows : Joined<["-"], "mwindows">, Group<m_Group>, Flags<[NoXarchOption]>;
-def mdll : Joined<["-"], "mdll">, Group<m_Group>, Flags<[NoXarchOption]>;
-def municode : Joined<["-"], "municode">, Group<m_Group>, Flags<[NoXarchOption]>;
-def mthreads : Joined<["-"], "mthreads">, Group<m_Group>, Flags<[NoXarchOption]>;
-def mcpu_EQ : Joined<["-"], "mcpu=">, Group<m_Group>;
+def mconsole : Joined<["-"], "mconsole">, Group<m_Group>;
+def mwindows : Joined<["-"], "mwindows">, Group<m_Group>;
+def mdll : Joined<["-"], "mdll">, Group<m_Group>;
+def municode : Joined<["-"], "municode">, Group<m_Group>;
+def mthreads : Joined<["-"], "mthreads">, Group<m_Group>;
+def mguard_EQ : Joined<["-"], "mguard=">, Group<m_Group>,
+ HelpText<"Enable or disable Control Flow Guard checks and guard tables emission">,
+ Values<"none,cf,cf-nochecks">;
def mmcu_EQ : Joined<["-"], "mmcu=">, Group<m_Group>;
def msim : Flag<["-"], "msim">, Group<m_Group>;
-def mdynamic_no_pic : Joined<["-"], "mdynamic-no-pic">, Group<m_Group>;
def mfix_and_continue : Flag<["-"], "mfix-and-continue">, Group<clang_ignored_m_Group>;
def mieee_fp : Flag<["-"], "mieee-fp">, Group<clang_ignored_m_Group>;
def minline_all_stringops : Flag<["-"], "minline-all-stringops">, Group<clang_ignored_m_Group>;
def mno_inline_all_stringops : Flag<["-"], "mno-inline-all-stringops">, Group<clang_ignored_m_Group>;
-def malign_double : Flag<["-"], "malign-double">, Group<m_Group>, Flags<[CC1Option]>,
+} // let Flags = [TargetSpecific]
+def malign_double : Flag<["-"], "malign-double">, Group<m_Group>,
+ Visibility<[ClangOption, CC1Option]>,
HelpText<"Align doubles to two words in structs (x86 only)">,
MarshallingInfoFlag<LangOpts<"AlignDouble">>;
+let Flags = [TargetSpecific] in {
def mfloat_abi_EQ : Joined<["-"], "mfloat-abi=">, Group<m_Group>, Values<"soft,softfp,hard">;
def mfpmath_EQ : Joined<["-"], "mfpmath=">, Group<m_Group>;
def mfpu_EQ : Joined<["-"], "mfpu=">, Group<m_Group>;
def mhwdiv_EQ : Joined<["-"], "mhwdiv=">, Group<m_Group>;
def mhwmult_EQ : Joined<["-"], "mhwmult=">, Group<m_Group>;
-def mglobal_merge : Flag<["-"], "mglobal-merge">, Group<m_Group>, Flags<[CC1Option]>,
+} // let Flags = [TargetSpecific]
+def mglobal_merge : Flag<["-"], "mglobal-merge">, Group<m_Group>,
+ Visibility<[ClangOption, CC1Option]>,
HelpText<"Enable merging of globals">;
+let Flags = [TargetSpecific] in {
def mhard_float : Flag<["-"], "mhard-float">, Group<m_Group>;
-def miphoneos_version_min_EQ : Joined<["-"], "miphoneos-version-min=">, Group<m_Group>;
def mios_version_min_EQ : Joined<["-"], "mios-version-min=">,
- Alias<miphoneos_version_min_EQ>, HelpText<"Set iOS deployment target">;
-def mios_simulator_version_min_EQ : Joined<["-"], "mios-simulator-version-min=">;
-def miphonesimulator_version_min_EQ : Joined<["-"], "miphonesimulator-version-min=">, Alias<mios_simulator_version_min_EQ>;
+ Group<m_Group>, HelpText<"Set iOS deployment target">;
+def : Joined<["-"], "miphoneos-version-min=">,
+ Group<m_Group>, Alias<mios_version_min_EQ>;
+def mios_simulator_version_min_EQ : Joined<["-"], "mios-simulator-version-min=">, Group<m_Group>;
+def : Joined<["-"], "miphonesimulator-version-min=">, Alias<mios_simulator_version_min_EQ>;
def mkernel : Flag<["-"], "mkernel">, Group<m_Group>;
-def mlinker_version_EQ : Joined<["-"], "mlinker-version=">,
+def mlinker_version_EQ : Joined<["-"], "mlinker-version=">, Group<m_Group>,
Flags<[NoXarchOption]>;
-def mllvm : Separate<["-"], "mllvm">, Flags<[CC1Option,CC1AsOption,CoreOption]>,
+} // let Flags = [TargetSpecific]
+def mllvm : Separate<["-"], "mllvm">,
+ Visibility<[ClangOption, CC1Option, CC1AsOption, CLOption, DXCOption, FC1Option, FlangOption]>,
HelpText<"Additional arguments to forward to LLVM's option processing">,
MarshallingInfoStringVector<FrontendOpts<"LLVMArgs">>;
-def mmacosx_version_min_EQ : Joined<["-"], "mmacosx-version-min=">,
- Group<m_Group>, HelpText<"Set Mac OS X deployment target">;
+def : Joined<["-"], "mllvm=">,
+ Visibility<[ClangOption, CLOption, DXCOption, FlangOption]>, Alias<mllvm>,
+ HelpText<"Alias for -mllvm">, MetaVarName<"<arg>">;
+def mmlir : Separate<["-"], "mmlir">,
+ Visibility<[ClangOption, CLOption, FC1Option, FlangOption]>,
+ HelpText<"Additional arguments to forward to MLIR's option processing">;
+def ffuchsia_api_level_EQ : Joined<["-"], "ffuchsia-api-level=">,
+ Group<m_Group>, Visibility<[ClangOption, CC1Option]>,
+ HelpText<"Set Fuchsia API level">,
+ MarshallingInfoInt<LangOpts<"FuchsiaAPILevel">>;
def mmacos_version_min_EQ : Joined<["-"], "mmacos-version-min=">,
- Group<m_Group>, Alias<mmacosx_version_min_EQ>;
-def mms_bitfields : Flag<["-"], "mms-bitfields">, Group<m_Group>, Flags<[CC1Option]>,
+ Group<m_Group>, HelpText<"Set macOS deployment target">;
+def : Joined<["-"], "mmacosx-version-min=">,
+ Group<m_Group>, Alias<mmacos_version_min_EQ>;
+def mms_bitfields : Flag<["-"], "mms-bitfields">, Group<m_Group>,
+ Visibility<[ClangOption, CC1Option]>,
HelpText<"Set the default structure layout to be compatible with the Microsoft compiler standard">,
MarshallingInfoFlag<LangOpts<"MSBitfields">>;
-def moutline : Flag<["-"], "moutline">, Group<f_clang_Group>, Flags<[CC1Option]>,
+def moutline : Flag<["-"], "moutline">, Group<f_clang_Group>,
+ Visibility<[ClangOption, CC1Option]>,
HelpText<"Enable function outlining (AArch64 only)">;
-def mno_outline : Flag<["-"], "mno-outline">, Group<f_clang_Group>, Flags<[CC1Option]>,
+def mno_outline : Flag<["-"], "mno-outline">, Group<f_clang_Group>,
+ Visibility<[ClangOption, CC1Option]>,
HelpText<"Disable function outlining (AArch64 only)">;
def mno_ms_bitfields : Flag<["-"], "mno-ms-bitfields">, Group<m_Group>,
HelpText<"Do not set the default structure layout to be compatible with the Microsoft compiler standard">;
-def mstackrealign : Flag<["-"], "mstackrealign">, Group<m_Group>, Flags<[CC1Option]>,
+def mskip_rax_setup : Flag<["-"], "mskip-rax-setup">, Group<m_Group>,
+ Visibility<[ClangOption, CC1Option]>,
+ HelpText<"Skip setting up RAX register when passing variable arguments (x86 only)">,
+ MarshallingInfoFlag<CodeGenOpts<"SkipRaxSetup">>;
+def mno_skip_rax_setup : Flag<["-"], "mno-skip-rax-setup">, Group<m_Group>,
+ Visibility<[ClangOption, CC1Option]>;
+def mstackrealign : Flag<["-"], "mstackrealign">, Group<m_Group>,
+ Visibility<[ClangOption, CC1Option]>,
HelpText<"Force realign the stack at entry to every function">,
MarshallingInfoFlag<CodeGenOpts<"StackRealignment">>;
-def mstack_alignment : Joined<["-"], "mstack-alignment=">, Group<m_Group>, Flags<[CC1Option]>,
+def mstack_alignment : Joined<["-"], "mstack-alignment=">, Group<m_Group>,
+ Visibility<[ClangOption, CC1Option]>,
HelpText<"Set the stack alignment">,
MarshallingInfoInt<CodeGenOpts<"StackAlignment">>;
-def mstack_probe_size : Joined<["-"], "mstack-probe-size=">, Group<m_Group>, Flags<[CC1Option]>,
+def mstack_probe_size : Joined<["-"], "mstack-probe-size=">, Group<m_Group>,
+ Visibility<[ClangOption, CC1Option]>,
HelpText<"Set the stack probe size">,
MarshallingInfoInt<CodeGenOpts<"StackProbeSize">, "4096">;
def mstack_arg_probe : Flag<["-"], "mstack-arg-probe">, Group<m_Group>,
HelpText<"Enable stack probes">;
-def mno_stack_arg_probe : Flag<["-"], "mno-stack-arg-probe">, Group<m_Group>, Flags<[CC1Option]>,
+def mzos_sys_include_EQ : Joined<["-"], "mzos-sys-include=">, MetaVarName<"<SysInclude>">,
+ HelpText<"Path to system headers on z/OS">;
+def mno_stack_arg_probe : Flag<["-"], "mno-stack-arg-probe">, Group<m_Group>,
+ Visibility<[ClangOption, CC1Option]>,
HelpText<"Disable stack probes which are enabled by default">,
MarshallingInfoFlag<CodeGenOpts<"NoStackArgProbe">>;
-def mthread_model : Separate<["-"], "mthread-model">, Group<m_Group>, Flags<[CC1Option]>,
- HelpText<"The thread model to use, e.g. posix, single (posix by default)">, Values<"posix,single">,
+def mthread_model : Separate<["-"], "mthread-model">, Group<m_Group>,
+ Visibility<[ClangOption, CC1Option]>,
+ HelpText<"The thread model to use. Defaults to 'posix')">, Values<"posix,single">,
NormalizedValues<["POSIX", "Single"]>, NormalizedValuesScope<"LangOptions::ThreadModelKind">,
MarshallingInfoEnum<LangOpts<"ThreadModel">, "POSIX">;
-def meabi : Separate<["-"], "meabi">, Group<m_Group>, Flags<[CC1Option]>,
- HelpText<"Set EABI type, e.g. 4, 5 or gnu (default depends on triple)">, Values<"default,4,5,gnu">,
+def meabi : Separate<["-"], "meabi">, Group<m_Group>,
+ Visibility<[ClangOption, CC1Option]>,
+ HelpText<"Set EABI type. Default depends on triple)">, Values<"default,4,5,gnu">,
MarshallingInfoEnum<TargetOpts<"EABIVersion">, "Default">,
NormalizedValuesScope<"llvm::EABI">,
NormalizedValues<["Default", "EABI4", "EABI5", "GNU"]>;
+def mtargetos_EQ : Joined<["-"], "mtargetos=">, Group<m_Group>,
+ HelpText<"Set the deployment target to be the specified OS and OS version">;
+def mzos_hlq_le_EQ : Joined<["-"], "mzos-hlq-le=">, MetaVarName<"<LeHLQ>">,
+ HelpText<"High level qualifier for z/OS Language Environment datasets">;
+def mzos_hlq_clang_EQ : Joined<["-"], "mzos-hlq-clang=">, MetaVarName<"<ClangHLQ>">,
+ HelpText<"High level qualifier for z/OS C++RT side deck datasets">;
+def mzos_hlq_csslib_EQ : Joined<["-"], "mzos-hlq-csslib=">, MetaVarName<"<CsslibHLQ>">,
+ HelpText<"High level qualifier for z/OS CSSLIB dataset">;
def mno_constant_cfstrings : Flag<["-"], "mno-constant-cfstrings">, Group<m_Group>;
-def mno_global_merge : Flag<["-"], "mno-global-merge">, Group<m_Group>, Flags<[CC1Option]>,
+def mno_global_merge : Flag<["-"], "mno-global-merge">, Group<m_Group>,
+ Visibility<[ClangOption, CC1Option]>,
HelpText<"Disable merging of globals">;
def mno_pascal_strings : Flag<["-"], "mno-pascal-strings">,
Alias<fno_pascal_strings>;
def mno_red_zone : Flag<["-"], "mno-red-zone">, Group<m_Group>;
-def mno_tls_direct_seg_refs : Flag<["-"], "mno-tls-direct-seg-refs">, Group<m_Group>, Flags<[CC1Option]>,
+def mno_tls_direct_seg_refs : Flag<["-"], "mno-tls-direct-seg-refs">, Group<m_Group>,
+ Visibility<[ClangOption, CC1Option]>,
HelpText<"Disable direct TLS access through segment registers">,
MarshallingInfoFlag<CodeGenOpts<"IndirectTlsSegRefs">>;
def mno_relax_all : Flag<["-"], "mno-relax-all">, Group<m_Group>;
+let Flags = [TargetSpecific] in {
def mno_rtd: Flag<["-"], "mno-rtd">, Group<m_Group>;
def mno_soft_float : Flag<["-"], "mno-soft-float">, Group<m_Group>;
def mno_stackrealign : Flag<["-"], "mno-stackrealign">, Group<m_Group>;
+} // let Flags = [TargetSpecific]
-def mretpoline : Flag<["-"], "mretpoline">, Group<m_Group>, Flags<[CoreOption,NoXarchOption]>;
-def mno_retpoline : Flag<["-"], "mno-retpoline">, Group<m_Group>, Flags<[CoreOption,NoXarchOption]>;
+def mretpoline : Flag<["-"], "mretpoline">, Group<m_Group>,
+ Visibility<[ClangOption, CLOption]>;
+def mno_retpoline : Flag<["-"], "mno-retpoline">, Group<m_Group>,
+ Visibility<[ClangOption, CLOption]>;
defm speculative_load_hardening : BoolOption<"m", "speculative-load-hardening",
CodeGenOpts<"SpeculativeLoadHardening">, DefaultFalse,
- PosFlag<SetTrue, [CC1Option]>, NegFlag<SetFalse>, BothFlags<[CoreOption]>>,
+ PosFlag<SetTrue, [], [ClangOption, CC1Option]>,
+ NegFlag<SetFalse>, BothFlags<[], [ClangOption, CLOption]>>,
Group<m_Group>;
-def mlvi_hardening : Flag<["-"], "mlvi-hardening">, Group<m_Group>, Flags<[CoreOption,NoXarchOption]>,
+def mlvi_hardening : Flag<["-"], "mlvi-hardening">, Group<m_Group>,
+ Visibility<[ClangOption, CLOption]>,
HelpText<"Enable all mitigations for Load Value Injection (LVI)">;
-def mno_lvi_hardening : Flag<["-"], "mno-lvi-hardening">, Group<m_Group>, Flags<[CoreOption,NoXarchOption]>,
+def mno_lvi_hardening : Flag<["-"], "mno-lvi-hardening">, Group<m_Group>,
+ Visibility<[ClangOption, CLOption]>,
HelpText<"Disable mitigations for Load Value Injection (LVI)">;
-def mlvi_cfi : Flag<["-"], "mlvi-cfi">, Group<m_Group>, Flags<[CoreOption,NoXarchOption]>,
+def mlvi_cfi : Flag<["-"], "mlvi-cfi">, Group<m_Group>, Flags<[NoXarchOption]>,
+ Visibility<[ClangOption, CLOption]>,
HelpText<"Enable only control-flow mitigations for Load Value Injection (LVI)">;
-def mno_lvi_cfi : Flag<["-"], "mno-lvi-cfi">, Group<m_Group>, Flags<[CoreOption,NoXarchOption]>,
+def mno_lvi_cfi : Flag<["-"], "mno-lvi-cfi">, Group<m_Group>,
+ Visibility<[ClangOption, CLOption]>,
HelpText<"Disable control-flow mitigations for Load Value Injection (LVI)">;
-def m_seses : Flag<["-"], "mseses">, Group<m_Group>, Flags<[CoreOption, NoXarchOption]>,
+def m_seses : Flag<["-"], "mseses">, Group<m_Group>, Flags<[NoXarchOption]>,
+ Visibility<[ClangOption, CLOption]>,
HelpText<"Enable speculative execution side effect suppression (SESES). "
"Includes LVI control flow integrity mitigations">;
-def mno_seses : Flag<["-"], "mno-seses">, Group<m_Group>, Flags<[CoreOption, NoXarchOption]>,
+def mno_seses : Flag<["-"], "mno-seses">, Group<m_Group>,
+ Visibility<[ClangOption, CLOption]>,
HelpText<"Disable speculative execution side effect suppression (SESES)">;
def mrelax : Flag<["-"], "mrelax">, Group<m_Group>,
@@ -3175,30 +4605,41 @@ def mno_relax : Flag<["-"], "mno-relax">, Group<m_Group>,
def msmall_data_limit_EQ : Joined<["-"], "msmall-data-limit=">, Group<m_Group>,
Alias<G>,
HelpText<"Put global and static data smaller than the limit into a special section">;
+let Flags = [TargetSpecific] in {
def msave_restore : Flag<["-"], "msave-restore">, Group<m_riscv_Features_Group>,
HelpText<"Enable using library calls for save and restore">;
def mno_save_restore : Flag<["-"], "mno-save-restore">, Group<m_riscv_Features_Group>,
HelpText<"Disable using library calls for save and restore">;
-def mcmodel_EQ_medlow : Flag<["-"], "mcmodel=medlow">, Group<m_riscv_Features_Group>,
- Flags<[CC1Option]>, Alias<mcmodel_EQ>, AliasArgs<["small"]>,
- HelpText<"Equivalent to -mcmodel=small, compatible with RISC-V gcc.">;
-def mcmodel_EQ_medany : Flag<["-"], "mcmodel=medany">, Group<m_riscv_Features_Group>,
- Flags<[CC1Option]>, Alias<mcmodel_EQ>, AliasArgs<["medium"]>,
- HelpText<"Equivalent to -mcmodel=medium, compatible with RISC-V gcc.">;
+} // let Flags = [TargetSpecific]
+let Flags = [TargetSpecific] in {
def menable_experimental_extensions : Flag<["-"], "menable-experimental-extensions">, Group<m_Group>,
HelpText<"Enable use of experimental RISC-V extensions.">;
-
-def munaligned_access : Flag<["-"], "munaligned-access">, Group<m_arm_Features_Group>,
- HelpText<"Allow memory accesses to be unaligned (AArch32/AArch64 only)">;
-def mno_unaligned_access : Flag<["-"], "mno-unaligned-access">, Group<m_arm_Features_Group>,
- HelpText<"Force all memory accesses to be aligned (AArch32/AArch64 only)">;
-def mstrict_align : Flag<["-"], "mstrict-align">, Alias<mno_unaligned_access>, Flags<[CC1Option,HelpHidden]>,
+def mrvv_vector_bits_EQ : Joined<["-"], "mrvv-vector-bits=">, Group<m_Group>,
+ Visibility<[ClangOption, FlangOption]>,
+ HelpText<"Specify the size in bits of an RVV vector register">,
+ DocBrief<"Defaults to the vector length agnostic value of \"scalable\". "
+ "Accepts power of 2 values between 64 and 65536. Also accepts "
+ "\"zvl\" to use the value implied by -march/-mcpu. On Clang, value "
+ "will be reflected in __riscv_v_fixed_vlen preprocessor define "
+ "(RISC-V only)">;
+
+def munaligned_access : Flag<["-"], "munaligned-access">, Group<m_Group>,
+ HelpText<"Allow memory accesses to be unaligned (AArch32/AArch64/LoongArch/RISC-V only)">;
+def mno_unaligned_access : Flag<["-"], "mno-unaligned-access">, Group<m_Group>,
+ HelpText<"Force all memory accesses to be aligned (AArch32/AArch64/LoongArch/RISC-V only)">;
+} // let Flags = [TargetSpecific]
+def mstrict_align : Flag<["-"], "mstrict-align">, Alias<mno_unaligned_access>,
+ Flags<[HelpHidden]>, Visibility<[ClangOption, CC1Option]>,
HelpText<"Force all memory accesses to be aligned (same as mno-unaligned-access)">;
+def mno_strict_align : Flag<["-"], "mno-strict-align">, Alias<munaligned_access>,
+ Flags<[HelpHidden]>, Visibility<[ClangOption, CC1Option]>,
+ HelpText<"Allow memory accesses to be unaligned (same as munaligned-access)">;
+let Flags = [TargetSpecific] in {
def mno_thumb : Flag<["-"], "mno-thumb">, Group<m_arm_Features_Group>;
def mrestrict_it: Flag<["-"], "mrestrict-it">, Group<m_arm_Features_Group>,
- HelpText<"Disallow generation of deprecated IT blocks for ARMv8. It is on by default for ARMv8 Thumb mode.">;
+ HelpText<"Disallow generation of complex IT blocks. It is off by default.">;
def mno_restrict_it: Flag<["-"], "mno-restrict-it">, Group<m_arm_Features_Group>,
- HelpText<"Allow generation of deprecated IT blocks for ARMv8. It is off by default for ARMv8 Thumb mode">;
+ HelpText<"Allow generation of complex IT blocks.">;
def marm : Flag<["-"], "marm">, Alias<mno_thumb>;
def ffixed_r9 : Flag<["-"], "ffixed-r9">, Group<m_arm_Features_Group>,
HelpText<"Reserve the r9 register (ARM only)">;
@@ -3210,23 +4651,49 @@ def mnocrc : Flag<["-"], "mnocrc">, Group<m_arm_Features_Group>,
HelpText<"Disallow use of CRC instructions (ARM only)">;
def mno_neg_immediates: Flag<["-"], "mno-neg-immediates">, Group<m_arm_Features_Group>,
HelpText<"Disallow converting instructions with negative immediates to their negation or inversion.">;
+} // let Flags = [TargetSpecific]
def mcmse : Flag<["-"], "mcmse">, Group<m_arm_Features_Group>,
- Flags<[NoXarchOption,CC1Option]>,
+ Visibility<[ClangOption, CC1Option]>,
HelpText<"Allow use of CMSE (Armv8-M Security Extensions)">,
MarshallingInfoFlag<LangOpts<"Cmse">>;
def ForceAAPCSBitfieldLoad : Flag<["-"], "faapcs-bitfield-load">, Group<m_arm_Features_Group>,
- Flags<[NoXarchOption,CC1Option]>,
+ Visibility<[ClangOption, CC1Option]>,
HelpText<"Follows the AAPCS standard that all volatile bit-field write generates at least one load. (ARM only).">,
MarshallingInfoFlag<CodeGenOpts<"ForceAAPCSBitfieldLoad">>;
defm aapcs_bitfield_width : BoolOption<"f", "aapcs-bitfield-width",
CodeGenOpts<"AAPCSBitfieldWidth">, DefaultTrue,
- NegFlag<SetFalse, [], "Do not follow">, PosFlag<SetTrue, [], "Follow">,
- BothFlags<[NoXarchOption, CC1Option], " the AAPCS standard requirement stating that"
+ NegFlag<SetFalse, [], [ClangOption], "Do not follow">,
+ PosFlag<SetTrue, [], [ClangOption], "Follow">,
+ BothFlags<[], [ClangOption, CC1Option],
+ " the AAPCS standard requirement stating that"
" volatile bit-field width is dictated by the field container type. (ARM only).">>,
Group<m_arm_Features_Group>;
-
+let Flags = [TargetSpecific] in {
+def mframe_chain : Joined<["-"], "mframe-chain=">,
+ Group<m_arm_Features_Group>, Values<"none,aapcs,aapcs+leaf">,
+ HelpText<"Select the frame chain model used to emit frame records (Arm only).">;
def mgeneral_regs_only : Flag<["-"], "mgeneral-regs-only">, Group<m_Group>,
HelpText<"Generate code which only uses the general purpose registers (AArch64/x86 only)">;
+def mfix_cmse_cve_2021_35465 : Flag<["-"], "mfix-cmse-cve-2021-35465">,
+ Group<m_arm_Features_Group>,
+ HelpText<"Work around VLLDM erratum CVE-2021-35465 (ARM only)">;
+def mno_fix_cmse_cve_2021_35465 : Flag<["-"], "mno-fix-cmse-cve-2021-35465">,
+ Group<m_arm_Features_Group>,
+ HelpText<"Don't work around VLLDM erratum CVE-2021-35465 (ARM only)">;
+def mfix_cortex_a57_aes_1742098 : Flag<["-"], "mfix-cortex-a57-aes-1742098">,
+ Group<m_arm_Features_Group>,
+ HelpText<"Work around Cortex-A57 Erratum 1742098 (ARM only)">;
+def mno_fix_cortex_a57_aes_1742098 : Flag<["-"], "mno-fix-cortex-a57-aes-1742098">,
+ Group<m_arm_Features_Group>,
+ HelpText<"Don't work around Cortex-A57 Erratum 1742098 (ARM only)">;
+def mfix_cortex_a72_aes_1655431 : Flag<["-"], "mfix-cortex-a72-aes-1655431">,
+ Group<m_arm_Features_Group>,
+ HelpText<"Work around Cortex-A72 Erratum 1655431 (ARM only)">,
+ Alias<mfix_cortex_a57_aes_1742098>;
+def mno_fix_cortex_a72_aes_1655431 : Flag<["-"], "mno-fix-cortex-a72-aes-1655431">,
+ Group<m_arm_Features_Group>,
+ HelpText<"Don't work around Cortex-A72 Erratum 1655431 (ARM only)">,
+ Alias<mno_fix_cortex_a57_aes_1742098>;
def mfix_cortex_a53_835769 : Flag<["-"], "mfix-cortex-a53-835769">,
Group<m_aarch64_Features_Group>,
HelpText<"Workaround Cortex-A53 erratum 835769 (AArch64 only)">;
@@ -3236,6 +4703,11 @@ def mno_fix_cortex_a53_835769 : Flag<["-"], "mno-fix-cortex-a53-835769">,
def mmark_bti_property : Flag<["-"], "mmark-bti-property">,
Group<m_aarch64_Features_Group>,
HelpText<"Add .note.gnu.property with BTI to assembly files (AArch64 only)">;
+def mno_bti_at_return_twice : Flag<["-"], "mno-bti-at-return-twice">,
+ Group<m_arm_Features_Group>,
+ HelpText<"Do not add a BTI instruction after a setjmp or other"
+ " return-twice construct (Arm/AArch64 only)">;
+
foreach i = {1-31} in
def ffixed_x#i : Flag<["-"], "ffixed-x"#i>, Group<m_Group>,
HelpText<"Reserve the x"#i#" register (AArch64/RISC-V only)">;
@@ -3244,25 +4716,41 @@ foreach i = {8-15,18} in
def fcall_saved_x#i : Flag<["-"], "fcall-saved-x"#i>, Group<m_aarch64_Features_Group>,
HelpText<"Make the x"#i#" register call-saved (AArch64 only)">;
-def msve_vector_bits_EQ : Joined<["-"], "msve-vector-bits=">,
- Group<m_aarch64_Features_Group>, Flags<[NoXarchOption,CC1Option]>,
+def msve_vector_bits_EQ : Joined<["-"], "msve-vector-bits=">, Group<m_aarch64_Features_Group>,
+ Visibility<[ClangOption, FlangOption]>,
HelpText<"Specify the size in bits of an SVE vector register. Defaults to the"
- " vector length agnostic value of \"scalable\". (AArch64 only)">,
- Values<"128,256,512,1024,2048,scalable">,
- NormalizedValues<["128", "256", "512", "1024", "2048", "0"]>,
- MarshallingInfoEnum<LangOpts<"ArmSveVectorBits">, "0">;
+ " vector length agnostic value of \"scalable\". (AArch64 only)">;
+} // let Flags = [TargetSpecific]
+
+def mvscale_min_EQ : Joined<["-"], "mvscale-min=">,
+ Visibility<[CC1Option, FC1Option]>,
+ HelpText<"Specify the vscale minimum. Defaults to \"1\". (AArch64/RISC-V only)">,
+ MarshallingInfoInt<LangOpts<"VScaleMin">>;
+def mvscale_max_EQ : Joined<["-"], "mvscale-max=">,
+ Visibility<[CC1Option, FC1Option]>,
+ HelpText<"Specify the vscale maximum. Defaults to the"
+ " vector length agnostic value of \"0\". (AArch64/RISC-V only)">,
+ MarshallingInfoInt<LangOpts<"VScaleMax">>;
def msign_return_address_EQ : Joined<["-"], "msign-return-address=">,
- Flags<[CC1Option]>, Group<m_Group>, Values<"none,all,non-leaf">,
+ Visibility<[ClangOption, CC1Option]>,
+ Group<m_Group>, Values<"none,all,non-leaf">,
HelpText<"Select return address signing scope">;
+let Flags = [TargetSpecific] in {
def mbranch_protection_EQ : Joined<["-"], "mbranch-protection=">,
+ Group<m_Group>,
HelpText<"Enforce targets of indirect branches and function returns">;
-def mharden_sls_EQ : Joined<["-"], "mharden-sls=">,
- HelpText<"Select straight-line speculation hardening scope">;
+def mharden_sls_EQ : Joined<["-"], "mharden-sls=">, Group<m_Group>,
+ HelpText<"Select straight-line speculation hardening scope (ARM/AArch64/X86"
+ " only). <arg> must be: all, none, retbr(ARM/AArch64),"
+ " blr(ARM/AArch64), comdat(ARM/AArch64), nocomdat(ARM/AArch64),"
+ " return(X86), indirect-jmp(X86)">;
def msimd128 : Flag<["-"], "msimd128">, Group<m_wasm_Features_Group>;
def mno_simd128 : Flag<["-"], "mno-simd128">, Group<m_wasm_Features_Group>;
+def mrelaxed_simd : Flag<["-"], "mrelaxed-simd">, Group<m_wasm_Features_Group>;
+def mno_relaxed_simd : Flag<["-"], "mno-relaxed-simd">, Group<m_wasm_Features_Group>;
def mnontrapping_fptoint : Flag<["-"], "mnontrapping-fptoint">, Group<m_wasm_Features_Group>;
def mno_nontrapping_fptoint : Flag<["-"], "mno-nontrapping-fptoint">, Group<m_wasm_Features_Group>;
def msign_ext : Flag<["-"], "msign-ext">, Group<m_wasm_Features_Group>;
@@ -3281,26 +4769,35 @@ def mtail_call : Flag<["-"], "mtail-call">, Group<m_wasm_Features_Group>;
def mno_tail_call : Flag<["-"], "mno-tail-call">, Group<m_wasm_Features_Group>;
def mreference_types : Flag<["-"], "mreference-types">, Group<m_wasm_Features_Group>;
def mno_reference_types : Flag<["-"], "mno-reference-types">, Group<m_wasm_Features_Group>;
+def mextended_const : Flag<["-"], "mextended-const">, Group<m_wasm_Features_Group>;
+def mno_extended_const : Flag<["-"], "mno-extended-const">, Group<m_wasm_Features_Group>;
+def mmultimemory : Flag<["-"], "mmultimemory">, Group<m_wasm_Features_Group>;
+def mno_multimemory : Flag<["-"], "mno-multimemory">, Group<m_wasm_Features_Group>;
def mexec_model_EQ : Joined<["-"], "mexec-model=">, Group<m_wasm_Features_Driver_Group>,
Values<"command,reactor">,
- HelpText<"Execution model (WebAssembly only)">;
+ HelpText<"Execution model (WebAssembly only)">,
+ DocBrief<"Select between \"command\" and \"reactor\" executable models. "
+ "Commands have a main-function which scopes the lifetime of the "
+ "program. Reactors are activated and remain active until "
+ "explicitly terminated.">;
+} // let Flags = [TargetSpecific]
defm amdgpu_ieee : BoolOption<"m", "amdgpu-ieee",
CodeGenOpts<"EmitIEEENaNCompliantInsts">, DefaultTrue,
- PosFlag<SetTrue, [], "Sets the IEEE bit in the expected default floating point "
+ PosFlag<SetTrue, [], [ClangOption], "Sets the IEEE bit in the expected default floating point "
" mode register. Floating point opcodes that support exception flag "
"gathering quiet and propagate signaling NaN inputs per IEEE 754-2008. "
"This option changes the ABI. (AMDGPU only)">,
- NegFlag<SetFalse, [CC1Option]>>, Group<m_Group>;
+ NegFlag<SetFalse, [], [ClangOption, CC1Option]>>, Group<m_Group>;
def mcode_object_version_EQ : Joined<["-"], "mcode-object-version=">, Group<m_Group>,
- HelpText<"Specify code object ABI version. Defaults to 3. (AMDGPU only)">,
- MetaVarName<"<version>">, Values<"2,3,4">;
+ HelpText<"Specify code object ABI version. Defaults to 5. (AMDGPU only)">,
+ Visibility<[ClangOption, FlangOption, CC1Option, FC1Option]>,
+ Values<"none,4,5">,
+ NormalizedValuesScope<"llvm::CodeObjectVersionKind">,
+ NormalizedValues<["COV_None", "COV_4", "COV_5"]>,
+ MarshallingInfoEnum<TargetOpts<"CodeObjectVersion">, "COV_5">;
-defm code_object_v3_legacy : SimpleMFlag<"code-object-v3",
- "Legacy option to specify code object ABI V3",
- "Legacy option to specify code object ABI V2",
- " (AMDGPU only)">;
defm cumode : SimpleMFlag<"cumode",
"Specify CU wavefront", "Specify WGP wavefront",
" execution mode (AMDGPU only)", m_amdgpu_Features_Group>;
@@ -3312,12 +4809,18 @@ defm wavefrontsize64 : SimpleMFlag<"wavefrontsize64",
defm unsafe_fp_atomics : BoolOption<"m", "unsafe-fp-atomics",
TargetOpts<"AllowAMDGPUUnsafeFPAtomics">, DefaultFalse,
- PosFlag<SetTrue, [CC1Option], "Enable unsafe floating point atomic instructions (AMDGPU only)">,
+ PosFlag<SetTrue, [], [ClangOption, CC1Option],
+ "Enable generation of unsafe floating point "
+ "atomic instructions. May generate more efficient code, but may not "
+ "respect rounding and denormal modes, and may give incorrect results "
+ "for certain memory destinations. (AMDGPU only)">,
NegFlag<SetFalse>>, Group<m_Group>;
-def faltivec : Flag<["-"], "faltivec">, Group<f_Group>, Flags<[NoXarchOption]>;
-def fno_altivec : Flag<["-"], "fno-altivec">, Group<f_Group>, Flags<[NoXarchOption]>;
-def maltivec : Flag<["-"], "maltivec">, Group<m_ppc_Features_Group>;
+def faltivec : Flag<["-"], "faltivec">, Group<f_Group>;
+def fno_altivec : Flag<["-"], "fno-altivec">, Group<f_Group>;
+let Flags = [TargetSpecific] in {
+def maltivec : Flag<["-"], "maltivec">, Group<m_ppc_Features_Group>,
+ HelpText<"Enable AltiVec vector initializer syntax">;
def mno_altivec : Flag<["-"], "mno-altivec">, Group<m_ppc_Features_Group>;
def mpcrel: Flag<["-"], "mpcrel">, Group<m_ppc_Features_Group>;
def mno_pcrel: Flag<["-"], "mno-pcrel">, Group<m_ppc_Features_Group>;
@@ -3326,11 +4829,12 @@ def mno_prefixed: Flag<["-"], "mno-prefixed">, Group<m_ppc_Features_Group>;
def mspe : Flag<["-"], "mspe">, Group<m_ppc_Features_Group>;
def mno_spe : Flag<["-"], "mno-spe">, Group<m_ppc_Features_Group>;
def mefpu2 : Flag<["-"], "mefpu2">, Group<m_ppc_Features_Group>;
-def mabi_EQ_vec_extabi : Flag<["-"], "mabi=vec-extabi">, Group<m_Group>, Flags<[CC1Option]>,
- HelpText<"Enable the extended Altivec ABI on AIX (AIX only). Uses volatile and nonvolatile vector registers">,
- MarshallingInfoFlag<LangOpts<"EnableAIXExtendedAltivecABI">>;
-def mabi_EQ_vec_default : Flag<["-"], "mabi=vec-default">, Group<m_Group>, Flags<[CC1Option]>,
- HelpText<"Enable the default Altivec ABI on AIX (AIX only). Uses only volatile vector registers.">;
+} // let Flags = [TargetSpecific]
+def mabi_EQ_quadword_atomics : Flag<["-"], "mabi=quadword-atomics">,
+ Group<m_Group>, Visibility<[ClangOption, CC1Option]>,
+ HelpText<"Enable quadword atomics ABI on AIX (AIX PPC64 only). Uses lqarx/stqcx. instructions.">,
+ MarshallingInfoFlag<LangOpts<"EnableAIXQuadwordAtomicsABI">>;
+let Flags = [TargetSpecific] in {
def mvsx : Flag<["-"], "mvsx">, Group<m_ppc_Features_Group>;
def mno_vsx : Flag<["-"], "mno-vsx">, Group<m_ppc_Features_Group>;
def msecure_plt : Flag<["-"], "msecure-plt">, Group<m_ppc_Features_Group>;
@@ -3372,7 +4876,11 @@ def mno_mfocrf : Flag<["-"], "mno-mfocrf">, Group<m_ppc_Features_Group>;
def mno_mfcrf : Flag<["-"], "mno-mfcrf">, Alias<mno_mfocrf>;
def mpopcntd : Flag<["-"], "mpopcntd">, Group<m_ppc_Features_Group>;
def mno_popcntd : Flag<["-"], "mno-popcntd">, Group<m_ppc_Features_Group>;
-def mcrbits : Flag<["-"], "mcrbits">, Group<m_ppc_Features_Group>;
+def mcrbits : Flag<["-"], "mcrbits">, Group<m_ppc_Features_Group>,
+ HelpText<"Control the CR-bit tracking feature on PowerPC. ``-mcrbits`` "
+ "(the enablement of CR-bit tracking support) is the default for "
+ "POWER8 and above, as well as for all other CPUs when "
+ "optimization is applied (-O2 and above).">;
def mno_crbits : Flag<["-"], "mno-crbits">, Group<m_ppc_Features_Group>;
def minvariant_function_descriptors :
Flag<["-"], "minvariant-function-descriptors">, Group<m_ppc_Features_Group>;
@@ -3393,30 +4901,57 @@ def mrop_protect : Flag<["-"], "mrop-protect">,
Group<m_ppc_Features_Group>;
def mprivileged : Flag<["-"], "mprivileged">,
Group<m_ppc_Features_Group>;
+
+defm regnames : BoolOption<"m", "regnames",
+ CodeGenOpts<"PPCUseFullRegisterNames">, DefaultFalse,
+ PosFlag<SetTrue, [], [ClangOption, CC1Option], "Use full register names when writing assembly output">,
+ NegFlag<SetFalse, [], [ClangOption], "Use only register numbers when writing assembly output">>,
+ Group<m_Group>;
+} // let Flags = [TargetSpecific]
+def maix_small_local_exec_tls : Flag<["-"], "maix-small-local-exec-tls">,
+ Group<m_ppc_Features_Group>,
+ HelpText<"Produce a faster access sequence for local-exec TLS variables "
+ "where the offset from the TLS base is encoded as an "
+ "immediate operand (AIX 64-bit only). "
+ "This access sequence is not used for variables larger than 32KB.">;
def maix_struct_return : Flag<["-"], "maix-struct-return">,
- Group<m_Group>, Flags<[CC1Option]>,
- HelpText<"Return all structs in memory (PPC32 only)">;
+ Group<m_Group>, Visibility<[ClangOption, CC1Option]>,
+ HelpText<"Return all structs in memory (PPC32 only)">,
+ DocBrief<"Override the default ABI for 32-bit targets to return all "
+ "structs in memory, as in the Power 32-bit ABI for Linux (2011), "
+ "and on AIX and Darwin.">;
def msvr4_struct_return : Flag<["-"], "msvr4-struct-return">,
- Group<m_Group>, Flags<[CC1Option]>,
- HelpText<"Return small structs in registers (PPC32 only)">;
-
+ Group<m_Group>, Visibility<[ClangOption, CC1Option]>,
+ HelpText<"Return small structs in registers (PPC32 only)">,
+ DocBrief<"Override the default ABI for 32-bit targets to return small "
+ "structs in registers, as in the System V ABI (1995).">;
+def mxcoff_roptr : Flag<["-"], "mxcoff-roptr">, Group<m_Group>,
+ Flags<[TargetSpecific]>, Visibility<[ClangOption, CC1Option]>,
+ HelpText<"Place constant objects with relocatable address values in the RO data section and add -bforceimprw to the linker flags (AIX only)">;
+def mno_xcoff_roptr : Flag<["-"], "mno-xcoff-roptr">, Group<m_Group>, TargetSpecific;
+
+let Flags = [TargetSpecific] in {
def mvx : Flag<["-"], "mvx">, Group<m_Group>;
def mno_vx : Flag<["-"], "mno-vx">, Group<m_Group>;
+} // let Flags = [TargetSpecific]
defm zvector : BoolFOption<"zvector",
LangOpts<"ZVector">, DefaultFalse,
- PosFlag<SetTrue, [CC1Option], "Enable System z vector language extension">,
+ PosFlag<SetTrue, [], [ClangOption, CC1Option],
+ "Enable System z vector language extension">,
NegFlag<SetFalse>>;
def mzvector : Flag<["-"], "mzvector">, Alias<fzvector>;
def mno_zvector : Flag<["-"], "mno-zvector">, Alias<fno_zvector>;
+def mxcoff_build_id_EQ : Joined<["-"], "mxcoff-build-id=">, Group<Link_Group>, MetaVarName<"<0xHEXSTRING>">,
+ HelpText<"On AIX, request creation of a build-id string, \"0xHEXSTRING\", in the string table of the loader section inside the linked binary">;
def mignore_xcoff_visibility : Flag<["-"], "mignore-xcoff-visibility">, Group<m_Group>,
HelpText<"Not emit the visibility attribute for asm in AIX OS or give all symbols 'unspecified' visibility in XCOFF object file">,
- Flags<[CC1Option]>;
+ Flags<[TargetSpecific]>, Visibility<[ClangOption, CC1Option]>;
defm backchain : BoolOption<"m", "backchain",
CodeGenOpts<"Backchain">, DefaultFalse,
- PosFlag<SetTrue, [], "Link stack frames through backchain on System Z">,
- NegFlag<SetFalse>, BothFlags<[NoXarchOption,CC1Option]>>, Group<m_Group>;
+ PosFlag<SetTrue, [], [ClangOption], "Link stack frames through backchain on System Z">,
+ NegFlag<SetFalse>, BothFlags<[], [ClangOption, CC1Option]>>, Group<m_Group>;
def mno_warn_nonportable_cfstrings : Flag<["-"], "mno-warn-nonportable-cfstrings">, Group<m_Group>;
def mno_omit_leaf_frame_pointer : Flag<["-"], "mno-omit-leaf-frame-pointer">, Group<m_Group>;
@@ -3428,57 +4963,89 @@ def mred_zone : Flag<["-"], "mred-zone">, Group<m_Group>;
def mtls_direct_seg_refs : Flag<["-"], "mtls-direct-seg-refs">, Group<m_Group>,
HelpText<"Enable direct TLS access through segment registers (default)">;
def mregparm_EQ : Joined<["-"], "mregparm=">, Group<m_Group>;
-def mrelax_all : Flag<["-"], "mrelax-all">, Group<m_Group>, Flags<[CC1Option,CC1AsOption]>,
+def mrelax_all : Flag<["-"], "mrelax-all">, Group<m_Group>,
+ Visibility<[ClangOption, CC1Option, CC1AsOption]>,
HelpText<"(integrated-as) Relax all machine instructions">,
MarshallingInfoFlag<CodeGenOpts<"RelaxAll">>;
def mincremental_linker_compatible : Flag<["-"], "mincremental-linker-compatible">, Group<m_Group>,
- Flags<[CC1Option,CC1AsOption]>,
+ Visibility<[ClangOption, CC1Option, CC1AsOption]>,
HelpText<"(integrated-as) Emit an object file which can be used with an incremental linker">,
MarshallingInfoFlag<CodeGenOpts<"IncrementalLinkerCompatible">>;
def mno_incremental_linker_compatible : Flag<["-"], "mno-incremental-linker-compatible">, Group<m_Group>,
HelpText<"(integrated-as) Emit an object file which cannot be used with an incremental linker">;
-def mrtd : Flag<["-"], "mrtd">, Group<m_Group>, Flags<[CC1Option]>,
+def mrtd : Flag<["-"], "mrtd">, Group<m_Group>,
+ Visibility<[ClangOption, CC1Option]>,
HelpText<"Make StdCall calling convention the default">;
def msmall_data_threshold_EQ : Joined <["-"], "msmall-data-threshold=">,
Group<m_Group>, Alias<G>;
-def msoft_float : Flag<["-"], "msoft-float">, Group<m_Group>, Flags<[CC1Option]>,
+def msoft_float : Flag<["-"], "msoft-float">, Group<m_Group>,
+ Visibility<[ClangOption, CC1Option]>,
HelpText<"Use software floating point">,
MarshallingInfoFlag<CodeGenOpts<"SoftFloat">>;
-def moutline_atomics : Flag<["-"], "moutline-atomics">, Group<f_clang_Group>, Flags<[CC1Option]>,
+def mno_fmv : Flag<["-"], "mno-fmv">, Group<f_clang_Group>,
+ Visibility<[ClangOption, CC1Option]>,
+ HelpText<"Disable function multiversioning">;
+def moutline_atomics : Flag<["-"], "moutline-atomics">, Group<f_clang_Group>,
+ Visibility<[ClangOption, CC1Option]>,
HelpText<"Generate local calls to out-of-line atomic operations">;
-def mno_outline_atomics : Flag<["-"], "mno-outline-atomics">, Group<f_clang_Group>, Flags<[CC1Option]>,
+def mno_outline_atomics : Flag<["-"], "mno-outline-atomics">, Group<f_clang_Group>,
+ Visibility<[ClangOption, CC1Option]>,
HelpText<"Don't generate local calls to out-of-line atomic operations">;
def mno_implicit_float : Flag<["-"], "mno-implicit-float">, Group<m_Group>,
- HelpText<"Don't generate implicit floating point instructions">;
+ HelpText<"Don't generate implicit floating point or vector instructions">;
def mimplicit_float : Flag<["-"], "mimplicit-float">, Group<m_Group>;
-def mrecip : Flag<["-"], "mrecip">, Group<m_Group>;
-def mrecip_EQ : CommaJoined<["-"], "mrecip=">, Group<m_Group>, Flags<[CC1Option]>,
+def mrecip : Flag<["-"], "mrecip">, Group<m_Group>,
+ HelpText<"Equivalent to '-mrecip=all'">;
+def mrecip_EQ : CommaJoined<["-"], "mrecip=">, Group<m_Group>,
+ Visibility<[ClangOption, CC1Option]>,
+ HelpText<"Control use of approximate reciprocal and reciprocal square root instructions followed by <n> iterations of "
+ "Newton-Raphson refinement. "
+ "<value> = ( ['!'] ['vec-'] ('rcp'|'sqrt') [('h'|'s'|'d')] [':'<n>] ) | 'all' | 'default' | 'none'">,
MarshallingInfoStringVector<CodeGenOpts<"Reciprocals">>;
-def mprefer_vector_width_EQ : Joined<["-"], "mprefer-vector-width=">, Group<m_Group>, Flags<[CC1Option]>,
+def mprefer_vector_width_EQ : Joined<["-"], "mprefer-vector-width=">, Group<m_Group>,
+ Visibility<[ClangOption, CC1Option]>,
HelpText<"Specifies preferred vector width for auto-vectorization. Defaults to 'none' which allows target specific decisions.">,
MarshallingInfoString<CodeGenOpts<"PreferVectorWidth">>;
-def mstack_protector_guard_EQ : Joined<["-"], "mstack-protector-guard=">, Group<m_Group>, Flags<[CC1Option]>,
+def mstack_protector_guard_EQ : Joined<["-"], "mstack-protector-guard=">, Group<m_Group>,
+ Visibility<[ClangOption, CC1Option]>,
HelpText<"Use the given guard (global, tls) for addressing the stack-protector guard">,
MarshallingInfoString<CodeGenOpts<"StackProtectorGuard">>;
-def mstack_protector_guard_offset_EQ : Joined<["-"], "mstack-protector-guard-offset=">, Group<m_Group>, Flags<[CC1Option]>,
+def mstack_protector_guard_offset_EQ : Joined<["-"], "mstack-protector-guard-offset=">, Group<m_Group>,
+ Visibility<[ClangOption, CC1Option]>,
HelpText<"Use the given offset for addressing the stack-protector guard">,
MarshallingInfoInt<CodeGenOpts<"StackProtectorGuardOffset">, "INT_MAX", "int">;
-def mstack_protector_guard_reg_EQ : Joined<["-"], "mstack-protector-guard-reg=">, Group<m_Group>, Flags<[CC1Option]>,
+def mstack_protector_guard_symbol_EQ : Joined<["-"], "mstack-protector-guard-symbol=">, Group<m_Group>,
+ Visibility<[ClangOption, CC1Option]>,
+ HelpText<"Use the given symbol for addressing the stack-protector guard">,
+ MarshallingInfoString<CodeGenOpts<"StackProtectorGuardSymbol">>;
+def mstack_protector_guard_reg_EQ : Joined<["-"], "mstack-protector-guard-reg=">, Group<m_Group>,
+ Visibility<[ClangOption, CC1Option]>,
HelpText<"Use the given reg for addressing the stack-protector guard">,
MarshallingInfoString<CodeGenOpts<"StackProtectorGuardReg">>;
def mfentry : Flag<["-"], "mfentry">, HelpText<"Insert calls to fentry at function entry (x86/SystemZ only)">,
- Flags<[CC1Option]>, Group<m_Group>,
+ Visibility<[ClangOption, CC1Option]>, Group<m_Group>,
MarshallingInfoFlag<CodeGenOpts<"CallFEntry">>;
+def mlsx : Flag<["-"], "mlsx">, Group<m_loongarch_Features_Group>,
+ HelpText<"Enable Loongson SIMD Extension (LSX).">;
+def mno_lsx : Flag<["-"], "mno-lsx">, Group<m_loongarch_Features_Group>,
+ HelpText<"Disable Loongson SIMD Extension (LSX).">;
+def mlasx : Flag<["-"], "mlasx">, Group<m_loongarch_Features_Group>,
+ HelpText<"Enable Loongson Advanced SIMD Extension (LASX).">;
+def mno_lasx : Flag<["-"], "mno-lasx">, Group<m_loongarch_Features_Group>,
+ HelpText<"Disable Loongson Advanced SIMD Extension (LASX).">;
def mnop_mcount : Flag<["-"], "mnop-mcount">, HelpText<"Generate mcount/__fentry__ calls as nops. To activate they need to be patched in.">,
- Flags<[CC1Option]>, Group<m_Group>,
+ Visibility<[ClangOption, CC1Option]>, Group<m_Group>,
MarshallingInfoFlag<CodeGenOpts<"MNopMCount">>;
def mrecord_mcount : Flag<["-"], "mrecord-mcount">, HelpText<"Generate a __mcount_loc section entry for each __fentry__ call.">,
- Flags<[CC1Option]>, Group<m_Group>,
+ Visibility<[ClangOption, CC1Option]>, Group<m_Group>,
MarshallingInfoFlag<CodeGenOpts<"RecordMCount">>;
def mpacked_stack : Flag<["-"], "mpacked-stack">, HelpText<"Use packed stack layout (SystemZ only).">,
- Flags<[CC1Option]>, Group<m_Group>,
+ Visibility<[ClangOption, CC1Option]>, Group<m_Group>,
MarshallingInfoFlag<CodeGenOpts<"PackedStack">>;
-def mno_packed_stack : Flag<["-"], "mno-packed-stack">, Flags<[CC1Option]>, Group<m_Group>;
+def mno_packed_stack : Flag<["-"], "mno-packed-stack">,
+ Visibility<[ClangOption, CC1Option]>, Group<m_Group>;
+
+let Flags = [TargetSpecific] in {
def mips16 : Flag<["-"], "mips16">, Group<m_mips_Features_Group>;
def mno_mips16 : Flag<["-"], "mno-mips16">, Group<m_mips_Features_Group>;
def mmicromips : Flag<["-"], "mmicromips">, Group<m_mips_Features_Group>;
@@ -3491,12 +5058,15 @@ 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>;
+} // let Flags = [TargetSpecific]
def mbranch_likely : Flag<["-"], "mbranch-likely">, Group<m_Group>,
IgnoredGCCCompat;
def mno_branch_likely : Flag<["-"], "mno-branch-likely">, Group<m_Group>,
IgnoredGCCCompat;
+let Flags = [TargetSpecific] in {
def mindirect_jump_EQ : Joined<["-"], "mindirect-jump=">,
Group<m_mips_Features_Group>,
HelpText<"Change indirect jump instructions to inhibit speculation">;
@@ -3504,8 +5074,8 @@ def mdsp : Flag<["-"], "mdsp">, Group<m_mips_Features_Group>;
def mno_dsp : Flag<["-"], "mno-dsp">, Group<m_mips_Features_Group>;
def mdspr2 : Flag<["-"], "mdspr2">, Group<m_mips_Features_Group>;
def mno_dspr2 : Flag<["-"], "mno-dspr2">, Group<m_mips_Features_Group>;
-def msingle_float : Flag<["-"], "msingle-float">, Group<m_mips_Features_Group>;
-def mdouble_float : Flag<["-"], "mdouble-float">, Group<m_mips_Features_Group>;
+def msingle_float : Flag<["-"], "msingle-float">, Group<m_Group>;
+def mdouble_float : Flag<["-"], "mdouble-float">, Group<m_Group>;
def mmadd4 : Flag<["-"], "mmadd4">, Group<m_mips_Features_Group>,
HelpText<"Enable the generation of 4-operand madd.s, madd.d and related instructions.">;
def mno_madd4 : Flag<["-"], "mno-madd4">, Group<m_mips_Features_Group>,
@@ -3562,6 +5132,7 @@ def mvirt : Flag<["-"], "mvirt">, Group<m_mips_Features_Group>;
def mno_virt : Flag<["-"], "mno-virt">, Group<m_mips_Features_Group>;
def mginv : Flag<["-"], "mginv">, Group<m_mips_Features_Group>;
def mno_ginv : Flag<["-"], "mno-ginv">, Group<m_mips_Features_Group>;
+} // let Flags = [TargetSpecific]
def mips1 : Flag<["-"], "mips1">,
Alias<march_EQ>, AliasArgs<["mips1"]>, Group<m_mips_Features_Group>,
HelpText<"Equivalent to -march=mips1">, Flags<[HelpHidden]>;
@@ -3626,59 +5197,88 @@ def mno_relax_pic_calls : Flag<["-"], "mno-relax-pic-calls">,
"call sequences into direct calls (MIPS only)">, Flags<[HelpHidden]>;
def mglibc : Flag<["-"], "mglibc">, Group<m_libc_Group>, Flags<[HelpHidden]>;
def muclibc : Flag<["-"], "muclibc">, Group<m_libc_Group>, Flags<[HelpHidden]>;
-def module_file_info : Flag<["-"], "module-file-info">, Flags<[NoXarchOption,CC1Option]>, Group<Action_Group>,
+def module_file_info : Flag<["-"], "module-file-info">, Flags<[]>,
+ Visibility<[ClangOption, CC1Option]>, Group<Action_Group>,
HelpText<"Provide information about a particular module file">;
def mthumb : Flag<["-"], "mthumb">, Group<m_Group>;
def mtune_EQ : Joined<["-"], "mtune=">, Group<m_Group>,
- HelpText<"Only supported on X86 and RISC-V. Otherwise accepted for compatibility with GCC.">;
+ HelpText<"Only supported on AArch64, PowerPC, RISC-V, SPARC, SystemZ, and X86">;
def multi__module : Flag<["-"], "multi_module">;
def multiply__defined__unused : Separate<["-"], "multiply_defined_unused">;
def multiply__defined : Separate<["-"], "multiply_defined">;
def mwarn_nonportable_cfstrings : Flag<["-"], "mwarn-nonportable-cfstrings">, Group<m_Group>;
-def no_canonical_prefixes : Flag<["-"], "no-canonical-prefixes">, Flags<[HelpHidden, CoreOption]>,
- HelpText<"Use relative instead of canonical paths">;
+def canonical_prefixes : Flag<["-"], "canonical-prefixes">,
+ Flags<[HelpHidden]>, Visibility<[ClangOption, CLOption, DXCOption]>,
+ HelpText<"Use absolute paths for invoking subcommands (default)">;
+def no_canonical_prefixes : Flag<["-"], "no-canonical-prefixes">,
+ Flags<[HelpHidden]>, Visibility<[ClangOption, CLOption, DXCOption]>,
+ HelpText<"Use relative paths for invoking subcommands">;
def no_cpp_precomp : Flag<["-"], "no-cpp-precomp">, Group<clang_ignored_f_Group>;
-def no_integrated_cpp : Flag<["-", "--"], "no-integrated-cpp">, Flags<[NoXarchOption]>;
+def no_integrated_cpp : Flag<["-", "--"], "no-integrated-cpp">;
def no_pedantic : Flag<["-", "--"], "no-pedantic">, Group<pedantic_Group>;
def no__dead__strip__inits__and__terms : Flag<["-"], "no_dead_strip_inits_and_terms">;
-def nobuiltininc : Flag<["-"], "nobuiltininc">, Flags<[CC1Option, CoreOption]>,
+def nobuiltininc : Flag<["-"], "nobuiltininc">,
+ Visibility<[ClangOption, CC1Option, CLOption, DXCOption]>,
+ Group<IncludePath_Group>,
HelpText<"Disable builtin #include directories">,
MarshallingInfoNegativeFlag<HeaderSearchOpts<"UseBuiltinIncludes">>;
-def nogpuinc : Flag<["-"], "nogpuinc">, HelpText<"Do not add include paths for CUDA/HIP and"
+def nogpuinc : Flag<["-"], "nogpuinc">, Group<IncludePath_Group>,
+ HelpText<"Do not add include paths for CUDA/HIP and"
" do not include the default CUDA/HIP wrapper headers">;
+def nohipwrapperinc : Flag<["-"], "nohipwrapperinc">, Group<IncludePath_Group>,
+ HelpText<"Do not include the default HIP wrapper headers and include paths">;
def : Flag<["-"], "nocudainc">, Alias<nogpuinc>;
-def nogpulib : Flag<["-"], "nogpulib">,
+def nogpulib : Flag<["-"], "nogpulib">, MarshallingInfoFlag<LangOpts<"NoGPULib">>,
+ Visibility<[ClangOption, CC1Option, FlangOption, FC1Option]>,
HelpText<"Do not link device library for CUDA/HIP device compilation">;
def : Flag<["-"], "nocudalib">, Alias<nogpulib>;
+def gpulibc : Flag<["-"], "gpulibc">, Visibility<[ClangOption, CC1Option, FlangOption, FC1Option]>,
+ HelpText<"Link the LLVM C Library for GPUs">;
+def nogpulibc : Flag<["-"], "nogpulibc">, Visibility<[ClangOption, CC1Option, FlangOption, FC1Option]>;
def nodefaultlibs : Flag<["-"], "nodefaultlibs">;
+def nodriverkitlib : Flag<["-"], "nodriverkitlib">;
def nofixprebinding : Flag<["-"], "nofixprebinding">;
def nolibc : Flag<["-"], "nolibc">;
def nomultidefs : Flag<["-"], "nomultidefs">;
-def nopie : Flag<["-"], "nopie">;
-def no_pie : Flag<["-"], "no-pie">, Alias<nopie>;
+def nopie : Flag<["-"], "nopie">, Visibility<[ClangOption, FlangOption]>, Flags<[TargetSpecific]>; // OpenBSD
+def no_pie : Flag<["-"], "no-pie">, Visibility<[ClangOption, FlangOption]>;
def noprebind : Flag<["-"], "noprebind">;
def noprofilelib : Flag<["-"], "noprofilelib">;
def noseglinkedit : Flag<["-"], "noseglinkedit">;
def nostartfiles : Flag<["-"], "nostartfiles">, Group<Link_Group>;
-def nostdinc : Flag<["-"], "nostdinc">, Flags<[CoreOption]>;
-def nostdlibinc : Flag<["-"], "nostdlibinc">;
-def nostdincxx : Flag<["-"], "nostdinc++">, Flags<[CC1Option]>,
+def nostdinc : Flag<["-"], "nostdinc">,
+ Visibility<[ClangOption, CLOption, DXCOption]>, Group<IncludePath_Group>;
+def nostdlibinc : Flag<["-"], "nostdlibinc">, Group<IncludePath_Group>;
+def nostdincxx : Flag<["-"], "nostdinc++">, Visibility<[ClangOption, CC1Option]>,
+ Group<IncludePath_Group>,
HelpText<"Disable standard #include directories for the C++ standard library">,
MarshallingInfoNegativeFlag<HeaderSearchOpts<"UseStandardCXXIncludes">>;
def nostdlib : Flag<["-"], "nostdlib">, Group<Link_Group>;
def nostdlibxx : Flag<["-"], "nostdlib++">;
def object : Flag<["-"], "object">;
-def o : JoinedOrSeparate<["-"], "o">, Flags<[NoXarchOption, RenderAsInput,
- CC1Option, CC1AsOption, FC1Option, FlangOption]>,
+def o : JoinedOrSeparate<["-"], "o">,
+ Flags<[NoXarchOption]>,
+ Visibility<[ClangOption, CC1Option, CC1AsOption, FC1Option, FlangOption]>,
HelpText<"Write output to <file>">, MetaVarName<"<file>">,
MarshallingInfoString<FrontendOpts<"OutputFile">>;
+def object_file_name_EQ : Joined<["-"], "object-file-name=">,
+ Visibility<[ClangOption, CC1Option, CC1AsOption, CLOption, DXCOption]>,
+ HelpText<"Set the output <file> for debug infos">, MetaVarName<"<file>">,
+ MarshallingInfoString<CodeGenOpts<"ObjectFilenameForDebug">>;
+def object_file_name : Separate<["-"], "object-file-name">,
+ Visibility<[ClangOption, CC1Option, CC1AsOption, CLOption, DXCOption]>,
+ Alias<object_file_name_EQ>;
def pagezero__size : JoinedOrSeparate<["-"], "pagezero_size">;
def pass_exit_codes : Flag<["-", "--"], "pass-exit-codes">, Flags<[Unsupported]>;
-def pedantic_errors : Flag<["-", "--"], "pedantic-errors">, Group<pedantic_Group>, Flags<[CC1Option]>,
+def pedantic_errors : Flag<["-", "--"], "pedantic-errors">, Group<pedantic_Group>,
+ Visibility<[ClangOption, CC1Option]>,
MarshallingInfoFlag<DiagnosticOpts<"PedanticErrors">>;
-def pedantic : Flag<["-", "--"], "pedantic">, Group<pedantic_Group>, Flags<[CC1Option,FlangOption,FC1Option]>,
+def pedantic : Flag<["-", "--"], "pedantic">, Group<pedantic_Group>,
+ Visibility<[ClangOption, CC1Option, FlangOption, FC1Option]>,
HelpText<"Warn on language extensions">, MarshallingInfoFlag<DiagnosticOpts<"Pedantic">>;
-def pg : Flag<["-"], "pg">, HelpText<"Enable mcount instrumentation">, Flags<[CC1Option]>,
+def p : Flag<["-"], "p">, HelpText<"Enable mcount instrumentation with prof">;
+def pg : Flag<["-"], "pg">, HelpText<"Enable mcount instrumentation">,
+ Visibility<[ClangOption, CC1Option]>,
MarshallingInfoFlag<CodeGenOpts<"InstrumentForProfiling">>;
def pipe : Flag<["-", "--"], "pipe">,
HelpText<"Use pipes between commands, when possible">;
@@ -3686,69 +5286,107 @@ def prebind__all__twolevel__modules : Flag<["-"], "prebind_all_twolevel_modules"
def prebind : Flag<["-"], "prebind">;
def preload : Flag<["-"], "preload">;
def print_file_name_EQ : Joined<["-", "--"], "print-file-name=">,
- HelpText<"Print the full library path of <file>">, MetaVarName<"<file>">;
-def print_ivar_layout : Flag<["-"], "print-ivar-layout">, Flags<[CC1Option]>,
+ HelpText<"Print the full library path of <file>">, MetaVarName<"<file>">,
+ Visibility<[ClangOption, CLOption]>;
+def print_ivar_layout : Flag<["-"], "print-ivar-layout">,
+ Visibility<[ClangOption, CC1Option]>,
HelpText<"Enable Objective-C Ivar layout bitmap print trace">,
MarshallingInfoFlag<LangOpts<"ObjCGCBitmapPrint">>;
def print_libgcc_file_name : Flag<["-", "--"], "print-libgcc-file-name">,
HelpText<"Print the library path for the currently used compiler runtime "
- "library (\"libgcc.a\" or \"libclang_rt.builtins.*.a\")">;
+ "library (\"libgcc.a\" or \"libclang_rt.builtins.*.a\")">,
+ Visibility<[ClangOption, CLOption]>;
def print_multi_directory : Flag<["-", "--"], "print-multi-directory">;
def print_multi_lib : Flag<["-", "--"], "print-multi-lib">;
+def print_multi_flags : Flag<["-", "--"], "print-multi-flags-experimental">,
+ HelpText<"Print the flags used for selecting multilibs (experimental)">;
def print_multi_os_directory : Flag<["-", "--"], "print-multi-os-directory">,
Flags<[Unsupported]>;
def print_target_triple : Flag<["-", "--"], "print-target-triple">,
- HelpText<"Print the normalized target triple">;
+ HelpText<"Print the normalized target triple">,
+ Visibility<[ClangOption, FlangOption, CLOption]>;
def print_effective_triple : Flag<["-", "--"], "print-effective-triple">,
- HelpText<"Print the effective target triple">;
-def print_multiarch : Flag<["-", "--"], "print-multiarch">,
- HelpText<"Print the multiarch target triple">;
+ HelpText<"Print the effective target triple">,
+ Visibility<[ClangOption, FlangOption, CLOption]>;
+// GCC --disable-multiarch, GCC --enable-multiarch (upstream and Debian
+// specific) have different behaviors. We choose not to support the option.
+def : Flag<["-", "--"], "print-multiarch">, Flags<[Unsupported]>;
def print_prog_name_EQ : Joined<["-", "--"], "print-prog-name=">,
- HelpText<"Print the full program path of <name>">, MetaVarName<"<name>">;
+ HelpText<"Print the full program path of <name>">, MetaVarName<"<name>">,
+ Visibility<[ClangOption, CLOption]>;
def print_resource_dir : Flag<["-", "--"], "print-resource-dir">,
- HelpText<"Print the resource directory pathname">;
+ HelpText<"Print the resource directory pathname">,
+ Visibility<[ClangOption, CLOption]>;
def print_search_dirs : Flag<["-", "--"], "print-search-dirs">,
- HelpText<"Print the paths used for finding libraries and programs">;
+ HelpText<"Print the paths used for finding libraries and programs">,
+ Visibility<[ClangOption, CLOption]>;
def print_targets : Flag<["-", "--"], "print-targets">,
- HelpText<"Print the registered targets">;
+ HelpText<"Print the registered targets">,
+ Visibility<[ClangOption, CLOption]>;
def print_rocm_search_dirs : Flag<["-", "--"], "print-rocm-search-dirs">,
- HelpText<"Print the paths used for finding ROCm installation">;
+ HelpText<"Print the paths used for finding ROCm installation">,
+ Visibility<[ClangOption, CLOption]>;
def print_runtime_dir : Flag<["-", "--"], "print-runtime-dir">,
- HelpText<"Print the directory pathname containing clangs runtime libraries">;
+ HelpText<"Print the directory pathname containing clangs runtime libraries">,
+ Visibility<[ClangOption, CLOption]>;
+def print_diagnostic_options : Flag<["-", "--"], "print-diagnostic-options">,
+ HelpText<"Print all of Clang's warning options">,
+ Visibility<[ClangOption, CLOption]>;
def private__bundle : Flag<["-"], "private_bundle">;
def pthreads : Flag<["-"], "pthreads">;
defm pthread : BoolOption<"", "pthread",
LangOpts<"POSIXThreads">, DefaultFalse,
- PosFlag<SetTrue, [], "Support POSIX threads in generated code">,
- NegFlag<SetFalse>, BothFlags<[CC1Option]>>;
-def p : Flag<["-"], "p">;
+ PosFlag<SetTrue, [], [ClangOption], "Support POSIX threads in generated code">,
+ NegFlag<SetFalse>,
+ BothFlags<[], [ClangOption, CC1Option, FlangOption, FC1Option]>>;
def pie : Flag<["-"], "pie">, Group<Link_Group>;
def static_pie : Flag<["-"], "static-pie">, Group<Link_Group>;
def read__only__relocs : Separate<["-"], "read_only_relocs">;
def remap : Flag<["-"], "remap">;
-def rewrite_objc : Flag<["-"], "rewrite-objc">, Flags<[NoXarchOption,CC1Option]>,
+def rewrite_objc : Flag<["-"], "rewrite-objc">, Flags<[NoXarchOption]>,
+ Visibility<[ClangOption, CC1Option]>,
HelpText<"Rewrite Objective-C source to C++">, Group<Action_Group>;
-def rewrite_legacy_objc : Flag<["-"], "rewrite-legacy-objc">, Flags<[NoXarchOption]>,
+def rewrite_legacy_objc : Flag<["-"], "rewrite-legacy-objc">,
+ Flags<[NoXarchOption]>,
HelpText<"Rewrite Legacy Objective-C source to C++">;
-def rdynamic : Flag<["-"], "rdynamic">, Group<Link_Group>;
+def rdynamic : Flag<["-"], "rdynamic">, Group<Link_Group>,
+ Visibility<[ClangOption, FlangOption]>;
def resource_dir : Separate<["-"], "resource-dir">,
- Flags<[NoXarchOption, CC1Option, CoreOption, HelpHidden]>,
+ Flags<[NoXarchOption, HelpHidden]>,
+ Visibility<[ClangOption, CC1Option, CLOption, DXCOption]>,
HelpText<"The directory which holds the compiler resource files">,
MarshallingInfoString<HeaderSearchOpts<"ResourceDir">>;
-def resource_dir_EQ : Joined<["-"], "resource-dir=">, Flags<[NoXarchOption, CoreOption]>,
+def resource_dir_EQ : Joined<["-"], "resource-dir=">, Flags<[NoXarchOption]>,
+ Visibility<[ClangOption, CLOption, DXCOption]>,
Alias<resource_dir>;
-def rpath : Separate<["-"], "rpath">, Flags<[LinkerInput]>, Group<Link_Group>;
-def rtlib_EQ : Joined<["-", "--"], "rtlib=">,
+def rpath : Separate<["-"], "rpath">, Flags<[LinkerInput]>, Group<Link_Group>,
+ Visibility<[ClangOption, CLOption, DXCOption, FlangOption]>;
+def rtlib_EQ : Joined<["-", "--"], "rtlib=">, Visibility<[ClangOption, CLOption]>,
HelpText<"Compiler runtime library to use">;
def frtlib_add_rpath: Flag<["-"], "frtlib-add-rpath">, Flags<[NoArgumentUnused]>,
- HelpText<"Add -rpath with architecture-specific resource directory to the linker flags">;
-def fno_rtlib_add_rpath: Flag<["-"], "fno-rtlib-add-rpath">, Flags<[NoArgumentUnused]>,
- HelpText<"Do not add -rpath with architecture-specific resource directory to the linker flags">;
-def r : Flag<["-"], "r">, Flags<[LinkerInput,NoArgumentUnused]>,
+ HelpText<"Add -rpath with architecture-specific resource directory to the linker flags. "
+ "When --hip-link is specified, also add -rpath with HIP runtime library directory to the linker flags">;
+def fno_rtlib_add_rpath: Flag<["-"], "fno-rtlib-add-rpath">,
+ Flags<[NoArgumentUnused]>,
+ HelpText<"Do not add -rpath with architecture-specific resource directory to the linker flags. "
+ "When --hip-link is specified, do not add -rpath with HIP runtime library directory to the linker flags">;
+def offload_add_rpath: Flag<["--"], "offload-add-rpath">,
+ Flags<[NoArgumentUnused]>,
+ Alias<frtlib_add_rpath>;
+def no_offload_add_rpath: Flag<["--"], "no-offload-add-rpath">,
+ Flags<[NoArgumentUnused]>,
+ Alias<frtlib_add_rpath>;
+def r : Flag<["-"], "r">, Flags<[LinkerInput, NoArgumentUnused]>,
Group<Link_Group>;
-def save_temps_EQ : Joined<["-", "--"], "save-temps=">, Flags<[CC1Option, NoXarchOption]>,
+def regcall4 : Flag<["-"], "regcall4">, Group<m_Group>,
+ Visibility<[ClangOption, CC1Option]>,
+ HelpText<"Set __regcall4 as a default calling convention to respect __regcall ABI v.4">,
+ MarshallingInfoFlag<LangOpts<"RegCall4">>;
+def save_temps_EQ : Joined<["-", "--"], "save-temps=">, Flags<[NoXarchOption]>,
+ Visibility<[ClangOption, CC1Option, FlangOption, FC1Option]>,
HelpText<"Save intermediate compilation results.">;
def save_temps : Flag<["-", "--"], "save-temps">, Flags<[NoXarchOption]>,
+ Visibility<[ClangOption, FlangOption, FC1Option]>,
Alias<save_temps_EQ>, AliasArgs<["cwd"]>,
HelpText<"Save intermediate compilation results">;
def save_stats_EQ : Joined<["-", "--"], "save-stats=">, Flags<[NoXarchOption]>,
@@ -3773,56 +5411,77 @@ def segs__read__only__addr : Separate<["-"], "segs_read_only_addr">;
def segs__read__write__addr : Separate<["-"], "segs_read_write_addr">;
def segs__read__ : Joined<["-"], "segs_read_">;
def shared_libgcc : Flag<["-"], "shared-libgcc">;
-def shared : Flag<["-", "--"], "shared">, Group<Link_Group>;
+def shared : Flag<["-", "--"], "shared">, Group<Link_Group>,
+ Visibility<[ClangOption, CLOption, DXCOption, FlangOption]>;
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">,
+ Visibility<[ClangOption, CLOption, DXCOption]>,
+ 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]>;
+def static : Flag<["-", "--"], "static">, Group<Link_Group>,
+ Visibility<[ClangOption, CLOption, DXCOption, FlangOption]>,
+ Flags<[NoArgumentUnused]>;
def std_default_EQ : Joined<["-"], "std-default=">;
-def std_EQ : Joined<["-", "--"], "std=">, Flags<[CC1Option,FlangOption,FC1Option]>,
+def std_EQ : Joined<["-", "--"], "std=">,
+ Visibility<[ClangOption, CC1Option, FlangOption, FC1Option]>,
Group<CompileOnly_Group>, HelpText<"Language standard to compile for">,
ValuesCode<[{
- const char *Values =
+ static constexpr const char VALUES_CODE [] =
#define LANGSTANDARD(id, name, lang, desc, features) name ","
#define LANGSTANDARD_ALIAS(id, alias) alias ","
#include "clang/Basic/LangStandards.def"
;
}]>;
-def stdlib_EQ : Joined<["-", "--"], "stdlib=">, Flags<[CC1Option]>,
+def stdlib_EQ : Joined<["-", "--"], "stdlib=">,
+ Visibility<[ClangOption, CC1Option]>,
HelpText<"C++ standard library to use">, Values<"libc++,libstdc++,platform">;
def stdlibxx_isystem : JoinedOrSeparate<["-"], "stdlib++-isystem">,
Group<clang_i_Group>,
HelpText<"Use directory as the C++ standard library include path">,
Flags<[NoXarchOption]>, MetaVarName<"<directory>">;
-def unwindlib_EQ : Joined<["-", "--"], "unwindlib=">, Flags<[CC1Option]>,
+def unwindlib_EQ : Joined<["-", "--"], "unwindlib=">,
+ Visibility<[ClangOption, CC1Option]>,
HelpText<"Unwind library to use">, Values<"libgcc,unwindlib,platform">;
def sub__library : JoinedOrSeparate<["-"], "sub_library">;
def sub__umbrella : JoinedOrSeparate<["-"], "sub_umbrella">;
def system_header_prefix : Joined<["--"], "system-header-prefix=">,
- Group<clang_i_Group>, Flags<[CC1Option]>, MetaVarName<"<prefix>">,
+ Group<clang_i_Group>, Visibility<[ClangOption, CC1Option]>,
+ MetaVarName<"<prefix>">,
HelpText<"Treat all #include paths starting with <prefix> as including a "
"system header.">;
def : Separate<["--"], "system-header-prefix">, Alias<system_header_prefix>;
def no_system_header_prefix : Joined<["--"], "no-system-header-prefix=">,
- Group<clang_i_Group>, Flags<[CC1Option]>, MetaVarName<"<prefix>">,
+ Group<clang_i_Group>, Visibility<[ClangOption, CC1Option]>,
+ MetaVarName<"<prefix>">,
HelpText<"Treat all #include paths starting with <prefix> as not including a "
"system header.">;
def : Separate<["--"], "no-system-header-prefix">, Alias<no_system_header_prefix>;
def s : Flag<["-"], "s">, Group<Link_Group>;
-def target : Joined<["--"], "target=">, Flags<[NoXarchOption, CoreOption]>,
+def target : Joined<["--"], "target=">, Flags<[NoXarchOption]>,
+ Visibility<[ClangOption, CLOption, DXCOption, FlangOption]>,
HelpText<"Generate code for the given target">;
+def darwin_target_variant : Separate<["-"], "darwin-target-variant">,
+ Flags<[NoXarchOption]>, Visibility<[ClangOption, CLOption]>,
+ HelpText<"Generate code for an additional runtime variant of the deployment target">;
def print_supported_cpus : Flag<["-", "--"], "print-supported-cpus">,
- Group<CompileOnly_Group>, Flags<[CC1Option, CoreOption]>,
+ Group<CompileOnly_Group>,
+ Visibility<[ClangOption, CC1Option, CLOption]>,
HelpText<"Print supported cpu models for the given target (if target is not specified,"
" it will print the supported cpus for the default target)">,
MarshallingInfoFlag<FrontendOpts<"PrintSupportedCPUs">>;
-def mcpu_EQ_QUESTION : Flag<["-"], "mcpu=?">, Alias<print_supported_cpus>;
-def mtune_EQ_QUESTION : Flag<["-"], "mtune=?">, Alias<print_supported_cpus>;
+def print_supported_extensions : Flag<["-", "--"], "print-supported-extensions">,
+ Visibility<[ClangOption, CC1Option, CLOption]>,
+ HelpText<"Print supported -march extensions (RISC-V, AArch64 and ARM only)">,
+ MarshallingInfoFlag<FrontendOpts<"PrintSupportedExtensions">>;
+def : Flag<["-"], "mcpu=help">, Alias<print_supported_cpus>;
+def : Flag<["-"], "mtune=help">, Alias<print_supported_cpus>;
def time : Flag<["-"], "time">,
HelpText<"Time individual commands">;
-def traditional_cpp : Flag<["-", "--"], "traditional-cpp">, Flags<[CC1Option]>,
+def traditional_cpp : Flag<["-", "--"], "traditional-cpp">,
+ Visibility<[ClangOption, CC1Option]>,
HelpText<"Enable some traditional CPP emulation">,
MarshallingInfoFlag<LangOpts<"TraditionalCPP">>;
def traditional : Flag<["-", "--"], "traditional">;
@@ -3833,16 +5492,18 @@ def twolevel__namespace : Flag<["-"], "twolevel_namespace">;
def t : Flag<["-"], "t">, Group<Link_Group>;
def umbrella : Separate<["-"], "umbrella">;
def undefined : JoinedOrSeparate<["-"], "undefined">, Group<u_Group>;
-def undef : Flag<["-"], "undef">, Group<u_Group>, Flags<[CC1Option]>,
+def undef : Flag<["-"], "undef">, Group<u_Group>,
+ Visibility<[ClangOption, CC1Option]>,
HelpText<"undef all system defines">,
MarshallingInfoNegativeFlag<PreprocessorOpts<"UsePredefines">>;
def unexported__symbols__list : Separate<["-"], "unexported_symbols_list">;
def u : JoinedOrSeparate<["-"], "u">, Group<u_Group>;
-def v : Flag<["-"], "v">, Flags<[CC1Option, CoreOption]>,
+def v : Flag<["-"], "v">,
+ Visibility<[ClangOption, CC1Option, CLOption, DXCOption, FlangOption]>,
HelpText<"Show commands to run and use verbose output">,
MarshallingInfoFlag<HeaderSearchOpts<"Verbose">>;
def altivec_src_compat : Joined<["-"], "faltivec-src-compat=">,
- Flags<[CC1Option]>, Group<f_Group>,
+ Visibility<[ClangOption, CC1Option]>, Group<f_Group>,
HelpText<"Source-level compatibility for Altivec vectors (for PowerPC "
"targets). This includes results of vector comparison (scalar for "
"'xl', vector for 'gcc') as well as behavior when initializing with "
@@ -3853,7 +5514,8 @@ def altivec_src_compat : Joined<["-"], "faltivec-src-compat=">,
NormalizedValuesScope<"LangOptions::AltivecSrcCompatKind">,
NormalizedValues<["Mixed", "GCC", "XL"]>,
MarshallingInfoEnum<LangOpts<"AltivecSrcCompat">, "Mixed">;
-def verify_debug_info : Flag<["--"], "verify-debug-info">, Flags<[NoXarchOption]>,
+def verify_debug_info : Flag<["--"], "verify-debug-info">,
+ Flags<[NoXarchOption]>,
HelpText<"Verify the binary representation of debug output">;
def weak_l : Joined<["-"], "weak-l">, Flags<[LinkerInput]>;
def weak__framework : Separate<["-"], "weak_framework">, Flags<[LinkerInput]>;
@@ -3862,33 +5524,50 @@ def weak__reference__mismatches : Separate<["-"], "weak_reference_mismatches">;
def whatsloaded : Flag<["-"], "whatsloaded">;
def why_load : Flag<["-"], "why_load">;
def whyload : Flag<["-"], "whyload">, Alias<why_load>;
-def w : Flag<["-"], "w">, HelpText<"Suppress all warnings">, Flags<[CC1Option]>,
+def w : Flag<["-"], "w">, HelpText<"Suppress all warnings">,
+ Visibility<[ClangOption, CC1Option]>,
MarshallingInfoFlag<DiagnosticOpts<"IgnoreWarnings">>;
-def x : JoinedOrSeparate<["-"], "x">, Flags<[NoXarchOption,CC1Option]>,
+def x : JoinedOrSeparate<["-"], "x">,
+Flags<[NoXarchOption]>,
+ Visibility<[ClangOption, CC1Option, FlangOption, FC1Option, CLOption]>,
HelpText<"Treat subsequent input files as having type <language>">,
MetaVarName<"<language>">;
def y : Joined<["-"], "y">;
defm integrated_as : BoolFOption<"integrated-as",
CodeGenOpts<"DisableIntegratedAS">, DefaultFalse,
- NegFlag<SetTrue, [CC1Option], "Disable">, PosFlag<SetFalse, [], "Enable">,
- BothFlags<[], " the integrated assembler">>;
+ NegFlag<SetTrue, [], [ClangOption, CC1Option, FlangOption], "Disable">,
+ PosFlag<SetFalse, [], [ClangOption, CC1Option, FlangOption], "Enable">,
+ BothFlags<[], [ClangOption], " the integrated assembler">>;
def fintegrated_cc1 : Flag<["-"], "fintegrated-cc1">,
- Flags<[CoreOption, NoXarchOption]>, Group<f_Group>,
+ Visibility<[ClangOption, CLOption, DXCOption]>,
+ Group<f_Group>,
HelpText<"Run cc1 in-process">;
def fno_integrated_cc1 : Flag<["-"], "fno-integrated-cc1">,
- Flags<[CoreOption, NoXarchOption]>, Group<f_Group>,
+ Visibility<[ClangOption, CLOption, DXCOption]>,
+ Group<f_Group>,
HelpText<"Spawn a separate process for each cc1">;
-def : Flag<["-"], "integrated-as">, Alias<fintegrated_as>, Flags<[NoXarchOption]>;
+def fintegrated_objemitter : Flag<["-"], "fintegrated-objemitter">,
+ Visibility<[ClangOption, CLOption]>,
+ Group<f_Group>,
+ HelpText<"Use internal machine object code emitter.">;
+def fno_integrated_objemitter : Flag<["-"], "fno-integrated-objemitter">,
+ Visibility<[ClangOption, CLOption]>,
+ Group<f_Group>,
+ HelpText<"Use external machine object code emitter.">;
+
+def : Flag<["-"], "integrated-as">, Alias<fintegrated_as>;
def : Flag<["-"], "no-integrated-as">, Alias<fno_integrated_as>,
- Flags<[CC1Option, NoXarchOption]>;
+ Visibility<[ClangOption, CC1Option, FlangOption]>;
-def working_directory : JoinedOrSeparate<["-"], "working-directory">, Flags<[CC1Option]>,
+def working_directory : Separate<["-"], "working-directory">,
+ Visibility<[ClangOption, CC1Option]>,
HelpText<"Resolve file paths relative to the specified directory">,
MarshallingInfoString<FileSystemOpts<"WorkingDir">>;
-def working_directory_EQ : Joined<["-"], "working-directory=">, Flags<[CC1Option]>,
+def working_directory_EQ : Joined<["-"], "working-directory=">,
+ Visibility<[ClangOption, CC1Option]>,
Alias<working_directory>;
// Double dash options, which are usually an alias for one of the previous
@@ -3899,10 +5578,13 @@ def _mhwdiv : Separate<["--"], "mhwdiv">, Alias<mhwdiv_EQ>;
def _CLASSPATH_EQ : Joined<["--"], "CLASSPATH=">, Alias<fclasspath_EQ>;
def _CLASSPATH : Separate<["--"], "CLASSPATH">, Alias<fclasspath_EQ>;
def _all_warnings : Flag<["--"], "all-warnings">, Alias<Wall>;
-def _analyzer_no_default_checks : Flag<["--"], "analyzer-no-default-checks">, Flags<[NoXarchOption]>;
-def _analyzer_output : JoinedOrSeparate<["--"], "analyzer-output">, Flags<[NoXarchOption]>,
+def _analyzer_no_default_checks : Flag<["--"], "analyzer-no-default-checks">,
+ Flags<[NoXarchOption]>;
+def _analyzer_output : JoinedOrSeparate<["--"], "analyzer-output">,
+ Flags<[NoXarchOption]>,
HelpText<"Static analyzer report output format (html|plist|plist-multi-file|plist-html|sarif|sarif-html|text).">;
-def _analyze : Flag<["--"], "analyze">, Flags<[NoXarchOption, CoreOption]>,
+def _analyze : Flag<["--"], "analyze">, Flags<[NoXarchOption]>,
+ Visibility<[ClangOption, CLOption]>,
HelpText<"Run the static analyzer">;
def _assemble : Flag<["--"], "assemble">, Alias<S>;
def _assert_EQ : Joined<["--"], "assert=">, Alias<A>;
@@ -3932,8 +5614,6 @@ def _for_linker_EQ : Joined<["--"], "for-linker=">, Alias<Xlinker>;
def _for_linker : Separate<["--"], "for-linker">, Alias<Xlinker>;
def _force_link_EQ : Joined<["--"], "force-link=">, Alias<u>;
def _force_link : Separate<["--"], "force-link">, Alias<u>;
-def _help_hidden : Flag<["--"], "help-hidden">,
- HelpText<"Display help for hidden options">;
def _imacros_EQ : Joined<["--"], "imacros=">, Alias<imacros>;
def _include_barrier : Flag<["--"], "include-barrier">, Alias<I_>;
def _include_directory_after_EQ : Joined<["--"], "include-directory-after=">, Alias<idirafter>;
@@ -3975,22 +5655,20 @@ def _print_diagnostic_categories : Flag<["--"], "print-diagnostic-categories">;
def _print_file_name : Separate<["--"], "print-file-name">, Alias<print_file_name_EQ>;
def _print_missing_file_dependencies : Flag<["--"], "print-missing-file-dependencies">, Alias<MG>;
def _print_prog_name : Separate<["--"], "print-prog-name">, Alias<print_prog_name_EQ>;
-def _profile_blocks : Flag<["--"], "profile-blocks">, Alias<a>;
def _profile : Flag<["--"], "profile">, Alias<p>;
def _resource_EQ : Joined<["--"], "resource=">, Alias<fcompile_resource_EQ>;
def _resource : Separate<["--"], "resource">, Alias<fcompile_resource_EQ>;
def _rtlib : Separate<["--"], "rtlib">, Alias<rtlib_EQ>;
-def _serialize_diags : Separate<["-", "--"], "serialize-diagnostics">, Flags<[NoXarchOption]>,
+def _serialize_diags : Separate<["-", "--"], "serialize-diagnostics">,
+ Flags<[NoXarchOption]>,
HelpText<"Serialize compiler diagnostics to a file">;
// We give --version different semantics from -version.
def _version : Flag<["--"], "version">,
- Flags<[CoreOption, CC1Option, FC1Option, FlangOption]>,
+ Visibility<[ClangOption, CLOption, DXCOption, FlangOption]>,
HelpText<"Print version information">;
def _signed_char : Flag<["--"], "signed-char">, Alias<fsigned_char>;
def _std : Separate<["--"], "std">, Alias<std_EQ>;
def _stdlib : Separate<["--"], "stdlib">, Alias<stdlib_EQ>;
-def _sysroot_EQ : Joined<["--"], "sysroot=">;
-def _sysroot : Separate<["--"], "sysroot">, Alias<_sysroot_EQ>;
def _target_help : Flag<["--"], "target-help">;
def _trace_includes : Flag<["--"], "trace-includes">, Alias<H>;
def _undefine_macro_EQ : Joined<["--"], "undefine-macro=">, Alias<U>;
@@ -4002,9 +5680,44 @@ def _warn__EQ : Joined<["--"], "warn-=">, Alias<W_Joined>;
def _warn_ : Joined<["--"], "warn-">, Alias<W_Joined>;
def _write_dependencies : Flag<["--"], "write-dependencies">, Alias<MD>;
def _write_user_dependencies : Flag<["--"], "write-user-dependencies">, Alias<MMD>;
-def _ : Joined<["--"], "">, Flags<[Unsupported]>;
+
+def _help_hidden : Flag<["--"], "help-hidden">,
+ Visibility<[ClangOption, FlangOption]>,
+ HelpText<"Display help for hidden options">;
+def _sysroot_EQ : Joined<["--"], "sysroot=">, Visibility<[ClangOption, FlangOption]>;
+def _sysroot : Separate<["--"], "sysroot">, Alias<_sysroot_EQ>;
+
+//===----------------------------------------------------------------------===//
+// pie/pic options (clang + flang-new)
+//===----------------------------------------------------------------------===//
+let Visibility = [ClangOption, FlangOption] in {
+
+def fPIC : Flag<["-"], "fPIC">, Group<f_Group>;
+def fno_PIC : Flag<["-"], "fno-PIC">, Group<f_Group>;
+def fPIE : Flag<["-"], "fPIE">, Group<f_Group>;
+def fno_PIE : Flag<["-"], "fno-PIE">, Group<f_Group>;
+def fpic : Flag<["-"], "fpic">, Group<f_Group>;
+def fno_pic : Flag<["-"], "fno-pic">, Group<f_Group>;
+def fpie : Flag<["-"], "fpie">, Group<f_Group>;
+def fno_pie : Flag<["-"], "fno-pie">, Group<f_Group>;
+
+} // let Vis = [Default, FlangOption]
+
+//===----------------------------------------------------------------------===//
+// Target Options (clang + flang-new)
+//===----------------------------------------------------------------------===//
+let Flags = [TargetSpecific] in {
+let Visibility = [ClangOption, FlangOption] in {
+
+def mcpu_EQ : Joined<["-"], "mcpu=">, Group<m_Group>,
+ HelpText<"For a list of available CPUs for the target use '-mcpu=help'">;
+def mdynamic_no_pic : Joined<["-"], "mdynamic-no-pic">, Group<m_Group>;
+
+} // let Vis = [Default, FlangOption]
+} // let Flags = [TargetSpecific]
// Hexagon feature flags.
+let Flags = [TargetSpecific] in {
def mieee_rnd_near : Flag<["-"], "mieee-rnd-near">,
Group<m_hexagon_Features_Group>;
def mv5 : Flag<["-"], "mv5">, Group<m_hexagon_Features_Group>, Alias<mcpu_EQ>,
@@ -4025,6 +5738,14 @@ def mv67t : Flag<["-"], "mv67t">, Group<m_hexagon_Features_Group>,
Alias<mcpu_EQ>, AliasArgs<["hexagonv67t"]>;
def mv68 : Flag<["-"], "mv68">, Group<m_hexagon_Features_Group>,
Alias<mcpu_EQ>, AliasArgs<["hexagonv68"]>;
+def mv69 : Flag<["-"], "mv69">, Group<m_hexagon_Features_Group>,
+ Alias<mcpu_EQ>, AliasArgs<["hexagonv69"]>;
+def mv71 : Flag<["-"], "mv71">, Group<m_hexagon_Features_Group>,
+ Alias<mcpu_EQ>, AliasArgs<["hexagonv71"]>;
+def mv71t : Flag<["-"], "mv71t">, Group<m_hexagon_Features_Group>,
+ Alias<mcpu_EQ>, AliasArgs<["hexagonv71t"]>;
+def mv73 : Flag<["-"], "mv73">, Group<m_hexagon_Features_Group>,
+ Alias<mcpu_EQ>, AliasArgs<["hexagonv73"]>;
def mhexagon_hvx : Flag<["-"], "mhvx">, Group<m_hexagon_Features_HVX_Group>,
HelpText<"Enable Hexagon Vector eXtensions">;
def mhexagon_hvx_EQ : Joined<["-"], "mhvx=">,
@@ -4036,26 +5757,80 @@ def mno_hexagon_hvx : Flag<["-"], "mno-hvx">,
def mhexagon_hvx_length_EQ : Joined<["-"], "mhvx-length=">,
Group<m_hexagon_Features_HVX_Group>, HelpText<"Set Hexagon Vector Length">,
Values<"64B,128B">;
-def ffixed_r19: Flag<["-"], "ffixed-r19">,
+def mhexagon_hvx_qfloat : Flag<["-"], "mhvx-qfloat">,
+ Group<m_hexagon_Features_HVX_Group>,
+ HelpText<"Enable Hexagon HVX QFloat instructions">;
+def mno_hexagon_hvx_qfloat : Flag<["-"], "mno-hvx-qfloat">,
+ Group<m_hexagon_Features_HVX_Group>,
+ HelpText<"Disable Hexagon HVX QFloat instructions">;
+def mhexagon_hvx_ieee_fp : Flag<["-"], "mhvx-ieee-fp">,
+ Group<m_hexagon_Features_Group>,
+ HelpText<"Enable Hexagon HVX IEEE floating-point">;
+def mno_hexagon_hvx_ieee_fp : Flag<["-"], "mno-hvx-ieee-fp">,
+ Group<m_hexagon_Features_Group>,
+ HelpText<"Disable Hexagon HVX IEEE floating-point">;
+def ffixed_r19: Flag<["-"], "ffixed-r19">, Group<f_Group>,
HelpText<"Reserve register r19 (Hexagon only)">;
+} // let Flags = [TargetSpecific]
def mmemops : Flag<["-"], "mmemops">, Group<m_hexagon_Features_Group>,
- Flags<[CC1Option]>, HelpText<"Enable generation of memop instructions">;
+ Visibility<[ClangOption, CC1Option]>,
+ HelpText<"Enable generation of memop instructions">;
def mno_memops : Flag<["-"], "mno-memops">, Group<m_hexagon_Features_Group>,
- Flags<[CC1Option]>, HelpText<"Disable generation of memop instructions">;
+ Visibility<[ClangOption, CC1Option]>,
+ HelpText<"Disable generation of memop instructions">;
def mpackets : Flag<["-"], "mpackets">, Group<m_hexagon_Features_Group>,
- Flags<[CC1Option]>, HelpText<"Enable generation of instruction packets">;
+ Visibility<[ClangOption, CC1Option]>,
+ HelpText<"Enable generation of instruction packets">;
def mno_packets : Flag<["-"], "mno-packets">, Group<m_hexagon_Features_Group>,
- Flags<[CC1Option]>, HelpText<"Disable generation of instruction packets">;
+ Visibility<[ClangOption, CC1Option]>,
+ HelpText<"Disable generation of instruction packets">;
def mnvj : Flag<["-"], "mnvj">, Group<m_hexagon_Features_Group>,
- Flags<[CC1Option]>, HelpText<"Enable generation of new-value jumps">;
+ Visibility<[ClangOption, CC1Option]>,
+ HelpText<"Enable generation of new-value jumps">;
def mno_nvj : Flag<["-"], "mno-nvj">, Group<m_hexagon_Features_Group>,
- Flags<[CC1Option]>, HelpText<"Disable generation of new-value jumps">;
+ Visibility<[ClangOption, CC1Option]>,
+ HelpText<"Disable generation of new-value jumps">;
def mnvs : Flag<["-"], "mnvs">, Group<m_hexagon_Features_Group>,
- Flags<[CC1Option]>, HelpText<"Enable generation of new-value stores">;
+ Visibility<[ClangOption, CC1Option]>,
+ HelpText<"Enable generation of new-value stores">;
def mno_nvs : Flag<["-"], "mno-nvs">, Group<m_hexagon_Features_Group>,
- Flags<[CC1Option]>, HelpText<"Disable generation of new-value stores">;
+ Visibility<[ClangOption, CC1Option]>,
+ HelpText<"Disable generation of new-value stores">;
+def mcabac: Flag<["-"], "mcabac">, Group<m_hexagon_Features_Group>,
+ HelpText<"Enable CABAC instructions">;
+
+// SPARC feature flags
+let Flags = [TargetSpecific] in {
+def mfpu : Flag<["-"], "mfpu">, Group<m_sparc_Features_Group>;
+def mno_fpu : Flag<["-"], "mno-fpu">, Group<m_sparc_Features_Group>;
+def mfsmuld : Flag<["-"], "mfsmuld">, Group<m_sparc_Features_Group>;
+def mno_fsmuld : Flag<["-"], "mno-fsmuld">, Group<m_sparc_Features_Group>;
+def mpopc : Flag<["-"], "mpopc">, Group<m_sparc_Features_Group>;
+def mno_popc : Flag<["-"], "mno-popc">, Group<m_sparc_Features_Group>;
+def mvis : Flag<["-"], "mvis">, Group<m_sparc_Features_Group>;
+def mno_vis : Flag<["-"], "mno-vis">, Group<m_sparc_Features_Group>;
+def mvis2 : Flag<["-"], "mvis2">, Group<m_sparc_Features_Group>;
+def mno_vis2 : Flag<["-"], "mno-vis2">, Group<m_sparc_Features_Group>;
+def mvis3 : Flag<["-"], "mvis3">, Group<m_sparc_Features_Group>;
+def mno_vis3 : Flag<["-"], "mno-vis3">, Group<m_sparc_Features_Group>;
+def mhard_quad_float : Flag<["-"], "mhard-quad-float">, Group<m_sparc_Features_Group>;
+def msoft_quad_float : Flag<["-"], "msoft-quad-float">, Group<m_sparc_Features_Group>;
+foreach i = 1 ... 7 in
+ def ffixed_g#i : Flag<["-"], "ffixed-g"#i>, Group<m_sparc_Features_Group>,
+ HelpText<"Reserve the G"#i#" register (SPARC only)">;
+foreach i = 0 ... 5 in
+ def ffixed_o#i : Flag<["-"], "ffixed-o"#i>, Group<m_sparc_Features_Group>,
+ HelpText<"Reserve the O"#i#" register (SPARC only)">;
+foreach i = 0 ... 7 in
+ def ffixed_l#i : Flag<["-"], "ffixed-l"#i>, Group<m_sparc_Features_Group>,
+ HelpText<"Reserve the L"#i#" register (SPARC only)">;
+foreach i = 0 ... 5 in
+ def ffixed_i#i : Flag<["-"], "ffixed-i"#i>, Group<m_sparc_Features_Group>,
+ HelpText<"Reserve the I"#i#" register (SPARC only)">;
+} // let Flags = [TargetSpecific]
// M68k features flags
+let Flags = [TargetSpecific] in {
def m68000 : Flag<["-"], "m68000">, Group<m_m68k_Features_Group>;
def m68010 : Flag<["-"], "m68010">, Group<m_m68k_Features_Group>;
def m68020 : Flag<["-"], "m68020">, Group<m_m68k_Features_Group>;
@@ -4063,18 +5838,23 @@ def m68030 : Flag<["-"], "m68030">, Group<m_m68k_Features_Group>;
def m68040 : Flag<["-"], "m68040">, Group<m_m68k_Features_Group>;
def m68060 : Flag<["-"], "m68060">, Group<m_m68k_Features_Group>;
+def m68881 : Flag<["-"], "m68881">, Group<m_m68k_Features_Group>;
+
foreach i = {0-6} in
def ffixed_a#i : Flag<["-"], "ffixed-a"#i>, Group<m_m68k_Features_Group>,
HelpText<"Reserve the a"#i#" register (M68k only)">;
foreach i = {0-7} in
def ffixed_d#i : Flag<["-"], "ffixed-d"#i>, Group<m_m68k_Features_Group>,
HelpText<"Reserve the d"#i#" register (M68k only)">;
+} // let Flags = [TargetSpecific]
// X86 feature flags
+let Flags = [TargetSpecific] in {
def mx87 : Flag<["-"], "mx87">, Group<m_x86_Features_Group>;
def mno_x87 : Flag<["-"], "mno-x87">, Group<m_x86_Features_Group>;
def m80387 : Flag<["-"], "m80387">, Alias<mx87>;
def mno_80387 : Flag<["-"], "mno-80387">, Alias<mno_x87>;
+def mno_fp_ret_in_387 : Flag<["-"], "mno-fp-ret-in-387">, Alias<mno_x87>;
def mmmx : Flag<["-"], "mmmx">, Group<m_x86_Features_Group>;
def mno_mmx : Flag<["-"], "mno-mmx">, Group<m_x86_Features_Group>;
def m3dnow : Flag<["-"], "m3dnow">, Group<m_x86_Features_Group>;
@@ -4083,10 +5863,16 @@ def m3dnowa : Flag<["-"], "m3dnowa">, Group<m_x86_Features_Group>;
def mno_3dnowa : Flag<["-"], "mno-3dnowa">, Group<m_x86_Features_Group>;
def mamx_bf16 : Flag<["-"], "mamx-bf16">, Group<m_x86_Features_Group>;
def mno_amx_bf16 : Flag<["-"], "mno-amx-bf16">, Group<m_x86_Features_Group>;
-def mtamx_int8 : Flag<["-"], "mamx-int8">, Group<m_x86_Features_Group>;
+def mamx_complex : Flag<["-"], "mamx-complex">, Group<m_x86_Features_Group>;
+def mno_amx_complex : Flag<["-"], "mno-amx-complex">, Group<m_x86_Features_Group>;
+def mamx_fp16 : Flag<["-"], "mamx-fp16">, Group<m_x86_Features_Group>;
+def mno_amx_fp16 : Flag<["-"], "mno-amx-fp16">, Group<m_x86_Features_Group>;
+def mamx_int8 : Flag<["-"], "mamx-int8">, Group<m_x86_Features_Group>;
def mno_amx_int8 : Flag<["-"], "mno-amx-int8">, Group<m_x86_Features_Group>;
def mamx_tile : Flag<["-"], "mamx-tile">, Group<m_x86_Features_Group>;
def mno_amx_tile : Flag<["-"], "mno-amx-tile">, Group<m_x86_Features_Group>;
+def mcmpccxadd : Flag<["-"], "mcmpccxadd">, Group<m_x86_Features_Group>;
+def mno_cmpccxadd : Flag<["-"], "mno-cmpccxadd">, Group<m_x86_Features_Group>;
def msse : Flag<["-"], "msse">, Group<m_x86_Features_Group>;
def mno_sse : Flag<["-"], "mno-sse">, Group<m_x86_Features_Group>;
def msse2 : Flag<["-"], "msse2">, Group<m_x86_Features_Group>;
@@ -4097,7 +5883,11 @@ def mssse3 : Flag<["-"], "mssse3">, Group<m_x86_Features_Group>;
def mno_ssse3 : Flag<["-"], "mno-ssse3">, Group<m_x86_Features_Group>;
def msse4_1 : Flag<["-"], "msse4.1">, Group<m_x86_Features_Group>;
def mno_sse4_1 : Flag<["-"], "mno-sse4.1">, Group<m_x86_Features_Group>;
+} // let Flags = [TargetSpecific]
+// TODO: Make -msse4.2 TargetSpecific after
+// https://github.com/llvm/llvm-project/issues/63270 is fixed.
def msse4_2 : Flag<["-"], "msse4.2">, Group<m_x86_Features_Group>;
+let Flags = [TargetSpecific] in {
def mno_sse4_2 : Flag<["-"], "mno-sse4.2">, Group<m_x86_Features_Group>;
def msse4 : Flag<["-"], "msse4">, Alias<msse4_2>;
// -mno-sse4 turns off sse4.1 which has the effect of turning off everything
@@ -4108,6 +5898,12 @@ def msse4a : Flag<["-"], "msse4a">, Group<m_x86_Features_Group>;
def mno_sse4a : Flag<["-"], "mno-sse4a">, Group<m_x86_Features_Group>;
def mavx : Flag<["-"], "mavx">, Group<m_x86_Features_Group>;
def mno_avx : Flag<["-"], "mno-avx">, Group<m_x86_Features_Group>;
+def mavx10_1_256 : Flag<["-"], "mavx10.1-256">, Group<m_x86_AVX10_Features_Group>;
+def mno_avx10_1_256 : Flag<["-"], "mno-avx10.1-256">, Group<m_x86_AVX10_Features_Group>;
+def mavx10_1_512 : Flag<["-"], "mavx10.1-512">, Group<m_x86_AVX10_Features_Group>;
+def mno_avx10_1_512 : Flag<["-"], "mno-avx10.1-512">, Group<m_x86_AVX10_Features_Group>;
+def mavx10_1 : Flag<["-"], "mavx10.1">, Alias<mavx10_1_256>;
+def mno_avx10_1 : Flag<["-"], "mno-avx10.1">, Alias<mno_avx10_1_256>;
def mavx2 : Flag<["-"], "mavx2">, Group<m_x86_Features_Group>;
def mno_avx2 : Flag<["-"], "mno-avx2">, Group<m_x86_Features_Group>;
def mavx512f : Flag<["-"], "mavx512f">, Group<m_x86_Features_Group>;
@@ -4124,6 +5920,8 @@ def mavx512dq : Flag<["-"], "mavx512dq">, Group<m_x86_Features_Group>;
def mno_avx512dq : Flag<["-"], "mno-avx512dq">, Group<m_x86_Features_Group>;
def mavx512er : Flag<["-"], "mavx512er">, Group<m_x86_Features_Group>;
def mno_avx512er : Flag<["-"], "mno-avx512er">, Group<m_x86_Features_Group>;
+def mavx512fp16 : Flag<["-"], "mavx512fp16">, Group<m_x86_Features_Group>;
+def mno_avx512fp16 : Flag<["-"], "mno-avx512fp16">, Group<m_x86_Features_Group>;
def mavx512ifma : Flag<["-"], "mavx512ifma">, Group<m_x86_Features_Group>;
def mno_avx512ifma : Flag<["-"], "mno-avx512ifma">, Group<m_x86_Features_Group>;
def mavx512pf : Flag<["-"], "mavx512pf">, Group<m_x86_Features_Group>;
@@ -4140,6 +5938,14 @@ def mavx512vpopcntdq : Flag<["-"], "mavx512vpopcntdq">, Group<m_x86_Features_Gro
def mno_avx512vpopcntdq : Flag<["-"], "mno-avx512vpopcntdq">, Group<m_x86_Features_Group>;
def mavx512vp2intersect : Flag<["-"], "mavx512vp2intersect">, Group<m_x86_Features_Group>;
def mno_avx512vp2intersect : Flag<["-"], "mno-avx512vp2intersect">, Group<m_x86_Features_Group>;
+def mavxifma : Flag<["-"], "mavxifma">, Group<m_x86_Features_Group>;
+def mno_avxifma : Flag<["-"], "mno-avxifma">, Group<m_x86_Features_Group>;
+def mavxneconvert : Flag<["-"], "mavxneconvert">, Group<m_x86_Features_Group>;
+def mno_avxneconvert : Flag<["-"], "mno-avxneconvert">, Group<m_x86_Features_Group>;
+def mavxvnniint16 : Flag<["-"], "mavxvnniint16">, Group<m_x86_Features_Group>;
+def mno_avxvnniint16 : Flag<["-"], "mno-avxvnniint16">, Group<m_x86_Features_Group>;
+def mavxvnniint8 : Flag<["-"], "mavxvnniint8">, Group<m_x86_Features_Group>;
+def mno_avxvnniint8 : Flag<["-"], "mno-avxvnniint8">, Group<m_x86_Features_Group>;
def mavxvnni : Flag<["-"], "mavxvnni">, Group<m_x86_Features_Group>;
def mno_avxvnni : Flag<["-"], "mno-avxvnni">, Group<m_x86_Features_Group>;
def madx : Flag<["-"], "madx">, Group<m_x86_Features_Group>;
@@ -4160,10 +5966,14 @@ def mwbnoinvd : Flag<["-"], "mwbnoinvd">, Group<m_x86_Features_Group>;
def mno_wbnoinvd : Flag<["-"], "mno-wbnoinvd">, Group<m_x86_Features_Group>;
def mclzero : Flag<["-"], "mclzero">, Group<m_x86_Features_Group>;
def mno_clzero : Flag<["-"], "mno-clzero">, Group<m_x86_Features_Group>;
+def mcrc32 : Flag<["-"], "mcrc32">, Group<m_x86_Features_Group>;
+def mno_crc32 : Flag<["-"], "mno-crc32">, Group<m_x86_Features_Group>;
def mcx16 : Flag<["-"], "mcx16">, Group<m_x86_Features_Group>;
def mno_cx16 : Flag<["-"], "mno-cx16">, Group<m_x86_Features_Group>;
def menqcmd : Flag<["-"], "menqcmd">, Group<m_x86_Features_Group>;
def mno_enqcmd : Flag<["-"], "mno-enqcmd">, Group<m_x86_Features_Group>;
+def mevex512 : Flag<["-"], "mevex512">, Group<m_x86_Features_Group>;
+def mno_evex512 : Flag<["-"], "mno-evex512">, Group<m_x86_Features_Group>;
def mf16c : Flag<["-"], "mf16c">, Group<m_x86_Features_Group>;
def mno_f16c : Flag<["-"], "mno-f16c">, Group<m_x86_Features_Group>;
def mfma : Flag<["-"], "mfma">, Group<m_x86_Features_Group>;
@@ -4204,14 +6014,20 @@ def mpconfig : Flag<["-"], "mpconfig">, Group<m_x86_Features_Group>;
def mno_pconfig : Flag<["-"], "mno-pconfig">, Group<m_x86_Features_Group>;
def mpopcnt : Flag<["-"], "mpopcnt">, Group<m_x86_Features_Group>;
def mno_popcnt : Flag<["-"], "mno-popcnt">, Group<m_x86_Features_Group>;
+def mprefetchi : Flag<["-"], "mprefetchi">, Group<m_x86_Features_Group>;
+def mno_prefetchi : Flag<["-"], "mno-prefetchi">, Group<m_x86_Features_Group>;
def mprefetchwt1 : Flag<["-"], "mprefetchwt1">, Group<m_x86_Features_Group>;
def mno_prefetchwt1 : Flag<["-"], "mno-prefetchwt1">, Group<m_x86_Features_Group>;
def mprfchw : Flag<["-"], "mprfchw">, Group<m_x86_Features_Group>;
def mno_prfchw : Flag<["-"], "mno-prfchw">, Group<m_x86_Features_Group>;
def mptwrite : Flag<["-"], "mptwrite">, Group<m_x86_Features_Group>;
def mno_ptwrite : Flag<["-"], "mno-ptwrite">, Group<m_x86_Features_Group>;
+def mraoint : Flag<["-"], "mraoint">, Group<m_x86_Features_Group>;
+def mno_raoint : Flag<["-"], "mno-raoint">, Group<m_x86_Features_Group>;
def mrdpid : Flag<["-"], "mrdpid">, Group<m_x86_Features_Group>;
def mno_rdpid : Flag<["-"], "mno-rdpid">, Group<m_x86_Features_Group>;
+def mrdpru : Flag<["-"], "mrdpru">, Group<m_x86_Features_Group>;
+def mno_rdpru : Flag<["-"], "mno-rdpru">, Group<m_x86_Features_Group>;
def mrdrnd : Flag<["-"], "mrdrnd">, Group<m_x86_Features_Group>;
def mno_rdrnd : Flag<["-"], "mno-rdrnd">, Group<m_x86_Features_Group>;
def mrtm : Flag<["-"], "mrtm">, Group<m_x86_Features_Group>;
@@ -4226,12 +6042,20 @@ def msgx : Flag<["-"], "msgx">, Group<m_x86_Features_Group>;
def mno_sgx : Flag<["-"], "mno-sgx">, Group<m_x86_Features_Group>;
def msha : Flag<["-"], "msha">, Group<m_x86_Features_Group>;
def mno_sha : Flag<["-"], "mno-sha">, Group<m_x86_Features_Group>;
+def msha512 : Flag<["-"], "msha512">, Group<m_x86_Features_Group>;
+def mno_sha512 : Flag<["-"], "mno-sha512">, Group<m_x86_Features_Group>;
+def msm3 : Flag<["-"], "msm3">, Group<m_x86_Features_Group>;
+def mno_sm3 : Flag<["-"], "mno-sm3">, Group<m_x86_Features_Group>;
+def msm4 : Flag<["-"], "msm4">, Group<m_x86_Features_Group>;
+def mno_sm4 : Flag<["-"], "mno-sm4">, Group<m_x86_Features_Group>;
def mtbm : Flag<["-"], "mtbm">, Group<m_x86_Features_Group>;
def mno_tbm : Flag<["-"], "mno-tbm">, Group<m_x86_Features_Group>;
def mtsxldtrk : Flag<["-"], "mtsxldtrk">, Group<m_x86_Features_Group>;
def mno_tsxldtrk : Flag<["-"], "mno-tsxldtrk">, Group<m_x86_Features_Group>;
def muintr : Flag<["-"], "muintr">, Group<m_x86_Features_Group>;
def mno_uintr : Flag<["-"], "mno-uintr">, Group<m_x86_Features_Group>;
+def musermsr : Flag<["-"], "musermsr">, Group<m_x86_Features_Group>;
+def mno_usermsr : Flag<["-"], "mno-usermsr">, Group<m_x86_Features_Group>;
def mvaes : Flag<["-"], "mvaes">, Group<m_x86_Features_Group>;
def mno_vaes : Flag<["-"], "mno-vaes">, Group<m_x86_Features_Group>;
def mvpclmulqdq : Flag<["-"], "mvpclmulqdq">, Group<m_x86_Features_Group>;
@@ -4254,12 +6078,34 @@ def mretpoline_external_thunk : Flag<["-"], "mretpoline-external-thunk">, Group<
def mno_retpoline_external_thunk : Flag<["-"], "mno-retpoline-external-thunk">, Group<m_x86_Features_Group>;
def mvzeroupper : Flag<["-"], "mvzeroupper">, Group<m_x86_Features_Group>;
def mno_vzeroupper : Flag<["-"], "mno-vzeroupper">, Group<m_x86_Features_Group>;
+def mno_gather : Flag<["-"], "mno-gather">, Group<m_Group>,
+ HelpText<"Disable generation of gather instructions in auto-vectorization(x86 only)">;
+def mno_scatter : Flag<["-"], "mno-scatter">, Group<m_Group>,
+ HelpText<"Disable generation of scatter instructions in auto-vectorization(x86 only)">;
+def mapx_features_EQ : CommaJoined<["-"], "mapx-features=">, Group<m_x86_Features_Group>,
+ HelpText<"Enable features of APX">, Values<"egpr,push2pop2,ppx,ndd,ccmp,cf">;
+def mno_apx_features_EQ : CommaJoined<["-"], "mno-apx-features=">, Group<m_x86_Features_Group>,
+ HelpText<"Disable features of APX">, Values<"egpr,push2pop2,ppx,ndd,ccmp,cf">;
+// Features egpr, push2pop2, ppx and ndd are validated with llvm-test-suite && cpu2017 on Intel SDE.
+// For stability, we turn on these features only for -mapxf. After a feature pass the validation,
+// we will add it to -mapxf.
+def mapxf : Flag<["-"], "mapxf">, Alias<mapx_features_EQ>, AliasArgs<["egpr","push2pop2","ppx", "ndd"]>;
+def mno_apxf : Flag<["-"], "mno-apxf">, Alias<mno_apx_features_EQ>, AliasArgs<["egpr","push2pop2","ppx","ndd"]>;
+} // let Flags = [TargetSpecific]
+
+// VE feature flags
+let Flags = [TargetSpecific] in {
+def mvevpu : Flag<["-"], "mvevpu">, Group<m_ve_Features_Group>,
+ HelpText<"Emit VPU instructions for VE">;
+def mno_vevpu : Flag<["-"], "mno-vevpu">, Group<m_ve_Features_Group>;
+} // let Flags = [TargetSpecific]
// These are legacy user-facing driver-level option spellings. They are always
// aliases for options that are spelled using the more common Unix / GNU flag
// style of double-dash and equals-joined flags.
-def gcc_toolchain_legacy_spelling : Separate<["-"], "gcc-toolchain">, Alias<gcc_toolchain>;
-def target_legacy_spelling : Separate<["-"], "target">, Alias<target>;
+def target_legacy_spelling : Separate<["-"], "target">,
+ Alias<target>,
+ Visibility<[ClangOption, CLOption, DXCOption, FlangOption]>;
// Special internal option to handle -Xlinker --no-demangle.
def Z_Xlinker__no_demangle : Flag<["-"], "Z-Xlinker-no-demangle">,
@@ -4271,9 +6117,11 @@ def Zlinker_input : Separate<["-"], "Zlinker-input">,
// Reserved library options.
def Z_reserved_lib_stdcxx : Flag<["-"], "Z-reserved-lib-stdc++">,
- Flags<[LinkerInput, NoArgumentUnused, Unsupported]>, Group<reserved_lib_Group>;
+ Flags<[LinkerInput, NoArgumentUnused, Unsupported]>,
+ Group<reserved_lib_Group>;
def Z_reserved_lib_cckext : Flag<["-"], "Z-reserved-lib-cckext">,
- Flags<[LinkerInput, NoArgumentUnused, Unsupported]>, Group<reserved_lib_Group>;
+ Flags<[LinkerInput, NoArgumentUnused, Unsupported]>,
+ Group<reserved_lib_Group>;
// Ignored options
multiclass BooleanFFlag<string name> {
@@ -4281,24 +6129,30 @@ multiclass BooleanFFlag<string name> {
def fno_#NAME : Flag<["-"], "fno-"#name>;
}
+multiclass FlangIgnoredDiagOpt<string name> {
+ def unsupported_warning_w#NAME : Flag<["-", "--"], "W"#name>,
+ Visibility<[FlangOption]>, Group<flang_ignored_w_Group>;
+}
+
defm : BooleanFFlag<"keep-inline-functions">, Group<clang_ignored_gcc_optimization_f_Group>;
def fprofile_dir : Joined<["-"], "fprofile-dir=">, Group<f_Group>;
// The default value matches BinutilsVersion in MCAsmInfo.h.
def fbinutils_version_EQ : Joined<["-"], "fbinutils-version=">,
- MetaVarName<"<major.minor>">, Group<f_Group>, Flags<[CC1Option]>,
+ MetaVarName<"<major.minor>">, Group<f_Group>,
+ Visibility<[ClangOption, CC1Option]>,
HelpText<"Produced object files can use all ELF features supported by this "
"binutils version and newer. If -fno-integrated-as is specified, the "
"generated assembly will consider GNU as support. 'none' means that all ELF "
"features can be used, regardless of binutils support. Defaults to 2.26.">;
-def fuse_ld_EQ : Joined<["-"], "fuse-ld=">, Group<f_Group>, Flags<[CoreOption, LinkOption]>;
+def fuse_ld_EQ : Joined<["-"], "fuse-ld=">, Group<f_Group>,
+ Flags<[LinkOption]>, Visibility<[ClangOption, FlangOption, CLOption]>;
def ld_path_EQ : Joined<["--"], "ld-path=">, Group<Link_Group>;
defm align_labels : BooleanFFlag<"align-labels">, Group<clang_ignored_gcc_optimization_f_Group>;
def falign_labels_EQ : Joined<["-"], "falign-labels=">, Group<clang_ignored_gcc_optimization_f_Group>;
defm align_loops : BooleanFFlag<"align-loops">, Group<clang_ignored_gcc_optimization_f_Group>;
-def falign_loops_EQ : Joined<["-"], "falign-loops=">, Group<clang_ignored_gcc_optimization_f_Group>;
defm align_jumps : BooleanFFlag<"align-jumps">, Group<clang_ignored_gcc_optimization_f_Group>;
def falign_jumps_EQ : Joined<["-"], "falign-jumps=">, Group<clang_ignored_gcc_optimization_f_Group>;
@@ -4306,12 +6160,15 @@ def falign_jumps_EQ : Joined<["-"], "falign-jumps=">, Group<clang_ignored_gcc_op
// ignore it for now to avoid breaking builds that use it.
def fdiagnostics_show_location_EQ : Joined<["-"], "fdiagnostics-show-location=">, Group<clang_ignored_f_Group>;
-defm fcheck_new : BooleanFFlag<"check-new">, Group<clang_ignored_f_Group>;
+defm check_new : BoolOption<"f", "check-new",
+ LangOpts<"CheckNew">, DefaultFalse,
+ PosFlag<SetTrue, [], [ClangOption], "Do not assume C++ operator new may not return NULL">,
+ NegFlag<SetFalse>, BothFlags<[], [ClangOption, CC1Option]>>;
+
defm caller_saves : BooleanFFlag<"caller-saves">, Group<clang_ignored_gcc_optimization_f_Group>;
defm reorder_blocks : BooleanFFlag<"reorder-blocks">, Group<clang_ignored_gcc_optimization_f_Group>;
defm branch_count_reg : BooleanFFlag<"branch-count-reg">, Group<clang_ignored_gcc_optimization_f_Group>;
defm default_inline : BooleanFFlag<"default-inline">, Group<clang_ignored_gcc_optimization_f_Group>;
-defm fat_lto_objects : BooleanFFlag<"fat-lto-objects">, Group<clang_ignored_gcc_optimization_f_Group>;
defm float_store : BooleanFFlag<"float-store">, Group<clang_ignored_gcc_optimization_f_Group>;
defm friend_injection : BooleanFFlag<"friend-injection">, Group<clang_ignored_f_Group>;
defm function_attribute_list : BooleanFFlag<"function-attribute-list">, Group<clang_ignored_f_Group>;
@@ -4337,7 +6194,11 @@ defm ipa_cp : BooleanFFlag<"ipa-cp">,
defm ivopts : BooleanFFlag<"ivopts">, Group<clang_ignored_gcc_optimization_f_Group>;
defm semantic_interposition : BoolFOption<"semantic-interposition",
LangOpts<"SemanticInterposition">, DefaultFalse,
- PosFlag<SetTrue, [CC1Option]>, NegFlag<SetFalse>>;
+ PosFlag<SetTrue, [], [ClangOption, CC1Option]>,
+ NegFlag<SetFalse>>,
+ DocBrief<[{Enable semantic interposition. Semantic interposition allows for the
+interposition of a symbol by another at runtime, thus preventing a range of
+inter-procedural optimisation.}]>;
defm non_call_exceptions : BooleanFFlag<"non-call-exceptions">, Group<clang_ignored_f_Group>;
defm peel_loops : BooleanFFlag<"peel-loops">, Group<clang_ignored_gcc_optimization_f_Group>;
defm permissive : BooleanFFlag<"permissive">, Group<clang_ignored_f_Group>;
@@ -4368,6 +6229,7 @@ defm tree_salias : BooleanFFlag<"tree-salias">, Group<clang_ignored_f_Group>;
defm tree_ter : BooleanFFlag<"tree-ter">, Group<clang_ignored_gcc_optimization_f_Group>;
defm tree_vectorizer_verbose : BooleanFFlag<"tree-vectorizer-verbose">, Group<clang_ignored_f_Group>;
defm tree_vrp : BooleanFFlag<"tree-vrp">, Group<clang_ignored_gcc_optimization_f_Group>;
+defm : BooleanFFlag<"unit-at-a-time">, Group<clang_ignored_gcc_optimization_f_Group>;
defm unroll_all_loops : BooleanFFlag<"unroll-all-loops">, Group<clang_ignored_gcc_optimization_f_Group>;
defm unsafe_loop_optimizations : BooleanFFlag<"unsafe-loop-optimizations">,
Group<clang_ignored_gcc_optimization_f_Group>;
@@ -4390,7 +6252,6 @@ def static_libgfortran : Flag<["-"], "static-libgfortran">, Group<gfortran_Group
def fblas_matmul_limit_EQ : Joined<["-"], "fblas-matmul-limit=">, Group<gfortran_Group>;
def fcheck_EQ : Joined<["-"], "fcheck=">, Group<gfortran_Group>;
def fcoarray_EQ : Joined<["-"], "fcoarray=">, Group<gfortran_Group>;
-def fconvert_EQ : Joined<["-"], "fconvert=">, Group<gfortran_Group>;
def ffpe_trap_EQ : Joined<["-"], "ffpe-trap=">, Group<gfortran_Group>;
def ffree_line_length_VALUE : Joined<["-"], "ffree-line-length-">, Group<gfortran_Group>;
def finit_character_EQ : Joined<["-"], "finit-character=">, Group<gfortran_Group>;
@@ -4407,7 +6268,7 @@ def frecord_marker_EQ : Joined<["-"], "frecord-marker=">, Group<gfortran_Group>;
defm aggressive_function_elimination : BooleanFFlag<"aggressive-function-elimination">, Group<gfortran_Group>;
defm align_commons : BooleanFFlag<"align-commons">, Group<gfortran_Group>;
defm all_intrinsics : BooleanFFlag<"all-intrinsics">, Group<gfortran_Group>;
-defm automatic : BooleanFFlag<"automatic">, Group<gfortran_Group>;
+def fautomatic : Flag<["-"], "fautomatic">; // -fno-automatic is significant
defm backtrace : BooleanFFlag<"backtrace">, Group<gfortran_Group>;
defm bounds_check : BooleanFFlag<"bounds-check">, Group<gfortran_Group>;
defm check_array_temporaries : BooleanFFlag<"check-array-temporaries">, Group<gfortran_Group>;
@@ -4439,35 +6300,88 @@ defm recursive : BooleanFFlag<"recursive">, Group<gfortran_Group>;
defm repack_arrays : BooleanFFlag<"repack-arrays">, Group<gfortran_Group>;
defm second_underscore : BooleanFFlag<"second-underscore">, Group<gfortran_Group>;
defm sign_zero : BooleanFFlag<"sign-zero">, Group<gfortran_Group>;
-defm stack_arrays : BooleanFFlag<"stack-arrays">, Group<gfortran_Group>;
-defm underscoring : BooleanFFlag<"underscoring">, Group<gfortran_Group>;
defm whole_file : BooleanFFlag<"whole-file">, Group<gfortran_Group>;
+// -W <arg> options unsupported by the flang compiler
+// If any of these options are passed into flang's compiler driver,
+// a warning will be raised and the argument will be claimed
+defm : FlangIgnoredDiagOpt<"extra">;
+defm : FlangIgnoredDiagOpt<"aliasing">;
+defm : FlangIgnoredDiagOpt<"ampersand">;
+defm : FlangIgnoredDiagOpt<"array-bounds">;
+defm : FlangIgnoredDiagOpt<"c-binding-type">;
+defm : FlangIgnoredDiagOpt<"character-truncation">;
+defm : FlangIgnoredDiagOpt<"conversion">;
+defm : FlangIgnoredDiagOpt<"do-subscript">;
+defm : FlangIgnoredDiagOpt<"function-elimination">;
+defm : FlangIgnoredDiagOpt<"implicit-interface">;
+defm : FlangIgnoredDiagOpt<"implicit-procedure">;
+defm : FlangIgnoredDiagOpt<"intrinsic-shadow">;
+defm : FlangIgnoredDiagOpt<"use-without-only">;
+defm : FlangIgnoredDiagOpt<"intrinsics-std">;
+defm : FlangIgnoredDiagOpt<"line-truncation">;
+defm : FlangIgnoredDiagOpt<"no-align-commons">;
+defm : FlangIgnoredDiagOpt<"no-overwrite-recursive">;
+defm : FlangIgnoredDiagOpt<"no-tabs">;
+defm : FlangIgnoredDiagOpt<"real-q-constant">;
+defm : FlangIgnoredDiagOpt<"surprising">;
+defm : FlangIgnoredDiagOpt<"underflow">;
+defm : FlangIgnoredDiagOpt<"unused-parameter">;
+defm : FlangIgnoredDiagOpt<"realloc-lhs">;
+defm : FlangIgnoredDiagOpt<"realloc-lhs-all">;
+defm : FlangIgnoredDiagOpt<"frontend-loop-interchange">;
+defm : FlangIgnoredDiagOpt<"target-lifetime">;
+
// C++ SYCL options
-def fsycl : Flag<["-"], "fsycl">, Flags<[NoXarchOption, CoreOption]>,
+def fsycl : Flag<["-"], "fsycl">,
+ Visibility<[ClangOption, CLOption]>,
Group<sycl_Group>, HelpText<"Enables SYCL kernels compilation for device">;
-def fno_sycl : Flag<["-"], "fno-sycl">, Flags<[NoXarchOption, CoreOption]>,
+def fno_sycl : Flag<["-"], "fno-sycl">,
+ Visibility<[ClangOption, CLOption]>,
Group<sycl_Group>, HelpText<"Disables SYCL kernels compilation for device">;
+// OS-specific options
+let Flags = [TargetSpecific] in {
+defm android_pad_segment : BooleanFFlag<"android-pad-segment">, Group<f_Group>;
+} // let Flags = [TargetSpecific]
+
+//===----------------------------------------------------------------------===//
+// FLangOption + NoXarchOption
+//===----------------------------------------------------------------------===//
+
+def flang_experimental_hlfir : Flag<["-"], "flang-experimental-hlfir">,
+ Flags<[HelpHidden]>, Visibility<[FlangOption, FC1Option]>,
+ HelpText<"Use HLFIR lowering (experimental)">;
+
+def flang_deprecated_no_hlfir : Flag<["-"], "flang-deprecated-no-hlfir">,
+ Flags<[HelpHidden]>, Visibility<[FlangOption, FC1Option]>,
+ HelpText<"Do not use HLFIR lowering (deprecated)">;
+
+def flang_experimental_polymorphism : Flag<["-"], "flang-experimental-polymorphism">,
+ Flags<[HelpHidden]>, Visibility<[FlangOption, FC1Option]>,
+ HelpText<"Enable Fortran 2003 polymorphism (experimental)">;
+
+
//===----------------------------------------------------------------------===//
// FLangOption + CoreOption + NoXarchOption
//===----------------------------------------------------------------------===//
-let Flags = [FlangOption, FlangOnlyOption, NoXarchOption, CoreOption] in {
+
def Xflang : Separate<["-"], "Xflang">,
HelpText<"Pass <arg> to the flang compiler">, MetaVarName<"<arg>">,
- Flags<[NoXarchOption, CoreOption]>, Group<CompileOnly_Group>;
-}
+ Flags<[NoXarchOption]>, Visibility<[FlangOption, CLOption]>,
+ Group<CompileOnly_Group>;
//===----------------------------------------------------------------------===//
// FlangOption and FC1 Options
//===----------------------------------------------------------------------===//
-let Flags = [FC1Option, FlangOption, FlangOnlyOption] in {
+
+let Visibility = [FC1Option, FlangOption] in {
def cpp : Flag<["-"], "cpp">, Group<f_Group>,
HelpText<"Enable predefined and command line preprocessor macros">;
def nocpp : Flag<["-"], "nocpp">, Group<f_Group>,
HelpText<"Disable predefined and command line preprocessor macros">;
-def module_dir : Separate<["-"], "module-dir">, MetaVarName<"<dir>">,
+def module_dir : JoinedOrSeparate<["-"], "module-dir">, MetaVarName<"<dir>">,
HelpText<"Put MODULE files in <dir>">,
DocBrief<[{This option specifies where to put .mod files for compiled modules.
It is also added to the list of directories to be searched by an USE statement.
@@ -4482,47 +6396,60 @@ def ffixed_line_length_EQ : Joined<["-"], "ffixed-line-length=">, Group<f_Group>
DocBrief<[{Set column after which characters are ignored in typical fixed-form lines in the source
file}]>;
def ffixed_line_length_VALUE : Joined<["-"], "ffixed-line-length-">, Group<f_Group>, Alias<ffixed_line_length_EQ>;
-def fopenacc : Flag<["-"], "fopenacc">, Group<f_Group>,
- HelpText<"Enable OpenACC">;
+def fconvert_EQ : Joined<["-"], "fconvert=">, Group<f_Group>,
+ HelpText<"Set endian conversion of data for unformatted files">;
def fdefault_double_8 : Flag<["-"],"fdefault-double-8">, Group<f_Group>,
HelpText<"Set the default double precision kind to an 8 byte wide type">;
def fdefault_integer_8 : Flag<["-"],"fdefault-integer-8">, Group<f_Group>,
- HelpText<"Set the default integer kind to an 8 byte wide type">;
+ HelpText<"Set the default integer and logical kind to an 8 byte wide type">;
def fdefault_real_8 : Flag<["-"],"fdefault-real-8">, Group<f_Group>,
HelpText<"Set the default real kind to an 8 byte wide type">;
def flarge_sizes : Flag<["-"],"flarge-sizes">, Group<f_Group>,
HelpText<"Use INTEGER(KIND=8) for the result type in size-related intrinsics">;
-def fbackslash : Flag<["-"], "fbackslash">, Group<f_Group>,
- HelpText<"Specify that backslash in string introduces an escape character">,
- DocBrief<[{Change the interpretation of backslashes in string literals from
-a single backslash character to "C-style" escape characters.}]>;
-def fno_backslash : Flag<["-"], "fno-backslash">, Group<f_Group>;
-def fxor_operator : Flag<["-"], "fxor-operator">, Group<f_Group>,
- HelpText<"Enable .XOR. as a synonym of .NEQV.">;
-def fno_xor_operator : Flag<["-"], "fno-xor-operator">, Group<f_Group>;
-def flogical_abbreviations : Flag<["-"], "flogical-abbreviations">, Group<f_Group>,
- HelpText<"Enable logical abbreviations">;
-def fno_logical_abbreviations : Flag<["-"], "fno-logical-abbreviations">, Group<f_Group>;
-def fimplicit_none : Flag<["-"], "fimplicit-none">, Group<f_Group>,
- HelpText<"No implicit typing allowed unless overridden by IMPLICIT statements">;
-def fno_implicit_none : Flag<["-"], "fno-implicit-none">, Group<f_Group>;
+
def falternative_parameter_statement : Flag<["-"], "falternative-parameter-statement">, Group<f_Group>,
HelpText<"Enable the old style PARAMETER statement">;
def fintrinsic_modules_path : Separate<["-"], "fintrinsic-modules-path">, Group<f_Group>, MetaVarName<"<dir>">,
HelpText<"Specify where to find the compiled intrinsic modules">,
- DocBrief<[{This option specifies the location of pre-compiled intrinsic modules,
+ DocBrief<[{This option specifies the location of pre-compiled intrinsic modules,
if they are not in the default location expected by the compiler.}]>;
-}
+
+defm backslash : OptInFC1FFlag<"backslash", "Specify that backslash in string introduces an escape character">;
+defm xor_operator : OptInFC1FFlag<"xor-operator", "Enable .XOR. as a synonym of .NEQV.">;
+defm logical_abbreviations : OptInFC1FFlag<"logical-abbreviations", "Enable logical abbreviations">;
+defm implicit_none : OptInFC1FFlag<"implicit-none", "No implicit typing allowed unless overridden by IMPLICIT statements">;
+defm underscoring : OptInFC1FFlag<"underscoring", "Appends one trailing underscore to external names">;
+defm ppc_native_vec_elem_order: BoolOptionWithoutMarshalling<"f", "ppc-native-vector-element-order",
+ PosFlag<SetTrue, [], [ClangOption], "Specifies PowerPC native vector element order (default)">,
+ NegFlag<SetFalse, [], [ClangOption], "Specifies PowerPC non-native vector element order">>;
+
+def fno_automatic : Flag<["-"], "fno-automatic">, Group<f_Group>,
+ HelpText<"Implies the SAVE attribute for non-automatic local objects in subprograms unless RECURSIVE">;
+
+defm stack_arrays : BoolOptionWithoutMarshalling<"f", "stack-arrays",
+ PosFlag<SetTrue, [], [ClangOption], "Attempt to allocate array temporaries on the stack, no matter their size">,
+ NegFlag<SetFalse, [], [ClangOption], "Allocate array temporaries on the heap (default)">>;
+defm loop_versioning : BoolOptionWithoutMarshalling<"f", "version-loops-for-stride",
+ PosFlag<SetTrue, [], [ClangOption], "Create unit-strided versions of loops">,
+ NegFlag<SetFalse, [], [ClangOption], "Do not create unit-strided loops (default)">>;
+} // let Visibility = [FC1Option, FlangOption]
def J : JoinedOrSeparate<["-"], "J">,
- Flags<[RenderJoined, FlangOption, FC1Option, FlangOnlyOption]>,
+ Flags<[RenderJoined]>, Visibility<[FlangOption, FC1Option]>,
Group<gfortran_Group>,
Alias<module_dir>;
+let Visibility = [FlangOption] in {
+def no_fortran_main : Flag<["-"], "fno-fortran-main">,
+ Visibility<[FlangOption]>, Group<f_Group>,
+ HelpText<"Do not include Fortran_main.a (provided by Flang) when linking">;
+} // let Visibility = [ FlangOption ]
+
//===----------------------------------------------------------------------===//
// FC1 Options
//===----------------------------------------------------------------------===//
-let Flags = [FC1Option, FlangOnlyOption] in {
+
+let Visibility = [FC1Option] in {
def fget_definition : MultiArg<["-"], "fget-definition", 3>,
HelpText<"Get the symbol definition from <line> <start-column> <end-column>">,
@@ -4545,6 +6472,8 @@ def fdebug_dump_parse_tree : Flag<["-"], "fdebug-dump-parse-tree">, Group<Action
HelpText<"Dump the parse tree">,
DocBrief<[{Run the Parser and the semantic checks, and then output the
parse tree.}]>;
+def fdebug_dump_pft : Flag<["-"], "fdebug-dump-pft">, Group<Action_Group>,
+ HelpText<"Dump the pre-fir parse tree">;
def fdebug_dump_parse_tree_no_sema : Flag<["-"], "fdebug-dump-parse-tree-no-sema">, Group<Action_Group>,
HelpText<"Dump the parse tree (skips the semantic checks)">,
DocBrief<[{Run the Parser and then output the parse tree. Semantic
@@ -4559,39 +6488,64 @@ def fdebug_measure_parse_tree : Flag<["-"], "fdebug-measure-parse-tree">, Group<
HelpText<"Measure the parse tree">;
def fdebug_pre_fir_tree : Flag<["-"], "fdebug-pre-fir-tree">, Group<Action_Group>,
HelpText<"Dump the pre-FIR tree">;
-def fdebug_module_writer : Flag<["-"],"fdebug-module-writer">,
+def fdebug_module_writer : Flag<["-"],"fdebug-module-writer">,
HelpText<"Enable debug messages while writing module files">;
def fget_symbols_sources : Flag<["-"], "fget-symbols-sources">, Group<Action_Group>,
HelpText<"Dump symbols and their source code locations">;
def module_suffix : Separate<["-"], "module-suffix">, Group<f_Group>, MetaVarName<"<suffix>">,
HelpText<"Use <suffix> as the suffix for module files (the default value is `.mod`)">;
-def fanalyzed_objects_for_unparse : Flag<["-"],
- "fanalyzed-objects-for-unparse">, Group<f_Group>;
-def fno_analyzed_objects_for_unparse : Flag<["-"],
- "fno-analyzed-objects-for-unparse">, Group<f_Group>,
- HelpText<"Do not use the analyzed objects when unparsing">;
+def fno_reformat : Flag<["-"], "fno-reformat">, Group<Preprocessor_Group>,
+ HelpText<"Dump the cooked character stream in -E mode">;
+defm analyzed_objects_for_unparse : OptOutFC1FFlag<"analyzed-objects-for-unparse", "", "Do not use the analyzed objects when unparsing">;
-}
+def emit_fir : Flag<["-"], "emit-fir">, Group<Action_Group>,
+ HelpText<"Build the parse tree, then lower it to FIR">;
+def emit_mlir : Flag<["-"], "emit-mlir">, Alias<emit_fir>;
+
+def emit_hlfir : Flag<["-"], "emit-hlfir">, Group<Action_Group>,
+ HelpText<"Build the parse tree, then lower it to HLFIR">;
+
+} // let Visibility = [FC1Option]
//===----------------------------------------------------------------------===//
-// CC1 Options
+// Target Options (cc1 + cc1as)
//===----------------------------------------------------------------------===//
-let Flags = [CC1Option, NoDriverOption] in {
+let Visibility = [CC1Option, CC1AsOption] in {
+
+def tune_cpu : Separate<["-"], "tune-cpu">,
+ HelpText<"Tune for a specific cpu type">,
+ MarshallingInfoString<TargetOpts<"TuneCPU">>;
+def target_abi : Separate<["-"], "target-abi">,
+ HelpText<"Target a particular ABI type">,
+ MarshallingInfoString<TargetOpts<"ABI">>;
+def target_sdk_version_EQ : Joined<["-"], "target-sdk-version=">,
+ HelpText<"The version of target SDK used for compilation">;
+def darwin_target_variant_sdk_version_EQ : Joined<["-"],
+ "darwin-target-variant-sdk-version=">,
+ HelpText<"The version of darwin target variant SDK used for compilation">;
+
+} // let Visibility = [CC1Option, CC1AsOption]
+
+let Visibility = [ClangOption, CC1Option, CC1AsOption] in {
+
+def darwin_target_variant_triple : Separate<["-"], "darwin-target-variant-triple">,
+ HelpText<"Specify the darwin target variant triple">,
+ MarshallingInfoString<TargetOpts<"DarwinTargetVariantTriple">>,
+ Normalizer<"normalizeTriple">;
+
+} // let Visibility = [ClangOption, CC1Option, CC1AsOption]
//===----------------------------------------------------------------------===//
-// Target Options
+// Target Options (cc1 + cc1as + fc1)
//===----------------------------------------------------------------------===//
-let Flags = [CC1Option, CC1AsOption, NoDriverOption] in {
+let Visibility = [CC1Option, CC1AsOption, FC1Option] in {
def target_cpu : Separate<["-"], "target-cpu">,
HelpText<"Target a specific cpu type">,
MarshallingInfoString<TargetOpts<"CPU">>;
-def tune_cpu : Separate<["-"], "tune-cpu">,
- HelpText<"Tune for a specific cpu type">,
- MarshallingInfoString<TargetOpts<"TuneCPU">>;
def target_feature : Separate<["-"], "target-feature">,
HelpText<"Target specific attributes">,
MarshallingInfoStringVector<TargetOpts<"FeaturesAsWritten">>;
@@ -4599,13 +6553,14 @@ def triple : Separate<["-"], "triple">,
HelpText<"Specify target triple (e.g. i686-apple-darwin9)">,
MarshallingInfoString<TargetOpts<"Triple">, "llvm::Triple::normalize(llvm::sys::getDefaultTargetTriple())">,
AlwaysEmit, Normalizer<"normalizeTriple">;
-def target_abi : Separate<["-"], "target-abi">,
- HelpText<"Target a particular ABI type">,
- MarshallingInfoString<TargetOpts<"ABI">>;
-def target_sdk_version_EQ : Joined<["-"], "target-sdk-version=">,
- HelpText<"The version of target SDK used for compilation">;
-}
+} // let Visibility = [CC1Option, CC1AsOption, FC1Option]
+
+//===----------------------------------------------------------------------===//
+// Target Options (other)
+//===----------------------------------------------------------------------===//
+
+let Visibility = [CC1Option] in {
def target_linker_version : Separate<["-"], "target-linker-version">,
HelpText<"Target linker version">,
@@ -4617,24 +6572,24 @@ def mfpmath : Separate<["-"], "mfpmath">,
defm padding_on_unsigned_fixed_point : BoolOption<"f", "padding-on-unsigned-fixed-point",
LangOpts<"PaddingOnUnsignedFixedPoint">, DefaultFalse,
- PosFlag<SetTrue, [], "Force each unsigned fixed point type to have an extra bit of padding to align their scales with those of signed fixed point types">,
+ PosFlag<SetTrue, [], [ClangOption], "Force each unsigned fixed point type to have an extra bit of padding to align their scales with those of signed fixed point types">,
NegFlag<SetFalse>>,
ShouldParseIf<ffixed_point.KeyPath>;
+} // let Visibility = [CC1Option]
+
//===----------------------------------------------------------------------===//
// Analyzer Options
//===----------------------------------------------------------------------===//
+let Visibility = [CC1Option] in {
+
def analysis_UnoptimizedCFG : Flag<["-"], "unoptimized-cfg">,
HelpText<"Generate unoptimized CFGs for all analyses">,
MarshallingInfoFlag<AnalyzerOpts<"UnoptimizedCFG">>;
def analysis_CFGAddImplicitDtors : Flag<["-"], "cfg-add-implicit-dtors">,
HelpText<"Add C++ implicit destructors to CFGs for all analyses">;
-def analyzer_store : Separate<["-"], "analyzer-store">,
- HelpText<"Source Code Analysis - Abstract Memory Store Models">;
-def analyzer_store_EQ : Joined<["-"], "analyzer-store=">, Alias<analyzer_store>;
-
def analyzer_constraints : Separate<["-"], "analyzer-constraints">,
HelpText<"Source Code Analysis - Symbolic Constraint Engines">;
def analyzer_constraints_EQ : Joined<["-"], "analyzer-constraints=">,
@@ -4652,9 +6607,6 @@ def analyzer_purge_EQ : Joined<["-"], "analyzer-purge=">, Alias<analyzer_purge>;
def analyzer_opt_analyze_headers : Flag<["-"], "analyzer-opt-analyze-headers">,
HelpText<"Force the static analyzer to analyze functions defined in header files">,
MarshallingInfoFlag<AnalyzerOpts<"AnalyzeAll">>;
-def analyzer_opt_analyze_nested_blocks : Flag<["-"], "analyzer-opt-analyze-nested-blocks">,
- HelpText<"Analyze the definitions of blocks in addition to functions">,
- MarshallingInfoFlag<AnalyzerOpts<"AnalyzeNestedBlocks">>;
def analyzer_display_progress : Flag<["-"], "analyzer-display-progress">,
HelpText<"Emit verbose output about the analyzer's progress">,
MarshallingInfoFlag<AnalyzerOpts<"AnalyzerDisplayProgress">>;
@@ -4698,7 +6650,7 @@ def analyzer_stats : Flag<["-"], "analyzer-stats">,
def analyzer_checker : Separate<["-"], "analyzer-checker">,
HelpText<"Choose analyzer checkers to enable">,
ValuesCode<[{
- const char *Values =
+ static constexpr const char VALUES_CODE [] =
#define GET_CHECKERS
#define CHECKER(FULLNAME, CLASS, HT, DOC_URI, IS_HIDDEN) FULLNAME ","
#include "clang/StaticAnalyzer/Checkers/Checkers.inc"
@@ -4775,23 +6727,39 @@ def analyzer_werror : Flag<["-"], "analyzer-werror">,
HelpText<"Emit analyzer results as errors rather than warnings">,
MarshallingInfoFlag<AnalyzerOpts<"AnalyzerWerror">>;
+} // let Visibility = [CC1Option]
+
//===----------------------------------------------------------------------===//
// Migrator Options
//===----------------------------------------------------------------------===//
+
def migrator_no_nsalloc_error : Flag<["-"], "no-ns-alloc-error">,
HelpText<"Do not error on use of NSAllocateCollectable/NSReallocateCollectable">,
+ Visibility<[CC1Option]>,
MarshallingInfoFlag<MigratorOpts<"NoNSAllocReallocError">>;
def migrator_no_finalize_removal : Flag<["-"], "no-finalize-removal">,
HelpText<"Do not remove finalize method in gc mode">,
+ Visibility<[CC1Option]>,
MarshallingInfoFlag<MigratorOpts<"NoFinalizeRemoval">>;
//===----------------------------------------------------------------------===//
// CodeGen Options
//===----------------------------------------------------------------------===//
-let Flags = [CC1Option, CC1AsOption, NoDriverOption] in {
+let Visibility = [CC1Option, CC1AsOption, FC1Option] in {
+
+def mrelocation_model : Separate<["-"], "mrelocation-model">,
+ HelpText<"The relocation model to use">, Values<"static,pic,ropi,rwpi,ropi-rwpi,dynamic-no-pic">,
+ NormalizedValuesScope<"llvm::Reloc">,
+ NormalizedValues<["Static", "PIC_", "ROPI", "RWPI", "ROPI_RWPI", "DynamicNoPIC"]>,
+ MarshallingInfoEnum<CodeGenOpts<"RelocationModel">, "PIC_">;
def debug_info_kind_EQ : Joined<["-"], "debug-info-kind=">;
+
+} // let Visibility = [CC1Option, CC1AsOption, FC1Option]
+
+let Visibility = [CC1Option, CC1AsOption] in {
+
def debug_info_macro : Flag<["-"], "debug-info-macro">,
HelpText<"Emit macro debug information">,
MarshallingInfoFlag<CodeGenOpts<"MacroDebugInfo">>;
@@ -4811,8 +6779,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,zstd">,
+ NormalizedValuesScope<"llvm::DebugCompressionType">, NormalizedValues<["None", "Zlib", "Zstd"]>,
MarshallingInfoEnum<CodeGenOpts<"CompressDebugSections">, "None">;
def compress_debug_sections : Flag<["-", "--"], "compress-debug-sections">,
Alias<compress_debug_sections_EQ>, AliasArgs<["zlib"]>;
@@ -4825,19 +6793,17 @@ def massembler_no_warn : Flag<["-"], "massembler-no-warn">,
def massembler_fatal_warnings : Flag<["-"], "massembler-fatal-warnings">,
HelpText<"Make assembler warnings fatal">,
MarshallingInfoFlag<CodeGenOpts<"FatalWarnings">>;
-def mrelax_relocations : Flag<["--"], "mrelax-relocations">,
- HelpText<"Use relaxable elf relocations">,
- MarshallingInfoFlag<CodeGenOpts<"RelaxELFRelocations">>;
+def mrelax_relocations_no : Flag<["-"], "mrelax-relocations=no">,
+ HelpText<"Disable x86 relax relocations">,
+ MarshallingInfoNegativeFlag<CodeGenOpts<"RelaxELFRelocations">>;
def msave_temp_labels : Flag<["-"], "msave-temp-labels">,
HelpText<"Save temporary labels in the symbol table. "
"Note this may change .s semantics and shouldn't generally be used "
"on compiler-generated code.">,
MarshallingInfoFlag<CodeGenOpts<"SaveTempLabels">>;
-def mrelocation_model : Separate<["-"], "mrelocation-model">,
- HelpText<"The relocation model to use">, Values<"static,pic,ropi,rwpi,ropi-rwpi,dynamic-no-pic">,
- NormalizedValuesScope<"llvm::Reloc">,
- NormalizedValues<["Static", "PIC_", "ROPI", "RWPI", "ROPI_RWPI", "DynamicNoPIC"]>,
- MarshallingInfoEnum<CodeGenOpts<"RelocationModel">, "PIC_">;
+def mno_type_check : Flag<["-"], "mno-type-check">,
+ HelpText<"Don't perform type checking of the assembly code (wasm only)">,
+ MarshallingInfoFlag<CodeGenOpts<"NoTypeCheck">>;
def fno_math_builtin : Flag<["-"], "fno-math-builtin">,
HelpText<"Disable implicit builtin knowledge of math functions">,
MarshallingInfoFlag<LangOpts<"NoMathBuiltin">>;
@@ -4845,8 +6811,17 @@ def fno_use_ctor_homing: Flag<["-"], "fno-use-ctor-homing">,
HelpText<"Don't use constructor homing for debug info">;
def fuse_ctor_homing: Flag<["-"], "fuse-ctor-homing">,
HelpText<"Use constructor homing if we are using limited debug info already">;
-}
+def as_secure_log_file : Separate<["-"], "as-secure-log-file">,
+ HelpText<"Emit .secure_log_unique directives to this filename.">,
+ MarshallingInfoString<CodeGenOpts<"AsSecureLogFile">>;
+
+} // let Visibility = [CC1Option, CC1AsOption]
+
+let Visibility = [CC1Option] in {
+def llvm_verify_each : Flag<["-"], "llvm-verify-each">,
+ HelpText<"Run the LLVM verifier after every LLVM pass">,
+ MarshallingInfoFlag<CodeGenOpts<"VerifyEach">>;
def disable_llvm_verifier : Flag<["-"], "disable-llvm-verifier">,
HelpText<"Don't run the LLVM IR verifier pass">,
MarshallingInfoNegativeFlag<CodeGenOpts<"VerifyModule">>;
@@ -4882,7 +6857,7 @@ def fforbid_guard_variables : Flag<["-"], "fforbid-guard-variables">,
HelpText<"Emit an error if a C++ static local initializer would need a guard variable">,
MarshallingInfoFlag<CodeGenOpts<"ForbidGuardVariables">>;
def no_implicit_float : Flag<["-"], "no-implicit-float">,
- HelpText<"Don't generate implicit floating point instructions">,
+ HelpText<"Don't generate implicit floating point or vector instructions">,
MarshallingInfoFlag<CodeGenOpts<"NoImplicitFloat">>;
def fdump_vtable_layouts : Flag<["-"], "fdump-vtable-layouts">,
HelpText<"Dump the layouts of all vtables that will be emitted in a translation unit">,
@@ -4890,18 +6865,10 @@ def fdump_vtable_layouts : Flag<["-"], "fdump-vtable-layouts">,
def fmerge_functions : Flag<["-"], "fmerge-functions">,
HelpText<"Permit merging of identical functions when optimizing.">,
MarshallingInfoFlag<CodeGenOpts<"MergeFunctions">>;
-def coverage_data_file : Separate<["-"], "coverage-data-file">,
- HelpText<"Emit coverage data to this filename.">,
- MarshallingInfoString<CodeGenOpts<"CoverageDataFile">>,
- ShouldParseIf<!strconcat(fprofile_arcs.KeyPath, "||", ftest_coverage.KeyPath)>;
-def coverage_data_file_EQ : Joined<["-"], "coverage-data-file=">,
- Alias<coverage_data_file>;
-def coverage_notes_file : Separate<["-"], "coverage-notes-file">,
- HelpText<"Emit coverage notes to this filename.">,
- MarshallingInfoString<CodeGenOpts<"CoverageNotesFile">>,
- ShouldParseIf<!strconcat(fprofile_arcs.KeyPath, "||", ftest_coverage.KeyPath)>;
-def coverage_notes_file_EQ : Joined<["-"], "coverage-notes-file=">,
- Alias<coverage_notes_file>;
+def : Joined<["-"], "coverage-data-file=">,
+ MarshallingInfoString<CodeGenOpts<"CoverageDataFile">>;
+def : Joined<["-"], "coverage-notes-file=">,
+ MarshallingInfoString<CodeGenOpts<"CoverageNotesFile">>;
def coverage_version_EQ : Joined<["-"], "coverage-version=">,
HelpText<"Four-byte version string for gcov files.">;
def dump_coverage_mapping : Flag<["-"], "dump-coverage-mapping">,
@@ -4921,25 +6888,12 @@ def new_struct_path_tbaa : Flag<["-"], "new-struct-path-tbaa">,
def mdebug_pass : Separate<["-"], "mdebug-pass">,
HelpText<"Enable additional debug output">,
MarshallingInfoString<CodeGenOpts<"DebugPass">>;
-def mframe_pointer_EQ : Joined<["-"], "mframe-pointer=">,
- HelpText<"Specify which frame pointers to retain (all, non-leaf, none).">, Values<"all,non-leaf,none">,
- NormalizedValuesScope<"CodeGenOptions::FramePointerKind">, NormalizedValues<["All", "NonLeaf", "None"]>,
- MarshallingInfoEnum<CodeGenOpts<"FramePointer">, "None">;
-def mdisable_tail_calls : Flag<["-"], "mdisable-tail-calls">,
- HelpText<"Disable tail call optimization, keeping the call stack accurate">,
- MarshallingInfoFlag<CodeGenOpts<"DisableTailCalls">>;
-def menable_no_infinities : Flag<["-"], "menable-no-infs">,
- HelpText<"Allow optimization to assume there are no infinities.">,
- MarshallingInfoFlag<LangOpts<"NoHonorInfs">>, ImpliedByAnyOf<[ffinite_math_only.KeyPath]>;
-def menable_no_nans : Flag<["-"], "menable-no-nans">,
- HelpText<"Allow optimization to assume there are no NaNs.">,
- MarshallingInfoFlag<LangOpts<"NoHonorNaNs">>, ImpliedByAnyOf<[ffinite_math_only.KeyPath]>;
-def mreassociate : Flag<["-"], "mreassociate">,
- HelpText<"Allow reassociation transformations for floating-point instructions">,
- MarshallingInfoFlag<LangOpts<"AllowFPReassoc">>, ImpliedByAnyOf<[menable_unsafe_fp_math.KeyPath]>;
def mabi_EQ_ieeelongdouble : Flag<["-"], "mabi=ieeelongdouble">,
HelpText<"Use IEEE 754 quadruple-precision for long double">,
MarshallingInfoFlag<LangOpts<"PPCIEEELongDouble">>;
+def mabi_EQ_vec_extabi : Flag<["-"], "mabi=vec-extabi">,
+ HelpText<"Enable the extended Altivec ABI on AIX. Use volatile and nonvolatile vector registers">,
+ MarshallingInfoFlag<LangOpts<"EnableAIXExtendedAltivecABI">>;
def mfloat_abi : Separate<["-"], "mfloat-abi">,
HelpText<"The float ABI to use">,
MarshallingInfoString<CodeGenOpts<"FloatABI">>;
@@ -4954,28 +6908,26 @@ def mregparm : Separate<["-"], "mregparm">,
def msmall_data_limit : Separate<["-"], "msmall-data-limit">,
HelpText<"Put global and static data smaller than the limit into a special section">,
MarshallingInfoInt<CodeGenOpts<"SmallDataLimit">>;
-def munwind_tables : Flag<["-"], "munwind-tables">,
+def funwind_tables_EQ : Joined<["-"], "funwind-tables=">,
HelpText<"Generate unwinding tables for all functions">,
- MarshallingInfoFlag<CodeGenOpts<"UnwindTables">>;
-def mconstructor_aliases : Flag<["-"], "mconstructor-aliases">,
- HelpText<"Emit complete constructors and destructors as aliases when possible">,
- MarshallingInfoFlag<CodeGenOpts<"CXXCtorDtorAliases">>;
+ MarshallingInfoInt<CodeGenOpts<"UnwindTables">>;
+defm constructor_aliases : BoolOption<"m", "constructor-aliases",
+ CodeGenOpts<"CXXCtorDtorAliases">, DefaultFalse,
+ PosFlag<SetTrue, [], [ClangOption], "Enable">,
+ NegFlag<SetFalse, [], [ClangOption], "Disable">,
+ BothFlags<[], [ClangOption, CC1Option],
+ " emitting complete constructors and destructors as aliases when possible">>;
def mlink_bitcode_file : Separate<["-"], "mlink-bitcode-file">,
HelpText<"Link the given bitcode file before performing optimizations.">;
def mlink_builtin_bitcode : Separate<["-"], "mlink-builtin-bitcode">,
HelpText<"Link and internalize needed symbols from the given bitcode file "
"before performing optimizations.">;
-def mlink_cuda_bitcode : Separate<["-"], "mlink-cuda-bitcode">,
- Alias<mlink_builtin_bitcode>;
def vectorize_loops : Flag<["-"], "vectorize-loops">,
HelpText<"Run the Loop vectorization passes">,
MarshallingInfoFlag<CodeGenOpts<"VectorizeLoop">>;
def vectorize_slp : Flag<["-"], "vectorize-slp">,
HelpText<"Run the SLP vectorization passes">,
MarshallingInfoFlag<CodeGenOpts<"VectorizeSLP">>;
-def dependent_lib : Joined<["--"], "dependent-lib=">,
- HelpText<"Add dependent library">,
- MarshallingInfoStringVector<CodeGenOpts<"DependentLibraries">>;
def linker_option : Joined<["--"], "linker-option=">,
HelpText<"Add linker option">,
MarshallingInfoStringVector<CodeGenOpts<"LinkerOptions">>;
@@ -5018,6 +6970,10 @@ def fsanitize_coverage_pc_table
: Flag<["-"], "fsanitize-coverage-pc-table">,
HelpText<"Create a table of coverage-instrumented PCs">,
MarshallingInfoFlag<CodeGenOpts<"SanitizeCoveragePCTable">>;
+def fsanitize_coverage_control_flow
+ : Flag<["-"], "fsanitize-coverage-control-flow">,
+ HelpText<"Collect control flow of function">,
+ MarshallingInfoFlag<CodeGenOpts<"SanitizeCoverageControlFlow">>;
def fsanitize_coverage_trace_pc
: Flag<["-"], "fsanitize-coverage-trace-pc">,
HelpText<"Enable PC tracing in sanitizer coverage">,
@@ -5034,13 +6990,32 @@ def fsanitize_coverage_stack_depth
: Flag<["-"], "fsanitize-coverage-stack-depth">,
HelpText<"Enable max stack depth tracing">,
MarshallingInfoFlag<CodeGenOpts<"SanitizeCoverageStackDepth">>;
+def fsanitize_coverage_trace_loads
+ : Flag<["-"], "fsanitize-coverage-trace-loads">,
+ HelpText<"Enable tracing of loads">,
+ MarshallingInfoFlag<CodeGenOpts<"SanitizeCoverageTraceLoads">>;
+def fsanitize_coverage_trace_stores
+ : Flag<["-"], "fsanitize-coverage-trace-stores">,
+ HelpText<"Enable tracing of stores">,
+ MarshallingInfoFlag<CodeGenOpts<"SanitizeCoverageTraceStores">>;
+def fexperimental_sanitize_metadata_EQ_covered
+ : Flag<["-"], "fexperimental-sanitize-metadata=covered">,
+ HelpText<"Emit PCs for code covered with binary analysis sanitizers">,
+ MarshallingInfoFlag<CodeGenOpts<"SanitizeBinaryMetadataCovered">>;
+def fexperimental_sanitize_metadata_EQ_atomics
+ : Flag<["-"], "fexperimental-sanitize-metadata=atomics">,
+ HelpText<"Emit PCs for atomic operations used by binary analysis sanitizers">,
+ MarshallingInfoFlag<CodeGenOpts<"SanitizeBinaryMetadataAtomics">>;
+def fexperimental_sanitize_metadata_EQ_uar
+ : Flag<["-"], "fexperimental-sanitize-metadata=uar">,
+ HelpText<"Emit PCs for start of functions that are subject for use-after-return checking.">,
+ MarshallingInfoFlag<CodeGenOpts<"SanitizeBinaryMetadataUAR">>;
def fpatchable_function_entry_offset_EQ
: Joined<["-"], "fpatchable-function-entry-offset=">, MetaVarName<"<M>">,
HelpText<"Generate M NOPs before function entry">,
MarshallingInfoInt<CodeGenOpts<"PatchableFunctionEntryOffset">>;
def fprofile_instrument_EQ : Joined<["-"], "fprofile-instrument=">,
- HelpText<"Enable PGO instrumentation. The accepted value is clang, llvm, "
- "or none">, Values<"none,clang,llvm,csllvm">,
+ HelpText<"Enable PGO instrumentation">, Values<"none,clang,llvm,csllvm">,
NormalizedValuesScope<"CodeGenOptions">,
NormalizedValues<["ProfileNone", "ProfileClangInstr", "ProfileIRInstr", "ProfileCSIRInstr"]>,
MarshallingInfoEnum<CodeGenOpts<"ProfileInstr">, "ProfileNone">;
@@ -5058,16 +7033,9 @@ def flto_visibility_public_std:
MarshallingInfoFlag<CodeGenOpts<"LTOVisibilityPublicStd">>;
defm lto_unit : BoolOption<"f", "lto-unit",
CodeGenOpts<"LTOUnit">, DefaultFalse,
- PosFlag<SetTrue, [CC1Option], "Emit IR to support LTO unit features (CFI, whole program vtable opt)">,
+ PosFlag<SetTrue, [], [ClangOption, CC1Option],
+ "Emit IR to support LTO unit features (CFI, whole program vtable opt)">,
NegFlag<SetFalse>>;
-defm debug_pass_manager : BoolOption<"f", "debug-pass-manager",
- CodeGenOpts<"DebugPassManager">, DefaultFalse,
- PosFlag<SetTrue, [], "Prints debug information for the new pass manager">,
- NegFlag<SetFalse, [], "Disables debug printing for the new pass manager">>;
-def fexperimental_debug_variable_locations : Flag<["-"],
- "fexperimental-debug-variable-locations">,
- HelpText<"Use experimental new value-tracking variable locations">,
- MarshallingInfoFlag<CodeGenOpts<"ValueTrackingVariableLocations">>;
def fverify_debuginfo_preserve
: Flag<["-"], "fverify-debuginfo-preserve">,
HelpText<"Enable Debug Info Metadata preservation testing in "
@@ -5090,6 +7058,10 @@ def msign_return_address_key_EQ : Joined<["-"], "msign-return-address-key=">,
Values<"a_key,b_key">;
def mbranch_target_enforce : Flag<["-"], "mbranch-target-enforce">,
MarshallingInfoFlag<LangOpts<"BranchTargetEnforcement">>;
+def mbranch_protection_pauth_lr : Flag<["-"], "mbranch-protection-pauth-lr">,
+ MarshallingInfoFlag<LangOpts<"BranchProtectionPAuthLR">>;
+def mguarded_control_stack : Flag<["-"], "mguarded-control-stack">,
+ MarshallingInfoFlag<LangOpts<"GuardedControlStack">>;
def fno_dllexport_inlines : Flag<["-"], "fno-dllexport-inlines">,
MarshallingInfoNegativeFlag<LangOpts<"DllExportInlines">>;
def cfguard_no_checks : Flag<["-"], "cfguard-no-checks">,
@@ -5105,10 +7077,28 @@ def ehcontguard : Flag<["-"], "ehcontguard">,
def fdenormal_fp_math_f32_EQ : Joined<["-"], "fdenormal-fp-math-f32=">,
Group<f_Group>;
+def fctor_dtor_return_this : Flag<["-"], "fctor-dtor-return-this">,
+ HelpText<"Change the C++ ABI to returning `this` pointer from constructors "
+ "and non-deleting destructors. (No effect on Microsoft ABI)">,
+ MarshallingInfoFlag<CodeGenOpts<"CtorDtorReturnThis">>;
+
+def fexperimental_assignment_tracking_EQ : Joined<["-"], "fexperimental-assignment-tracking=">,
+ Group<f_Group>, CodeGenOpts<"EnableAssignmentTracking">,
+ NormalizedValuesScope<"CodeGenOptions::AssignmentTrackingOpts">,
+ Values<"disabled,enabled,forced">, NormalizedValues<["Disabled","Enabled","Forced"]>,
+ MarshallingInfoEnum<CodeGenOpts<"AssignmentTrackingMode">, "Enabled">;
+
+def enable_tlsdesc : Flag<["-"], "enable-tlsdesc">,
+ MarshallingInfoFlag<CodeGenOpts<"EnableTLSDESC">>;
+
+} // let Visibility = [CC1Option]
+
//===----------------------------------------------------------------------===//
// Dependency Output Options
//===----------------------------------------------------------------------===//
+let Visibility = [CC1Option] in {
+
def sys_header_deps : Flag<["-"], "sys-header-deps">,
HelpText<"Include system headers in dependency output">,
MarshallingInfoFlag<DependencyOutputOpts<"IncludeSystemHeaders">>;
@@ -5118,13 +7108,25 @@ def module_file_deps : Flag<["-"], "module-file-deps">,
def header_include_file : Separate<["-"], "header-include-file">,
HelpText<"Filename (or -) to write header include output to">,
MarshallingInfoString<DependencyOutputOpts<"HeaderIncludeOutputFile">>;
+def header_include_format_EQ : Joined<["-"], "header-include-format=">,
+ HelpText<"set format in which header info is emitted">,
+ Values<"textual,json">, NormalizedValues<["HIFMT_Textual", "HIFMT_JSON"]>,
+ MarshallingInfoEnum<DependencyOutputOpts<"HeaderIncludeFormat">, "HIFMT_Textual">;
+def header_include_filtering_EQ : Joined<["-"], "header-include-filtering=">,
+ HelpText<"set the flag that enables filtering header information">,
+ Values<"none,only-direct-system">, NormalizedValues<["HIFIL_None", "HIFIL_Only_Direct_System"]>,
+ MarshallingInfoEnum<DependencyOutputOpts<"HeaderIncludeFiltering">, "HIFIL_None">;
def show_includes : Flag<["--"], "show-includes">,
HelpText<"Print cl.exe style /showIncludes to stdout">;
+} // let Visibility = [CC1Option]
+
//===----------------------------------------------------------------------===//
// Diagnostic Options
//===----------------------------------------------------------------------===//
+let Visibility = [CC1Option] in {
+
def diagnostic_log_file : Separate<["-"], "diagnostic-log-file">,
HelpText<"Filename (or -) to log diagnostics to">,
MarshallingInfoString<DiagnosticOpts<"DiagnosticLogFile">>;
@@ -5133,11 +7135,13 @@ def diagnostic_serialized_file : Separate<["-"], "serialize-diagnostic-file">,
HelpText<"File for serializing diagnostics in a binary format">;
def fdiagnostics_format : Separate<["-"], "fdiagnostics-format">,
- HelpText<"Change diagnostic formatting to match IDE and command line tools">, Values<"clang,msvc,vi">,
- NormalizedValuesScope<"DiagnosticOptions">, NormalizedValues<["Clang", "MSVC", "Vi"]>,
+ HelpText<"Change diagnostic formatting to match IDE and command line tools">,
+ Values<"clang,msvc,vi,sarif,SARIF">,
+ NormalizedValuesScope<"DiagnosticOptions">, NormalizedValues<["Clang", "MSVC", "Vi", "SARIF", "SARIF"]>,
MarshallingInfoEnum<DiagnosticOpts<"Format">, "Clang">;
def fdiagnostics_show_category : Separate<["-"], "fdiagnostics-show-category">,
- HelpText<"Print diagnostic category">, Values<"none,id,name">,
+ HelpText<"Print diagnostic category">,
+ Values<"none,id,name">,
NormalizedValues<["0", "1", "2"]>,
MarshallingInfoEnum<DiagnosticOpts<"ShowCategories">, "0">;
def fno_diagnostics_use_presumed_location : Flag<["-"], "fno-diagnostics-use-presumed-location">,
@@ -5149,22 +7153,6 @@ def ftabstop : Separate<["-"], "ftabstop">, MetaVarName<"<N>">,
def ferror_limit : Separate<["-"], "ferror-limit">, MetaVarName<"<N>">,
HelpText<"Set the maximum number of errors to emit before stopping (0 = no limit).">,
MarshallingInfoInt<DiagnosticOpts<"ErrorLimit">>;
-def fmacro_backtrace_limit : Separate<["-"], "fmacro-backtrace-limit">, MetaVarName<"<N>">,
- HelpText<"Set the maximum number of entries to print in a macro expansion backtrace (0 = no limit).">,
- MarshallingInfoInt<DiagnosticOpts<"MacroBacktraceLimit">, "DiagnosticOptions::DefaultMacroBacktraceLimit">;
-def ftemplate_backtrace_limit : Separate<["-"], "ftemplate-backtrace-limit">, MetaVarName<"<N>">,
- HelpText<"Set the maximum number of entries to print in a template instantiation backtrace (0 = no limit).">,
- MarshallingInfoInt<DiagnosticOpts<"TemplateBacktraceLimit">, "DiagnosticOptions::DefaultTemplateBacktraceLimit">;
-def fconstexpr_backtrace_limit : Separate<["-"], "fconstexpr-backtrace-limit">, MetaVarName<"<N>">,
- HelpText<"Set the maximum number of entries to print in a constexpr evaluation backtrace (0 = no limit).">,
- MarshallingInfoInt<DiagnosticOpts<"ConstexprBacktraceLimit">, "DiagnosticOptions::DefaultConstexprBacktraceLimit">;
-def fspell_checking_limit : Separate<["-"], "fspell-checking-limit">, MetaVarName<"<N>">,
- HelpText<"Set the maximum number of times to perform spell checking on unrecognized identifiers (0 = no limit).">,
- MarshallingInfoInt<DiagnosticOpts<"SpellCheckingLimit">, "DiagnosticOptions::DefaultSpellCheckingLimit">;
-def fcaret_diagnostics_max_lines :
- Separate<["-"], "fcaret-diagnostics-max-lines">, MetaVarName<"<N>">,
- HelpText<"Set the maximum number of source lines to show in a caret diagnostic">,
- MarshallingInfoInt<DiagnosticOpts<"SnippetLineLimit">, "DiagnosticOptions::DefaultSnippetLineLimit">;
def verify_EQ : CommaJoined<["-"], "verify=">,
MetaVarName<"<prefixes>">,
HelpText<"Verify diagnostic output using comment directives that start with"
@@ -5179,10 +7167,14 @@ def Wno_rewrite_macros : Flag<["-"], "Wno-rewrite-macros">,
HelpText<"Silence ObjC rewriting warnings">,
MarshallingInfoFlag<DiagnosticOpts<"NoRewriteMacros">>;
+} // let Visibility = [CC1Option]
+
//===----------------------------------------------------------------------===//
// Frontend Options
//===----------------------------------------------------------------------===//
+let Visibility = [CC1Option] in {
+
// This isn't normally used, it is just here so we can parse a
// CompilerInvocation out of a driver-derived argument vector.
def cc1 : Flag<["-"], "cc1">;
@@ -5228,16 +7220,23 @@ def code_completion_with_fixits : Flag<["-"], "code-completion-with-fixits">,
def disable_free : Flag<["-"], "disable-free">,
HelpText<"Disable freeing of memory on exit">,
MarshallingInfoFlag<FrontendOpts<"DisableFree">>;
-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">>;
+defm clear_ast_before_backend : BoolOption<"",
+ "clear-ast-before-backend",
+ CodeGenOpts<"ClearASTBeforeBackend">,
+ DefaultFalse,
+ PosFlag<SetTrue, [], [ClangOption], "Clear">,
+ NegFlag<SetFalse, [], [ClangOption], "Don't clear">,
+ BothFlags<[], [ClangOption], " the Clang AST before running backend code generation">>;
+defm enable_noundef_analysis : BoolOption<"",
+ "enable-noundef-analysis",
+ CodeGenOpts<"EnableNoundefAttrs">,
+ DefaultTrue,
+ PosFlag<SetTrue, [], [ClangOption], "Enable">,
+ NegFlag<SetFalse, [], [ClangOption], "Disable">,
+ BothFlags<[], [ClangOption], " analyzing function argument and return types for mandatory definedness">>;
def discard_value_names : Flag<["-"], "discard-value-names">,
HelpText<"Discard value names in LLVM IR">,
MarshallingInfoFlag<CodeGenOpts<"DiscardValueNames">>;
-def load : Separate<["-"], "load">, MetaVarName<"<dsopath>">,
- HelpText<"Load the named plugin (dynamic shared object)">;
-def plugin : Separate<["-"], "plugin">, MetaVarName<"<name>">,
- HelpText<"Use the named plugin action instead of the default action (use \"help\" to list available options)">;
def plugin_arg : JoinedAndSeparate<["-"], "plugin-arg-">,
MetaVarName<"<name> <arg>">,
HelpText<"Pass <arg> to plugin <name>">;
@@ -5250,6 +7249,8 @@ def ast_dump_filter : Separate<["-"], "ast-dump-filter">,
" nodes having a certain substring in a qualified name. Use"
" -ast-list to list all filterable declaration node names.">,
MarshallingInfoString<FrontendOpts<"ASTDumpFilter">>;
+def ast_dump_filter_EQ : Joined<["-"], "ast-dump-filter=">,
+ Alias<ast_dump_filter>;
def fno_modules_global_index : Flag<["-"], "fno-modules-global-index">,
HelpText<"Do not automatically generate or update the global module index">,
MarshallingInfoNegativeFlag<FrontendOpts<"UseGlobalModuleIndex">>;
@@ -5260,6 +7261,10 @@ def fmodule_map_file_home_is_cwd : Flag<["-"], "fmodule-map-file-home-is-cwd">,
HelpText<"Use the current working directory as the home directory of "
"module maps specified by -fmodule-map-file=<FILE>">,
MarshallingInfoFlag<HeaderSearchOpts<"ModuleMapFileHomeIsCwd">>;
+def fmodule_file_home_is_cwd : Flag<["-"], "fmodule-file-home-is-cwd">,
+ HelpText<"Use the current working directory as the base directory of "
+ "compiled module files.">,
+ MarshallingInfoFlag<HeaderSearchOpts<"ModuleFileHomeIsCwd">>;
def fmodule_feature : Separate<["-"], "fmodule-feature">,
MetaVarName<"<feature>">,
HelpText<"Enable <feature> in module map requires declarations">,
@@ -5273,14 +7278,20 @@ def fmodules_embed_all_files : Joined<["-"], "fmodules-embed-all-files">,
HelpText<"Embed the contents of all files read by this compilation into "
"the produced module file.">,
MarshallingInfoFlag<FrontendOpts<"ModulesEmbedAllFiles">>;
-// FIXME: We only need this in C++ modules / Modules TS if we might textually
+defm fimplicit_modules_use_lock : BoolOption<"f", "implicit-modules-use-lock",
+ FrontendOpts<"BuildingImplicitModuleUsesLock">, DefaultTrue,
+ NegFlag<SetFalse>,
+ PosFlag<SetTrue, [], [ClangOption],
+ "Use filesystem locks for implicit modules builds to avoid "
+ "duplicating work in competing clang invocations.">>;
+// FIXME: We only need this in C++ modules if we might textually
// enter a different module (eg, when building a header unit).
def fmodules_local_submodule_visibility :
Flag<["-"], "fmodules-local-submodule-visibility">,
HelpText<"Enforce name visibility rules across submodules of the same "
"top-level module.">,
MarshallingInfoFlag<LangOpts<"ModulesLocalVisibility">>,
- ImpliedByAnyOf<[fmodules_ts.KeyPath, cpp_modules.KeyPath]>;
+ ImpliedByAnyOf<[fcxx_modules.KeyPath]>;
def fmodules_codegen :
Flag<["-"], "fmodules-codegen">,
HelpText<"Generate code for uses of this module that assumes an explicit "
@@ -5299,20 +7310,16 @@ def ftest_module_file_extension_EQ :
Joined<["-"], "ftest-module-file-extension=">,
HelpText<"introduce a module file extension for testing purposes. "
"The argument is parsed as blockname:major:minor:hashed:user info">;
-def fconcepts_ts : Flag<["-"], "fconcepts-ts">,
- HelpText<"Enable C++ Extensions for Concepts. (deprecated - use -std=c++2a)">;
-def fno_concept_satisfaction_caching : Flag<["-"],
- "fno-concept-satisfaction-caching">,
- HelpText<"Disable satisfaction caching for C++2a Concepts.">,
- MarshallingInfoNegativeFlag<LangOpts<"ConceptSatisfactionCaching">>;
defm recovery_ast : BoolOption<"f", "recovery-ast",
LangOpts<"RecoveryAST">, DefaultTrue,
- NegFlag<SetFalse>, PosFlag<SetTrue, [], "Preserve expressions in AST rather "
+ NegFlag<SetFalse>,
+ PosFlag<SetTrue, [], [ClangOption], "Preserve expressions in AST rather "
"than dropping them when encountering semantic errors">>;
defm recovery_ast_type : BoolOption<"f", "recovery-ast-type",
LangOpts<"RecoveryASTType">, DefaultTrue,
- NegFlag<SetFalse>, PosFlag<SetTrue, [], "Preserve the type for recovery "
+ NegFlag<SetFalse>,
+ PosFlag<SetTrue, [], [ClangOption], "Preserve the type for recovery "
"expressions when possible">>;
let Group = Action_Group in {
@@ -5362,12 +7369,10 @@ def emit_module : Flag<["-"], "emit-module">,
HelpText<"Generate pre-compiled module file from a module map">;
def emit_module_interface : Flag<["-"], "emit-module-interface">,
HelpText<"Generate pre-compiled module file from a C++ module interface">;
-def emit_header_module : Flag<["-"], "emit-header-module">,
- HelpText<"Generate pre-compiled module file from a set of header files">;
+def emit_header_unit : Flag<["-"], "emit-header-unit">,
+ HelpText<"Generate C++20 header units from header files">;
def emit_pch : Flag<["-"], "emit-pch">,
HelpText<"Generate pre-compiled header file">;
-def emit_llvm_bc : Flag<["-"], "emit-llvm-bc">,
- HelpText<"Build ASTs then convert to LLVM, emit .bc file">;
def emit_llvm_only : Flag<["-"], "emit-llvm-only">,
HelpText<"Build ASTs and convert to LLVM, discarding output">;
def emit_codegen_only : Flag<["-"], "emit-codegen-only">,
@@ -5387,34 +7392,30 @@ def print_dependency_directives_minimized_source : Flag<["-"],
defm emit_llvm_uselists : BoolOption<"", "emit-llvm-uselists",
CodeGenOpts<"EmitLLVMUseLists">, DefaultFalse,
- PosFlag<SetTrue, [], "Preserve">,
- NegFlag<SetFalse, [], "Don't preserve">,
- BothFlags<[], " order of LLVM use-lists when serializing">>;
+ PosFlag<SetTrue, [], [ClangOption], "Preserve">,
+ NegFlag<SetFalse, [], [ClangOption], "Don't preserve">,
+ BothFlags<[], [ClangOption], " order of LLVM use-lists when serializing">>;
def mt_migrate_directory : Separate<["-"], "mt-migrate-directory">,
HelpText<"Directory for temporary files produced during ARC or ObjC migration">,
MarshallingInfoString<FrontendOpts<"MTMigrateDir">>;
-def arcmt_action_EQ : Joined<["-"], "arcmt-action=">, Flags<[CC1Option, NoDriverOption]>,
- HelpText<"The ARC migration action to take">, Values<"check,modify,migrate">,
+def arcmt_action_EQ : Joined<["-"], "arcmt-action=">, Visibility<[CC1Option]>,
+ HelpText<"The ARC migration action to take">,
+ Values<"check,modify,migrate">,
NormalizedValuesScope<"FrontendOptions">,
NormalizedValues<["ARCMT_Check", "ARCMT_Modify", "ARCMT_Migrate"]>,
MarshallingInfoEnum<FrontendOpts<"ARCMTAction">, "ARCMT_None">;
-def opt_record_file : Separate<["-"], "opt-record-file">,
- HelpText<"File name to use for YAML optimization record output">,
- MarshallingInfoString<CodeGenOpts<"OptRecordFile">>;
-def opt_record_passes : Separate<["-"], "opt-record-passes">,
- HelpText<"Only record remark information for passes whose names match the given regular expression">;
-def opt_record_format : Separate<["-"], "opt-record-format">,
- HelpText<"The format used for serializing remarks (default: YAML)">;
-
def print_stats : Flag<["-"], "print-stats">,
HelpText<"Print performance metrics and statistics">,
MarshallingInfoFlag<FrontendOpts<"ShowStats">>;
def stats_file : Joined<["-"], "stats-file=">,
HelpText<"Filename to write statistics to">,
MarshallingInfoString<FrontendOpts<"StatsFile">>;
+def stats_file_append : Flag<["-"], "stats-file-append">,
+ HelpText<"If stats should be appended to stats-file instead of overwriting it">,
+ MarshallingInfoFlag<FrontendOpts<"AppendStats">>;
def fdump_record_layouts_simple : Flag<["-"], "fdump-record-layouts-simple">,
HelpText<"Dump record layout information in a simple form used for testing">,
MarshallingInfoFlag<LangOpts<"DumpRecordLayoutsSimple">>;
@@ -5465,23 +7466,58 @@ def aligned_alloc_unavailable : Flag<["-"], "faligned-alloc-unavailable">,
MarshallingInfoFlag<LangOpts<"AlignedAllocationUnavailable">>,
ShouldParseIf<faligned_allocation.KeyPath>;
+} // let Visibility = [CC1Option]
+
//===----------------------------------------------------------------------===//
// Language Options
//===----------------------------------------------------------------------===//
-let Flags = [CC1Option, CC1AsOption, NoDriverOption] in {
-
def version : Flag<["-"], "version">,
HelpText<"Print the compiler version">,
+ Visibility<[CC1Option, CC1AsOption, FC1Option]>,
MarshallingInfoFlag<FrontendOpts<"ShowVersion">>;
+
def main_file_name : Separate<["-"], "main-file-name">,
HelpText<"Main file name to use for debug info and source if missing">,
+ Visibility<[CC1Option, CC1AsOption]>,
MarshallingInfoString<CodeGenOpts<"MainFileName">>;
def split_dwarf_output : Separate<["-"], "split-dwarf-output">,
HelpText<"File name to use for split dwarf debug info output">,
+ Visibility<[CC1Option, CC1AsOption]>,
MarshallingInfoString<CodeGenOpts<"SplitDwarfOutput">>;
-}
+let Visibility = [CC1Option, FC1Option] in {
+
+def mreassociate : Flag<["-"], "mreassociate">,
+ HelpText<"Allow reassociation transformations for floating-point instructions">,
+ MarshallingInfoFlag<LangOpts<"AllowFPReassoc">>, ImpliedByAnyOf<[funsafe_math_optimizations.KeyPath]>;
+def menable_no_nans : Flag<["-"], "menable-no-nans">,
+ HelpText<"Allow optimization to assume there are no NaNs.">,
+ MarshallingInfoFlag<LangOpts<"NoHonorNaNs">>, ImpliedByAnyOf<[ffinite_math_only.KeyPath]>;
+def menable_no_infinities : Flag<["-"], "menable-no-infs">,
+ HelpText<"Allow optimization to assume there are no infinities.">,
+ MarshallingInfoFlag<LangOpts<"NoHonorInfs">>, ImpliedByAnyOf<[ffinite_math_only.KeyPath]>;
+
+def pic_level : Separate<["-"], "pic-level">,
+ HelpText<"Value for __PIC__">,
+ MarshallingInfoInt<LangOpts<"PICLevel">>;
+def pic_is_pie : Flag<["-"], "pic-is-pie">,
+ HelpText<"File is for a position independent executable">,
+ MarshallingInfoFlag<LangOpts<"PIE">>;
+
+def mframe_pointer_EQ : Joined<["-"], "mframe-pointer=">,
+ HelpText<"Specify which frame pointers to retain.">, Values<"all,non-leaf,none">,
+ NormalizedValuesScope<"CodeGenOptions::FramePointerKind">, NormalizedValues<["All", "NonLeaf", "None"]>,
+ MarshallingInfoEnum<CodeGenOpts<"FramePointer">, "None">;
+
+
+def dependent_lib : Joined<["--"], "dependent-lib=">,
+ HelpText<"Add dependent library">,
+ MarshallingInfoStringVector<CodeGenOpts<"DependentLibraries">>;
+
+} // let Visibility = [CC1Option, FC1Option]
+
+let Visibility = [CC1Option] in {
def fblocks_runtime_optional : Flag<["-"], "fblocks-runtime-optional">,
HelpText<"Weakly link in the blocks runtime">,
@@ -5501,13 +7537,15 @@ def fconstant_string_class : Separate<["-"], "fconstant-string-class">,
HelpText<"Specify the class to use for constant Objective-C string objects.">,
MarshallingInfoString<LangOpts<"ObjCConstantStringClass">>;
def fobjc_arc_cxxlib_EQ : Joined<["-"], "fobjc-arc-cxxlib=">,
- HelpText<"Objective-C++ Automatic Reference Counting standard library kind">, Values<"libc++,libstdc++,none">,
+ HelpText<"Objective-C++ Automatic Reference Counting standard library kind">,
+ Values<"libc++,libstdc++,none">,
NormalizedValues<["ARCXX_libcxx", "ARCXX_libstdcxx", "ARCXX_nolib"]>,
MarshallingInfoEnum<PreprocessorOpts<"ObjCXXARCStandardLibrary">, "ARCXX_nolib">;
def fobjc_runtime_has_weak : Flag<["-"], "fobjc-runtime-has-weak">,
HelpText<"The target Objective-C runtime supports ARC weak operations">;
def fobjc_dispatch_method_EQ : Joined<["-"], "fobjc-dispatch-method=">,
- HelpText<"Objective-C dispatch method to use">, Values<"legacy,non-legacy,mixed">,
+ HelpText<"Objective-C dispatch method to use">,
+ Values<"legacy,non-legacy,mixed">,
NormalizedValuesScope<"CodeGenOptions">, NormalizedValues<["Legacy", "NonLegacy", "Mixed"]>,
MarshallingInfoEnum<CodeGenOpts<"ObjCDispatchMethod">, "Legacy">;
def disable_objc_default_synthesize_properties : Flag<["-"], "disable-objc-default-synthesize-properties">,
@@ -5519,12 +7557,6 @@ def fencode_extended_block_signature : Flag<["-"], "fencode-extended-block-signa
def function_alignment : Separate<["-"], "function-alignment">,
HelpText<"default alignment for functions">,
MarshallingInfoInt<LangOpts<"FunctionAlignment">>;
-def pic_level : Separate<["-"], "pic-level">,
- HelpText<"Value for __PIC__">,
- MarshallingInfoInt<LangOpts<"PICLevel">>;
-def pic_is_pie : Flag<["-"], "pic-is-pie">,
- HelpText<"File is for a position independent executable">,
- MarshallingInfoFlag<LangOpts<"PIE">>;
def fhalf_no_semantic_interposition : Flag<["-"], "fhalf-no-semantic-interposition">,
HelpText<"Like -fno-semantic-interposition but don't use local aliases">,
MarshallingInfoFlag<LangOpts<"HalfNoSemanticInterposition">>;
@@ -5543,6 +7575,9 @@ def fallow_pch_with_different_modules_cache_path :
Flag<["-"], "fallow-pch-with-different-modules-cache-path">,
HelpText<"Accept a PCH file that was created with a different modules cache path">,
MarshallingInfoFlag<PreprocessorOpts<"AllowPCHWithDifferentModulesCachePath">>;
+def fno_modules_share_filemanager : Flag<["-"], "fno-modules-share-filemanager">,
+ HelpText<"Disable sharing the FileManager when building a module implicitly">,
+ MarshallingInfoNegativeFlag<FrontendOpts<"ModulesShareFileManager">>;
def dump_deserialized_pch_decls : Flag<["-"], "dump-deserialized-decls">,
HelpText<"Dump declarations that are deserialized from PCH, for testing">,
MarshallingInfoFlag<PreprocessorOpts<"DumpDeserializedPCHDecls">>;
@@ -5554,52 +7589,38 @@ def static_define : Flag<["-"], "static-define">,
HelpText<"Should __STATIC__ be defined">,
MarshallingInfoFlag<LangOpts<"Static">>;
def stack_protector : Separate<["-"], "stack-protector">,
- HelpText<"Enable stack protectors">, Values<"0,1,2,3">,
+ HelpText<"Enable stack protectors">,
+ Values<"0,1,2,3">,
NormalizedValuesScope<"LangOptions">,
NormalizedValues<["SSPOff", "SSPOn", "SSPStrong", "SSPReq"]>,
MarshallingInfoEnum<LangOpts<"StackProtector">, "SSPOff">;
def stack_protector_buffer_size : Separate<["-"], "stack-protector-buffer-size">,
HelpText<"Lower bound for a buffer to be considered for stack protection">,
MarshallingInfoInt<CodeGenOpts<"SSPBufferSize">, "8">;
-def fvisibility : Separate<["-"], "fvisibility">,
- HelpText<"Default type and symbol visibility">,
- MarshallingInfoVisibility<LangOpts<"ValueVisibilityMode">, "DefaultVisibility">,
- // Always emitting because of the relation to `-mignore-xcoff-visibility`.
- AlwaysEmit;
-def ftype_visibility : Separate<["-"], "ftype-visibility">,
+def ftype_visibility : Joined<["-"], "ftype-visibility=">,
HelpText<"Default type visibility">,
- MarshallingInfoVisibility<LangOpts<"TypeVisibilityMode">, fvisibility.KeyPath>;
+ MarshallingInfoVisibility<LangOpts<"TypeVisibilityMode">, fvisibility_EQ.KeyPath>;
def fapply_global_visibility_to_externs : Flag<["-"], "fapply-global-visibility-to-externs">,
HelpText<"Apply global symbol visibility to external declarations without an explicit visibility">,
MarshallingInfoFlag<LangOpts<"SetVisibilityForExternDecls">>;
-def ftemplate_depth : Separate<["-"], "ftemplate-depth">,
- HelpText<"Maximum depth of recursive template instantiation">,
- MarshallingInfoInt<LangOpts<"InstantiationDepth">, "1024">;
-def foperator_arrow_depth : Separate<["-"], "foperator-arrow-depth">,
- HelpText<"Maximum number of 'operator->'s to call for a member access">,
- MarshallingInfoInt<LangOpts<"ArrowDepth">, "256">;
-def fconstexpr_depth : Separate<["-"], "fconstexpr-depth">,
- HelpText<"Maximum depth of recursive constexpr function calls">,
- MarshallingInfoInt<LangOpts<"ConstexprCallDepth">, "512">;
-def fconstexpr_steps : Separate<["-"], "fconstexpr-steps">,
- HelpText<"Maximum number of steps in constexpr function evaluation">,
- MarshallingInfoInt<LangOpts<"ConstexprStepLimit">, "1048576">;
def fbracket_depth : Separate<["-"], "fbracket-depth">,
HelpText<"Maximum nesting level for parentheses, brackets, and braces">,
MarshallingInfoInt<LangOpts<"BracketDepth">, "256">;
defm const_strings : BoolOption<"f", "const-strings",
LangOpts<"ConstStrings">, DefaultFalse,
- PosFlag<SetTrue, [CC1Option], "Use">, NegFlag<SetFalse, [], "Don't use">,
- BothFlags<[], " a const qualified type for string literals in C and ObjC">>;
+ PosFlag<SetTrue, [], [ClangOption, CC1Option], "Use">,
+ NegFlag<SetFalse, [], [ClangOption], "Don't use">,
+ BothFlags<[], [ClangOption], " a const qualified type for string literals in C and ObjC">>;
def fno_bitfield_type_align : Flag<["-"], "fno-bitfield-type-align">,
HelpText<"Ignore bit-field types when aligning structures">,
MarshallingInfoFlag<LangOpts<"NoBitFieldTypeAlign">>;
def ffake_address_space_map : Flag<["-"], "ffake-address-space-map">,
HelpText<"Use a fake address space map; OpenCL testing purposes only">,
MarshallingInfoFlag<LangOpts<"FakeAddressSpaceMap">>;
-def faddress_space_map_mangling_EQ : Joined<["-"], "faddress-space-map-mangling=">, MetaVarName<"<yes|no|target>">,
+def faddress_space_map_mangling_EQ : Joined<["-"], "faddress-space-map-mangling=">,
HelpText<"Set the mode for address space map based mangling; OpenCL testing purposes only">,
- Values<"target,no,yes">, NormalizedValuesScope<"LangOptions">,
+ Values<"target,no,yes">,
+ NormalizedValuesScope<"LangOptions">,
NormalizedValues<["ASMM_Target", "ASMM_Off", "ASMM_On"]>,
MarshallingInfoEnum<LangOpts<"AddressSpaceMapMangling">, "ASMM_Target">;
def funknown_anytype : Flag<["-"], "funknown-anytype">,
@@ -5616,8 +7637,9 @@ def fdebugger_objc_literal : Flag<["-"], "fdebugger-objc-literal">,
MarshallingInfoFlag<LangOpts<"DebuggerObjCLiteral">>;
defm deprecated_macro : BoolOption<"f", "deprecated-macro",
LangOpts<"Deprecated">, DefaultFalse,
- PosFlag<SetTrue, [], "Defines">, NegFlag<SetFalse, [], "Undefines">,
- BothFlags<[], " the __DEPRECATED macro">>;
+ PosFlag<SetTrue, [], [ClangOption], "Defines">,
+ NegFlag<SetFalse, [], [ClangOption], "Undefines">,
+ BothFlags<[], [ClangOption], " the __DEPRECATED macro">>;
def fobjc_subscripting_legacy_runtime : Flag<["-"], "fobjc-subscripting-legacy-runtime">,
HelpText<"Allow Objective-C array and dictionary subscripting in legacy runtime">;
// TODO: Enforce values valid for MSVtorDispMode.
@@ -5631,34 +7653,34 @@ def fnative_half_type: Flag<["-"], "fnative-half-type">,
def fnative_half_arguments_and_returns : Flag<["-"], "fnative-half-arguments-and-returns">,
HelpText<"Use the native __fp16 type for arguments and returns (and skip ABI-specific lowering)">,
MarshallingInfoFlag<LangOpts<"NativeHalfArgsAndReturns">>,
- ImpliedByAnyOf<[open_cl.KeyPath, render_script.KeyPath]>;
-def fallow_half_arguments_and_returns : Flag<["-"], "fallow-half-arguments-and-returns">,
- HelpText<"Allow function arguments and returns of type half">,
- MarshallingInfoFlag<LangOpts<"HalfArgsAndReturns">>,
- ImpliedByAnyOf<[fnative_half_arguments_and_returns.KeyPath]>;
+ ImpliedByAnyOf<[open_cl.KeyPath, render_script.KeyPath, hlsl.KeyPath]>;
def fdefault_calling_conv_EQ : Joined<["-"], "fdefault-calling-conv=">,
- HelpText<"Set default calling convention">, Values<"cdecl,fastcall,stdcall,vectorcall,regcall">,
+ HelpText<"Set default calling convention">,
+ Values<"cdecl,fastcall,stdcall,vectorcall,regcall,rtdcall">,
NormalizedValuesScope<"LangOptions">,
- NormalizedValues<["DCC_CDecl", "DCC_FastCall", "DCC_StdCall", "DCC_VectorCall", "DCC_RegCall"]>,
+ NormalizedValues<["DCC_CDecl", "DCC_FastCall", "DCC_StdCall", "DCC_VectorCall", "DCC_RegCall", "DCC_RtdCall"]>,
MarshallingInfoEnum<LangOpts<"DefaultCallingConv">, "DCC_None">;
// These options cannot be marshalled, because they are used to set up the LangOptions defaults.
def finclude_default_header : Flag<["-"], "finclude-default-header">,
- HelpText<"Include default header file for OpenCL">;
+ HelpText<"Include default header file for OpenCL and HLSL">;
def fdeclare_opencl_builtins : Flag<["-"], "fdeclare-opencl-builtins">,
HelpText<"Add OpenCL builtin function declarations (experimental)">;
def fpreserve_vec3_type : Flag<["-"], "fpreserve-vec3-type">,
HelpText<"Preserve 3-component vector type">,
- MarshallingInfoFlag<CodeGenOpts<"PreserveVec3Type">>;
+ MarshallingInfoFlag<CodeGenOpts<"PreserveVec3Type">>,
+ ImpliedByAnyOf<[hlsl.KeyPath]>;
def fwchar_type_EQ : Joined<["-"], "fwchar-type=">,
- HelpText<"Select underlying type for wchar_t">, Values<"char,short,int">,
+ HelpText<"Select underlying type for wchar_t">,
+ Values<"char,short,int">,
NormalizedValues<["1", "2", "4"]>,
MarshallingInfoEnum<LangOpts<"WCharSize">, "0">;
defm signed_wchar : BoolOption<"f", "signed-wchar",
LangOpts<"WCharIsSigned">, DefaultTrue,
- NegFlag<SetFalse, [CC1Option], "Use an unsigned">, PosFlag<SetTrue, [], "Use a signed">,
- BothFlags<[], " type for wchar_t">>;
+ NegFlag<SetFalse, [], [ClangOption, CC1Option], "Use an unsigned">,
+ PosFlag<SetTrue, [], [ClangOption], "Use a signed">,
+ BothFlags<[], [ClangOption], " type for wchar_t">>;
def fcompatibility_qualified_id_block_param_type_checking : Flag<["-"], "fcompatibility-qualified-id-block-type-checking">,
HelpText<"Allow using blocks with parameters of more specific type than "
"the type system guarantees when a parameter is qualified id">,
@@ -5674,10 +7696,20 @@ def fobjc_gc_only : Flag<["-"], "fobjc-gc-only">, Group<f_Group>,
def fobjc_gc : Flag<["-"], "fobjc-gc">, Group<f_Group>,
HelpText<"Enable Objective-C garbage collection">;
+def fexperimental_max_bitint_width_EQ:
+ Joined<["-"], "fexperimental-max-bitint-width=">, Group<f_Group>,
+ MetaVarName<"<N>">,
+ HelpText<"Set the maximum bitwidth for _BitInt (this option is expected to be removed in the future)">,
+ MarshallingInfoInt<LangOpts<"MaxBitIntWidth">>;
+
+} // let Visibility = [CC1Option]
+
//===----------------------------------------------------------------------===//
// Header Search Options
//===----------------------------------------------------------------------===//
+let Visibility = [CC1Option] in {
+
def nostdsysteminc : Flag<["-"], "nostdsysteminc">,
HelpText<"Disable standard system #include directories">,
MarshallingInfoNegativeFlag<HeaderSearchOpts<"UseStandardSystemIncludes">>;
@@ -5691,30 +7723,34 @@ def fmodules_strict_context_hash : Flag<["-"], "fmodules-strict-context-hash">,
HelpText<"Enable hashing of all compiler options that could impact the "
"semantics of a module in an implicit build">,
MarshallingInfoFlag<HeaderSearchOpts<"ModulesStrictContextHash">>;
-def c_isystem : JoinedOrSeparate<["-"], "c-isystem">, MetaVarName<"<directory>">,
+def c_isystem : Separate<["-"], "c-isystem">, MetaVarName<"<directory>">,
HelpText<"Add directory to the C SYSTEM include search path">;
-def objc_isystem : JoinedOrSeparate<["-"], "objc-isystem">,
+def objc_isystem : Separate<["-"], "objc-isystem">,
MetaVarName<"<directory>">,
HelpText<"Add directory to the ObjC SYSTEM include search path">;
-def objcxx_isystem : JoinedOrSeparate<["-"], "objcxx-isystem">,
+def objcxx_isystem : Separate<["-"], "objcxx-isystem">,
MetaVarName<"<directory>">,
HelpText<"Add directory to the ObjC++ SYSTEM include search path">;
-def internal_isystem : JoinedOrSeparate<["-"], "internal-isystem">,
+def internal_isystem : Separate<["-"], "internal-isystem">,
MetaVarName<"<directory>">,
HelpText<"Add directory to the internal system include search path; these "
"are assumed to not be user-provided and are used to model system "
"and standard headers' paths.">;
-def internal_externc_isystem : JoinedOrSeparate<["-"], "internal-externc-isystem">,
+def internal_externc_isystem : Separate<["-"], "internal-externc-isystem">,
MetaVarName<"<directory>">,
HelpText<"Add directory to the internal system include search path with "
"implicit extern \"C\" semantics; these are assumed to not be "
"user-provided and are used to model system and standard headers' "
"paths.">;
+} // let Visibility = [CC1Option]
+
//===----------------------------------------------------------------------===//
// Preprocessor Options
//===----------------------------------------------------------------------===//
+let Visibility = [CC1Option] in {
+
def chain_include : Separate<["-"], "chain-include">, MetaVarName<"<file>">,
HelpText<"Include and chain a header file after turning it into PCH">;
def preamble_bytes_EQ : Joined<["-"], "preamble-bytes=">,
@@ -5729,19 +7765,18 @@ def setup_static_analyzer : Flag<["-"], "setup-static-analyzer">,
def disable_pragma_debug_crash : Flag<["-"], "disable-pragma-debug-crash">,
HelpText<"Disable any #pragma clang __debug that can lead to crashing behavior. This is meant for testing.">,
MarshallingInfoFlag<PreprocessorOpts<"DisablePragmaDebugCrash">>;
+def source_date_epoch : Separate<["-"], "source-date-epoch">,
+ MetaVarName<"<time since Epoch in seconds>">,
+ HelpText<"Time to be used in __DATE__, __TIME__, and __TIMESTAMP__ macros">;
-//===----------------------------------------------------------------------===//
-// OpenCL Options
-//===----------------------------------------------------------------------===//
-
-def cl_ext_EQ : CommaJoined<["-"], "cl-ext=">,
- HelpText<"OpenCL only. Enable or disable OpenCL extensions. The argument is a comma-separated sequence of one or more extension names, each prefixed by '+' or '-'.">,
- MarshallingInfoStringVector<TargetOpts<"OpenCLExtensionsAsWritten">>;
+} // let Visibility = [CC1Option]
//===----------------------------------------------------------------------===//
// CUDA Options
//===----------------------------------------------------------------------===//
+let Visibility = [CC1Option] in {
+
def fcuda_is_device : Flag<["-"], "fcuda-is-device">,
HelpText<"Generate code for CUDA device">,
MarshallingInfoFlag<LangOpts<"CUDAIsDevice">>;
@@ -5755,30 +7790,38 @@ def fno_cuda_host_device_constexpr : Flag<["-"], "fno-cuda-host-device-constexpr
HelpText<"Don't treat unattributed constexpr functions as __host__ __device__.">,
MarshallingInfoNegativeFlag<LangOpts<"CUDAHostDeviceConstexpr">>;
+} // let Visibility = [CC1Option]
+
//===----------------------------------------------------------------------===//
// OpenMP Options
//===----------------------------------------------------------------------===//
-def fopenmp_is_device : Flag<["-"], "fopenmp-is-device">,
+let Visibility = [CC1Option, FC1Option] in {
+
+def fopenmp_is_target_device : Flag<["-"], "fopenmp-is-target-device">,
HelpText<"Generate code only for an OpenMP target device.">;
+def : Flag<["-"], "fopenmp-is-device">, Alias<fopenmp_is_target_device>;
def fopenmp_host_ir_file_path : Separate<["-"], "fopenmp-host-ir-file-path">,
HelpText<"Path to the IR file produced by the frontend for the host.">;
+} // let Visibility = [CC1Option, FC1Option]
+
//===----------------------------------------------------------------------===//
// SYCL Options
//===----------------------------------------------------------------------===//
def fsycl_is_device : Flag<["-"], "fsycl-is-device">,
HelpText<"Generate code for SYCL device.">,
+ Visibility<[CC1Option]>,
MarshallingInfoFlag<LangOpts<"SYCLIsDevice">>;
def fsycl_is_host : Flag<["-"], "fsycl-is-host">,
HelpText<"SYCL host compilation">,
+ Visibility<[CC1Option]>,
MarshallingInfoFlag<LangOpts<"SYCLIsHost">>;
-} // let Flags = [CC1Option, NoDriverOption]
-
def sycl_std_EQ : Joined<["-"], "sycl-std=">, Group<sycl_Group>,
- Flags<[CC1Option, NoArgumentUnused, CoreOption]>,
+ Flags<[NoArgumentUnused]>,
+ Visibility<[ClangOption, CC1Option, CLOption]>,
HelpText<"SYCL language standard to compile for.">,
Values<"2020,2017,121,1.2.1,sycl-1.2.1">,
NormalizedValues<["SYCL_2020", "SYCL_2017", "SYCL_2017", "SYCL_2017", "SYCL_2017"]>,
@@ -5786,31 +7829,54 @@ def sycl_std_EQ : Joined<["-"], "sycl-std=">, Group<sycl_Group>,
MarshallingInfoEnum<LangOpts<"SYCLVersion">, "SYCL_None">,
ShouldParseIf<!strconcat(fsycl_is_device.KeyPath, "||", fsycl_is_host.KeyPath)>;
-defm cuda_approx_transcendentals : BoolFOption<"cuda-approx-transcendentals",
- LangOpts<"CUDADeviceApproxTranscendentals">, DefaultFalse,
- PosFlag<SetTrue, [CC1Option], "Use">, NegFlag<SetFalse, [], "Don't use">,
- BothFlags<[], " approximate transcendental functions">>,
- ShouldParseIf<fcuda_is_device.KeyPath>;
+defm gpu_approx_transcendentals : BoolFOption<"gpu-approx-transcendentals",
+ LangOpts<"GPUDeviceApproxTranscendentals">, DefaultFalse,
+ PosFlag<SetTrue, [], [ClangOption, CC1Option], "Use">,
+ NegFlag<SetFalse, [], [ClangOption], "Don't use">,
+ BothFlags<[], [ClangOption], " approximate transcendental functions">>;
+def : Flag<["-"], "fcuda-approx-transcendentals">, Alias<fgpu_approx_transcendentals>;
+def : Flag<["-"], "fno-cuda-approx-transcendentals">, Alias<fno_gpu_approx_transcendentals>;
//===----------------------------------------------------------------------===//
// Frontend Options - cc1 + fc1
//===----------------------------------------------------------------------===//
-let Flags = [CC1Option, FC1Option, NoDriverOption] in {
+
+let Visibility = [CC1Option, FC1Option] in {
let Group = Action_Group in {
def emit_obj : Flag<["-"], "emit-obj">,
HelpText<"Emit native object files">;
def init_only : Flag<["-"], "init-only">,
HelpText<"Only execute frontend initialization">;
+def emit_llvm_bc : Flag<["-"], "emit-llvm-bc">,
+ HelpText<"Build ASTs then convert to LLVM, emit .bc file">;
} // let Group = Action_Group
-} // let Flags = [CC1Option, FC1Option, NoDriverOption]
+
+def load : Separate<["-"], "load">, MetaVarName<"<dsopath>">,
+ HelpText<"Load the named plugin (dynamic shared object)">;
+def plugin : Separate<["-"], "plugin">, MetaVarName<"<name>">,
+ HelpText<"Use the named plugin action instead of the default action (use \"help\" to list available options)">;
+defm debug_pass_manager : BoolOption<"f", "debug-pass-manager",
+ CodeGenOpts<"DebugPassManager">, DefaultFalse,
+ PosFlag<SetTrue, [], [ClangOption], "Prints debug information for the new pass manager">,
+ NegFlag<SetFalse, [], [ClangOption], "Disables debug printing for the new pass manager">>;
+
+def opt_record_file : Separate<["-"], "opt-record-file">,
+ HelpText<"File name to use for YAML optimization record output">,
+ MarshallingInfoString<CodeGenOpts<"OptRecordFile">>;
+def opt_record_passes : Separate<["-"], "opt-record-passes">,
+ HelpText<"Only record remark information for passes whose names match the given regular expression">;
+def opt_record_format : Separate<["-"], "opt-record-format">,
+ HelpText<"The format used for serializing remarks (default: YAML)">;
+
+} // let Visibility = [CC1Option, FC1Option]
//===----------------------------------------------------------------------===//
// cc1as-only Options
//===----------------------------------------------------------------------===//
-let Flags = [CC1AsOption, NoDriverOption] in {
+let Visibility = [CC1AsOption] in {
// Language Options
def n : Flag<["-"], "n">,
@@ -5835,13 +7901,13 @@ def dwarf_debug_producer : Separate<["-"], "dwarf-debug-producer">,
def defsym : Separate<["-"], "defsym">,
HelpText<"Define a value for a symbol">;
-} // let Flags = [CC1AsOption]
+} // let Visibility = [CC1AsOption]
//===----------------------------------------------------------------------===//
// clang-cl Options
//===----------------------------------------------------------------------===//
-def cl_Group : OptionGroup<"<clang-cl options>">, Flags<[CLOption]>,
+def cl_Group : OptionGroup<"<clang-cl options>">,
HelpText<"CL.EXE COMPATIBILITY OPTIONS">;
def cl_compile_Group : OptionGroup<"<clang-cl compile-only options>">,
@@ -5850,33 +7916,43 @@ def cl_compile_Group : OptionGroup<"<clang-cl compile-only options>">,
def cl_ignored_Group : OptionGroup<"<clang-cl ignored options>">,
Group<cl_Group>;
-class CLFlag<string name> : Option<["/", "-"], name, KIND_FLAG>,
- Group<cl_Group>, Flags<[CLOption, NoXarchOption]>;
+class CLFlag<string name, list<OptionVisibility> vis = [CLOption]> :
+ Option<["/", "-"], name, KIND_FLAG>,
+ Group<cl_Group>, Flags<[NoXarchOption]>, Visibility<vis>;
-class CLCompileFlag<string name> : Option<["/", "-"], name, KIND_FLAG>,
- Group<cl_compile_Group>, Flags<[CLOption, NoXarchOption]>;
+class CLCompileFlag<string name, list<OptionVisibility> vis = [CLOption]> :
+ Option<["/", "-"], name, KIND_FLAG>,
+ Group<cl_compile_Group>, Flags<[NoXarchOption]>, Visibility<vis>;
-class CLIgnoredFlag<string name> : Option<["/", "-"], name, KIND_FLAG>,
- Group<cl_ignored_Group>, Flags<[CLOption, NoXarchOption]>;
+class CLIgnoredFlag<string name, list<OptionVisibility> vis = [CLOption]> :
+ Option<["/", "-"], name, KIND_FLAG>,
+ Group<cl_ignored_Group>, Flags<[NoXarchOption]>, Visibility<vis>;
-class CLJoined<string name> : Option<["/", "-"], name, KIND_JOINED>,
- Group<cl_Group>, Flags<[CLOption, NoXarchOption]>;
+class CLJoined<string name, list<OptionVisibility> vis = [CLOption]> :
+ Option<["/", "-"], name, KIND_JOINED>,
+ Group<cl_Group>, Flags<[NoXarchOption]>, Visibility<vis>;
-class CLCompileJoined<string name> : Option<["/", "-"], name, KIND_JOINED>,
- Group<cl_compile_Group>, Flags<[CLOption, NoXarchOption]>;
+class CLCompileJoined<string name, list<OptionVisibility> vis = [CLOption]> :
+ Option<["/", "-"], name, KIND_JOINED>,
+ Group<cl_compile_Group>, Flags<[NoXarchOption]>, Visibility<vis>;
-class CLIgnoredJoined<string name> : Option<["/", "-"], name, KIND_JOINED>,
- Group<cl_ignored_Group>, Flags<[CLOption, NoXarchOption, HelpHidden]>;
+class CLIgnoredJoined<string name, list<OptionVisibility> vis = [CLOption]> :
+ Option<["/", "-"], name, KIND_JOINED>,
+ Group<cl_ignored_Group>, Flags<[NoXarchOption, HelpHidden]>, Visibility<vis>;
-class CLJoinedOrSeparate<string name> : Option<["/", "-"], name,
- KIND_JOINED_OR_SEPARATE>, Group<cl_Group>, Flags<[CLOption, NoXarchOption]>;
+class CLJoinedOrSeparate<string name, list<OptionVisibility> vis = [CLOption]> :
+ Option<["/", "-"], name, KIND_JOINED_OR_SEPARATE>,
+ Group<cl_Group>, Flags<[NoXarchOption]>, Visibility<vis>;
-class CLCompileJoinedOrSeparate<string name> : Option<["/", "-"], name,
- KIND_JOINED_OR_SEPARATE>, Group<cl_compile_Group>,
- Flags<[CLOption, NoXarchOption]>;
+class CLCompileJoinedOrSeparate<string name,
+ list<OptionVisibility> vis = [CLOption]> :
+ Option<["/", "-"], name, KIND_JOINED_OR_SEPARATE>,
+ Group<cl_compile_Group>, Flags<[NoXarchOption]>, Visibility<vis>;
-class CLRemainingArgsJoined<string name> : Option<["/", "-"], name,
- KIND_REMAINING_ARGS_JOINED>, Group<cl_Group>, Flags<[CLOption, NoXarchOption]>;
+class CLRemainingArgsJoined<string name,
+ list<OptionVisibility> vis = [CLOption]> :
+ Option<["/", "-"], name, KIND_REMAINING_ARGS_JOINED>,
+ Group<cl_Group>, Flags<[NoXarchOption]>, Visibility<vis>;
// Aliases:
// (We don't put any of these in cl_compile_Group as the options they alias are
@@ -5902,19 +7978,18 @@ def _SLASH_diagnostics_column : CLFlag<"diagnostics:column">,
HelpText<"Disable caret diagnostics but keep column info">;
def _SLASH_diagnostics_classic : CLFlag<"diagnostics:classic">,
HelpText<"Disable column and caret diagnostics">;
-def _SLASH_D : CLJoinedOrSeparate<"D">, HelpText<"Define macro">,
- MetaVarName<"<macro[=value]>">, Alias<D>;
+def _SLASH_D : CLJoinedOrSeparate<"D", [CLOption, DXCOption]>,
+ HelpText<"Define macro">, MetaVarName<"<macro[=value]>">, Alias<D>;
def _SLASH_E : CLFlag<"E">, HelpText<"Preprocess to stdout">, Alias<E>;
def _SLASH_external_COLON_I : CLJoinedOrSeparate<"external:I">, Alias<isystem>,
HelpText<"Add directory to include search path with warnings suppressed">,
MetaVarName<"<dir>">;
-def _SLASH_fp_except : CLFlag<"fp:except">, HelpText<"">, Alias<ftrapping_math>;
-def _SLASH_fp_except_ : CLFlag<"fp:except-">,
- HelpText<"">, Alias<fno_trapping_math>;
+def _SLASH_fp_contract : CLFlag<"fp:contract">, HelpText<"">, Alias<ffp_contract>, AliasArgs<["on"]>;
+def _SLASH_fp_except : CLFlag<"fp:except">, HelpText<"">, Alias<ffp_exception_behavior_EQ>, AliasArgs<["strict"]>;
+def _SLASH_fp_except_ : CLFlag<"fp:except-">, HelpText<"">, Alias<ffp_exception_behavior_EQ>, AliasArgs<["ignore"]>;
def _SLASH_fp_fast : CLFlag<"fp:fast">, HelpText<"">, Alias<ffast_math>;
-def _SLASH_fp_precise : CLFlag<"fp:precise">,
- HelpText<"">, Alias<fno_fast_math>;
-def _SLASH_fp_strict : CLFlag<"fp:strict">, HelpText<"">, Alias<fno_fast_math>;
+def _SLASH_fp_precise : CLFlag<"fp:precise">, HelpText<"">, Alias<ffp_model_EQ>, AliasArgs<["precise"]>;
+def _SLASH_fp_strict : CLFlag<"fp:strict">, HelpText<"">, Alias<ffp_model_EQ>, AliasArgs<["strict"]>;
def _SLASH_fsanitize_EQ_address : CLFlag<"fsanitize=address">,
HelpText<"Enable AddressSanitizer">,
Alias<fsanitize_EQ>, AliasArgs<["address"]>;
@@ -5943,10 +8018,12 @@ def _SLASH_Gw : CLFlag<"Gw">, HelpText<"Put each data item in its own section">,
def _SLASH_Gw_ : CLFlag<"Gw-">,
HelpText<"Do not put each data item in its own section (default)">,
Alias<fno_data_sections>;
-def _SLASH_help : CLFlag<"help">, Alias<help>,
+def _SLASH_help : CLFlag<"help", [CLOption, DXCOption]>, Alias<help>,
HelpText<"Display available options">;
def _SLASH_HELP : CLFlag<"HELP">, Alias<help>;
-def _SLASH_I : CLJoinedOrSeparate<"I">,
+def _SLASH_hotpatch : CLFlag<"hotpatch">, Alias<fms_hotpatch>,
+ HelpText<"Create hotpatchable image">;
+def _SLASH_I : CLJoinedOrSeparate<"I", [CLOption, DXCOption]>,
HelpText<"Add directory to include search path">, MetaVarName<"<dir>">,
Alias<I>;
def _SLASH_J : CLFlag<"J">, HelpText<"Make char type unsigned">,
@@ -5954,7 +8031,7 @@ def _SLASH_J : CLFlag<"J">, HelpText<"Make char type unsigned">,
// The _SLASH_O option handles all the /O flags, but we also provide separate
// aliased options to provide separate help messages.
-def _SLASH_O : CLJoined<"O">,
+def _SLASH_O : CLJoined<"O", [CLOption, DXCOption]>,
HelpText<"Set multiple /O flags at once; e.g. '/O2y-' for '/O2 /Oy-'">,
MetaVarName<"<flags>">;
def : CLFlag<"O1">, Alias<_SLASH_O>, AliasArgs<["1"]>,
@@ -5967,7 +8044,7 @@ def : CLFlag<"Ob1">, Alias<_SLASH_O>, AliasArgs<["b1"]>,
HelpText<"Only inline functions explicitly or implicitly marked inline">;
def : CLFlag<"Ob2">, Alias<_SLASH_O>, AliasArgs<["b2"]>,
HelpText<"Inline functions as deemed beneficial by the compiler">;
-def : CLFlag<"Od">, Alias<_SLASH_O>, AliasArgs<["d"]>,
+def : CLFlag<"Od", [CLOption, DXCOption]>, Alias<_SLASH_O>, AliasArgs<["d"]>,
HelpText<"Disable optimization">;
def : CLFlag<"Og">, Alias<_SLASH_O>, AliasArgs<["g"]>,
HelpText<"No effect">;
@@ -6014,6 +8091,11 @@ def _SLASH_validate_charset : CLFlag<"validate-charset">,
Alias<W_Joined>, AliasArgs<["invalid-source-encoding"]>;
def _SLASH_validate_charset_ : CLFlag<"validate-charset-">,
Alias<W_Joined>, AliasArgs<["no-invalid-source-encoding"]>;
+def _SLASH_external_W0 : CLFlag<"external:W0">, HelpText<"Ignore warnings from system headers (default)">, Alias<Wno_system_headers>;
+def _SLASH_external_W1 : CLFlag<"external:W1">, HelpText<"Enable -Wsystem-headers">, Alias<Wsystem_headers>;
+def _SLASH_external_W2 : CLFlag<"external:W2">, HelpText<"Enable -Wsystem-headers">, Alias<Wsystem_headers>;
+def _SLASH_external_W3 : CLFlag<"external:W3">, HelpText<"Enable -Wsystem-headers">, Alias<Wsystem_headers>;
+def _SLASH_external_W4 : CLFlag<"external:W4">, HelpText<"Enable -Wsystem-headers">, Alias<Wsystem_headers>;
def _SLASH_W0 : CLFlag<"W0">, HelpText<"Disable all warnings">, Alias<w>;
def _SLASH_W1 : CLFlag<"W1">, HelpText<"Enable -Wall">, Alias<Wall>;
def _SLASH_W2 : CLFlag<"W2">, HelpText<"Enable -Wall">, Alias<Wall>;
@@ -6027,16 +8109,7 @@ def _SLASH_WX_ : CLFlag<"WX-">,
HelpText<"Do not treat warnings as errors (default)">,
Alias<W_Joined>, AliasArgs<["no-error"]>;
def _SLASH_w_flag : CLFlag<"w">, HelpText<"Disable all warnings">, Alias<w>;
-def _SLASH_wd4005 : CLFlag<"wd4005">, Alias<W_Joined>,
- AliasArgs<["no-macro-redefined"]>;
-def _SLASH_wd4018 : CLFlag<"wd4018">, Alias<W_Joined>,
- AliasArgs<["no-sign-compare"]>;
-def _SLASH_wd4100 : CLFlag<"wd4100">, Alias<W_Joined>,
- AliasArgs<["no-unused-parameter"]>;
-def _SLASH_wd4910 : CLFlag<"wd4910">, Alias<W_Joined>,
- AliasArgs<["no-dllexport-explicit-instantiation-decl"]>;
-def _SLASH_wd4996 : CLFlag<"wd4996">, Alias<W_Joined>,
- AliasArgs<["no-deprecated-declarations"]>;
+def _SLASH_wd : CLCompileJoined<"wd">;
def _SLASH_vd : CLJoined<"vd">, HelpText<"Control vtordisp placement">,
Alias<vtordisp_mode_EQ>;
def _SLASH_X : CLFlag<"X">,
@@ -6078,9 +8151,22 @@ def _SLASH_Zc_twoPhase : CLFlag<"Zc:twoPhase">,
def _SLASH_Zc_twoPhase_ : CLFlag<"Zc:twoPhase-">,
HelpText<"Disable two-phase name lookup in templates (default)">,
Alias<fdelayed_template_parsing>;
-def _SLASH_Z7 : CLFlag<"Z7">,
+def _SLASH_Zc_wchar_t : CLFlag<"Zc:wchar_t">,
+ HelpText<"Enable C++ builtin type wchar_t (default)">;
+def _SLASH_Zc_wchar_t_ : CLFlag<"Zc:wchar_t-">,
+ HelpText<"Disable C++ builtin type wchar_t">;
+def _SLASH_Z7 : CLFlag<"Z7">, Alias<g_Flag>,
HelpText<"Enable CodeView debug information in object files">;
-def _SLASH_Zi : CLFlag<"Zi">, Alias<_SLASH_Z7>,
+def _SLASH_ZH_MD5 : CLFlag<"ZH:MD5">,
+ HelpText<"Use MD5 for file checksums in debug info (default)">,
+ Alias<gsrc_hash_EQ>, AliasArgs<["md5"]>;
+def _SLASH_ZH_SHA1 : CLFlag<"ZH:SHA1">,
+ HelpText<"Use SHA1 for file checksums in debug info">,
+ Alias<gsrc_hash_EQ>, AliasArgs<["sha1"]>;
+def _SLASH_ZH_SHA_256 : CLFlag<"ZH:SHA_256">,
+ HelpText<"Use SHA256 for file checksums in debug info">,
+ Alias<gsrc_hash_EQ>, AliasArgs<["sha256"]>;
+def _SLASH_Zi : CLFlag<"Zi", [CLOption, DXCOption]>, Alias<g_Flag>,
HelpText<"Like /Z7">;
def _SLASH_Zp : CLJoined<"Zp">,
HelpText<"Set default maximum struct packing alignment">,
@@ -6088,7 +8174,7 @@ def _SLASH_Zp : CLJoined<"Zp">,
def _SLASH_Zp_flag : CLFlag<"Zp">,
HelpText<"Set default maximum struct packing alignment to 1">,
Alias<fpack_struct_EQ>, AliasArgs<["1"]>;
-def _SLASH_Zs : CLFlag<"Zs">, HelpText<"Syntax-check only">,
+def _SLASH_Zs : CLFlag<"Zs">, HelpText<"Run the preprocessor, parser and semantic analysis stages">,
Alias<fsyntax_only>;
def _SLASH_openmp_ : CLFlag<"openmp-">,
HelpText<"Disable OpenMP support">, Alias<fno_openmp>;
@@ -6103,6 +8189,12 @@ def _SLASH_tune : CLCompileJoined<"tune:">,
def _SLASH_QIntel_jcc_erratum : CLFlag<"QIntel-jcc-erratum">,
HelpText<"Align branches within 32-byte boundaries to mitigate the performance impact of the Intel JCC erratum.">,
Alias<mbranches_within_32B_boundaries>;
+def _SLASH_arm64EC : CLFlag<"arm64EC">,
+ HelpText<"Set build target to arm64ec">;
+def : CLFlag<"Qgather-">, Alias<mno_gather>,
+ HelpText<"Disable generation of gather instructions in auto-vectorization(x86 only)">;
+def : CLFlag<"Qscatter-">, Alias<mno_scatter>,
+ HelpText<"Disable generation of scatter instructions in auto-vectorization(x86 only)">;
// Non-aliases:
@@ -6119,7 +8211,7 @@ def _SLASH_EP : CLFlag<"EP">,
def _SLASH_external_env : CLJoined<"external:env:">,
HelpText<"Add dirs in env var <var> to include search path with warnings suppressed">,
MetaVarName<"<var>">;
-def _SLASH_FA : CLFlag<"FA">,
+def _SLASH_FA : CLJoined<"FA">,
HelpText<"Output assembly code file during compilation">;
def _SLASH_Fa : CLJoined<"Fa">,
HelpText<"Set assembly output file name (with /FA)">,
@@ -6146,18 +8238,25 @@ def _SLASH_GX_ : CLFlag<"GX-">,
def _SLASH_imsvc : CLJoinedOrSeparate<"imsvc">,
HelpText<"Add <dir> to system include search path, as if in %INCLUDE%">,
MetaVarName<"<dir>">;
+def _SLASH_JMC : CLFlag<"JMC">, Alias<fjmc>,
+ HelpText<"Enable just-my-code debugging">;
+def _SLASH_JMC_ : CLFlag<"JMC-">, Alias<fno_jmc>,
+ HelpText<"Disable just-my-code debugging (default)">;
def _SLASH_LD : CLFlag<"LD">, HelpText<"Create DLL">;
def _SLASH_LDd : CLFlag<"LDd">, HelpText<"Create debug DLL">;
def _SLASH_link : CLRemainingArgsJoined<"link">,
HelpText<"Forward options to the linker">, MetaVarName<"<options>">;
def _SLASH_MD : Option<["/", "-"], "MD", KIND_FLAG>, Group<_SLASH_M_Group>,
- Flags<[CLOption, NoXarchOption]>, HelpText<"Use DLL run-time">;
+ Flags<[NoXarchOption]>, Visibility<[CLOption]>, HelpText<"Use DLL run-time">;
def _SLASH_MDd : Option<["/", "-"], "MDd", KIND_FLAG>, Group<_SLASH_M_Group>,
- Flags<[CLOption, NoXarchOption]>, HelpText<"Use DLL debug run-time">;
+ Flags<[NoXarchOption]>, Visibility<[CLOption]>,
+ HelpText<"Use DLL debug run-time">;
def _SLASH_MT : Option<["/", "-"], "MT", KIND_FLAG>, Group<_SLASH_M_Group>,
- Flags<[CLOption, NoXarchOption]>, HelpText<"Use static run-time">;
+ Flags<[NoXarchOption]>, Visibility<[CLOption]>,
+ HelpText<"Use static run-time">;
def _SLASH_MTd : Option<["/", "-"], "MTd", KIND_FLAG>, Group<_SLASH_M_Group>,
- Flags<[CLOption, NoXarchOption]>, HelpText<"Use static debug run-time">;
+ Flags<[NoXarchOption]>, Visibility<[CLOption]>,
+ HelpText<"Use static debug run-time">;
def _SLASH_o : CLJoinedOrSeparate<"o">,
HelpText<"Deprecated (set output file name); use /Fe or /Fe">,
MetaVarName<"<file or dir/>">;
@@ -6172,6 +8271,8 @@ def _SLASH_TC : CLCompileFlag<"TC">, HelpText<"Treat all source files as C">;
def _SLASH_Tp : CLCompileJoinedOrSeparate<"Tp">,
HelpText<"Treat <file> as C++ source file">, MetaVarName<"<file>">;
def _SLASH_TP : CLCompileFlag<"TP">, HelpText<"Treat all source files as C++">;
+def _SLASH_diasdkdir : CLJoinedOrSeparate<"diasdkdir">,
+ HelpText<"Path to the DIA SDK">, MetaVarName<"<dir>">;
def _SLASH_vctoolsdir : CLJoinedOrSeparate<"vctoolsdir">,
HelpText<"Path to the VCToolChain">, MetaVarName<"<dir>">;
def _SLASH_vctoolsversion : CLJoinedOrSeparate<"vctoolsversion">,
@@ -6181,10 +8282,10 @@ def _SLASH_winsdkdir : CLJoinedOrSeparate<"winsdkdir">,
def _SLASH_winsdkversion : CLJoinedOrSeparate<"winsdkversion">,
HelpText<"Full version of the Windows SDK, defaults to newest found">;
def _SLASH_winsysroot : CLJoinedOrSeparate<"winsysroot">,
- HelpText<"Same as /vctoolsdir <dir>/VC/Tools/MSVC/<vctoolsversion> /winsdkdir <dir>/Windows Kits/10">,
+ HelpText<"Same as \"/diasdkdir <dir>/DIA SDK\" /vctoolsdir <dir>/VC/Tools/MSVC/<vctoolsversion> \"/winsdkdir <dir>/Windows Kits/10\"">,
MetaVarName<"<dir>">;
def _SLASH_volatile_iso : Option<["/", "-"], "volatile:iso", KIND_FLAG>,
- Group<_SLASH_volatile_Group>, Flags<[CLOption, NoXarchOption]>,
+ Visibility<[CLOption]>, Alias<fno_ms_volatile>,
HelpText<"Volatile loads and stores have standard semantics">;
def _SLASH_vmb : CLFlag<"vmb">,
HelpText<"Use a best-case representation method for member pointers">;
@@ -6199,11 +8300,11 @@ def _SLASH_vmv : CLFlag<"vmv">,
HelpText<"Set the default most-general representation to "
"virtual inheritance">;
def _SLASH_volatile_ms : Option<["/", "-"], "volatile:ms", KIND_FLAG>,
- Group<_SLASH_volatile_Group>, Flags<[CLOption, NoXarchOption]>,
+ Visibility<[CLOption]>, Alias<fms_volatile>,
HelpText<"Volatile loads and stores have acquire and release semantics">;
def _SLASH_clang : CLJoined<"clang:">,
HelpText<"Pass <arg> to the clang driver">, MetaVarName<"<arg>">;
-def _SLASH_Zl : CLFlag<"Zl">,
+def _SLASH_Zl : CLFlag<"Zl">, Alias<fms_omit_default_lib>,
HelpText<"Do not let object file auto-link default libraries">;
def _SLASH_Yc : CLJoined<"Yc">,
@@ -6232,6 +8333,18 @@ def _SLASH_Gv : CLFlag<"Gv">,
HelpText<"Set __vectorcall as a default calling convention">;
def _SLASH_Gregcall : CLFlag<"Gregcall">,
HelpText<"Set __regcall as a default calling convention">;
+def _SLASH_Gregcall4 : CLFlag<"Gregcall4">,
+ HelpText<"Set __regcall4 as a default calling convention to respect __regcall ABI v.4">;
+
+// GNU Driver aliases
+
+def : Separate<["-"], "Xmicrosoft-visualc-tools-root">, Alias<_SLASH_vctoolsdir>;
+def : Separate<["-"], "Xmicrosoft-visualc-tools-version">,
+ Alias<_SLASH_vctoolsversion>;
+def : Separate<["-"], "Xmicrosoft-windows-sdk-root">,
+ Alias<_SLASH_winsdkdir>;
+def : Separate<["-"], "Xmicrosoft-windows-sdk-version">,
+ Alias<_SLASH_winsdkversion>;
// Ignored:
@@ -6244,7 +8357,6 @@ def _SLASH_errorReport : CLIgnoredJoined<"errorReport">;
def _SLASH_FC : CLIgnoredFlag<"FC">;
def _SLASH_Fd : CLIgnoredJoined<"Fd">;
def _SLASH_FS : CLIgnoredFlag<"FS">;
-def _SLASH_JMC : CLIgnoredFlag<"JMC">;
def _SLASH_kernel_ : CLIgnoredFlag<"kernel-">;
def _SLASH_nologo : CLIgnoredFlag<"nologo">;
def _SLASH_RTC : CLIgnoredJoined<"RTC">;
@@ -6253,16 +8365,13 @@ def _SLASH_sdl_ : CLIgnoredFlag<"sdl-">;
def _SLASH_utf8 : CLIgnoredFlag<"utf-8">,
HelpText<"Set source and runtime encoding to UTF-8 (default)">;
def _SLASH_w : CLIgnoredJoined<"w">;
+def _SLASH_Wv_ : CLIgnoredJoined<"Wv">;
def _SLASH_Zc___cplusplus : CLIgnoredFlag<"Zc:__cplusplus">;
def _SLASH_Zc_auto : CLIgnoredFlag<"Zc:auto">;
def _SLASH_Zc_forScope : CLIgnoredFlag<"Zc:forScope">;
def _SLASH_Zc_inline : CLIgnoredFlag<"Zc:inline">;
def _SLASH_Zc_rvalueCast : CLIgnoredFlag<"Zc:rvalueCast">;
def _SLASH_Zc_ternary : CLIgnoredFlag<"Zc:ternary">;
-def _SLASH_Zc_wchar_t : CLIgnoredFlag<"Zc:wchar_t">;
-def _SLASH_ZH_MD5 : CLIgnoredFlag<"ZH:MD5">;
-def _SLASH_ZH_SHA1 : CLIgnoredFlag<"ZH:SHA1">;
-def _SLASH_ZH_SHA_256 : CLIgnoredFlag<"ZH:SHA_256">;
def _SLASH_Zm : CLIgnoredJoined<"Zm">;
def _SLASH_Zo : CLIgnoredFlag<"Zo">;
def _SLASH_Zo_ : CLIgnoredFlag<"Zo-">;
@@ -6277,12 +8386,12 @@ def _SLASH_AI : CLJoinedOrSeparate<"AI">;
def _SLASH_Bt : CLFlag<"Bt">;
def _SLASH_Bt_plus : CLFlag<"Bt+">;
def _SLASH_clr : CLJoined<"clr">;
+def _SLASH_d1 : CLJoined<"d1">;
def _SLASH_d2 : CLJoined<"d2">;
def _SLASH_doc : CLJoined<"doc">;
def _SLASH_experimental : CLJoined<"experimental:">;
def _SLASH_exportHeader : CLFlag<"exportHeader">;
def _SLASH_external : CLJoined<"external:">;
-def _SLASH_FA_joined : CLJoined<"FA">;
def _SLASH_favor : CLJoined<"favor">;
def _SLASH_fsanitize_address_use_after_return : CLJoined<"fsanitize-address-use-after-return">;
def _SLASH_fno_sanitize_address_vcasan_lib : CLJoined<"fno-sanitize-address-vcasan-lib">;
@@ -6309,7 +8418,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">;
@@ -6339,3 +8447,67 @@ def _SLASH_Ze : CLFlag<"Ze">;
def _SLASH_Zg : CLFlag<"Zg">;
def _SLASH_ZI : CLFlag<"ZI">;
def _SLASH_ZW : CLJoined<"ZW">;
+
+//===----------------------------------------------------------------------===//
+// clang-dxc Options
+//===----------------------------------------------------------------------===//
+
+def dxc_Group : OptionGroup<"<clang-dxc options>">, Visibility<[DXCOption]>,
+ HelpText<"dxc compatibility options">;
+class DXCFlag<string name> : Option<["/", "-"], name, KIND_FLAG>,
+ Group<dxc_Group>, Visibility<[DXCOption]>;
+class DXCJoinedOrSeparate<string name> : Option<["/", "-"], name,
+ KIND_JOINED_OR_SEPARATE>, Group<dxc_Group>,
+ Visibility<[DXCOption]>;
+
+def dxc_no_stdinc : DXCFlag<"hlsl-no-stdinc">,
+ HelpText<"HLSL only. Disables all standard includes containing non-native compiler types and functions.">;
+def dxc_Fo : DXCJoinedOrSeparate<"Fo">,
+ HelpText<"Output object file">;
+def dxc_Fc : DXCJoinedOrSeparate<"Fc">,
+ HelpText<"Output assembly listing file">;
+def dxil_validator_version : Option<["/", "-"], "validator-version", KIND_SEPARATE>,
+ Group<dxc_Group>, Flags<[HelpHidden]>,
+ Visibility<[DXCOption, ClangOption, CC1Option]>,
+ HelpText<"Override validator version for module. Format: <major.minor>;"
+ "Default: DXIL.dll version or current internal version">,
+ MarshallingInfoString<TargetOpts<"DxilValidatorVersion">>;
+def target_profile : DXCJoinedOrSeparate<"T">, MetaVarName<"<profile>">,
+ HelpText<"Set target profile">,
+ Values<"ps_6_0, ps_6_1, ps_6_2, ps_6_3, ps_6_4, ps_6_5, ps_6_6, ps_6_7,"
+ "vs_6_0, vs_6_1, vs_6_2, vs_6_3, vs_6_4, vs_6_5, vs_6_6, vs_6_7,"
+ "gs_6_0, gs_6_1, gs_6_2, gs_6_3, gs_6_4, gs_6_5, gs_6_6, gs_6_7,"
+ "hs_6_0, hs_6_1, hs_6_2, hs_6_3, hs_6_4, hs_6_5, hs_6_6, hs_6_7,"
+ "ds_6_0, ds_6_1, ds_6_2, ds_6_3, ds_6_4, ds_6_5, ds_6_6, ds_6_7,"
+ "cs_6_0, cs_6_1, cs_6_2, cs_6_3, cs_6_4, cs_6_5, cs_6_6, cs_6_7,"
+ "lib_6_3, lib_6_4, lib_6_5, lib_6_6, lib_6_7, lib_6_x,"
+ "ms_6_5, ms_6_6, ms_6_7,"
+ "as_6_5, as_6_6, as_6_7">;
+def emit_pristine_llvm : DXCFlag<"emit-pristine-llvm">,
+ HelpText<"Emit pristine LLVM IR from the frontend by not running any LLVM passes at all."
+ "Same as -S + -emit-llvm + -disable-llvm-passes.">;
+def fcgl : DXCFlag<"fcgl">, Alias<emit_pristine_llvm>;
+def enable_16bit_types : DXCFlag<"enable-16bit-types">, Alias<fnative_half_type>,
+ HelpText<"Enable 16-bit types and disable min precision types."
+ "Available in HLSL 2018 and shader model 6.2.">;
+def hlsl_entrypoint : Option<["-"], "hlsl-entry", KIND_SEPARATE>,
+ Group<dxc_Group>,
+ Visibility<[ClangOption, CC1Option]>,
+ MarshallingInfoString<TargetOpts<"HLSLEntry">, "\"main\"">,
+ HelpText<"Entry point name for hlsl">;
+def dxc_entrypoint : Option<["--", "/", "-"], "E", KIND_JOINED_OR_SEPARATE>,
+ Group<dxc_Group>,
+ Visibility<[DXCOption]>,
+ HelpText<"Entry point name">;
+def dxc_validator_path_EQ : Joined<["--"], "dxv-path=">, Group<dxc_Group>,
+ HelpText<"DXIL validator installation path">;
+def dxc_disable_validation : DXCFlag<"Vd">,
+ HelpText<"Disable validation">;
+def : Option<["/", "-"], "Qembed_debug", KIND_FLAG>, Group<dxc_Group>,
+ Flags<[Ignored]>, Visibility<[DXCOption]>,
+ HelpText<"Embed PDB in shader container (ignored)">;
+def spirv : DXCFlag<"spirv">,
+ HelpText<"Generate SPIR-V code">;
+def fspv_target_env_EQ : Joined<["-"], "fspv-target-env=">, Group<dxc_Group>,
+ HelpText<"Specify the target environment">,
+ Values<"vulkan1.2, vulkan1.3">;
diff --git a/contrib/llvm-project/clang/include/clang/Driver/Phases.h b/contrib/llvm-project/clang/include/clang/Driver/Phases.h
index ce914dd70514..9003c5857351 100644
--- a/contrib/llvm-project/clang/include/clang/Driver/Phases.h
+++ b/contrib/llvm-project/clang/include/clang/Driver/Phases.h
@@ -22,11 +22,10 @@ namespace phases {
Assemble,
Link,
IfsMerge,
- LastPhase = IfsMerge,
};
enum {
- MaxNumberOfPhases = LastPhase + 1
+ MaxNumberOfPhases = IfsMerge + 1
};
const char *getPhaseName(ID Id);
diff --git a/contrib/llvm-project/clang/include/clang/Driver/SanitizerArgs.h b/contrib/llvm-project/clang/include/clang/Driver/SanitizerArgs.h
index e9e329e7cb53..07070ec4fc06 100644
--- a/contrib/llvm-project/clang/include/clang/Driver/SanitizerArgs.h
+++ b/contrib/llvm-project/clang/include/clang/Driver/SanitizerArgs.h
@@ -30,14 +30,19 @@ class SanitizerArgs {
std::vector<std::string> SystemIgnorelistFiles;
std::vector<std::string> CoverageAllowlistFiles;
std::vector<std::string> CoverageIgnorelistFiles;
+ std::vector<std::string> BinaryMetadataIgnorelistFiles;
int CoverageFeatures = 0;
+ int BinaryMetadataFeatures = 0;
int MsanTrackOrigins = 0;
bool MsanUseAfterDtor = true;
+ bool MsanParamRetval = true;
bool CfiCrossDso = false;
bool CfiICallGeneralizePointers = false;
+ bool CfiICallNormalizeIntegers = false;
bool CfiCanonicalJumpTables = false;
int AsanFieldPadding = 0;
bool SharedRuntime = false;
+ bool StableABI = false;
bool AsanUseAfterScope = true;
bool AsanPoisonCustomArrayCookie = false;
bool AsanGlobalsDeadStripping = false;
@@ -63,11 +68,15 @@ class SanitizerArgs {
llvm::AsanDetectStackUseAfterReturnMode AsanUseAfterReturn =
llvm::AsanDetectStackUseAfterReturnMode::Invalid;
+ std::string MemtagMode;
+
public:
/// Parses the sanitizer arguments from an argument list.
- SanitizerArgs(const ToolChain &TC, const llvm::opt::ArgList &Args);
+ SanitizerArgs(const ToolChain &TC, const llvm::opt::ArgList &Args,
+ bool DiagnoseErrors = true);
bool needsSharedRt() const { return SharedRuntime; }
+ bool needsStableAbi() const { return StableABI; }
bool needsMemProfRt() const { return NeedsMemProfRt; }
bool needsAsanRt() const { return Sanitizers.has(SanitizerKind::Address); }
@@ -95,6 +104,27 @@ public:
bool needsStatsRt() const { return Stats; }
bool needsScudoRt() const { return Sanitizers.has(SanitizerKind::Scudo); }
+ bool hasMemTag() const {
+ return hasMemtagHeap() || hasMemtagStack() || hasMemtagGlobals();
+ }
+ bool hasMemtagHeap() const {
+ return Sanitizers.has(SanitizerKind::MemtagHeap);
+ }
+ bool hasMemtagStack() const {
+ return Sanitizers.has(SanitizerKind::MemtagStack);
+ }
+ bool hasMemtagGlobals() const {
+ return Sanitizers.has(SanitizerKind::MemtagGlobals);
+ }
+ const std::string &getMemtagMode() const {
+ assert(!MemtagMode.empty());
+ return MemtagMode;
+ }
+
+ bool hasShadowCallStack() const {
+ return Sanitizers.has(SanitizerKind::ShadowCallStack);
+ }
+
bool requiresPIE() const;
bool needsUnwindTables() const;
bool needsLTO() const;
diff --git a/contrib/llvm-project/clang/include/clang/Driver/Tool.h b/contrib/llvm-project/clang/include/clang/Driver/Tool.h
index cc0a09fb2747..42cf99a4a970 100644
--- a/contrib/llvm-project/clang/include/clang/Driver/Tool.h
+++ b/contrib/llvm-project/clang/include/clang/Driver/Tool.h
@@ -52,6 +52,7 @@ public:
const ToolChain &getToolChain() const { return TheToolChain; }
virtual bool hasIntegratedAssembler() const { return false; }
+ virtual bool hasIntegratedBackend() const { return true; }
virtual bool canEmitIR() const { return false; }
virtual bool hasIntegratedCPP() const = 0;
virtual bool isLinkJob() const { return false; }
diff --git a/contrib/llvm-project/clang/include/clang/Driver/ToolChain.h b/contrib/llvm-project/clang/include/clang/Driver/ToolChain.h
index 882ae40086ce..2d0c1f826c17 100644
--- a/contrib/llvm-project/clang/include/clang/Driver/ToolChain.h
+++ b/contrib/llvm-project/clang/include/clang/Driver/ToolChain.h
@@ -9,7 +9,6 @@
#ifndef LLVM_CLANG_DRIVER_TOOLCHAIN_H
#define LLVM_CLANG_DRIVER_TOOLCHAIN_H
-#include "clang/Basic/DebugInfoOptions.h"
#include "clang/Basic/LLVM.h"
#include "clang/Basic/LangOptions.h"
#include "clang/Basic/Sanitizers.h"
@@ -21,14 +20,16 @@
#include "llvm/ADT/FloatingPointMode.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
-#include "llvm/ADT/Triple.h"
+#include "llvm/Frontend/Debug/Options.h"
#include "llvm/MC/MCTargetOptions.h"
#include "llvm/Option/Option.h"
#include "llvm/Support/VersionTuple.h"
#include "llvm/Target/TargetOptions.h"
+#include "llvm/TargetParser/Triple.h"
#include <cassert>
#include <climits>
#include <memory>
+#include <optional>
#include <string>
#include <utility>
@@ -108,11 +109,24 @@ public:
UNW_Libgcc
};
+ enum class UnwindTableLevel {
+ None,
+ Synchronous,
+ Asynchronous,
+ };
+
enum RTTIMode {
RM_Enabled,
RM_Disabled,
};
+ struct BitCodeLibraryInfo {
+ std::string Path;
+ bool ShouldInternalize;
+ BitCodeLibraryInfo(StringRef Path, bool ShouldInternalize = true)
+ : Path(Path), ShouldInternalize(ShouldInternalize) {}
+ };
+
enum FileType { FT_Object, FT_Static, FT_Shared };
private:
@@ -143,7 +157,8 @@ private:
mutable std::unique_ptr<Tool> StaticLibTool;
mutable std::unique_ptr<Tool> IfsMerge;
mutable std::unique_ptr<Tool> OffloadBundler;
- mutable std::unique_ptr<Tool> OffloadWrapper;
+ mutable std::unique_ptr<Tool> OffloadPackager;
+ mutable std::unique_ptr<Tool> LinkerWrapper;
Tool *getClang() const;
Tool *getFlang() const;
@@ -153,9 +168,10 @@ private:
Tool *getIfsMerge() const;
Tool *getClangAs() const;
Tool *getOffloadBundler() const;
- Tool *getOffloadWrapper() const;
+ Tool *getOffloadPackager() const;
+ Tool *getLinkerWrapper() const;
- mutable std::unique_ptr<SanitizerArgs> SanitizerArguments;
+ mutable bool SanitizerArgsChecked = false;
mutable std::unique_ptr<XRayArgs> XRayArguments;
/// The effective clang triple for the current Job.
@@ -166,17 +182,24 @@ private:
EffectiveTriple = std::move(ET);
}
- mutable llvm::Optional<CXXStdlibType> cxxStdlibType;
- mutable llvm::Optional<RuntimeLibType> runtimeLibType;
- mutable llvm::Optional<UnwindLibType> unwindLibType;
+ std::optional<std::string>
+ getFallbackAndroidTargetPath(StringRef BaseDir) const;
+
+ mutable std::optional<CXXStdlibType> cxxStdlibType;
+ mutable std::optional<RuntimeLibType> runtimeLibType;
+ mutable std::optional<UnwindLibType> unwindLibType;
protected:
MultilibSet Multilibs;
- Multilib SelectedMultilib;
+ llvm::SmallVector<Multilib> SelectedMultilibs;
ToolChain(const Driver &D, const llvm::Triple &T,
const llvm::opt::ArgList &Args);
+ /// Executes the given \p Executable and returns the stdout.
+ llvm::Expected<std::unique_ptr<llvm::MemoryBuffer>>
+ executeToolChainProgram(StringRef Executable) const;
+
void setTripleEnvironment(llvm::Triple::EnvironmentType Env);
virtual Tool *buildAssembler() const;
@@ -189,6 +212,11 @@ protected:
FileType Type,
bool AddArch) const;
+ /// Find the target-specific subdirectory for the current target triple under
+ /// \p BaseDir, doing fallback triple searches as necessary.
+ /// \return The subdirectory path if it exists.
+ std::optional<std::string> getTargetSubDirPath(StringRef BaseDir) const;
+
/// \name Utilities for implementing subclasses.
///@{
static void addSystemInclude(const llvm::opt::ArgList &DriverArgs,
@@ -204,6 +232,9 @@ protected:
static void addSystemIncludes(const llvm::opt::ArgList &DriverArgs,
llvm::opt::ArgStringList &CC1Args,
ArrayRef<StringRef> Paths);
+
+ static std::string concat(StringRef Path, const Twine &A, const Twine &B = "",
+ const Twine &C = "", const Twine &D = "");
///@}
public:
@@ -246,6 +277,10 @@ public:
return EffectiveTriple;
}
+ bool hasEffectiveTriple() const {
+ return !EffectiveTriple.getTriple().empty();
+ }
+
path_list &getLibraryPaths() { return LibraryPaths; }
const path_list &getLibraryPaths() const { return LibraryPaths; }
@@ -257,9 +292,23 @@ public:
const MultilibSet &getMultilibs() const { return Multilibs; }
- const Multilib &getMultilib() const { return SelectedMultilib; }
+ const llvm::SmallVector<Multilib> &getSelectedMultilibs() const {
+ return SelectedMultilibs;
+ }
- const SanitizerArgs& getSanitizerArgs() const;
+ /// Get flags suitable for multilib selection, based on the provided clang
+ /// command line arguments. The command line arguments aren't suitable to be
+ /// used directly for multilib selection because they are not normalized and
+ /// normalization is a complex process. The result of this function is similar
+ /// to clang command line arguments except that the list of arguments is
+ /// incomplete. Only certain command line arguments are processed. If more
+ /// command line arguments are needed for multilib selection then this
+ /// function should be extended.
+ /// To allow users to find out what flags are returned, clang accepts a
+ /// -print-multi-flags-experimental argument.
+ Multilib::flags_list getMultilibFlags(const llvm::opt::ArgList &) const;
+
+ SanitizerArgs getSanitizerArgs(const llvm::opt::ArgList &JobArgs) const;
const XRayArgs& getXRayArgs() const;
@@ -341,10 +390,7 @@ public:
/// is LLD. If it's set, it can be assumed that the linker is LLD built
/// at the same revision as clang, and clang can make assumptions about
/// LLD's supported flags, error output, etc.
- /// If LinkerIsLLDDarwinNew is non-nullptr, it's set if the linker is
- /// the new version in lld/MachO.
- std::string GetLinkerPath(bool *LinkerIsLLD = nullptr,
- bool *LinkerIsLLDDarwinNew = nullptr) const;
+ std::string GetLinkerPath(bool *LinkerIsLLD = nullptr) const;
/// Returns the linker path for emitting a static library.
std::string GetStaticLibToolPath() const;
@@ -375,11 +421,26 @@ public:
/// IsIntegratedAssemblerDefault - Does this tool chain enable -integrated-as
/// by default.
- virtual bool IsIntegratedAssemblerDefault() const { return false; }
+ virtual bool IsIntegratedAssemblerDefault() const { return true; }
+
+ /// IsIntegratedBackendDefault - Does this tool chain enable
+ /// -fintegrated-objemitter by default.
+ virtual bool IsIntegratedBackendDefault() const { return true; }
+
+ /// IsIntegratedBackendSupported - Does this tool chain support
+ /// -fintegrated-objemitter.
+ virtual bool IsIntegratedBackendSupported() const { return true; }
+
+ /// IsNonIntegratedBackendSupported - Does this tool chain support
+ /// -fno-integrated-objemitter.
+ virtual bool IsNonIntegratedBackendSupported() const { return false; }
/// Check if the toolchain should use the integrated assembler.
virtual bool useIntegratedAs() const;
+ /// Check if the toolchain should use the integrated backend.
+ virtual bool useIntegratedBackend() const;
+
/// Check if the toolchain should use AsmParser to parse inlineAsm when
/// integrated assembler is not default.
virtual bool parseInlineAsmUsingAsmParser() const { return false; }
@@ -402,6 +463,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
@@ -445,15 +509,15 @@ public:
StringRef Component,
FileType Type = ToolChain::FT_Static) const;
- // Returns target specific runtime path if it exists.
- virtual std::string getRuntimePath() const;
+ // Returns the target specific runtime path if it exists.
+ std::optional<std::string> getRuntimePath() const;
// Returns target specific standard library path if it exists.
- virtual std::string getStdlibPath() const;
+ std::optional<std::string> getStdlibPath() const;
- // Returns <ResourceDir>/lib/<OSName>/<arch>. This is used by runtimes (such
- // as OpenMP) to find arch-specific libraries.
- std::string getArchSpecificLibPath() const;
+ // Returns <ResourceDir>/lib/<OSName>/<arch> or <ResourceDir>/lib/<triple>.
+ // This is used by runtimes (such as OpenMP) to find arch-specific libraries.
+ virtual path_list getArchSpecificLibPaths() const;
// Returns <OSname> part of above.
virtual StringRef getOSLibName() const;
@@ -464,9 +528,9 @@ public:
/// Returns true if gcov instrumentation (-fprofile-arcs or --coverage) is on.
static bool needsGCovInstrumentation(const llvm::opt::ArgList &Args);
- /// IsUnwindTablesDefault - Does this tool chain use -funwind-tables
- /// by default.
- virtual bool IsUnwindTablesDefault(const llvm::opt::ArgList &Args) const;
+ /// How detailed should the unwind tables be by default.
+ virtual UnwindTableLevel
+ getDefaultUnwindTableLevel(const llvm::opt::ArgList &Args) const;
/// Test whether this toolchain supports outline atomics by default.
virtual bool
@@ -478,15 +542,12 @@ public:
virtual bool isPICDefault() const = 0;
/// Test whether this toolchain defaults to PIE.
- virtual bool isPIEDefault() const = 0;
-
- /// Test whether this toolchaind defaults to non-executable stacks.
- virtual bool isNoExecStackDefault() const;
+ virtual bool isPIEDefault(const llvm::opt::ArgList &Args) const = 0;
/// Tests whether this toolchain forces its default for PIC, PIE or
/// non-PIC. If this returns true, any PIC related flags should be ignored
- /// and instead the results of \c isPICDefault() and \c isPIEDefault() are
- /// used exclusively.
+ /// and instead the results of \c isPICDefault() and \c isPIEDefault(const
+ /// llvm::opt::ArgList &Args) are used exclusively.
virtual bool isPICDefaultForced() const = 0;
/// SupportsProfiling - Does this tool chain support -pg.
@@ -496,17 +557,20 @@ public:
virtual void CheckObjCARC() const {}
/// Get the default debug info format. Typically, this is DWARF.
- virtual codegenoptions::DebugInfoFormat getDefaultDebugFormat() const {
- return codegenoptions::DIF_DWARF;
+ virtual llvm::codegenoptions::DebugInfoFormat getDefaultDebugFormat() const {
+ return llvm::codegenoptions::DIF_DWARF;
}
/// UseDwarfDebugFlags - Embed the compile options to clang into the Dwarf
/// compile unit information.
virtual bool UseDwarfDebugFlags() const { return false; }
+ /// Add an additional -fdebug-prefix-map entry.
+ virtual std::string GetGlobalDebugPathRemapping() const { return {}; }
+
// Return the DWARF version to emit, in the absence of arguments
// to the contrary.
- virtual unsigned GetDefaultDwarfVersion() const { return 4; }
+ virtual unsigned GetDefaultDwarfVersion() const;
// 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
@@ -530,8 +594,9 @@ public:
}
/// Adjust debug information kind considering all passed options.
- virtual void adjustDebugInfoKind(codegenoptions::DebugInfoKind &DebugInfoKind,
- const llvm::opt::ArgList &Args) const {}
+ virtual void
+ adjustDebugInfoKind(llvm::codegenoptions::DebugInfoKind &DebugInfoKind,
+ const llvm::opt::ArgList &Args) const {}
/// GetExceptionModel - Return the tool chain exception model.
virtual llvm::ExceptionHandling
@@ -546,6 +611,9 @@ public:
/// isThreadModelSupported() - Does this target support a thread model?
virtual bool isThreadModelSupported(const StringRef Model) const;
+ /// isBareMetal - Is this a bare metal target.
+ virtual bool isBareMetal() const { return false; }
+
virtual std::string getMultiarchTriple(const Driver &D,
const llvm::Triple &TargetTriple,
StringRef SysRoot) const {
@@ -597,6 +665,11 @@ public:
llvm::opt::ArgStringList &CC1Args,
Action::OffloadKind DeviceOffloadKind) const;
+ /// Add options that need to be passed to cc1as for this target.
+ virtual void
+ addClangCC1ASTargetOptions(const llvm::opt::ArgList &Args,
+ llvm::opt::ArgStringList &CC1ASArgs) const;
+
/// Add warning options that need to be passed to cc1 for this target.
virtual void addClangWarningOptions(llvm::opt::ArgStringList &CC1Args) const;
@@ -659,6 +732,10 @@ public:
bool addFastMathRuntimeIfAvailable(
const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs) const;
+ /// getSystemGPUArchs - Use a tool to detect the user's availible GPUs.
+ virtual Expected<SmallVector<std::string>>
+ getSystemGPUArchs(const llvm::opt::ArgList &Args) const;
+
/// addProfileRTLibs - When -fprofile-instr-profile is specified, try to pass
/// a suitable profile runtime library to the linker.
virtual void addProfileRTLibs(const llvm::opt::ArgList &Args,
@@ -680,9 +757,14 @@ public:
virtual VersionTuple computeMSVCVersion(const Driver *D,
const llvm::opt::ArgList &Args) const;
- /// Get paths of HIP device libraries.
- virtual llvm::SmallVector<std::string, 12>
- getHIPDeviceLibs(const llvm::opt::ArgList &Args) const;
+ /// Get paths for device libraries.
+ virtual llvm::SmallVector<BitCodeLibraryInfo, 12>
+ getDeviceLibs(const llvm::opt::ArgList &Args) const;
+
+ /// Add the system specific linker arguments to use
+ /// for the given HIP runtime library type.
+ virtual void AddHIPRuntimeLibArgs(const llvm::opt::ArgList &Args,
+ llvm::opt::ArgStringList &CmdArgs) const {}
/// Return sanitizers which are available in this toolchain.
virtual SanitizerMask getSupportedSanitizers() const;
@@ -704,6 +786,22 @@ public:
const llvm::fltSemantics *FPType = nullptr) const {
return llvm::DenormalMode::getIEEE();
}
+
+ // We want to expand the shortened versions of the triples passed in to
+ // the values used for the bitcode libraries.
+ static llvm::Triple getOpenMPTriple(StringRef TripleStr) {
+ llvm::Triple TT(TripleStr);
+ if (TT.getVendor() == llvm::Triple::UnknownVendor ||
+ TT.getOS() == llvm::Triple::UnknownOS) {
+ if (TT.getArch() == llvm::Triple::nvptx)
+ return llvm::Triple("nvptx-nvidia-cuda");
+ if (TT.getArch() == llvm::Triple::nvptx64)
+ return llvm::Triple("nvptx64-nvidia-cuda");
+ if (TT.getArch() == llvm::Triple::amdgcn)
+ return llvm::Triple("amdgcn-amd-amdhsa");
+ }
+ return TT;
+ }
};
/// Set a ToolChain's effective triple. Reset it when the registration object
diff --git a/contrib/llvm-project/clang/include/clang/Driver/Types.def b/contrib/llvm-project/clang/include/clang/Driver/Types.def
index 997eea445c22..f72c27e1ee70 100644
--- a/contrib/llvm-project/clang/include/clang/Driver/Types.def
+++ b/contrib/llvm-project/clang/include/clang/Driver/Types.def
@@ -37,14 +37,16 @@
// C family source language (with and without preprocessing).
TYPE("cpp-output", PP_C, INVALID, "i", phases::Compile, phases::Backend, phases::Assemble, phases::Link)
TYPE("c", C, PP_C, "c", phases::Preprocess, phases::Compile, phases::Backend, phases::Assemble, phases::Link)
-TYPE("cl", CL, PP_C, "cl", phases::Preprocess, phases::Compile, phases::Backend, phases::Assemble, phases::Link)
-TYPE("clcpp", CLCXX, PP_CXX, "clcpp", phases::Preprocess, phases::Compile, phases::Backend, phases::Assemble, phases::Link)
+TYPE("cl", CL, PP_CL, "cl", phases::Preprocess, phases::Compile, phases::Backend, phases::Assemble, phases::Link)
+TYPE("cl-cpp-output", PP_CL, INVALID, "cli", phases::Compile, phases::Backend, phases::Assemble, phases::Link)
+TYPE("clcpp", CLCXX, PP_CLCXX, "clcpp", phases::Preprocess, phases::Compile, phases::Backend, phases::Assemble, phases::Link)
+TYPE("clcpp-cpp-output", PP_CLCXX, INVALID, "clii", phases::Compile, phases::Backend, phases::Assemble, phases::Link)
TYPE("cuda-cpp-output", PP_CUDA, INVALID, "cui", phases::Compile, phases::Backend, phases::Assemble, phases::Link)
TYPE("cuda", CUDA, PP_CUDA, "cu", phases::Preprocess, phases::Compile, phases::Backend, phases::Assemble, phases::Link)
TYPE("cuda", CUDA_DEVICE, PP_CUDA, "cu", phases::Preprocess, phases::Compile, phases::Backend, phases::Assemble, phases::Link)
-TYPE("hip-cpp-output", PP_HIP, INVALID, "cui", phases::Compile, phases::Backend, phases::Assemble, phases::Link)
-TYPE("hip", HIP, PP_HIP, "cu", phases::Preprocess, phases::Compile, phases::Backend, phases::Assemble, phases::Link)
-TYPE("hip", HIP_DEVICE, PP_HIP, "cu", phases::Preprocess, phases::Compile, phases::Backend, phases::Assemble, phases::Link)
+TYPE("hip-cpp-output", PP_HIP, INVALID, "hipi", phases::Compile, phases::Backend, phases::Assemble, phases::Link)
+TYPE("hip", HIP, PP_HIP, "hip", phases::Preprocess, phases::Compile, phases::Backend, phases::Assemble, phases::Link)
+TYPE("hip", HIP_DEVICE, PP_HIP, "hip", phases::Preprocess, phases::Compile, phases::Backend, phases::Assemble, phases::Link)
TYPE("objective-c-cpp-output", PP_ObjC, INVALID, "mi", phases::Compile, phases::Backend, phases::Assemble, phases::Link)
TYPE("objc-cpp-output", PP_ObjC_Alias, INVALID, "mi", phases::Compile, phases::Backend, phases::Assemble, phases::Link)
TYPE("objective-c", ObjC, PP_ObjC, "m", phases::Preprocess, phases::Compile, phases::Backend, phases::Assemble, phases::Link)
@@ -54,6 +56,7 @@ TYPE("objective-c++-cpp-output", PP_ObjCXX, INVALID, "mii", phases
TYPE("objc++-cpp-output", PP_ObjCXX_Alias, INVALID, "mii", phases::Compile, phases::Backend, phases::Assemble, phases::Link)
TYPE("objective-c++", ObjCXX, PP_ObjCXX, "mm", phases::Preprocess, phases::Compile, phases::Backend, phases::Assemble, phases::Link)
TYPE("renderscript", RenderScript, PP_C, "rs", phases::Preprocess, phases::Compile, phases::Backend, phases::Assemble, phases::Link)
+TYPE("hlsl", HLSL, PP_CXX, "hlsl", phases::Preprocess, phases::Compile, phases::Backend, phases::Assemble)
// C family input files to precompile.
TYPE("c-header-cpp-output", PP_CHeader, INVALID, "i", phases::Precompile)
@@ -63,7 +66,11 @@ TYPE("objective-c-header-cpp-output", PP_ObjCHeader, INVALID, "mi", phases
TYPE("objective-c-header", ObjCHeader, PP_ObjCHeader, "h", phases::Preprocess, phases::Precompile)
TYPE("c++-header-cpp-output", PP_CXXHeader, INVALID, "ii", phases::Precompile)
TYPE("c++-header", CXXHeader, PP_CXXHeader, "hh", phases::Preprocess, phases::Precompile)
-TYPE("objective-c++-header-cpp-output", PP_ObjCXXHeader, INVALID, "mii", phases::Precompile)
+TYPE("c++-header-unit-cpp-output", PP_CXXHeaderUnit,INVALID, "iih", phases::Precompile)
+TYPE("c++-header-unit-header", CXXHUHeader, PP_CXXHeaderUnit,"hh", phases::Preprocess, phases::Precompile)
+TYPE("c++-system-header", CXXSHeader, PP_CXXHeaderUnit,"hh", phases::Preprocess, phases::Precompile)
+TYPE("c++-user-header", CXXUHeader, PP_CXXHeaderUnit,"hh", phases::Preprocess, phases::Precompile)
+TYPE("objective-c++-header-cpp-output", PP_ObjCXXHeader, INVALID,"mii", phases::Precompile)
TYPE("objective-c++-header", ObjCXXHeader, PP_ObjCXXHeader, "h", phases::Preprocess, phases::Precompile)
TYPE("c++-module", CXXModule, PP_CXXModule, "cppm", phases::Preprocess, phases::Precompile, phases::Compile, phases::Backend, phases::Assemble, phases::Link)
TYPE("c++-module-cpp-output", PP_CXXModule, INVALID, "iim", phases::Precompile, phases::Compile, phases::Backend, phases::Assemble, phases::Link)
@@ -72,7 +79,7 @@ TYPE("c++-module-cpp-output", PP_CXXModule, INVALID, "iim", phases
TYPE("ada", Ada, INVALID, nullptr, phases::Compile, phases::Backend, phases::Assemble, phases::Link)
TYPE("assembler", PP_Asm, INVALID, "s", phases::Assemble, phases::Link)
TYPE("assembler-with-cpp", Asm, PP_Asm, "S", phases::Preprocess, phases::Assemble, phases::Link)
-TYPE("f95", PP_Fortran, INVALID, nullptr, phases::Compile, phases::Backend, phases::Assemble, phases::Link)
+TYPE("f95", PP_Fortran, INVALID, "i", phases::Compile, phases::Backend, phases::Assemble, phases::Link)
TYPE("f95-cpp-input", Fortran, PP_Fortran, nullptr, phases::Preprocess, phases::Compile, phases::Backend, phases::Assemble, phases::Link)
TYPE("java", Java, INVALID, nullptr, phases::Compile, phases::Backend, phases::Assemble, phases::Link)
@@ -88,11 +95,12 @@ TYPE("ast", AST, INVALID, "ast", phases
TYPE("ifs", IFS, INVALID, "ifs", phases::IfsMerge)
TYPE("ifs-cpp", IFS_CPP, INVALID, "ifs", phases::Compile, phases::IfsMerge)
TYPE("pcm", ModuleFile, INVALID, "pcm", phases::Compile, phases::Backend, phases::Assemble, phases::Link)
+TYPE("header-unit", HeaderUnit, INVALID, "pcm", phases::Compile, phases::Backend, phases::Assemble, phases::Link)
TYPE("plist", Plist, INVALID, "plist", phases::Compile, phases::Backend, phases::Assemble, phases::Link)
TYPE("rewritten-objc", RewrittenObjC,INVALID, "cpp", phases::Compile, phases::Backend, phases::Assemble, phases::Link)
TYPE("rewritten-legacy-objc", RewrittenLegacyObjC,INVALID, "cpp", phases::Compile, phases::Backend, phases::Assemble, phases::Link)
TYPE("remap", Remap, INVALID, "remap", phases::Compile, phases::Backend, phases::Assemble, phases::Link)
-TYPE("precompiled-header", PCH, INVALID, "gch", phases::Compile, phases::Backend, phases::Assemble, phases::Link)
+TYPE("precompiled-header", PCH, INVALID, "pch", phases::Compile, phases::Backend, phases::Assemble, phases::Link)
TYPE("object", Object, INVALID, "o", phases::Link)
TYPE("treelang", Treelang, INVALID, nullptr, phases::Compile, phases::Backend, phases::Assemble, phases::Link)
TYPE("image", Image, INVALID, "out", phases::Compile, phases::Backend, phases::Assemble, phases::Link)
@@ -100,4 +108,6 @@ 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::Precompile)
+TYPE("dx-container", DX_CONTAINER, INVALID, "dxo", phases::Compile, phases::Backend)
TYPE("none", Nothing, INVALID, nullptr, phases::Compile, phases::Backend, phases::Assemble, phases::Link)
diff --git a/contrib/llvm-project/clang/include/clang/Driver/Types.h b/contrib/llvm-project/clang/include/clang/Driver/Types.h
index 6a1f57416ae5..121b58a6b477 100644
--- a/contrib/llvm-project/clang/include/clang/Driver/Types.h
+++ b/contrib/llvm-project/clang/include/clang/Driver/Types.h
@@ -43,7 +43,7 @@ namespace types {
/// getTypeTempSuffix - Return the suffix to use when creating a
/// temp file of this type, or null if unspecified.
- const char *getTypeTempSuffix(ID Id, bool CLMode = false);
+ const char *getTypeTempSuffix(ID Id, bool CLStyle = false);
/// onlyPrecompileType - Should this type only be precompiled.
bool onlyPrecompileType(ID Id);
@@ -66,6 +66,17 @@ namespace types {
/// isAcceptedByClang - Can clang handle this input type.
bool isAcceptedByClang(ID Id);
+ /// isAcceptedByFlang - Can flang handle this input type.
+ bool isAcceptedByFlang(ID Id);
+
+ /// isDerivedFromC - Is the input derived from C.
+ ///
+ /// That is, does the lexer follow the rules of
+ /// TokenConcatenation::AvoidConcat. If this is the case, the preprocessor may
+ /// add and remove whitespace between tokens. Used to determine whether the
+ /// input can be processed by -fminimize-whitespace.
+ bool isDerivedFromC(ID Id);
+
/// isCXX - Is this a "C++" input (C++ and Obj-C++ sources and headers).
bool isCXX(ID Id);
@@ -84,8 +95,8 @@ namespace types {
/// isOpenCL - Is this an "OpenCL" input.
bool isOpenCL(ID Id);
- /// isFortran - Is this a Fortran input.
- bool isFortran(ID Id);
+ /// isHLSL - Is this an HLSL input.
+ bool isHLSL(ID Id);
/// isSrcFile - Is this a source file, i.e. something that still has to be
/// preprocessed. The logic behind this is the same that decides if the first
@@ -103,7 +114,7 @@ namespace types {
/// getCompilationPhases - Get the list of compilation phases ('Phases') to be
/// done for type 'Id' up until including LastPhase.
llvm::SmallVector<phases::ID, phases::MaxNumberOfPhases>
- getCompilationPhases(ID Id, phases::ID LastPhase = phases::LastPhase);
+ getCompilationPhases(ID Id, phases::ID LastPhase = phases::IfsMerge);
llvm::SmallVector<phases::ID, phases::MaxNumberOfPhases>
getCompilationPhases(const clang::driver::Driver &Driver,
llvm::opt::DerivedArgList &DAL, ID Id);
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/Driver/XRayArgs.h b/contrib/llvm-project/clang/include/clang/Driver/XRayArgs.h
index 6ed99a127669..bdd3d979547e 100644
--- a/contrib/llvm-project/clang/include/clang/Driver/XRayArgs.h
+++ b/contrib/llvm-project/clang/include/clang/Driver/XRayArgs.h
@@ -25,15 +25,8 @@ class XRayArgs {
std::vector<std::string> ExtraDeps;
std::vector<std::string> Modes;
XRayInstrSet InstrumentationBundle;
- bool XRayInstrument = false;
- int InstructionThreshold = 200;
- bool XRayAlwaysEmitCustomEvents = false;
- bool XRayAlwaysEmitTypedEvents = false;
+ llvm::opt::Arg *XRayInstrument = nullptr;
bool XRayRT = true;
- bool XRayIgnoreLoops = false;
- bool XRayFunctionIndex;
- int XRayFunctionGroups = 1;
- int XRaySelectedFunctionGroup = 0;
public:
/// Parses the XRay arguments from an argument list.
diff --git a/contrib/llvm-project/clang/include/clang/ExtractAPI/API.h b/contrib/llvm-project/clang/include/clang/ExtractAPI/API.h
new file mode 100644
index 000000000000..0a0f1bd1e95f
--- /dev/null
+++ b/contrib/llvm-project/clang/include/clang/ExtractAPI/API.h
@@ -0,0 +1,1675 @@
+//===- ExtractAPI/API.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 defines the APIRecord-based structs and the APISet class.
+///
+/// Clang ExtractAPI is a tool to collect API information from a given set of
+/// header files. The structures in this file describe data representations of
+/// the API information collected for various kinds of symbols.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_EXTRACTAPI_API_H
+#define LLVM_CLANG_EXTRACTAPI_API_H
+
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclObjC.h"
+#include "clang/AST/RawCommentList.h"
+#include "clang/Basic/SourceLocation.h"
+#include "clang/Basic/Specifiers.h"
+#include "clang/ExtractAPI/AvailabilityInfo.h"
+#include "clang/ExtractAPI/DeclarationFragments.h"
+#include "llvm/ADT/MapVector.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Allocator.h"
+#include "llvm/Support/Casting.h"
+#include "llvm/TargetParser/Triple.h"
+#include <memory>
+#include <type_traits>
+
+namespace clang {
+namespace extractapi {
+
+class Template {
+ struct TemplateParameter {
+ // "class", "typename", or concept name
+ std::string Type;
+ std::string Name;
+ unsigned int Index;
+ unsigned int Depth;
+ bool IsParameterPack;
+
+ TemplateParameter(std::string Type, std::string Name, unsigned int Index,
+ unsigned int Depth, bool IsParameterPack)
+ : Type(Type), Name(Name), Index(Index), Depth(Depth),
+ IsParameterPack(IsParameterPack) {}
+ };
+
+ struct TemplateConstraint {
+ // type name of the constraint, if it has one
+ std::string Type;
+ std::string Kind;
+ std::string LHS, RHS;
+ };
+ llvm::SmallVector<TemplateParameter> Parameters;
+ llvm::SmallVector<TemplateConstraint> Constraints;
+
+public:
+ Template() = default;
+
+ Template(const TemplateDecl *Decl) {
+ for (auto *const Parameter : *Decl->getTemplateParameters()) {
+ const auto *Param = dyn_cast<TemplateTypeParmDecl>(Parameter);
+ if (!Param) // some params are null
+ continue;
+ std::string Type;
+ if (Param->hasTypeConstraint())
+ Type = Param->getTypeConstraint()->getNamedConcept()->getName().str();
+ else if (Param->wasDeclaredWithTypename())
+ Type = "typename";
+ else
+ Type = "class";
+
+ addTemplateParameter(Type, Param->getName().str(), Param->getIndex(),
+ Param->getDepth(), Param->isParameterPack());
+ }
+ }
+
+ Template(const ClassTemplatePartialSpecializationDecl *Decl) {
+ for (auto *const Parameter : *Decl->getTemplateParameters()) {
+ const auto *Param = dyn_cast<TemplateTypeParmDecl>(Parameter);
+ if (!Param) // some params are null
+ continue;
+ std::string Type;
+ if (Param->hasTypeConstraint())
+ Type = Param->getTypeConstraint()->getNamedConcept()->getName().str();
+ else if (Param->wasDeclaredWithTypename())
+ Type = "typename";
+ else
+ Type = "class";
+
+ addTemplateParameter(Type, Param->getName().str(), Param->getIndex(),
+ Param->getDepth(), Param->isParameterPack());
+ }
+ }
+
+ Template(const VarTemplatePartialSpecializationDecl *Decl) {
+ for (auto *const Parameter : *Decl->getTemplateParameters()) {
+ const auto *Param = dyn_cast<TemplateTypeParmDecl>(Parameter);
+ if (!Param) // some params are null
+ continue;
+ std::string Type;
+ if (Param->hasTypeConstraint())
+ Type = Param->getTypeConstraint()->getNamedConcept()->getName().str();
+ else if (Param->wasDeclaredWithTypename())
+ Type = "typename";
+ else
+ Type = "class";
+
+ addTemplateParameter(Type, Param->getName().str(), Param->getIndex(),
+ Param->getDepth(), Param->isParameterPack());
+ }
+ }
+
+ const llvm::SmallVector<TemplateParameter> &getParameters() const {
+ return Parameters;
+ }
+
+ const llvm::SmallVector<TemplateConstraint> &getConstraints() const {
+ return Constraints;
+ }
+
+ void addTemplateParameter(std::string Type, std::string Name,
+ unsigned int Index, unsigned int Depth,
+ bool IsParameterPack) {
+ Parameters.emplace_back(Type, Name, Index, Depth, IsParameterPack);
+ }
+
+ bool empty() const { return Parameters.empty() && Constraints.empty(); }
+};
+
+/// DocComment is a vector of RawComment::CommentLine.
+///
+/// Each line represents one line of striped documentation comment,
+/// with source range information. This simplifies calculating the source
+/// location of a character in the doc comment for pointing back to the source
+/// file.
+/// e.g.
+/// \code
+/// /// This is a documentation comment
+/// ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~' First line.
+/// /// with multiple lines.
+/// ^~~~~~~~~~~~~~~~~~~~~~~' Second line.
+/// \endcode
+using DocComment = std::vector<RawComment::CommentLine>;
+
+// Classes deriving from APIRecord need to have USR be the first constructor
+// argument. This is so that they are compatible with `addTopLevelRecord`
+// defined in API.cpp
+/// The base representation of an API record. Holds common symbol information.
+struct APIRecord {
+ /// Discriminator for LLVM-style RTTI (dyn_cast<> et al.)
+ enum RecordKind {
+ RK_Unknown,
+ RK_Namespace,
+ RK_GlobalFunction,
+ RK_GlobalFunctionTemplate,
+ RK_GlobalFunctionTemplateSpecialization,
+ RK_GlobalVariable,
+ RK_GlobalVariableTemplate,
+ RK_GlobalVariableTemplateSpecialization,
+ RK_GlobalVariableTemplatePartialSpecialization,
+ RK_EnumConstant,
+ RK_Enum,
+ RK_StructField,
+ RK_Struct,
+ RK_UnionField,
+ RK_Union,
+ RK_StaticField,
+ RK_CXXField,
+ RK_CXXFieldTemplate,
+ RK_CXXClass,
+ RK_ClassTemplate,
+ RK_ClassTemplateSpecialization,
+ RK_ClassTemplatePartialSpecialization,
+ RK_Concept,
+ RK_CXXStaticMethod,
+ RK_CXXInstanceMethod,
+ RK_CXXConstructorMethod,
+ RK_CXXDestructorMethod,
+ RK_CXXMethodTemplate,
+ RK_CXXMethodTemplateSpecialization,
+ RK_ObjCInstanceProperty,
+ RK_ObjCClassProperty,
+ RK_ObjCIvar,
+ RK_ObjCClassMethod,
+ RK_ObjCInstanceMethod,
+ RK_ObjCInterface,
+ RK_ObjCCategory,
+ RK_ObjCCategoryModule,
+ RK_ObjCProtocol,
+ RK_MacroDefinition,
+ RK_Typedef,
+ };
+
+ /// Stores information about the context of the declaration of this API.
+ /// This is roughly analogous to the DeclContext hierarchy for an AST Node.
+ struct HierarchyInformation {
+ /// The USR of the parent API.
+ StringRef ParentUSR;
+ /// The name of the parent API.
+ StringRef ParentName;
+ /// The record kind of the parent API.
+ RecordKind ParentKind = RK_Unknown;
+ /// A pointer to the parent APIRecord if known.
+ APIRecord *ParentRecord = nullptr;
+
+ HierarchyInformation() = default;
+ HierarchyInformation(StringRef ParentUSR, StringRef ParentName,
+ RecordKind Kind, APIRecord *ParentRecord = nullptr)
+ : ParentUSR(ParentUSR), ParentName(ParentName), ParentKind(Kind),
+ ParentRecord(ParentRecord) {}
+
+ bool empty() const {
+ return ParentUSR.empty() && ParentName.empty() &&
+ ParentKind == RK_Unknown && ParentRecord == nullptr;
+ }
+ };
+
+ StringRef USR;
+ StringRef Name;
+ PresumedLoc Location;
+ AvailabilityInfo Availability;
+ LinkageInfo Linkage;
+
+ /// Documentation comment lines attached to this symbol declaration.
+ DocComment Comment;
+
+ /// Declaration fragments of this symbol declaration.
+ DeclarationFragments Declaration;
+
+ /// SubHeading provides a more detailed representation than the plain
+ /// declaration name.
+ ///
+ /// SubHeading is an array of declaration fragments of tagged declaration
+ /// name, with potentially more tokens (for example the \c +/- symbol for
+ /// Objective-C class/instance methods).
+ DeclarationFragments SubHeading;
+
+ /// Information about the parent record of this record.
+ HierarchyInformation ParentInformation;
+
+ /// Whether the symbol was defined in a system header.
+ bool IsFromSystemHeader;
+
+private:
+ const RecordKind Kind;
+
+public:
+ RecordKind getKind() const { return Kind; }
+
+ APIRecord() = delete;
+
+ APIRecord(RecordKind Kind, StringRef USR, StringRef Name,
+ PresumedLoc Location, AvailabilityInfo Availability,
+ LinkageInfo Linkage, const DocComment &Comment,
+ DeclarationFragments Declaration, DeclarationFragments SubHeading,
+ bool IsFromSystemHeader)
+ : USR(USR), Name(Name), Location(Location),
+ Availability(std::move(Availability)), Linkage(Linkage),
+ Comment(Comment), Declaration(Declaration), SubHeading(SubHeading),
+ IsFromSystemHeader(IsFromSystemHeader), Kind(Kind) {}
+
+ APIRecord(RecordKind Kind, StringRef USR, StringRef Name)
+ : USR(USR), Name(Name), Kind(Kind) {}
+
+ // Pure virtual destructor to make APIRecord abstract
+ virtual ~APIRecord() = 0;
+};
+
+struct NamespaceRecord : APIRecord {
+ NamespaceRecord(StringRef USR, StringRef Name, PresumedLoc Loc,
+ AvailabilityInfo Availability, LinkageInfo Linkage,
+ const DocComment &Comment, DeclarationFragments Declaration,
+ DeclarationFragments SubHeading, bool IsFromSystemHeader)
+ : APIRecord(RK_Namespace, USR, Name, Loc, std::move(Availability),
+ Linkage, Comment, Declaration, SubHeading,
+ IsFromSystemHeader) {}
+
+ static bool classof(const APIRecord *Record) {
+ return Record->getKind() == RK_Namespace;
+ }
+};
+
+/// This holds information associated with global functions.
+struct GlobalFunctionRecord : APIRecord {
+ FunctionSignature Signature;
+
+ GlobalFunctionRecord(StringRef USR, StringRef Name, PresumedLoc Loc,
+ AvailabilityInfo Availability, LinkageInfo Linkage,
+ const DocComment &Comment,
+ DeclarationFragments Declaration,
+ DeclarationFragments SubHeading,
+ FunctionSignature Signature, bool IsFromSystemHeader)
+ : APIRecord(RK_GlobalFunction, USR, Name, Loc, std::move(Availability),
+ Linkage, Comment, Declaration, SubHeading,
+ IsFromSystemHeader),
+ Signature(Signature) {}
+
+ GlobalFunctionRecord(RecordKind Kind, StringRef USR, StringRef Name,
+ PresumedLoc Loc, AvailabilityInfo Availability,
+ LinkageInfo Linkage, const DocComment &Comment,
+ DeclarationFragments Declaration,
+ DeclarationFragments SubHeading,
+ FunctionSignature Signature, bool IsFromSystemHeader)
+ : APIRecord(Kind, USR, Name, Loc, std::move(Availability), Linkage,
+ Comment, Declaration, SubHeading, IsFromSystemHeader),
+ Signature(Signature) {}
+
+ static bool classof(const APIRecord *Record) {
+ return Record->getKind() == RK_GlobalFunction;
+ }
+
+private:
+ virtual void anchor();
+};
+
+struct GlobalFunctionTemplateRecord : GlobalFunctionRecord {
+ Template Templ;
+
+ GlobalFunctionTemplateRecord(StringRef USR, StringRef Name, PresumedLoc Loc,
+ AvailabilityInfo Availability,
+ LinkageInfo Linkage, const DocComment &Comment,
+ DeclarationFragments Declaration,
+ DeclarationFragments SubHeading,
+ FunctionSignature Signature, Template Template,
+ bool IsFromSystemHeader)
+ : GlobalFunctionRecord(RK_GlobalFunctionTemplate, USR, Name, Loc,
+ std::move(Availability), Linkage, Comment,
+ Declaration, SubHeading, Signature,
+ IsFromSystemHeader),
+ Templ(Template) {}
+
+ static bool classof(const APIRecord *Record) {
+ return Record->getKind() == RK_GlobalFunctionTemplate;
+ }
+};
+
+struct GlobalFunctionTemplateSpecializationRecord : GlobalFunctionRecord {
+ GlobalFunctionTemplateSpecializationRecord(
+ StringRef USR, StringRef Name, PresumedLoc Loc,
+ AvailabilityInfo Availability, LinkageInfo Linkage,
+ const DocComment &Comment, DeclarationFragments Declaration,
+ DeclarationFragments SubHeading, FunctionSignature Signature,
+ bool IsFromSystemHeader)
+ : GlobalFunctionRecord(RK_GlobalFunctionTemplateSpecialization, USR, Name,
+ Loc, std::move(Availability), Linkage, Comment,
+ Declaration, SubHeading, Signature,
+ IsFromSystemHeader) {}
+
+ static bool classof(const APIRecord *Record) {
+ return Record->getKind() == RK_GlobalFunctionTemplateSpecialization;
+ }
+};
+
+/// This holds information associated with global functions.
+struct GlobalVariableRecord : APIRecord {
+ GlobalVariableRecord(StringRef USR, StringRef Name, PresumedLoc Loc,
+ AvailabilityInfo Availability, LinkageInfo Linkage,
+ const DocComment &Comment,
+ DeclarationFragments Declaration,
+ DeclarationFragments SubHeading, bool IsFromSystemHeader)
+ : APIRecord(RK_GlobalVariable, USR, Name, Loc, std::move(Availability),
+ Linkage, Comment, Declaration, SubHeading,
+ IsFromSystemHeader) {}
+
+ GlobalVariableRecord(RecordKind Kind, StringRef USR, StringRef Name,
+ PresumedLoc Loc, AvailabilityInfo Availability,
+ LinkageInfo Linkage, const DocComment &Comment,
+ DeclarationFragments Declaration,
+ DeclarationFragments SubHeading, bool IsFromSystemHeader)
+ : APIRecord(Kind, USR, Name, Loc, std::move(Availability), Linkage,
+ Comment, Declaration, SubHeading, IsFromSystemHeader) {}
+
+ static bool classof(const APIRecord *Record) {
+ return Record->getKind() == RK_GlobalVariable;
+ }
+
+private:
+ virtual void anchor();
+};
+
+struct GlobalVariableTemplateRecord : GlobalVariableRecord {
+ Template Templ;
+
+ GlobalVariableTemplateRecord(StringRef USR, StringRef Name, PresumedLoc Loc,
+ AvailabilityInfo Availability,
+ LinkageInfo Linkage, const DocComment &Comment,
+ DeclarationFragments Declaration,
+ DeclarationFragments SubHeading,
+ class Template Template, bool IsFromSystemHeader)
+ : GlobalVariableRecord(RK_GlobalVariableTemplate, USR, Name, Loc,
+ std::move(Availability), Linkage, Comment,
+ Declaration, SubHeading, IsFromSystemHeader),
+ Templ(Template) {}
+
+ static bool classof(const APIRecord *Record) {
+ return Record->getKind() == RK_GlobalVariableTemplate;
+ }
+};
+
+struct GlobalVariableTemplateSpecializationRecord : GlobalVariableRecord {
+ GlobalVariableTemplateSpecializationRecord(
+ StringRef USR, StringRef Name, PresumedLoc Loc,
+ AvailabilityInfo Availability, LinkageInfo Linkage,
+ const DocComment &Comment, DeclarationFragments Declaration,
+ DeclarationFragments SubHeading, bool IsFromSystemHeader)
+ : GlobalVariableRecord(RK_GlobalVariableTemplateSpecialization, USR, Name,
+ Loc, std::move(Availability), Linkage, Comment,
+ Declaration, SubHeading, IsFromSystemHeader) {}
+
+ static bool classof(const APIRecord *Record) {
+ return Record->getKind() == RK_GlobalVariableTemplateSpecialization;
+ }
+};
+
+struct GlobalVariableTemplatePartialSpecializationRecord
+ : GlobalVariableRecord {
+ Template Templ;
+
+ GlobalVariableTemplatePartialSpecializationRecord(
+ StringRef USR, StringRef Name, PresumedLoc Loc,
+ AvailabilityInfo Availability, LinkageInfo Linkage,
+ const DocComment &Comment, DeclarationFragments Declaration,
+ DeclarationFragments SubHeading, class Template Template,
+ bool IsFromSystemHeader)
+ : GlobalVariableRecord(RK_GlobalVariableTemplatePartialSpecialization,
+ USR, Name, Loc, std::move(Availability), Linkage,
+ Comment, Declaration, SubHeading,
+ IsFromSystemHeader),
+ Templ(Template) {}
+
+ static bool classof(const APIRecord *Record) {
+ return Record->getKind() == RK_GlobalVariableTemplatePartialSpecialization;
+ }
+};
+
+/// This holds information associated with enum constants.
+struct EnumConstantRecord : APIRecord {
+ EnumConstantRecord(StringRef USR, StringRef Name, PresumedLoc Loc,
+ AvailabilityInfo Availability, const DocComment &Comment,
+ DeclarationFragments Declaration,
+ DeclarationFragments SubHeading, bool IsFromSystemHeader)
+ : APIRecord(RK_EnumConstant, USR, Name, Loc, std::move(Availability),
+ LinkageInfo::none(), Comment, Declaration, SubHeading,
+ IsFromSystemHeader) {}
+
+ static bool classof(const APIRecord *Record) {
+ return Record->getKind() == RK_EnumConstant;
+ }
+
+private:
+ virtual void anchor();
+};
+
+/// This holds information associated with enums.
+struct EnumRecord : APIRecord {
+ SmallVector<std::unique_ptr<EnumConstantRecord>> Constants;
+
+ EnumRecord(StringRef USR, StringRef Name, PresumedLoc Loc,
+ AvailabilityInfo Availability, const DocComment &Comment,
+ DeclarationFragments Declaration, DeclarationFragments SubHeading,
+ bool IsFromSystemHeader)
+ : APIRecord(RK_Enum, USR, Name, Loc, std::move(Availability),
+ LinkageInfo::none(), Comment, Declaration, SubHeading,
+ IsFromSystemHeader) {}
+
+ static bool classof(const APIRecord *Record) {
+ return Record->getKind() == RK_Enum;
+ }
+
+private:
+ virtual void anchor();
+};
+
+/// This holds information associated with struct fields.
+struct RecordFieldRecord : APIRecord {
+ RecordFieldRecord(StringRef USR, StringRef Name, PresumedLoc Loc,
+ AvailabilityInfo Availability, const DocComment &Comment,
+ DeclarationFragments Declaration,
+ DeclarationFragments SubHeading, RecordKind Kind,
+ bool IsFromSystemHeader)
+ : APIRecord(Kind, USR, Name, Loc, std::move(Availability),
+ LinkageInfo::none(), Comment, Declaration, SubHeading,
+ IsFromSystemHeader) {}
+
+ static bool classof(const APIRecord *Record) {
+ return Record->getKind() == RK_StructField ||
+ Record->getKind() == RK_UnionField;
+ }
+
+private:
+ virtual void anchor();
+};
+
+/// This holds information associated with structs.
+struct RecordRecord : APIRecord {
+ SmallVector<std::unique_ptr<RecordFieldRecord>> Fields;
+
+ RecordRecord(StringRef USR, StringRef Name, PresumedLoc Loc,
+ AvailabilityInfo Availability, const DocComment &Comment,
+ DeclarationFragments Declaration,
+ DeclarationFragments SubHeading, RecordKind Kind,
+ bool IsFromSystemHeader)
+ : APIRecord(Kind, USR, Name, Loc, std::move(Availability),
+ LinkageInfo::none(), Comment, Declaration, SubHeading,
+ IsFromSystemHeader) {}
+
+ static bool classof(const APIRecord *Record) {
+ return Record->getKind() == RK_Struct || Record->getKind() == RK_Union;
+ }
+
+private:
+ virtual void anchor();
+};
+
+struct CXXFieldRecord : APIRecord {
+ AccessControl Access;
+
+ CXXFieldRecord(StringRef USR, StringRef Name, PresumedLoc Loc,
+ AvailabilityInfo Availability, const DocComment &Comment,
+ DeclarationFragments Declaration,
+ DeclarationFragments SubHeading, AccessControl Access,
+ bool IsFromSystemHeader)
+ : APIRecord(RK_CXXField, USR, Name, Loc, std::move(Availability),
+ LinkageInfo::none(), Comment, Declaration, SubHeading,
+ IsFromSystemHeader),
+ Access(Access) {}
+
+ CXXFieldRecord(RecordKind Kind, StringRef USR, StringRef Name,
+ PresumedLoc Loc, AvailabilityInfo Availability,
+ const DocComment &Comment, DeclarationFragments Declaration,
+ DeclarationFragments SubHeading, AccessControl Access,
+ bool IsFromSystemHeader)
+ : APIRecord(Kind, USR, Name, Loc, std::move(Availability),
+ LinkageInfo::none(), Comment, Declaration, SubHeading,
+ IsFromSystemHeader),
+ Access(Access) {}
+
+ static bool classof(const APIRecord *Record) {
+ return Record->getKind() == RK_CXXField;
+ }
+
+private:
+ virtual void anchor();
+};
+
+struct CXXFieldTemplateRecord : CXXFieldRecord {
+ Template Templ;
+
+ CXXFieldTemplateRecord(StringRef USR, StringRef Name, PresumedLoc Loc,
+ AvailabilityInfo Availability,
+ const DocComment &Comment,
+ DeclarationFragments Declaration,
+ DeclarationFragments SubHeading, AccessControl Access,
+ Template Template, bool IsFromSystemHeader)
+ : CXXFieldRecord(RK_CXXFieldTemplate, USR, Name, Loc,
+ std::move(Availability), Comment, Declaration,
+ SubHeading, Access, IsFromSystemHeader),
+ Templ(Template) {}
+
+ static bool classof(const APIRecord *Record) {
+ return Record->getKind() == RK_CXXFieldTemplate;
+ }
+};
+
+struct CXXMethodRecord : APIRecord {
+ FunctionSignature Signature;
+ AccessControl Access;
+
+ CXXMethodRecord() = delete;
+
+ CXXMethodRecord(RecordKind Kind, StringRef USR, StringRef Name,
+ PresumedLoc Loc, AvailabilityInfo Availability,
+ const DocComment &Comment, DeclarationFragments Declaration,
+ DeclarationFragments SubHeading, FunctionSignature Signature,
+ AccessControl Access, bool IsFromSystemHeader)
+ : APIRecord(Kind, USR, Name, Loc, std::move(Availability),
+ LinkageInfo::none(), Comment, Declaration, SubHeading,
+ IsFromSystemHeader),
+ Signature(Signature), Access(Access) {}
+
+ virtual ~CXXMethodRecord() = 0;
+};
+
+struct CXXConstructorRecord : CXXMethodRecord {
+ CXXConstructorRecord(StringRef USR, StringRef Name, PresumedLoc Loc,
+ AvailabilityInfo Availability, const DocComment &Comment,
+ DeclarationFragments Declaration,
+ DeclarationFragments SubHeading,
+ FunctionSignature Signature, AccessControl Access,
+ bool IsFromSystemHeader)
+ : CXXMethodRecord(RK_CXXConstructorMethod, USR, Name, Loc,
+ std::move(Availability), Comment, Declaration,
+ SubHeading, Signature, Access, IsFromSystemHeader) {}
+ static bool classof(const APIRecord *Record) {
+ return Record->getKind() == RK_CXXConstructorMethod;
+ }
+
+private:
+ virtual void anchor();
+};
+
+struct CXXDestructorRecord : CXXMethodRecord {
+ CXXDestructorRecord(StringRef USR, StringRef Name, PresumedLoc Loc,
+ AvailabilityInfo Availability, const DocComment &Comment,
+ DeclarationFragments Declaration,
+ DeclarationFragments SubHeading,
+ FunctionSignature Signature, AccessControl Access,
+ bool IsFromSystemHeader)
+ : CXXMethodRecord(RK_CXXDestructorMethod, USR, Name, Loc,
+ std::move(Availability), Comment, Declaration,
+ SubHeading, Signature, Access, IsFromSystemHeader) {}
+ static bool classof(const APIRecord *Record) {
+ return Record->getKind() == RK_CXXDestructorMethod;
+ }
+
+private:
+ virtual void anchor();
+};
+
+struct CXXStaticMethodRecord : CXXMethodRecord {
+ CXXStaticMethodRecord(StringRef USR, StringRef Name, PresumedLoc Loc,
+ AvailabilityInfo Availability,
+ const DocComment &Comment,
+ DeclarationFragments Declaration,
+ DeclarationFragments SubHeading,
+ FunctionSignature Signature, AccessControl Access,
+ bool IsFromSystemHeader)
+ : CXXMethodRecord(RK_CXXStaticMethod, USR, Name, Loc,
+ std::move(Availability), Comment, Declaration,
+ SubHeading, Signature, Access, IsFromSystemHeader) {}
+ static bool classof(const APIRecord *Record) {
+ return Record->getKind() == RK_CXXStaticMethod;
+ }
+
+private:
+ virtual void anchor();
+};
+
+struct CXXInstanceMethodRecord : CXXMethodRecord {
+ CXXInstanceMethodRecord(StringRef USR, StringRef Name, PresumedLoc Loc,
+ AvailabilityInfo Availability,
+ const DocComment &Comment,
+ DeclarationFragments Declaration,
+ DeclarationFragments SubHeading,
+ FunctionSignature Signature, AccessControl Access,
+ bool IsFromSystemHeader)
+ : CXXMethodRecord(RK_CXXInstanceMethod, USR, Name, Loc,
+ std::move(Availability), Comment, Declaration,
+ SubHeading, Signature, Access, IsFromSystemHeader) {}
+
+ static bool classof(const APIRecord *Record) {
+ return Record->getKind() == RK_CXXInstanceMethod;
+ }
+
+private:
+ virtual void anchor();
+};
+
+struct CXXMethodTemplateRecord : CXXMethodRecord {
+ Template Templ;
+
+ CXXMethodTemplateRecord(StringRef USR, StringRef Name, PresumedLoc Loc,
+ AvailabilityInfo Availability,
+ const DocComment &Comment,
+ DeclarationFragments Declaration,
+ DeclarationFragments SubHeading,
+ FunctionSignature Signature, AccessControl Access,
+ Template Template, bool IsFromSystemHeader)
+ : CXXMethodRecord(RK_CXXMethodTemplate, USR, Name, Loc,
+ std::move(Availability), Comment, Declaration,
+ SubHeading, Signature, Access, IsFromSystemHeader),
+ Templ(Template) {}
+
+ static bool classof(const APIRecord *Record) {
+ return Record->getKind() == RK_CXXMethodTemplate;
+ }
+};
+
+struct CXXMethodTemplateSpecializationRecord : CXXMethodRecord {
+ CXXMethodTemplateSpecializationRecord(
+ StringRef USR, StringRef Name, PresumedLoc Loc,
+ AvailabilityInfo Availability, const DocComment &Comment,
+ DeclarationFragments Declaration, DeclarationFragments SubHeading,
+ FunctionSignature Signature, AccessControl Access,
+ bool IsFromSystemHeader)
+ : CXXMethodRecord(RK_CXXMethodTemplateSpecialization, USR, Name, Loc,
+ std::move(Availability), Comment, Declaration,
+ SubHeading, Signature, Access, IsFromSystemHeader) {}
+
+ static bool classof(const APIRecord *Record) {
+ return Record->getKind() == RK_CXXMethodTemplateSpecialization;
+ }
+};
+
+/// This holds information associated with Objective-C properties.
+struct ObjCPropertyRecord : APIRecord {
+ /// The attributes associated with an Objective-C property.
+ enum AttributeKind : unsigned {
+ NoAttr = 0,
+ ReadOnly = 1,
+ Dynamic = 1 << 2,
+ };
+
+ AttributeKind Attributes;
+ StringRef GetterName;
+ StringRef SetterName;
+ bool IsOptional;
+
+ ObjCPropertyRecord(RecordKind Kind, StringRef USR, StringRef Name,
+ PresumedLoc Loc, AvailabilityInfo Availability,
+ const DocComment &Comment,
+ DeclarationFragments Declaration,
+ DeclarationFragments SubHeading, AttributeKind Attributes,
+ StringRef GetterName, StringRef SetterName,
+ bool IsOptional, bool IsFromSystemHeader)
+ : APIRecord(Kind, USR, Name, Loc, std::move(Availability),
+ LinkageInfo::none(), Comment, Declaration, SubHeading,
+ IsFromSystemHeader),
+ Attributes(Attributes), GetterName(GetterName), SetterName(SetterName),
+ IsOptional(IsOptional) {}
+
+ bool isReadOnly() const { return Attributes & ReadOnly; }
+ bool isDynamic() const { return Attributes & Dynamic; }
+
+ virtual ~ObjCPropertyRecord() = 0;
+};
+
+struct ObjCInstancePropertyRecord : ObjCPropertyRecord {
+ ObjCInstancePropertyRecord(StringRef USR, StringRef Name, PresumedLoc Loc,
+ AvailabilityInfo Availability,
+ const DocComment &Comment,
+ DeclarationFragments Declaration,
+ DeclarationFragments SubHeading,
+ AttributeKind Attributes, StringRef GetterName,
+ StringRef SetterName, bool IsOptional,
+ bool IsFromSystemHeader)
+ : ObjCPropertyRecord(RK_ObjCInstanceProperty, USR, Name, Loc,
+ std::move(Availability), Comment, Declaration,
+ SubHeading, Attributes, GetterName, SetterName,
+ IsOptional, IsFromSystemHeader) {}
+
+ static bool classof(const APIRecord *Record) {
+ return Record->getKind() == RK_ObjCInstanceProperty;
+ }
+
+private:
+ virtual void anchor();
+};
+
+struct ObjCClassPropertyRecord : ObjCPropertyRecord {
+ ObjCClassPropertyRecord(StringRef USR, StringRef Name, PresumedLoc Loc,
+ AvailabilityInfo Availability,
+ const DocComment &Comment,
+ DeclarationFragments Declaration,
+ DeclarationFragments SubHeading,
+ AttributeKind Attributes, StringRef GetterName,
+ StringRef SetterName, bool IsOptional,
+ bool IsFromSystemHeader)
+ : ObjCPropertyRecord(RK_ObjCClassProperty, USR, Name, Loc,
+ std::move(Availability), Comment, Declaration,
+ SubHeading, Attributes, GetterName, SetterName,
+ IsOptional, IsFromSystemHeader) {}
+
+ static bool classof(const APIRecord *Record) {
+ return Record->getKind() == RK_ObjCClassProperty;
+ }
+
+private:
+ virtual void anchor();
+};
+
+/// This holds information associated with Objective-C instance variables.
+struct ObjCInstanceVariableRecord : APIRecord {
+ using AccessControl = ObjCIvarDecl::AccessControl;
+ AccessControl Access;
+
+ ObjCInstanceVariableRecord(StringRef USR, StringRef Name, PresumedLoc Loc,
+ AvailabilityInfo Availability,
+ const DocComment &Comment,
+ DeclarationFragments Declaration,
+ DeclarationFragments SubHeading,
+ AccessControl Access, bool IsFromSystemHeader)
+ : APIRecord(RK_ObjCIvar, USR, Name, Loc, std::move(Availability),
+ LinkageInfo::none(), Comment, Declaration, SubHeading,
+ IsFromSystemHeader),
+ Access(Access) {}
+
+ static bool classof(const APIRecord *Record) {
+ return Record->getKind() == RK_ObjCIvar;
+ }
+
+private:
+ virtual void anchor();
+};
+
+/// This holds information associated with Objective-C methods.
+struct ObjCMethodRecord : APIRecord {
+ FunctionSignature Signature;
+
+ ObjCMethodRecord() = delete;
+
+ ObjCMethodRecord(RecordKind Kind, StringRef USR, StringRef Name,
+ PresumedLoc Loc, AvailabilityInfo Availability,
+ const DocComment &Comment, DeclarationFragments Declaration,
+ DeclarationFragments SubHeading, FunctionSignature Signature,
+ bool IsFromSystemHeader)
+ : APIRecord(Kind, USR, Name, Loc, std::move(Availability),
+ LinkageInfo::none(), Comment, Declaration, SubHeading,
+ IsFromSystemHeader),
+ Signature(Signature) {}
+
+ virtual ~ObjCMethodRecord() = 0;
+};
+
+struct ObjCInstanceMethodRecord : ObjCMethodRecord {
+ ObjCInstanceMethodRecord(StringRef USR, StringRef Name, PresumedLoc Loc,
+ AvailabilityInfo Availability,
+ const DocComment &Comment,
+ DeclarationFragments Declaration,
+ DeclarationFragments SubHeading,
+ FunctionSignature Signature, bool IsFromSystemHeader)
+ : ObjCMethodRecord(RK_ObjCInstanceMethod, USR, Name, Loc,
+ std::move(Availability), Comment, Declaration,
+ SubHeading, Signature, IsFromSystemHeader) {}
+ static bool classof(const APIRecord *Record) {
+ return Record->getKind() == RK_ObjCInstanceMethod;
+ }
+
+private:
+ virtual void anchor();
+};
+
+struct ObjCClassMethodRecord : ObjCMethodRecord {
+ ObjCClassMethodRecord(StringRef USR, StringRef Name, PresumedLoc Loc,
+ AvailabilityInfo Availability,
+ const DocComment &Comment,
+ DeclarationFragments Declaration,
+ DeclarationFragments SubHeading,
+ FunctionSignature Signature, bool IsFromSystemHeader)
+ : ObjCMethodRecord(RK_ObjCClassMethod, USR, Name, Loc,
+ std::move(Availability), Comment, Declaration,
+ SubHeading, Signature, IsFromSystemHeader) {}
+
+ static bool classof(const APIRecord *Record) {
+ return Record->getKind() == RK_ObjCClassMethod;
+ }
+
+private:
+ virtual void anchor();
+};
+
+/// This represents a reference to another symbol that might come from external
+/// sources.
+struct SymbolReference {
+ StringRef Name;
+ StringRef USR;
+
+ /// The source project/module/product of the referred symbol.
+ StringRef Source;
+
+ SymbolReference() = default;
+ SymbolReference(StringRef Name, StringRef USR = "", StringRef Source = "")
+ : Name(Name), USR(USR), Source(Source) {}
+ SymbolReference(const APIRecord &Record)
+ : Name(Record.Name), USR(Record.USR) {}
+ SymbolReference(const APIRecord *Record)
+ : Name(Record->Name), USR(Record->USR) {}
+
+ /// Determine if this SymbolReference is empty.
+ ///
+ /// \returns true if and only if all \c Name, \c USR, and \c Source is empty.
+ bool empty() const { return Name.empty() && USR.empty() && Source.empty(); }
+};
+
+struct StaticFieldRecord : CXXFieldRecord {
+ SymbolReference Context;
+
+ StaticFieldRecord(StringRef USR, StringRef Name, PresumedLoc Loc,
+ AvailabilityInfo Availability, LinkageInfo Linkage,
+ const DocComment &Comment, DeclarationFragments Declaration,
+ DeclarationFragments SubHeading, SymbolReference Context,
+ AccessControl Access, bool IsFromSystemHeader)
+ : CXXFieldRecord(RK_StaticField, USR, Name, Loc, std::move(Availability),
+ Comment, Declaration, SubHeading, Access,
+ IsFromSystemHeader),
+ Context(Context) {}
+
+ static bool classof(const APIRecord *Record) {
+ return Record->getKind() == RK_StaticField;
+ }
+};
+
+/// The base representation of an Objective-C container record. Holds common
+/// information associated with Objective-C containers.
+struct ObjCContainerRecord : APIRecord {
+ SmallVector<std::unique_ptr<ObjCMethodRecord>> Methods;
+ SmallVector<std::unique_ptr<ObjCPropertyRecord>> Properties;
+ SmallVector<std::unique_ptr<ObjCInstanceVariableRecord>> Ivars;
+ SmallVector<SymbolReference> Protocols;
+
+ ObjCContainerRecord() = delete;
+
+ ObjCContainerRecord(RecordKind Kind, StringRef USR, StringRef Name,
+ PresumedLoc Loc, AvailabilityInfo Availability,
+ LinkageInfo Linkage, const DocComment &Comment,
+ DeclarationFragments Declaration,
+ DeclarationFragments SubHeading, bool IsFromSystemHeader)
+ : APIRecord(Kind, USR, Name, Loc, std::move(Availability), Linkage,
+ Comment, Declaration, SubHeading, IsFromSystemHeader) {}
+
+ virtual ~ObjCContainerRecord() = 0;
+};
+
+struct CXXClassRecord : APIRecord {
+ SmallVector<std::unique_ptr<CXXFieldRecord>> Fields;
+ SmallVector<std::unique_ptr<CXXMethodRecord>> Methods;
+ SmallVector<SymbolReference> Bases;
+ AccessControl Access;
+
+ CXXClassRecord(StringRef USR, StringRef Name, PresumedLoc Loc,
+ AvailabilityInfo Availability, const DocComment &Comment,
+ DeclarationFragments Declaration,
+ DeclarationFragments SubHeading, RecordKind Kind,
+ AccessControl Access, bool IsFromSystemHeader)
+ : APIRecord(Kind, USR, Name, Loc, std::move(Availability),
+ LinkageInfo::none(), Comment, Declaration, SubHeading,
+ IsFromSystemHeader),
+ Access(Access) {}
+
+ static bool classof(const APIRecord *Record) {
+ return (Record->getKind() == RK_CXXClass);
+ }
+
+private:
+ virtual void anchor();
+};
+
+struct ClassTemplateRecord : CXXClassRecord {
+ Template Templ;
+
+ ClassTemplateRecord(StringRef USR, StringRef Name, PresumedLoc Loc,
+ AvailabilityInfo Availability, const DocComment &Comment,
+ DeclarationFragments Declaration,
+ DeclarationFragments SubHeading, Template Template,
+ AccessControl Access, bool IsFromSystemHeader)
+ : CXXClassRecord(USR, Name, Loc, std::move(Availability), Comment,
+ Declaration, SubHeading, RK_ClassTemplate, Access,
+ IsFromSystemHeader),
+ Templ(Template) {}
+
+ static bool classof(const APIRecord *Record) {
+ return Record->getKind() == RK_ClassTemplate;
+ }
+};
+
+struct ClassTemplateSpecializationRecord : CXXClassRecord {
+ ClassTemplateSpecializationRecord(
+ StringRef USR, StringRef Name, PresumedLoc Loc,
+ AvailabilityInfo Availability, const DocComment &Comment,
+ DeclarationFragments Declaration, DeclarationFragments SubHeading,
+ AccessControl Access, bool IsFromSystemHeader)
+ : CXXClassRecord(USR, Name, Loc, std::move(Availability), Comment,
+ Declaration, SubHeading, RK_ClassTemplateSpecialization,
+ Access, IsFromSystemHeader) {}
+
+ static bool classof(const APIRecord *Record) {
+ return Record->getKind() == RK_ClassTemplateSpecialization;
+ }
+};
+
+struct ClassTemplatePartialSpecializationRecord : CXXClassRecord {
+ Template Templ;
+ ClassTemplatePartialSpecializationRecord(
+ StringRef USR, StringRef Name, PresumedLoc Loc,
+ AvailabilityInfo Availability, const DocComment &Comment,
+ DeclarationFragments Declaration, DeclarationFragments SubHeading,
+ Template Template, AccessControl Access, bool IsFromSystemHeader)
+ : CXXClassRecord(USR, Name, Loc, std::move(Availability), Comment,
+ Declaration, SubHeading, RK_ClassTemplateSpecialization,
+ Access, IsFromSystemHeader),
+ Templ(Template) {}
+
+ static bool classof(const APIRecord *Record) {
+ return Record->getKind() == RK_ClassTemplatePartialSpecialization;
+ }
+};
+
+struct ConceptRecord : APIRecord {
+ Template Templ;
+
+ ConceptRecord(StringRef USR, StringRef Name, PresumedLoc Loc,
+ AvailabilityInfo Availability, const DocComment &Comment,
+ DeclarationFragments Declaration,
+ DeclarationFragments SubHeading, Template Template,
+ bool IsFromSystemHeader)
+ : APIRecord(RK_Concept, USR, Name, Loc, std::move(Availability),
+ LinkageInfo::none(), Comment, Declaration, SubHeading,
+ IsFromSystemHeader),
+ Templ(Template) {}
+};
+
+/// This holds information associated with Objective-C categories.
+struct ObjCCategoryRecord : ObjCContainerRecord {
+ SymbolReference Interface;
+ /// Determine whether the Category is derived from external class interface.
+ bool IsFromExternalModule = false;
+
+ ObjCCategoryRecord(StringRef USR, StringRef Name, PresumedLoc Loc,
+ AvailabilityInfo Availability, const DocComment &Comment,
+ DeclarationFragments Declaration,
+ DeclarationFragments SubHeading, SymbolReference Interface,
+ bool IsFromSystemHeader)
+ : ObjCContainerRecord(RK_ObjCCategory, USR, Name, Loc,
+ std::move(Availability), LinkageInfo::none(),
+ Comment, Declaration, SubHeading,
+ IsFromSystemHeader),
+ Interface(Interface) {}
+
+ static bool classof(const APIRecord *Record) {
+ return Record->getKind() == RK_ObjCCategory;
+ }
+
+private:
+ virtual void anchor();
+};
+
+/// This holds information associated with Objective-C interfaces/classes.
+struct ObjCInterfaceRecord : ObjCContainerRecord {
+ SymbolReference SuperClass;
+ // ObjCCategoryRecord%s are stored in and owned by APISet.
+ SmallVector<ObjCCategoryRecord *> Categories;
+
+ ObjCInterfaceRecord(StringRef USR, StringRef Name, PresumedLoc Loc,
+ AvailabilityInfo Availability, LinkageInfo Linkage,
+ const DocComment &Comment,
+ DeclarationFragments Declaration,
+ DeclarationFragments SubHeading,
+ SymbolReference SuperClass, bool IsFromSystemHeader)
+ : ObjCContainerRecord(RK_ObjCInterface, USR, Name, Loc,
+ std::move(Availability), Linkage, Comment,
+ Declaration, SubHeading, IsFromSystemHeader),
+ SuperClass(SuperClass) {}
+
+ static bool classof(const APIRecord *Record) {
+ return Record->getKind() == RK_ObjCInterface;
+ }
+
+private:
+ virtual void anchor();
+};
+
+/// This holds information associated with Objective-C protocols.
+struct ObjCProtocolRecord : ObjCContainerRecord {
+ ObjCProtocolRecord(StringRef USR, StringRef Name, PresumedLoc Loc,
+ AvailabilityInfo Availability, const DocComment &Comment,
+ DeclarationFragments Declaration,
+ DeclarationFragments SubHeading, bool IsFromSystemHeader)
+ : ObjCContainerRecord(RK_ObjCProtocol, USR, Name, Loc,
+ std::move(Availability), LinkageInfo::none(),
+ Comment, Declaration, SubHeading,
+ IsFromSystemHeader) {}
+
+ static bool classof(const APIRecord *Record) {
+ return Record->getKind() == RK_ObjCProtocol;
+ }
+
+private:
+ virtual void anchor();
+};
+
+/// This holds information associated with macro definitions.
+struct MacroDefinitionRecord : APIRecord {
+ MacroDefinitionRecord(StringRef USR, StringRef Name, PresumedLoc Loc,
+ DeclarationFragments Declaration,
+ DeclarationFragments SubHeading,
+ bool IsFromSystemHeader)
+ : APIRecord(RK_MacroDefinition, USR, Name, Loc, AvailabilityInfo(),
+ LinkageInfo(), {}, Declaration, SubHeading,
+ IsFromSystemHeader) {}
+
+ static bool classof(const APIRecord *Record) {
+ return Record->getKind() == RK_MacroDefinition;
+ }
+
+private:
+ virtual void anchor();
+};
+
+/// This holds information associated with typedefs.
+///
+/// Note: Typedefs for anonymous enums and structs typically don't get emitted
+/// by the serializers but still get a TypedefRecord. Instead we use the
+/// typedef name as a name for the underlying anonymous struct or enum.
+struct TypedefRecord : APIRecord {
+ SymbolReference UnderlyingType;
+
+ TypedefRecord(StringRef USR, StringRef Name, PresumedLoc Loc,
+ AvailabilityInfo Availability, const DocComment &Comment,
+ DeclarationFragments Declaration,
+ DeclarationFragments SubHeading, SymbolReference UnderlyingType,
+ bool IsFromSystemHeader)
+ : APIRecord(RK_Typedef, USR, Name, Loc, std::move(Availability),
+ LinkageInfo(), Comment, Declaration, SubHeading,
+ IsFromSystemHeader),
+ UnderlyingType(UnderlyingType) {}
+
+ static bool classof(const APIRecord *Record) {
+ return Record->getKind() == RK_Typedef;
+ }
+
+private:
+ virtual void anchor();
+};
+
+/// Check if a record type has a function signature mixin.
+///
+/// This is denoted by the record type having a ``Signature`` field of type
+/// FunctionSignature.
+template <typename RecordTy>
+struct has_function_signature : public std::false_type {};
+template <>
+struct has_function_signature<GlobalFunctionRecord> : public std::true_type {};
+template <>
+struct has_function_signature<ObjCMethodRecord> : public std::true_type {};
+template <>
+struct has_function_signature<ObjCInstanceMethodRecord>
+ : public std::true_type {};
+template <>
+struct has_function_signature<ObjCClassMethodRecord> : public std::true_type {};
+template <>
+struct has_function_signature<CXXInstanceMethodRecord> : public std::true_type {};
+template <>
+struct has_function_signature<CXXStaticMethodRecord> : public std::true_type {};
+template <>
+struct has_function_signature<CXXMethodTemplateRecord> : public std::true_type {
+};
+template <>
+struct has_function_signature<CXXMethodTemplateSpecializationRecord>
+ : public std::true_type {};
+
+template <typename RecordTy> struct has_access : public std::false_type {};
+template <> struct has_access<CXXInstanceMethodRecord> : public std::true_type {};
+template <> struct has_access<CXXStaticMethodRecord> : public std::true_type {};
+template <> struct has_access<CXXFieldRecord> : public std::true_type {};
+template <>
+struct has_access<CXXMethodTemplateRecord> : public std::true_type {};
+template <>
+struct has_access<CXXMethodTemplateSpecializationRecord>
+ : public std::true_type {};
+template <>
+struct has_access<CXXFieldTemplateRecord> : public std::true_type {};
+template <> struct has_access<CXXClassRecord> : public std::true_type {};
+template <> struct has_access<ClassTemplateRecord> : public std::true_type {};
+template <>
+struct has_access<ClassTemplateSpecializationRecord> : public std::true_type {};
+template <>
+struct has_access<ClassTemplatePartialSpecializationRecord>
+ : public std::true_type {};
+
+template <typename RecordTy> struct has_template : public std::false_type {};
+template <> struct has_template<ClassTemplateRecord> : public std::true_type {};
+template <>
+struct has_template<ClassTemplatePartialSpecializationRecord>
+ : public std::true_type {};
+template <> struct has_template<ConceptRecord> : public std::true_type {};
+template <>
+struct has_template<GlobalVariableTemplateRecord> : public std::true_type {};
+template <>
+struct has_template<GlobalVariableTemplatePartialSpecializationRecord>
+ : public std::true_type {};
+template <>
+struct has_template<CXXMethodTemplateRecord> : public std::true_type {};
+template <>
+struct has_template<CXXFieldTemplateRecord> : public std::true_type {};
+
+template <>
+struct has_template<GlobalFunctionTemplateRecord> : public std::true_type {};
+template <>
+struct has_function_signature<GlobalFunctionTemplateRecord>
+ : public std::true_type {};
+template <>
+struct has_function_signature<GlobalFunctionTemplateSpecializationRecord>
+ : public std::true_type {};
+
+/// APISet holds the set of API records collected from given inputs.
+class APISet {
+public:
+ NamespaceRecord *addNamespace(APIRecord *Parent, StringRef Name,
+ StringRef USR, PresumedLoc Loc,
+ AvailabilityInfo Availability,
+ LinkageInfo Linkage, const DocComment &Comment,
+ DeclarationFragments Declaration,
+ DeclarationFragments SubHeading,
+ bool IsFromSystemHeaderg);
+ /// Create and add a global variable record into the API set.
+ ///
+ /// Note: the caller is responsible for keeping the StringRef \p Name and
+ /// \p USR alive. APISet::copyString provides a way to copy strings into
+ /// APISet itself, and APISet::recordUSR(const Decl *D) is a helper method
+ /// to generate the USR for \c D and keep it alive in APISet.
+ GlobalVariableRecord *
+ addGlobalVar(StringRef Name, StringRef USR, PresumedLoc Loc,
+ AvailabilityInfo Availability, LinkageInfo Linkage,
+ const DocComment &Comment, DeclarationFragments Declaration,
+ DeclarationFragments SubHeadin, bool IsFromSystemHeaderg);
+
+ GlobalVariableTemplateRecord *
+ addGlobalVariableTemplate(StringRef Name, StringRef USR, PresumedLoc Loc,
+ AvailabilityInfo Availability, LinkageInfo Linkage,
+ const DocComment &Comment,
+ DeclarationFragments Declaration,
+ DeclarationFragments SubHeading, Template Template,
+ bool IsFromSystemHeader);
+
+ /// Create and add a function record into the API set.
+ ///
+ /// Note: the caller is responsible for keeping the StringRef \p Name and
+ /// \p USR alive. APISet::copyString provides a way to copy strings into
+ /// APISet itself, and APISet::recordUSR(const Decl *D) is a helper method
+ /// to generate the USR for \c D and keep it alive in APISet.
+ GlobalFunctionRecord *
+ addGlobalFunction(StringRef Name, StringRef USR, PresumedLoc Loc,
+ AvailabilityInfo Availability, LinkageInfo Linkage,
+ const DocComment &Comment, DeclarationFragments Declaration,
+ DeclarationFragments SubHeading,
+ FunctionSignature Signature, bool IsFromSystemHeader);
+
+ GlobalFunctionTemplateRecord *addGlobalFunctionTemplate(
+ StringRef Name, StringRef USR, PresumedLoc Loc,
+ AvailabilityInfo Availability, LinkageInfo Linkage,
+ const DocComment &Comment, DeclarationFragments Declaration,
+ DeclarationFragments SubHeading, FunctionSignature Signature,
+ Template Template, bool IsFromSystemHeader);
+
+ GlobalFunctionTemplateSpecializationRecord *
+ addGlobalFunctionTemplateSpecialization(
+ StringRef Name, StringRef USR, PresumedLoc Loc,
+ AvailabilityInfo Availability, LinkageInfo Linkage,
+ const DocComment &Comment, DeclarationFragments Declaration,
+ DeclarationFragments SubHeading, FunctionSignature Signature,
+ bool IsFromSystemHeader);
+
+ /// Create and add an enum constant record into the API set.
+ ///
+ /// Note: the caller is responsible for keeping the StringRef \p Name and
+ /// \p USR alive. APISet::copyString provides a way to copy strings into
+ /// APISet itself, and APISet::recordUSR(const Decl *D) is a helper method
+ /// to generate the USR for \c D and keep it alive in APISet.
+ EnumConstantRecord *
+ addEnumConstant(EnumRecord *Enum, StringRef Name, StringRef USR,
+ PresumedLoc Loc, AvailabilityInfo Availability,
+ const DocComment &Comment, DeclarationFragments Declaration,
+ DeclarationFragments SubHeading, bool IsFromSystemHeader);
+
+ /// Create and add an enum record into the API set.
+ ///
+ /// Note: the caller is responsible for keeping the StringRef \p Name and
+ /// \p USR alive. APISet::copyString provides a way to copy strings into
+ /// APISet itself, and APISet::recordUSR(const Decl *D) is a helper method
+ /// to generate the USR for \c D and keep it alive in APISet.
+ EnumRecord *addEnum(StringRef Name, StringRef USR, PresumedLoc Loc,
+ AvailabilityInfo Availability, const DocComment &Comment,
+ DeclarationFragments Declaration,
+ DeclarationFragments SubHeading, bool IsFromSystemHeader);
+
+ /// Create and add a record field record into the API set.
+ ///
+ /// Note: the caller is responsible for keeping the StringRef \p Name and
+ /// \p USR alive. APISet::copyString provides a way to copy strings into
+ /// APISet itself, and APISet::recordUSR(const Decl *D) is a helper method
+ /// to generate the USR for \c D and keep it alive in APISet.
+ RecordFieldRecord *
+ addRecordField(RecordRecord *Record, StringRef Name, StringRef USR,
+ PresumedLoc Loc, AvailabilityInfo Availability,
+ const DocComment &Comment, DeclarationFragments Declaration,
+ DeclarationFragments SubHeading, APIRecord::RecordKind Kind,
+ bool IsFromSystemHeader);
+
+ /// Create and add a record record into the API set.
+ ///
+ /// Note: the caller is responsible for keeping the StringRef \p Name and
+ /// \p USR alive. APISet::copyString provides a way to copy strings into
+ /// APISet itself, and APISet::recordUSR(const Decl *D) is a helper method
+ /// to generate the USR for \c D and keep it alive in APISet.
+ RecordRecord *addRecord(StringRef Name, StringRef USR, PresumedLoc Loc,
+ AvailabilityInfo Availability,
+ const DocComment &Comment,
+ DeclarationFragments Declaration,
+ DeclarationFragments SubHeading,
+ APIRecord::RecordKind Kind, bool IsFromSystemHeader);
+
+ StaticFieldRecord *
+ addStaticField(StringRef Name, StringRef USR, PresumedLoc Loc,
+ AvailabilityInfo Availability, LinkageInfo Linkage,
+ const DocComment &Comment, DeclarationFragments Declaration,
+ DeclarationFragments SubHeading, SymbolReference Context,
+ AccessControl Access, bool IsFromSystemHeaderg);
+
+ CXXFieldRecord *addCXXField(APIRecord *CXXClass, StringRef Name,
+ StringRef USR, PresumedLoc Loc,
+ AvailabilityInfo Availability,
+ const DocComment &Comment,
+ DeclarationFragments Declaration,
+ DeclarationFragments SubHeading,
+ AccessControl Access, bool IsFromSystemHeader);
+
+ CXXFieldTemplateRecord *addCXXFieldTemplate(
+ APIRecord *Parent, StringRef Name, StringRef USR, PresumedLoc Loc,
+ AvailabilityInfo Availability, const DocComment &Comment,
+ DeclarationFragments Declaration, DeclarationFragments SubHeading,
+ AccessControl Access, Template Template, bool IsFromSystemHeader);
+
+ CXXClassRecord *addCXXClass(APIRecord *Parent, StringRef Name, StringRef USR,
+ PresumedLoc Loc, AvailabilityInfo Availability,
+ const DocComment &Comment,
+ DeclarationFragments Declaration,
+ DeclarationFragments SubHeading,
+ APIRecord::RecordKind Kind, AccessControl Access,
+ bool IsFromSystemHeader);
+
+ ClassTemplateRecord *
+ addClassTemplate(APIRecord *Parent, StringRef Name, StringRef USR,
+ PresumedLoc Loc, AvailabilityInfo Availability,
+ const DocComment &Comment, DeclarationFragments Declaration,
+ DeclarationFragments SubHeading, Template Template,
+ AccessControl Access, bool IsFromSystemHeader);
+
+ ClassTemplateSpecializationRecord *addClassTemplateSpecialization(
+ APIRecord *Parent, StringRef Name, StringRef USR, PresumedLoc Loc,
+ AvailabilityInfo Availability, const DocComment &Comment,
+ DeclarationFragments Declaration, DeclarationFragments SubHeading,
+ AccessControl Access, bool IsFromSystemHeader);
+
+ ClassTemplatePartialSpecializationRecord *
+ addClassTemplatePartialSpecialization(
+ APIRecord *Parent, StringRef Name, StringRef USR, PresumedLoc Loc,
+ AvailabilityInfo Availability, const DocComment &Comment,
+ DeclarationFragments Declaration, DeclarationFragments SubHeading,
+ Template Template, AccessControl Access, bool IsFromSystemHeader);
+
+ GlobalVariableTemplateSpecializationRecord *
+ addGlobalVariableTemplateSpecialization(
+ StringRef Name, StringRef USR, PresumedLoc Loc,
+ AvailabilityInfo Availability, LinkageInfo Linkage,
+ const DocComment &Comment, DeclarationFragments Declaration,
+ DeclarationFragments SubHeading, bool IsFromSystemHeader);
+
+ GlobalVariableTemplatePartialSpecializationRecord *
+ addGlobalVariableTemplatePartialSpecialization(
+ StringRef Name, StringRef USR, PresumedLoc Loc,
+ AvailabilityInfo Availability, LinkageInfo Linkage,
+ const DocComment &Comment, DeclarationFragments Declaration,
+ DeclarationFragments SubHeading, Template Template,
+ bool IsFromSystemHeader);
+
+ CXXMethodRecord *addCXXInstanceMethod(
+ APIRecord *Parent, StringRef Name, StringRef USR, PresumedLoc Loc,
+ AvailabilityInfo Availability, const DocComment &Comment,
+ DeclarationFragments Declaration, DeclarationFragments SubHeading,
+ FunctionSignature Signature, AccessControl Access,
+ bool IsFromSystemHeader);
+
+ CXXMethodRecord *addCXXStaticMethod(
+ APIRecord *Parent, StringRef Name, StringRef USR, PresumedLoc Loc,
+ AvailabilityInfo Availability, const DocComment &Comment,
+ DeclarationFragments Declaration, DeclarationFragments SubHeading,
+ FunctionSignature Signature, AccessControl Access,
+ bool IsFromSystemHeader);
+
+ CXXMethodRecord *addCXXSpecialMethod(
+ APIRecord *Parent, StringRef Name, StringRef USR, PresumedLoc Loc,
+ AvailabilityInfo Availability, const DocComment &Comment,
+ DeclarationFragments Declaration, DeclarationFragments SubHeading,
+ FunctionSignature Signature, AccessControl Access,
+ bool IsFromSystemHeader);
+
+ CXXMethodTemplateRecord *addCXXMethodTemplate(
+ APIRecord *Parent, StringRef Name, StringRef USR, PresumedLoc Loc,
+ AvailabilityInfo Availability, const DocComment &Comment,
+ DeclarationFragments Declaration, DeclarationFragments SubHeading,
+ FunctionSignature Signature, AccessControl Access, Template Template,
+ bool IsFromSystemHeader);
+
+ CXXMethodTemplateSpecializationRecord *addCXXMethodTemplateSpec(
+ APIRecord *Parent, StringRef Name, StringRef USR, PresumedLoc Loc,
+ AvailabilityInfo Availability, const DocComment &Comment,
+ DeclarationFragments Declaration, DeclarationFragments SubHeading,
+ FunctionSignature Signature, AccessControl Access,
+ bool IsFromSystemHeader);
+
+ ConceptRecord *addConcept(StringRef Name, StringRef USR, PresumedLoc Loc,
+ AvailabilityInfo Availability,
+ const DocComment &Comment,
+ DeclarationFragments Declaration,
+ DeclarationFragments SubHeading, Template Template,
+ bool IsFromSystemHeader);
+
+ /// Create and add an Objective-C category record into the API set.
+ ///
+ /// Note: the caller is responsible for keeping the StringRef \p Name and
+ /// \p USR alive. APISet::copyString provides a way to copy strings into
+ /// APISet itself, and APISet::recordUSR(const Decl *D) is a helper method
+ /// to generate the USR for \c D and keep it alive in APISet.
+ ObjCCategoryRecord *
+ addObjCCategory(StringRef Name, StringRef USR, PresumedLoc Loc,
+ AvailabilityInfo Availability, const DocComment &Comment,
+ DeclarationFragments Declaration,
+ DeclarationFragments SubHeading, SymbolReference Interface,
+ bool IsFromSystemHeader, bool IsFromExternalModule);
+
+ /// Create and add an Objective-C interface record into the API set.
+ ///
+ /// Note: the caller is responsible for keeping the StringRef \p Name and
+ /// \p USR alive. APISet::copyString provides a way to copy strings into
+ /// APISet itself, and APISet::recordUSR(const Decl *D) is a helper method
+ /// to generate the USR for \c D and keep it alive in APISet.
+ ObjCInterfaceRecord *
+ addObjCInterface(StringRef Name, StringRef USR, PresumedLoc Loc,
+ AvailabilityInfo Availability, LinkageInfo Linkage,
+ const DocComment &Comment, DeclarationFragments Declaration,
+ DeclarationFragments SubHeading, SymbolReference SuperClass,
+ bool IsFromSystemHeader);
+
+ /// Create and add an Objective-C method record into the API set.
+ ///
+ /// Note: the caller is responsible for keeping the StringRef \p Name and
+ /// \p USR alive. APISet::copyString provides a way to copy strings into
+ /// APISet itself, and APISet::recordUSR(const Decl *D) is a helper method
+ /// to generate the USR for \c D and keep it alive in APISet.
+ ObjCMethodRecord *
+ addObjCMethod(ObjCContainerRecord *Container, StringRef Name, StringRef USR,
+ PresumedLoc Loc, AvailabilityInfo Availability,
+ const DocComment &Comment, DeclarationFragments Declaration,
+ DeclarationFragments SubHeading, FunctionSignature Signature,
+ bool IsInstanceMethod, bool IsFromSystemHeader);
+
+ /// Create and add an Objective-C property record into the API set.
+ ///
+ /// Note: the caller is responsible for keeping the StringRef \p Name and
+ /// \p USR alive. APISet::copyString provides a way to copy strings into
+ /// APISet itself, and APISet::recordUSR(const Decl *D) is a helper method
+ /// to generate the USR for \c D and keep it alive in APISet.
+ ObjCPropertyRecord *
+ addObjCProperty(ObjCContainerRecord *Container, StringRef Name, StringRef USR,
+ PresumedLoc Loc, AvailabilityInfo Availability,
+ const DocComment &Comment, DeclarationFragments Declaration,
+ DeclarationFragments SubHeading,
+ ObjCPropertyRecord::AttributeKind Attributes,
+ StringRef GetterName, StringRef SetterName, bool IsOptional,
+ bool IsInstanceProperty, bool IsFromSystemHeader);
+
+ /// Create and add an Objective-C instance variable record into the API set.
+ ///
+ /// Note: the caller is responsible for keeping the StringRef \p Name and
+ /// \p USR alive. APISet::copyString provides a way to copy strings into
+ /// APISet itself, and APISet::recordUSR(const Decl *D) is a helper method
+ /// to generate the USR for \c D and keep it alive in APISet.
+ ObjCInstanceVariableRecord *addObjCInstanceVariable(
+ ObjCContainerRecord *Container, StringRef Name, StringRef USR,
+ PresumedLoc Loc, AvailabilityInfo Availability, const DocComment &Comment,
+ DeclarationFragments Declaration, DeclarationFragments SubHeading,
+ ObjCInstanceVariableRecord::AccessControl Access,
+ bool IsFromSystemHeader);
+
+ /// Create and add an Objective-C protocol record into the API set.
+ ///
+ /// Note: the caller is responsible for keeping the StringRef \p Name and
+ /// \p USR alive. APISet::copyString provides a way to copy strings into
+ /// APISet itself, and APISet::recordUSR(const Decl *D) is a helper method
+ /// to generate the USR for \c D and keep it alive in APISet.
+ ObjCProtocolRecord *
+ addObjCProtocol(StringRef Name, StringRef USR, PresumedLoc Loc,
+ AvailabilityInfo Availability, const DocComment &Comment,
+ DeclarationFragments Declaration,
+ DeclarationFragments SubHeading, bool IsFromSystemHeader);
+
+ /// Create a macro definition record into the API set.
+ ///
+ /// Note: the caller is responsible for keeping the StringRef \p Name and
+ /// \p USR alive. APISet::copyString provides a way to copy strings into
+ /// APISet itself, and APISet::recordUSRForMacro(StringRef Name,
+ /// SourceLocation SL, const SourceManager &SM) is a helper method to generate
+ /// the USR for the macro and keep it alive in APISet.
+ MacroDefinitionRecord *addMacroDefinition(StringRef Name, StringRef USR,
+ PresumedLoc Loc,
+ DeclarationFragments Declaration,
+ DeclarationFragments SubHeading,
+ bool IsFromSystemHeader);
+
+ /// Create a typedef record into the API set.
+ ///
+ /// Note: the caller is responsible for keeping the StringRef \p Name and
+ /// \p USR alive. APISet::copyString provides a way to copy strings into
+ /// APISet itself, and APISet::recordUSR(const Decl *D) is a helper method
+ /// to generate the USR for \c D and keep it alive in APISet.
+ TypedefRecord *
+ addTypedef(StringRef Name, StringRef USR, PresumedLoc Loc,
+ AvailabilityInfo Availability, const DocComment &Comment,
+ DeclarationFragments Declaration, DeclarationFragments SubHeading,
+ SymbolReference UnderlyingType, bool IsFromSystemHeader);
+
+ /// A mapping type to store a set of APIRecord%s with the USR as the key.
+ template <typename RecordTy,
+ typename =
+ std::enable_if_t<std::is_base_of<APIRecord, RecordTy>::value>>
+ using RecordMap = llvm::MapVector<StringRef, std::unique_ptr<RecordTy>>;
+
+ /// Get the target triple for the ExtractAPI invocation.
+ const llvm::Triple &getTarget() const { return Target; }
+
+ /// Get the language used by the APIs.
+ Language getLanguage() const { return Lang; }
+
+ const RecordMap<NamespaceRecord> &getNamespaces() const { return Namespaces; }
+ const RecordMap<GlobalFunctionRecord> &getGlobalFunctions() const {
+ return GlobalFunctions;
+ }
+ const RecordMap<GlobalFunctionTemplateRecord> &
+ getGlobalFunctionTemplates() const {
+ return GlobalFunctionTemplates;
+ }
+ const RecordMap<GlobalFunctionTemplateSpecializationRecord> &
+ getGlobalFunctionTemplateSpecializations() const {
+ return GlobalFunctionTemplateSpecializations;
+ }
+ const RecordMap<GlobalVariableRecord> &getGlobalVariables() const {
+ return GlobalVariables;
+ }
+ const RecordMap<GlobalVariableTemplateRecord> &
+ getGlobalVariableTemplates() const {
+ return GlobalVariableTemplates;
+ }
+ const RecordMap<StaticFieldRecord> &getStaticFields() const {
+ return StaticFields;
+ }
+ const RecordMap<GlobalVariableTemplateSpecializationRecord> &
+ getGlobalVariableTemplateSpecializations() const {
+ return GlobalVariableTemplateSpecializations;
+ }
+ const RecordMap<GlobalVariableTemplatePartialSpecializationRecord> &
+ getGlobalVariableTemplatePartialSpecializations() const {
+ return GlobalVariableTemplatePartialSpecializations;
+ }
+ const RecordMap<EnumRecord> &getEnums() const { return Enums; }
+ const RecordMap<RecordRecord> &getRecords() const { return Records; }
+ const RecordMap<CXXClassRecord> &getCXXClasses() const { return CXXClasses; }
+ const RecordMap<CXXMethodTemplateRecord> &getCXXMethodTemplates() const {
+ return CXXMethodTemplates;
+ }
+ const RecordMap<CXXInstanceMethodRecord> &getCXXInstanceMethods() const {
+ return CXXInstanceMethods;
+ }
+ const RecordMap<CXXStaticMethodRecord> &getCXXStaticMethods() const {
+ return CXXStaticMethods;
+ }
+ const RecordMap<CXXFieldRecord> &getCXXFields() const { return CXXFields; }
+ const RecordMap<CXXMethodTemplateSpecializationRecord> &
+ getCXXMethodTemplateSpecializations() const {
+ return CXXMethodTemplateSpecializations;
+ }
+ const RecordMap<CXXFieldTemplateRecord> &getCXXFieldTemplates() const {
+ return CXXFieldTemplates;
+ }
+ const RecordMap<ClassTemplateRecord> &getClassTemplates() const {
+ return ClassTemplates;
+ }
+ const RecordMap<ClassTemplateSpecializationRecord> &
+ getClassTemplateSpecializations() const {
+ return ClassTemplateSpecializations;
+ }
+ const RecordMap<ClassTemplatePartialSpecializationRecord> &
+ getClassTemplatePartialSpecializations() const {
+ return ClassTemplatePartialSpecializations;
+ }
+ const RecordMap<ConceptRecord> &getConcepts() const { return Concepts; }
+ const RecordMap<ObjCCategoryRecord> &getObjCCategories() const {
+ return ObjCCategories;
+ }
+ const RecordMap<ObjCInterfaceRecord> &getObjCInterfaces() const {
+ return ObjCInterfaces;
+ }
+ const RecordMap<ObjCProtocolRecord> &getObjCProtocols() const {
+ return ObjCProtocols;
+ }
+ const RecordMap<MacroDefinitionRecord> &getMacros() const { return Macros; }
+ const RecordMap<TypedefRecord> &getTypedefs() const { return Typedefs; }
+
+ /// Finds the APIRecord for a given USR.
+ ///
+ /// \returns a pointer to the APIRecord associated with that USR or nullptr.
+ APIRecord *findRecordForUSR(StringRef USR) const;
+
+ /// Generate and store the USR of declaration \p D.
+ ///
+ /// Note: The USR string is stored in and owned by Allocator.
+ ///
+ /// \returns a StringRef of the generated USR string.
+ StringRef recordUSR(const Decl *D);
+
+ /// Generate and store the USR for a macro \p Name.
+ ///
+ /// Note: The USR string is stored in and owned by Allocator.
+ ///
+ /// \returns a StringRef to the generate USR string.
+ StringRef recordUSRForMacro(StringRef Name, SourceLocation SL,
+ const SourceManager &SM);
+
+ /// Copy \p String into the Allocator in this APISet.
+ ///
+ /// \returns a StringRef of the copied string in APISet::Allocator.
+ StringRef copyString(StringRef String);
+
+ APISet(const llvm::Triple &Target, Language Lang,
+ const std::string &ProductName)
+ : Target(Target), Lang(Lang), ProductName(ProductName) {}
+
+private:
+ /// BumpPtrAllocator to store generated/copied strings.
+ ///
+ /// Note: The main use for this is being able to deduplicate strings.
+ llvm::BumpPtrAllocator StringAllocator;
+
+ const llvm::Triple Target;
+ const Language Lang;
+
+ llvm::DenseMap<StringRef, APIRecord *> USRBasedLookupTable;
+ RecordMap<NamespaceRecord> Namespaces;
+ RecordMap<GlobalFunctionRecord> GlobalFunctions;
+ RecordMap<GlobalFunctionTemplateRecord> GlobalFunctionTemplates;
+ RecordMap<GlobalFunctionTemplateSpecializationRecord>
+ GlobalFunctionTemplateSpecializations;
+ RecordMap<GlobalVariableRecord> GlobalVariables;
+ RecordMap<GlobalVariableTemplateRecord> GlobalVariableTemplates;
+ RecordMap<GlobalVariableTemplateSpecializationRecord>
+ GlobalVariableTemplateSpecializations;
+ RecordMap<GlobalVariableTemplatePartialSpecializationRecord>
+ GlobalVariableTemplatePartialSpecializations;
+ RecordMap<ConceptRecord> Concepts;
+ RecordMap<StaticFieldRecord> StaticFields;
+ RecordMap<EnumRecord> Enums;
+ RecordMap<RecordRecord> Records;
+ RecordMap<CXXClassRecord> CXXClasses;
+ RecordMap<CXXFieldRecord> CXXFields;
+ RecordMap<CXXMethodRecord> CXXMethods;
+ RecordMap<CXXInstanceMethodRecord> CXXInstanceMethods;
+ RecordMap<CXXStaticMethodRecord> CXXStaticMethods;
+ RecordMap<CXXMethodTemplateRecord> CXXMethodTemplates;
+ RecordMap<CXXMethodTemplateSpecializationRecord>
+ CXXMethodTemplateSpecializations;
+ RecordMap<CXXFieldTemplateRecord> CXXFieldTemplates;
+ RecordMap<ClassTemplateRecord> ClassTemplates;
+ RecordMap<ClassTemplateSpecializationRecord> ClassTemplateSpecializations;
+ RecordMap<ClassTemplatePartialSpecializationRecord>
+ ClassTemplatePartialSpecializations;
+ RecordMap<ObjCCategoryRecord> ObjCCategories;
+ RecordMap<ObjCInterfaceRecord> ObjCInterfaces;
+ RecordMap<ObjCProtocolRecord> ObjCProtocols;
+ RecordMap<MacroDefinitionRecord> Macros;
+ RecordMap<TypedefRecord> Typedefs;
+
+public:
+ const std::string ProductName;
+};
+
+} // namespace extractapi
+} // namespace clang
+
+#endif // LLVM_CLANG_EXTRACTAPI_API_H
diff --git a/contrib/llvm-project/clang/include/clang/ExtractAPI/APIIgnoresList.h b/contrib/llvm-project/clang/include/clang/ExtractAPI/APIIgnoresList.h
new file mode 100644
index 000000000000..3eee8e336cb6
--- /dev/null
+++ b/contrib/llvm-project/clang/include/clang/ExtractAPI/APIIgnoresList.h
@@ -0,0 +1,76 @@
+//===- ExtractAPI/APIIgnoresList.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 defines APIIgnoresList which is a type that allows querying
+/// files containing symbols to ignore when extracting API information.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_API_IGNORES_LIST_H
+#define LLVM_CLANG_API_IGNORES_LIST_H
+
+#include "clang/Basic/FileManager.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/raw_ostream.h"
+
+#include <memory>
+#include <system_error>
+
+namespace llvm {
+class MemoryBuffer;
+} // namespace llvm
+
+namespace clang {
+namespace extractapi {
+
+struct IgnoresFileNotFound : public llvm::ErrorInfo<IgnoresFileNotFound> {
+ std::string Path;
+ static char ID;
+
+ explicit IgnoresFileNotFound(StringRef Path) : Path(Path) {}
+
+ virtual void log(llvm::raw_ostream &os) const override;
+
+ virtual std::error_code convertToErrorCode() const override;
+};
+
+/// A type that provides access to a new line separated list of symbol names to
+/// ignore when extracting API information.
+struct APIIgnoresList {
+ using FilePathList = std::vector<std::string>;
+
+ /// The API to use for generating from the files at \p IgnoresFilePathList.
+ ///
+ /// \returns an initialized APIIgnoresList or an Error.
+ static llvm::Expected<APIIgnoresList>
+ create(const FilePathList &IgnoresFilePathList, FileManager &FM);
+
+ APIIgnoresList() = default;
+
+ /// Check if \p SymbolName is specified in the APIIgnoresList and if it should
+ /// therefore be ignored.
+ bool shouldIgnore(llvm::StringRef SymbolName) const;
+
+private:
+ using SymbolNameList = llvm::SmallVector<llvm::StringRef, 32>;
+ using BufferList = llvm::SmallVector<std::unique_ptr<llvm::MemoryBuffer>>;
+
+ APIIgnoresList(SymbolNameList SymbolsToIgnore, BufferList Buffers)
+ : SymbolsToIgnore(std::move(SymbolsToIgnore)),
+ Buffers(std::move(Buffers)) {}
+
+ SymbolNameList SymbolsToIgnore;
+ BufferList Buffers;
+};
+
+} // namespace extractapi
+} // namespace clang
+
+#endif // LLVM_CLANG_API_IGNORES_LIST_H
diff --git a/contrib/llvm-project/clang/include/clang/ExtractAPI/AvailabilityInfo.h b/contrib/llvm-project/clang/include/clang/ExtractAPI/AvailabilityInfo.h
new file mode 100644
index 000000000000..3b8d6f46ed56
--- /dev/null
+++ b/contrib/llvm-project/clang/include/clang/ExtractAPI/AvailabilityInfo.h
@@ -0,0 +1,76 @@
+//===- ExtractAPI/AvailabilityInfo.h - Availability Info --------*- 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 defines the AvailabilityInfo struct that collects availability
+/// attributes of a symbol.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_EXTRACTAPI_AVAILABILITY_INFO_H
+#define LLVM_CLANG_EXTRACTAPI_AVAILABILITY_INFO_H
+
+#include "clang/AST/Decl.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/VersionTuple.h"
+#include "llvm/Support/raw_ostream.h"
+
+namespace clang {
+namespace extractapi {
+
+/// Stores availability attributes of a symbol.
+struct AvailabilityInfo {
+ /// The domain for which this availability info item applies
+ std::string Domain;
+ VersionTuple Introduced;
+ VersionTuple Deprecated;
+ VersionTuple Obsoleted;
+ bool UnconditionallyDeprecated = false;
+ bool UnconditionallyUnavailable = false;
+
+ AvailabilityInfo() = default;
+
+ /// Determine if this AvailabilityInfo represents the default availability.
+ bool isDefault() const { return *this == AvailabilityInfo(); }
+ /// Check if the symbol is unconditionally deprecated.
+ ///
+ /// i.e. \code __attribute__((deprecated)) \endcode
+ bool isUnconditionallyDeprecated() const { return UnconditionallyDeprecated; }
+ /// Check if the symbol is unconditionally unavailable.
+ ///
+ /// i.e. \code __attribute__((unavailable)) \endcode
+ bool isUnconditionallyUnavailable() const {
+ return UnconditionallyUnavailable;
+ }
+
+ AvailabilityInfo(StringRef Domain, VersionTuple I, VersionTuple D,
+ VersionTuple O, bool UD, bool UU)
+ : Domain(Domain), Introduced(I), Deprecated(D), Obsoleted(O),
+ UnconditionallyDeprecated(UD), UnconditionallyUnavailable(UU) {}
+
+ friend bool operator==(const AvailabilityInfo &Lhs,
+ const AvailabilityInfo &Rhs);
+
+public:
+ static AvailabilityInfo createFromDecl(const Decl *Decl);
+};
+
+inline bool operator==(const AvailabilityInfo &Lhs,
+ const AvailabilityInfo &Rhs) {
+ return std::tie(Lhs.Introduced, Lhs.Deprecated, Lhs.Obsoleted,
+ Lhs.UnconditionallyDeprecated,
+ Lhs.UnconditionallyUnavailable) ==
+ std::tie(Rhs.Introduced, Rhs.Deprecated, Rhs.Obsoleted,
+ Rhs.UnconditionallyDeprecated,
+ Rhs.UnconditionallyUnavailable);
+}
+
+} // namespace extractapi
+} // namespace clang
+
+#endif // LLVM_CLANG_EXTRACTAPI_AVAILABILITY_INFO_H
diff --git a/contrib/llvm-project/clang/include/clang/ExtractAPI/DeclarationFragments.h b/contrib/llvm-project/clang/include/clang/ExtractAPI/DeclarationFragments.h
new file mode 100644
index 000000000000..1b78c8b5931e
--- /dev/null
+++ b/contrib/llvm-project/clang/include/clang/ExtractAPI/DeclarationFragments.h
@@ -0,0 +1,454 @@
+//===- ExtractAPI/DeclarationFragments.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 defines the Declaration Fragments related classes.
+///
+/// Declaration Fragments represent parts of a symbol declaration tagged with
+/// syntactic/semantic information.
+/// See https://github.com/apple/swift-docc-symbolkit
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_EXTRACTAPI_DECLARATION_FRAGMENTS_H
+#define LLVM_CLANG_EXTRACTAPI_DECLARATION_FRAGMENTS_H
+
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclCXX.h"
+#include "clang/AST/DeclObjC.h"
+#include "clang/AST/DeclTemplate.h"
+#include "clang/AST/ExprCXX.h"
+#include "clang/AST/TypeLoc.h"
+#include "clang/Basic/Specifiers.h"
+#include "clang/Lex/MacroInfo.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
+#include <vector>
+
+namespace clang {
+namespace extractapi {
+
+/// DeclarationFragments is a vector of tagged important parts of a symbol's
+/// declaration.
+///
+/// The fragments sequence can be joined to form spans of declaration text, with
+/// attached information useful for purposes like syntax-highlighting etc.
+/// For example:
+/// \code
+/// const -> keyword "const"
+/// int -> type "int"
+/// pi; -> identifier "pi"
+/// \endcode
+class DeclarationFragments {
+public:
+ DeclarationFragments() = default;
+
+ /// The kind of a fragment.
+ enum class FragmentKind {
+ /// Unknown fragment kind.
+ None,
+
+ Keyword,
+ Attribute,
+ NumberLiteral,
+ StringLiteral,
+ Identifier,
+
+ /// Identifier that refers to a type in the context.
+ TypeIdentifier,
+
+ /// Parameter that's used as generics in the context. For example template
+ /// parameters.
+ GenericParameter,
+
+ /// External parameters in Objective-C methods.
+ /// For example, \c forKey in
+ /// \code{.m}
+ /// - (void) setValue:(Value)value forKey(Key)key
+ /// \endcode
+ ExternalParam,
+
+ /// Internal/local parameters in Objective-C methods.
+ /// For example, \c key in
+ /// \code{.m}
+ /// - (void) setValue:(Value)value forKey(Key)key
+ /// \endcode
+ InternalParam,
+
+ Text,
+ };
+
+ /// Fragment holds information of a single fragment.
+ struct Fragment {
+ std::string Spelling;
+ FragmentKind Kind;
+
+ /// The USR of the fragment symbol, if applicable.
+ std::string PreciseIdentifier;
+
+ /// The associated declaration, if applicable. This is not intended to be
+ /// used outside of libclang.
+ const Decl *Declaration;
+
+ Fragment(StringRef Spelling, FragmentKind Kind, StringRef PreciseIdentifier,
+ const Decl *Declaration)
+ : Spelling(Spelling), Kind(Kind), PreciseIdentifier(PreciseIdentifier),
+ Declaration(Declaration) {}
+ };
+
+ using FragmentIterator = std::vector<Fragment>::iterator;
+ using ConstFragmentIterator = std::vector<Fragment>::const_iterator;
+
+ const std::vector<Fragment> &getFragments() const { return Fragments; }
+
+ FragmentIterator begin() { return Fragments.begin(); }
+
+ FragmentIterator end() { return Fragments.end(); }
+
+ ConstFragmentIterator cbegin() const { return Fragments.cbegin(); }
+
+ ConstFragmentIterator cend() const { return Fragments.cend(); }
+
+ // Add a new Fragment at an arbitrary offset.
+ DeclarationFragments &insert(FragmentIterator It, StringRef Spelling,
+ FragmentKind Kind,
+ StringRef PreciseIdentifier = "",
+ const Decl *Declaration = nullptr) {
+ Fragments.insert(It,
+ Fragment(Spelling, Kind, PreciseIdentifier, Declaration));
+ return *this;
+ }
+
+ DeclarationFragments &insert(FragmentIterator It,
+ DeclarationFragments &&Other) {
+ Fragments.insert(It, std::make_move_iterator(Other.Fragments.begin()),
+ std::make_move_iterator(Other.Fragments.end()));
+ Other.Fragments.clear();
+ return *this;
+ }
+
+ /// Append a new Fragment to the end of the Fragments.
+ ///
+ /// \returns a reference to the DeclarationFragments object itself after
+ /// appending to chain up consecutive appends.
+ DeclarationFragments &append(StringRef Spelling, FragmentKind Kind,
+ StringRef PreciseIdentifier = "",
+ const Decl *Declaration = nullptr) {
+ if (Kind == FragmentKind::Text && !Fragments.empty() &&
+ Fragments.back().Kind == FragmentKind::Text) {
+ // If appending a text fragment, and the last fragment is also text,
+ // merge into the last fragment.
+ Fragments.back().Spelling.append(Spelling.data(), Spelling.size());
+ } else {
+ Fragments.emplace_back(Spelling, Kind, PreciseIdentifier, Declaration);
+ }
+ return *this;
+ }
+
+ /// Append another DeclarationFragments to the end.
+ ///
+ /// Note: \p Other is moved from and cannot be used after a call to this
+ /// method.
+ ///
+ /// \returns a reference to the DeclarationFragments object itself after
+ /// appending to chain up consecutive appends.
+ DeclarationFragments &append(DeclarationFragments &&Other) {
+ Fragments.insert(Fragments.end(),
+ std::make_move_iterator(Other.Fragments.begin()),
+ std::make_move_iterator(Other.Fragments.end()));
+ Other.Fragments.clear();
+ return *this;
+ }
+
+ DeclarationFragments &pop_back() {
+ Fragments.pop_back();
+ return *this;
+ }
+
+ DeclarationFragments &replace(std::string NewSpelling, unsigned Position) {
+ Fragments.at(Position).Spelling = NewSpelling;
+ return *this;
+ }
+
+ /// Append a text Fragment of a space character.
+ ///
+ /// \returns a reference to the DeclarationFragments object itself after
+ /// appending to chain up consecutive appends.
+ DeclarationFragments &appendSpace();
+
+ /// Get the string description of a FragmentKind \p Kind.
+ static StringRef getFragmentKindString(FragmentKind Kind);
+
+ /// Get the corresponding FragmentKind from string \p S.
+ static FragmentKind parseFragmentKindFromString(StringRef S);
+
+ static DeclarationFragments
+ getExceptionSpecificationString(ExceptionSpecificationType ExceptionSpec);
+
+ static DeclarationFragments getStructureTypeFragment(const RecordDecl *Decl);
+
+private:
+ std::vector<Fragment> Fragments;
+};
+
+class AccessControl {
+public:
+ AccessControl(std::string Access) : Access(Access) {}
+
+ const std::string &getAccess() const { return Access; }
+
+ bool empty() const { return Access.empty(); }
+
+private:
+ std::string Access;
+};
+
+/// Store function signature information with DeclarationFragments of the
+/// return type and parameters.
+class FunctionSignature {
+public:
+ FunctionSignature() = default;
+
+ /// Parameter holds the name and DeclarationFragments of a single parameter.
+ struct Parameter {
+ std::string Name;
+ DeclarationFragments Fragments;
+
+ Parameter(StringRef Name, DeclarationFragments Fragments)
+ : Name(Name), Fragments(Fragments) {}
+ };
+
+ const std::vector<Parameter> &getParameters() const { return Parameters; }
+ const DeclarationFragments &getReturnType() const { return ReturnType; }
+
+ FunctionSignature &addParameter(StringRef Name,
+ DeclarationFragments Fragments) {
+ Parameters.emplace_back(Name, Fragments);
+ return *this;
+ }
+
+ void setReturnType(DeclarationFragments RT) { ReturnType = RT; }
+
+ /// Determine if the FunctionSignature is empty.
+ ///
+ /// \returns true if the return type DeclarationFragments is empty and there
+ /// is no parameter, otherwise false.
+ bool empty() const {
+ return Parameters.empty() && ReturnType.getFragments().empty();
+ }
+
+private:
+ std::vector<Parameter> Parameters;
+ DeclarationFragments ReturnType;
+};
+
+/// A factory class to build DeclarationFragments for different kinds of Decl.
+class DeclarationFragmentsBuilder {
+public:
+ /// Build FunctionSignature for a function-like declaration \c FunctionT like
+ /// FunctionDecl, ObjCMethodDecl, or CXXMethodDecl.
+ ///
+ /// The logic and implementation of building a signature for a FunctionDecl,
+ /// CXXMethodDecl, and ObjCMethodDecl are exactly the same, but they do not
+ /// share a common base. This template helps reuse the code.
+ template <typename FunctionT>
+ static FunctionSignature getFunctionSignature(const FunctionT *Function);
+
+ static AccessControl getAccessControl(const Decl *Decl) {
+ switch (Decl->getAccess()) {
+ case AS_public:
+ case AS_none:
+ return AccessControl("public");
+ case AS_private:
+ return AccessControl("private");
+ case AS_protected:
+ return AccessControl("protected");
+ }
+ llvm_unreachable("Unhandled access control");
+ }
+
+ static DeclarationFragments
+ getFragmentsForNamespace(const NamespaceDecl *Decl);
+
+ /// Build DeclarationFragments for a variable declaration VarDecl.
+ static DeclarationFragments getFragmentsForVar(const VarDecl *);
+
+ static DeclarationFragments getFragmentsForVarTemplate(const VarDecl *);
+
+ /// Build DeclarationFragments for a function declaration FunctionDecl.
+ static DeclarationFragments getFragmentsForFunction(const FunctionDecl *);
+
+ /// Build DeclarationFragments for an enum constant declaration
+ /// EnumConstantDecl.
+ static DeclarationFragments
+ getFragmentsForEnumConstant(const EnumConstantDecl *);
+
+ /// Build DeclarationFragments for an enum declaration EnumDecl.
+ static DeclarationFragments getFragmentsForEnum(const EnumDecl *);
+
+ /// Build DeclarationFragments for a field declaration FieldDecl.
+ static DeclarationFragments getFragmentsForField(const FieldDecl *);
+
+ /// Build DeclarationFragments for a struct/union record declaration
+ /// RecordDecl.
+ static DeclarationFragments getFragmentsForRecordDecl(const RecordDecl *);
+
+ static DeclarationFragments getFragmentsForCXXClass(const CXXRecordDecl *);
+
+ static DeclarationFragments
+ getFragmentsForSpecialCXXMethod(const CXXMethodDecl *);
+
+ static DeclarationFragments getFragmentsForCXXMethod(const CXXMethodDecl *);
+
+ static DeclarationFragments
+ getFragmentsForConversionFunction(const CXXConversionDecl *);
+
+ static DeclarationFragments
+ getFragmentsForOverloadedOperator(const CXXMethodDecl *);
+
+ static DeclarationFragments
+ getFragmentsForTemplateParameters(ArrayRef<NamedDecl *>);
+
+ static std::string
+ getNameForTemplateArgument(const ArrayRef<NamedDecl *>, std::string);
+
+ static DeclarationFragments
+ getFragmentsForTemplateArguments(const ArrayRef<TemplateArgument>,
+ ASTContext &,
+ const std::optional<ArrayRef<NamedDecl *>>);
+
+ static DeclarationFragments getFragmentsForConcept(const ConceptDecl *);
+
+ static DeclarationFragments
+ getFragmentsForRedeclarableTemplate(const RedeclarableTemplateDecl *);
+
+ static DeclarationFragments getFragmentsForClassTemplateSpecialization(
+ const ClassTemplateSpecializationDecl *);
+
+ static DeclarationFragments getFragmentsForClassTemplatePartialSpecialization(
+ const ClassTemplatePartialSpecializationDecl *);
+
+ static DeclarationFragments getFragmentsForVarTemplateSpecialization(
+ const VarTemplateSpecializationDecl *);
+
+ static DeclarationFragments getFragmentsForVarTemplatePartialSpecialization(
+ const VarTemplatePartialSpecializationDecl *);
+
+ static DeclarationFragments
+ getFragmentsForFunctionTemplate(const FunctionTemplateDecl *Decl);
+
+ static DeclarationFragments
+ getFragmentsForFunctionTemplateSpecialization(const FunctionDecl *Decl);
+
+ /// Build DeclarationFragments for an Objective-C category declaration
+ /// ObjCCategoryDecl.
+ static DeclarationFragments
+ getFragmentsForObjCCategory(const ObjCCategoryDecl *);
+
+ /// Build DeclarationFragments for an Objective-C interface declaration
+ /// ObjCInterfaceDecl.
+ static DeclarationFragments
+ getFragmentsForObjCInterface(const ObjCInterfaceDecl *);
+
+ /// Build DeclarationFragments for an Objective-C method declaration
+ /// ObjCMethodDecl.
+ static DeclarationFragments getFragmentsForObjCMethod(const ObjCMethodDecl *);
+
+ /// Build DeclarationFragments for an Objective-C property declaration
+ /// ObjCPropertyDecl.
+ static DeclarationFragments
+ getFragmentsForObjCProperty(const ObjCPropertyDecl *);
+
+ /// Build DeclarationFragments for an Objective-C protocol declaration
+ /// ObjCProtocolDecl.
+ static DeclarationFragments
+ getFragmentsForObjCProtocol(const ObjCProtocolDecl *);
+
+ /// Build DeclarationFragments for a macro.
+ ///
+ /// \param Name name of the macro.
+ /// \param MD the associated MacroDirective.
+ static DeclarationFragments getFragmentsForMacro(StringRef Name,
+ const MacroDirective *MD);
+
+ /// Build DeclarationFragments for a typedef \p TypedefNameDecl.
+ static DeclarationFragments
+ getFragmentsForTypedef(const TypedefNameDecl *Decl);
+
+ /// Build sub-heading fragments for a NamedDecl.
+ static DeclarationFragments getSubHeading(const NamedDecl *);
+
+ /// Build sub-heading fragments for an Objective-C method.
+ static DeclarationFragments getSubHeading(const ObjCMethodDecl *);
+
+ /// Build a sub-heading for macro \p Name.
+ static DeclarationFragments getSubHeadingForMacro(StringRef Name);
+
+private:
+ DeclarationFragmentsBuilder() = delete;
+
+ /// Build DeclarationFragments for a QualType.
+ static DeclarationFragments getFragmentsForType(const QualType, ASTContext &,
+ DeclarationFragments &);
+
+ /// Build DeclarationFragments for a Type.
+ static DeclarationFragments getFragmentsForType(const Type *, ASTContext &,
+ DeclarationFragments &);
+
+ /// Build DeclarationFragments for a NestedNameSpecifier.
+ static DeclarationFragments getFragmentsForNNS(const NestedNameSpecifier *,
+ ASTContext &,
+ DeclarationFragments &);
+
+ /// Build DeclarationFragments for Qualifiers.
+ static DeclarationFragments getFragmentsForQualifiers(const Qualifiers quals);
+
+ /// Build DeclarationFragments for a parameter variable declaration
+ /// ParmVarDecl.
+ static DeclarationFragments getFragmentsForParam(const ParmVarDecl *);
+
+ static DeclarationFragments
+ getFragmentsForBlock(const NamedDecl *BlockDecl, FunctionTypeLoc &Block,
+ FunctionProtoTypeLoc &BlockProto,
+ DeclarationFragments &After);
+};
+
+template <typename FunctionT>
+FunctionSignature
+DeclarationFragmentsBuilder::getFunctionSignature(const FunctionT *Function) {
+ FunctionSignature Signature;
+
+ DeclarationFragments ReturnType, After;
+ ReturnType = getFragmentsForType(Function->getReturnType(),
+ Function->getASTContext(), After);
+ if (isa<FunctionDecl>(Function) &&
+ dyn_cast<FunctionDecl>(Function)->getDescribedFunctionTemplate() &&
+ ReturnType.begin()->Spelling.substr(0, 14).compare("type-parameter") ==
+ 0) {
+ std::string ProperArgName =
+ getNameForTemplateArgument(dyn_cast<FunctionDecl>(Function)
+ ->getDescribedFunctionTemplate()
+ ->getTemplateParameters()
+ ->asArray(),
+ ReturnType.begin()->Spelling);
+ ReturnType.begin()->Spelling.swap(ProperArgName);
+ }
+ ReturnType.append(std::move(After));
+ Signature.setReturnType(ReturnType);
+
+ for (const auto *Param : Function->parameters())
+ Signature.addParameter(Param->getName(), getFragmentsForParam(Param));
+
+ return Signature;
+}
+
+} // namespace extractapi
+} // namespace clang
+
+#endif // LLVM_CLANG_EXTRACTAPI_DECLARATION_FRAGMENTS_H
diff --git a/contrib/llvm-project/clang/include/clang/ExtractAPI/ExtractAPIActionBase.h b/contrib/llvm-project/clang/include/clang/ExtractAPI/ExtractAPIActionBase.h
new file mode 100644
index 000000000000..ac4f391db5f1
--- /dev/null
+++ b/contrib/llvm-project/clang/include/clang/ExtractAPI/ExtractAPIActionBase.h
@@ -0,0 +1,54 @@
+//===- ExtractAPI/ExtractAPIActionBase.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 defines the ExtractAPIActionBase class.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_EXTRACTAPI_ACTION_BASE_H
+#define LLVM_CLANG_EXTRACTAPI_ACTION_BASE_H
+
+#include "clang/ExtractAPI/API.h"
+#include "clang/ExtractAPI/APIIgnoresList.h"
+
+namespace clang {
+
+/// Base class to be used by front end actions to generate ExtarctAPI info
+///
+/// Deriving from this class equips an action with all the necessary tools to
+/// generate ExractAPI information in form of symbol-graphs
+class ExtractAPIActionBase {
+protected:
+ /// A representation of the APIs this action extracts.
+ std::unique_ptr<extractapi::APISet> API;
+
+ /// A stream to the output file of this action.
+ std::unique_ptr<raw_pwrite_stream> OS;
+
+ /// The product this action is extracting API information for.
+ std::string ProductName;
+
+ /// The synthesized input buffer that contains all the provided input header
+ /// files.
+ std::unique_ptr<llvm::MemoryBuffer> Buffer;
+
+ /// The list of symbols to ignore during serialization
+ extractapi::APIIgnoresList IgnoresList;
+
+ /// Implements EndSourceFileAction for Symbol-Graph generation
+ ///
+ /// Use the serializer to generate output symbol graph files from
+ /// the information gathered during the execution of Action.
+ void ImplEndSourceFileAction();
+};
+
+} // namespace clang
+
+#endif // LLVM_CLANG_EXTRACTAPI_ACTION_BASE_H
diff --git a/contrib/llvm-project/clang/include/clang/ExtractAPI/ExtractAPIVisitor.h b/contrib/llvm-project/clang/include/clang/ExtractAPI/ExtractAPIVisitor.h
new file mode 100644
index 000000000000..ac6f4e313540
--- /dev/null
+++ b/contrib/llvm-project/clang/include/clang/ExtractAPI/ExtractAPIVisitor.h
@@ -0,0 +1,1426 @@
+//===- ExtractAPI/ExtractAPIVisitor.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 defines the ExtractAPVisitor AST visitation interface.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_EXTRACTAPI_EXTRACT_API_VISITOR_H
+#define LLVM_CLANG_EXTRACTAPI_EXTRACT_API_VISITOR_H
+
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclCXX.h"
+#include "clang/AST/DeclTemplate.h"
+#include "clang/Basic/OperatorKinds.h"
+#include "clang/Basic/Specifiers.h"
+#include "clang/ExtractAPI/AvailabilityInfo.h"
+#include "clang/ExtractAPI/DeclarationFragments.h"
+#include "llvm/ADT/FunctionExtras.h"
+
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/ParentMapContext.h"
+#include "clang/AST/RecursiveASTVisitor.h"
+#include "clang/Basic/SourceManager.h"
+#include "clang/ExtractAPI/API.h"
+#include "clang/ExtractAPI/TypedefUnderlyingTypeResolver.h"
+#include "clang/Index/USRGeneration.h"
+#include "llvm/ADT/StringRef.h"
+#include <type_traits>
+
+namespace clang {
+namespace extractapi {
+namespace impl {
+
+template <typename Derived>
+class ExtractAPIVisitorBase : public RecursiveASTVisitor<Derived> {
+protected:
+ ExtractAPIVisitorBase(ASTContext &Context, APISet &API)
+ : Context(Context), API(API) {}
+
+public:
+ const APISet &getAPI() const { return API; }
+
+ bool VisitVarDecl(const VarDecl *Decl);
+
+ bool VisitFunctionDecl(const FunctionDecl *Decl);
+
+ bool VisitEnumDecl(const EnumDecl *Decl);
+
+ bool WalkUpFromFunctionDecl(const FunctionDecl *Decl);
+
+ bool WalkUpFromRecordDecl(const RecordDecl *Decl);
+
+ bool WalkUpFromCXXRecordDecl(const CXXRecordDecl *Decl);
+
+ bool WalkUpFromCXXMethodDecl(const CXXMethodDecl *Decl);
+
+ bool WalkUpFromClassTemplateSpecializationDecl(
+ const ClassTemplateSpecializationDecl *Decl);
+
+ bool WalkUpFromClassTemplatePartialSpecializationDecl(
+ const ClassTemplatePartialSpecializationDecl *Decl);
+
+ bool WalkUpFromVarTemplateDecl(const VarTemplateDecl *Decl);
+
+ bool WalkUpFromVarTemplateSpecializationDecl(
+ const VarTemplateSpecializationDecl *Decl);
+
+ bool WalkUpFromVarTemplatePartialSpecializationDecl(
+ const VarTemplatePartialSpecializationDecl *Decl);
+
+ bool WalkUpFromFunctionTemplateDecl(const FunctionTemplateDecl *Decl);
+
+ bool WalkUpFromNamespaceDecl(const NamespaceDecl *Decl);
+
+ bool VisitNamespaceDecl(const NamespaceDecl *Decl);
+
+ bool VisitRecordDecl(const RecordDecl *Decl);
+
+ bool VisitCXXRecordDecl(const CXXRecordDecl *Decl);
+
+ bool VisitCXXMethodDecl(const CXXMethodDecl *Decl);
+
+ bool VisitFieldDecl(const FieldDecl *Decl);
+
+ bool VisitCXXConversionDecl(const CXXConversionDecl *Decl);
+
+ bool VisitCXXConstructorDecl(const CXXConstructorDecl *Decl);
+
+ bool VisitCXXDestructorDecl(const CXXDestructorDecl *Decl);
+
+ bool VisitConceptDecl(const ConceptDecl *Decl);
+
+ bool VisitClassTemplateSpecializationDecl(
+ const ClassTemplateSpecializationDecl *Decl);
+
+ bool VisitClassTemplatePartialSpecializationDecl(
+ const ClassTemplatePartialSpecializationDecl *Decl);
+
+ bool VisitVarTemplateDecl(const VarTemplateDecl *Decl);
+
+ bool
+ VisitVarTemplateSpecializationDecl(const VarTemplateSpecializationDecl *Decl);
+
+ bool VisitVarTemplatePartialSpecializationDecl(
+ const VarTemplatePartialSpecializationDecl *Decl);
+
+ bool VisitFunctionTemplateDecl(const FunctionTemplateDecl *Decl);
+
+ bool VisitObjCInterfaceDecl(const ObjCInterfaceDecl *Decl);
+
+ bool VisitObjCProtocolDecl(const ObjCProtocolDecl *Decl);
+
+ bool VisitTypedefNameDecl(const TypedefNameDecl *Decl);
+
+ bool VisitObjCCategoryDecl(const ObjCCategoryDecl *Decl);
+
+ bool shouldDeclBeIncluded(const Decl *Decl) const;
+
+ const RawComment *fetchRawCommentForDecl(const Decl *Decl) const;
+
+protected:
+ /// Collect API information for the enum constants and associate with the
+ /// parent enum.
+ void recordEnumConstants(EnumRecord *EnumRecord,
+ const EnumDecl::enumerator_range Constants);
+
+ /// Collect API information for the record fields and associate with the
+ /// parent struct.
+ void recordRecordFields(RecordRecord *RecordRecord,
+ APIRecord::RecordKind FieldKind,
+ const RecordDecl::field_range Fields);
+
+ /// Collect API information for the Objective-C methods and associate with the
+ /// parent container.
+ void recordObjCMethods(ObjCContainerRecord *Container,
+ const ObjCContainerDecl::method_range Methods);
+
+ void recordObjCProperties(ObjCContainerRecord *Container,
+ const ObjCContainerDecl::prop_range Properties);
+
+ void recordObjCInstanceVariables(
+ ObjCContainerRecord *Container,
+ const llvm::iterator_range<
+ DeclContext::specific_decl_iterator<ObjCIvarDecl>>
+ Ivars);
+
+ void recordObjCProtocols(ObjCContainerRecord *Container,
+ ObjCInterfaceDecl::protocol_range Protocols);
+
+ ASTContext &Context;
+ APISet &API;
+
+ StringRef getTypedefName(const TagDecl *Decl) {
+ if (const auto *TypedefDecl = Decl->getTypedefNameForAnonDecl())
+ return TypedefDecl->getName();
+
+ return {};
+ }
+
+ bool isInSystemHeader(const Decl *D) {
+ return Context.getSourceManager().isInSystemHeader(D->getLocation());
+ }
+
+private:
+ Derived &getDerivedExtractAPIVisitor() {
+ return *static_cast<Derived *>(this);
+ }
+
+ SmallVector<SymbolReference> getBases(const CXXRecordDecl *Decl) {
+ // FIXME: store AccessSpecifier given by inheritance
+ SmallVector<SymbolReference> Bases;
+ for (const auto &BaseSpecifier : Decl->bases()) {
+ // skip classes not inherited as public
+ if (BaseSpecifier.getAccessSpecifier() != AccessSpecifier::AS_public)
+ continue;
+ SymbolReference BaseClass;
+ if (BaseSpecifier.getType().getTypePtr()->isTemplateTypeParmType()) {
+ BaseClass.Name = API.copyString(BaseSpecifier.getType().getAsString());
+ BaseClass.USR = API.recordUSR(
+ BaseSpecifier.getType()->getAs<TemplateTypeParmType>()->getDecl());
+ } else {
+ CXXRecordDecl *BaseClassDecl =
+ BaseSpecifier.getType().getTypePtr()->getAsCXXRecordDecl();
+ BaseClass.Name = BaseClassDecl->getName();
+ BaseClass.USR = API.recordUSR(BaseClassDecl);
+ }
+ Bases.emplace_back(BaseClass);
+ }
+ return Bases;
+ }
+
+ APIRecord *determineParentRecord(const DeclContext *Context) {
+ SmallString<128> ParentUSR;
+ if (Context->getDeclKind() == Decl::TranslationUnit)
+ return nullptr;
+
+ index::generateUSRForDecl(dyn_cast<Decl>(Context), ParentUSR);
+
+ APIRecord *Parent = API.findRecordForUSR(ParentUSR);
+ return Parent;
+ }
+};
+
+template <typename T>
+static void modifyRecords(const T &Records, const StringRef &Name) {
+ for (const auto &Record : Records) {
+ if (Name == Record.second.get()->Name) {
+ auto &DeclFragment = Record.second->Declaration;
+ DeclFragment.insert(DeclFragment.begin(), " ",
+ DeclarationFragments::FragmentKind::Text);
+ DeclFragment.insert(DeclFragment.begin(), "typedef",
+ DeclarationFragments::FragmentKind::Keyword, "",
+ nullptr);
+ DeclFragment.insert(--DeclFragment.end(), " { ... } ",
+ DeclarationFragments::FragmentKind::Text);
+ DeclFragment.insert(--DeclFragment.end(), Name,
+ DeclarationFragments::FragmentKind::Identifier);
+ break;
+ }
+ }
+}
+
+template <typename Derived>
+bool ExtractAPIVisitorBase<Derived>::VisitVarDecl(const VarDecl *Decl) {
+ // skip function parameters.
+ if (isa<ParmVarDecl>(Decl))
+ return true;
+
+ // Skip non-global variables in records (struct/union/class) but not static
+ // members.
+ if (Decl->getDeclContext()->isRecord() && !Decl->isStaticDataMember())
+ return true;
+
+ // Skip local variables inside function or method.
+ if (!Decl->isDefinedOutsideFunctionOrMethod())
+ return true;
+
+ // If this is a template but not specialization or instantiation, skip.
+ if (Decl->getASTContext().getTemplateOrSpecializationInfo(Decl) &&
+ Decl->getTemplateSpecializationKind() == TSK_Undeclared)
+ return true;
+
+ if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
+ return true;
+
+ // Collect symbol information.
+ StringRef Name = Decl->getName();
+ StringRef USR = API.recordUSR(Decl);
+ PresumedLoc Loc =
+ Context.getSourceManager().getPresumedLoc(Decl->getLocation());
+ LinkageInfo Linkage = Decl->getLinkageAndVisibility();
+ DocComment Comment;
+ if (auto *RawComment =
+ getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
+ Comment = RawComment->getFormattedLines(Context.getSourceManager(),
+ Context.getDiagnostics());
+
+ // Build declaration fragments and sub-heading for the variable.
+ DeclarationFragments Declaration =
+ DeclarationFragmentsBuilder::getFragmentsForVar(Decl);
+ DeclarationFragments SubHeading =
+ DeclarationFragmentsBuilder::getSubHeading(Decl);
+ if (Decl->isStaticDataMember()) {
+ SymbolReference Context;
+ // getDeclContext() should return a RecordDecl since we
+ // are currently handling a static data member.
+ auto *Record = cast<RecordDecl>(Decl->getDeclContext());
+ Context.Name = Record->getName();
+ Context.USR = API.recordUSR(Record);
+ auto Access = DeclarationFragmentsBuilder::getAccessControl(Decl);
+ API.addStaticField(Name, USR, Loc, AvailabilityInfo::createFromDecl(Decl),
+ Linkage, Comment, Declaration, SubHeading, Context,
+ Access, isInSystemHeader(Decl));
+ } else
+ // Add the global variable record to the API set.
+ API.addGlobalVar(Name, USR, Loc, AvailabilityInfo::createFromDecl(Decl),
+ Linkage, Comment, Declaration, SubHeading,
+ isInSystemHeader(Decl));
+ return true;
+}
+
+template <typename Derived>
+bool ExtractAPIVisitorBase<Derived>::VisitFunctionDecl(
+ const FunctionDecl *Decl) {
+ if (const auto *Method = dyn_cast<CXXMethodDecl>(Decl)) {
+ // Skip member function in class templates.
+ if (Method->getParent()->getDescribedClassTemplate() != nullptr)
+ return true;
+
+ // Skip methods in records.
+ for (const auto &P : Context.getParents(*Method)) {
+ if (P.template get<CXXRecordDecl>())
+ return true;
+ }
+
+ // Skip ConstructorDecl and DestructorDecl.
+ if (isa<CXXConstructorDecl>(Method) || isa<CXXDestructorDecl>(Method))
+ return true;
+ }
+
+ // Skip templated functions.
+ switch (Decl->getTemplatedKind()) {
+ case FunctionDecl::TK_NonTemplate:
+ case FunctionDecl::TK_DependentNonTemplate:
+ case FunctionDecl::TK_FunctionTemplateSpecialization:
+ break;
+ case FunctionDecl::TK_FunctionTemplate:
+ case FunctionDecl::TK_DependentFunctionTemplateSpecialization:
+ case FunctionDecl::TK_MemberSpecialization:
+ return true;
+ }
+
+ if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
+ return true;
+
+ // Collect symbol information.
+ StringRef Name = Decl->getName();
+ StringRef USR = API.recordUSR(Decl);
+ PresumedLoc Loc =
+ Context.getSourceManager().getPresumedLoc(Decl->getLocation());
+ LinkageInfo Linkage = Decl->getLinkageAndVisibility();
+ DocComment Comment;
+ if (auto *RawComment =
+ getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
+ Comment = RawComment->getFormattedLines(Context.getSourceManager(),
+ Context.getDiagnostics());
+
+ // Build declaration fragments, sub-heading, and signature of the function.
+ DeclarationFragments SubHeading =
+ DeclarationFragmentsBuilder::getSubHeading(Decl);
+ FunctionSignature Signature =
+ DeclarationFragmentsBuilder::getFunctionSignature(Decl);
+ if (Decl->getTemplateSpecializationInfo())
+ API.addGlobalFunctionTemplateSpecialization(
+ Name, USR, Loc, AvailabilityInfo::createFromDecl(Decl), Linkage,
+ Comment,
+ DeclarationFragmentsBuilder::
+ getFragmentsForFunctionTemplateSpecialization(Decl),
+ SubHeading, Signature, isInSystemHeader(Decl));
+ else
+ // Add the function record to the API set.
+ API.addGlobalFunction(
+ Name, USR, Loc, AvailabilityInfo::createFromDecl(Decl), Linkage,
+ Comment, DeclarationFragmentsBuilder::getFragmentsForFunction(Decl),
+ SubHeading, Signature, isInSystemHeader(Decl));
+ return true;
+}
+
+template <typename Derived>
+bool ExtractAPIVisitorBase<Derived>::VisitEnumDecl(const EnumDecl *Decl) {
+ if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
+ return true;
+
+ SmallString<128> QualifiedNameBuffer;
+ // Collect symbol information.
+ StringRef Name = Decl->getName();
+ if (Name.empty())
+ Name = getTypedefName(Decl);
+ if (Name.empty()) {
+ llvm::raw_svector_ostream OS(QualifiedNameBuffer);
+ Decl->printQualifiedName(OS);
+ Name = QualifiedNameBuffer.str();
+ }
+
+ StringRef USR = API.recordUSR(Decl);
+ PresumedLoc Loc =
+ Context.getSourceManager().getPresumedLoc(Decl->getLocation());
+ DocComment Comment;
+ if (auto *RawComment =
+ getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
+ Comment = RawComment->getFormattedLines(Context.getSourceManager(),
+ Context.getDiagnostics());
+
+ // Build declaration fragments and sub-heading for the enum.
+ DeclarationFragments Declaration =
+ DeclarationFragmentsBuilder::getFragmentsForEnum(Decl);
+ DeclarationFragments SubHeading =
+ DeclarationFragmentsBuilder::getSubHeading(Decl);
+ EnumRecord *EnumRecord = API.addEnum(
+ API.copyString(Name), USR, Loc, AvailabilityInfo::createFromDecl(Decl),
+ Comment, Declaration, SubHeading, isInSystemHeader(Decl));
+
+ // Now collect information about the enumerators in this enum.
+ getDerivedExtractAPIVisitor().recordEnumConstants(EnumRecord,
+ Decl->enumerators());
+
+ return true;
+}
+
+template <typename Derived>
+bool ExtractAPIVisitorBase<Derived>::WalkUpFromFunctionDecl(
+ const FunctionDecl *Decl) {
+ getDerivedExtractAPIVisitor().VisitFunctionDecl(Decl);
+ return true;
+}
+
+template <typename Derived>
+bool ExtractAPIVisitorBase<Derived>::WalkUpFromRecordDecl(
+ const RecordDecl *Decl) {
+ getDerivedExtractAPIVisitor().VisitRecordDecl(Decl);
+ return true;
+}
+
+template <typename Derived>
+bool ExtractAPIVisitorBase<Derived>::WalkUpFromCXXRecordDecl(
+ const CXXRecordDecl *Decl) {
+ getDerivedExtractAPIVisitor().VisitCXXRecordDecl(Decl);
+ return true;
+}
+
+template <typename Derived>
+bool ExtractAPIVisitorBase<Derived>::WalkUpFromCXXMethodDecl(
+ const CXXMethodDecl *Decl) {
+ getDerivedExtractAPIVisitor().VisitCXXMethodDecl(Decl);
+ return true;
+}
+
+template <typename Derived>
+bool ExtractAPIVisitorBase<Derived>::WalkUpFromClassTemplateSpecializationDecl(
+ const ClassTemplateSpecializationDecl *Decl) {
+ getDerivedExtractAPIVisitor().VisitClassTemplateSpecializationDecl(Decl);
+ return true;
+}
+
+template <typename Derived>
+bool ExtractAPIVisitorBase<Derived>::
+ WalkUpFromClassTemplatePartialSpecializationDecl(
+ const ClassTemplatePartialSpecializationDecl *Decl) {
+ getDerivedExtractAPIVisitor().VisitClassTemplatePartialSpecializationDecl(
+ Decl);
+ return true;
+}
+
+template <typename Derived>
+bool ExtractAPIVisitorBase<Derived>::WalkUpFromVarTemplateDecl(
+ const VarTemplateDecl *Decl) {
+ getDerivedExtractAPIVisitor().VisitVarTemplateDecl(Decl);
+ return true;
+}
+
+template <typename Derived>
+bool ExtractAPIVisitorBase<Derived>::WalkUpFromVarTemplateSpecializationDecl(
+ const VarTemplateSpecializationDecl *Decl) {
+ getDerivedExtractAPIVisitor().VisitVarTemplateSpecializationDecl(Decl);
+ return true;
+}
+
+template <typename Derived>
+bool ExtractAPIVisitorBase<Derived>::
+ WalkUpFromVarTemplatePartialSpecializationDecl(
+ const VarTemplatePartialSpecializationDecl *Decl) {
+ getDerivedExtractAPIVisitor().VisitVarTemplatePartialSpecializationDecl(Decl);
+ return true;
+}
+
+template <typename Derived>
+bool ExtractAPIVisitorBase<Derived>::WalkUpFromFunctionTemplateDecl(
+ const FunctionTemplateDecl *Decl) {
+ getDerivedExtractAPIVisitor().VisitFunctionTemplateDecl(Decl);
+ return true;
+}
+
+template <typename Derived>
+bool ExtractAPIVisitorBase<Derived>::WalkUpFromNamespaceDecl(
+ const NamespaceDecl *Decl) {
+ getDerivedExtractAPIVisitor().VisitNamespaceDecl(Decl);
+ return true;
+}
+
+template <typename Derived>
+bool ExtractAPIVisitorBase<Derived>::VisitNamespaceDecl(
+ const NamespaceDecl *Decl) {
+
+ if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
+ return true;
+ if (Decl->isAnonymousNamespace())
+ return true;
+ StringRef Name = Decl->getName();
+ StringRef USR = API.recordUSR(Decl);
+ LinkageInfo Linkage = Decl->getLinkageAndVisibility();
+ PresumedLoc Loc =
+ Context.getSourceManager().getPresumedLoc(Decl->getLocation());
+ DocComment Comment;
+ if (auto *RawComment =
+ getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
+ Comment = RawComment->getFormattedLines(Context.getSourceManager(),
+ Context.getDiagnostics());
+
+ // Build declaration fragments and sub-heading for the struct.
+ DeclarationFragments Declaration =
+ DeclarationFragmentsBuilder::getFragmentsForNamespace(Decl);
+ DeclarationFragments SubHeading =
+ DeclarationFragmentsBuilder::getSubHeading(Decl);
+ APIRecord *Parent = determineParentRecord(Decl->getDeclContext());
+ API.addNamespace(Parent, Name, USR, Loc,
+ AvailabilityInfo::createFromDecl(Decl), Linkage, Comment,
+ Declaration, SubHeading, isInSystemHeader(Decl));
+
+ return true;
+}
+
+template <typename Derived>
+bool ExtractAPIVisitorBase<Derived>::VisitRecordDecl(const RecordDecl *Decl) {
+ if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
+ return true;
+ // Collect symbol information.
+ StringRef Name = Decl->getName();
+ if (Name.empty())
+ Name = getTypedefName(Decl);
+ if (Name.empty())
+ return true;
+
+ StringRef USR = API.recordUSR(Decl);
+ PresumedLoc Loc =
+ Context.getSourceManager().getPresumedLoc(Decl->getLocation());
+ DocComment Comment;
+ if (auto *RawComment =
+ getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
+ Comment = RawComment->getFormattedLines(Context.getSourceManager(),
+ Context.getDiagnostics());
+
+ // Build declaration fragments and sub-heading for the struct.
+ DeclarationFragments Declaration =
+ DeclarationFragmentsBuilder::getFragmentsForRecordDecl(Decl);
+ DeclarationFragments SubHeading =
+ DeclarationFragmentsBuilder::getSubHeading(Decl);
+
+ auto RecordKind = APIRecord::RK_Struct;
+ auto FieldRecordKind = APIRecord::RK_StructField;
+
+ if (Decl->isUnion()) {
+ RecordKind = APIRecord::RK_Union;
+ FieldRecordKind = APIRecord::RK_UnionField;
+ }
+
+ RecordRecord *RecordRecord = API.addRecord(
+ Name, USR, Loc, AvailabilityInfo::createFromDecl(Decl), Comment,
+ Declaration, SubHeading, RecordKind, isInSystemHeader(Decl));
+
+ // Now collect information about the fields in this struct.
+ getDerivedExtractAPIVisitor().recordRecordFields(
+ RecordRecord, FieldRecordKind, Decl->fields());
+
+ return true;
+}
+
+template <typename Derived>
+bool ExtractAPIVisitorBase<Derived>::VisitCXXRecordDecl(
+ const CXXRecordDecl *Decl) {
+ if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl) ||
+ Decl->isImplicit())
+ return true;
+
+ StringRef Name = Decl->getName();
+ StringRef USR = API.recordUSR(Decl);
+ PresumedLoc Loc =
+ Context.getSourceManager().getPresumedLoc(Decl->getLocation());
+ DocComment Comment;
+ if (auto *RawComment =
+ getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
+ Comment = RawComment->getFormattedLines(Context.getSourceManager(),
+ Context.getDiagnostics());
+ DeclarationFragments Declaration =
+ DeclarationFragmentsBuilder::getFragmentsForCXXClass(Decl);
+ DeclarationFragments SubHeading =
+ DeclarationFragmentsBuilder::getSubHeading(Decl);
+
+ APIRecord::RecordKind Kind;
+ if (Decl->isUnion())
+ Kind = APIRecord::RecordKind::RK_Union;
+ else if (Decl->isStruct())
+ Kind = APIRecord::RecordKind::RK_Struct;
+ else
+ Kind = APIRecord::RecordKind::RK_CXXClass;
+ auto Access = DeclarationFragmentsBuilder::getAccessControl(Decl);
+
+ APIRecord *Parent = determineParentRecord(Decl->getDeclContext());
+ CXXClassRecord *CXXClassRecord;
+ if (Decl->getDescribedClassTemplate()) {
+ // Inject template fragments before class fragments.
+ Declaration.insert(
+ Declaration.begin(),
+ DeclarationFragmentsBuilder::getFragmentsForRedeclarableTemplate(
+ Decl->getDescribedClassTemplate()));
+ CXXClassRecord = API.addClassTemplate(
+ Parent, Name, USR, Loc, AvailabilityInfo::createFromDecl(Decl), Comment,
+ Declaration, SubHeading, Template(Decl->getDescribedClassTemplate()),
+ Access, isInSystemHeader(Decl));
+ } else
+ CXXClassRecord = API.addCXXClass(
+ Parent, Name, USR, Loc, AvailabilityInfo::createFromDecl(Decl), Comment,
+ Declaration, SubHeading, Kind, Access, isInSystemHeader(Decl));
+
+ CXXClassRecord->Bases = getBases(Decl);
+
+ return true;
+}
+
+template <typename Derived>
+bool ExtractAPIVisitorBase<Derived>::VisitCXXMethodDecl(
+ const CXXMethodDecl *Decl) {
+ if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl) ||
+ Decl->isImplicit())
+ return true;
+
+ if (isa<CXXConversionDecl>(Decl))
+ return true;
+ if (isa<CXXConstructorDecl>(Decl) || isa<CXXDestructorDecl>(Decl))
+ return true;
+
+ StringRef USR = API.recordUSR(Decl);
+ PresumedLoc Loc =
+ Context.getSourceManager().getPresumedLoc(Decl->getLocation());
+ DocComment Comment;
+ if (auto *RawComment =
+ getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
+ Comment = RawComment->getFormattedLines(Context.getSourceManager(),
+ Context.getDiagnostics());
+ DeclarationFragments SubHeading =
+ DeclarationFragmentsBuilder::getSubHeading(Decl);
+ auto Access = DeclarationFragmentsBuilder::getAccessControl(Decl);
+ auto Signature = DeclarationFragmentsBuilder::getFunctionSignature(Decl);
+
+ SmallString<128> ParentUSR;
+ index::generateUSRForDecl(dyn_cast<CXXRecordDecl>(Decl->getDeclContext()),
+ ParentUSR);
+ auto *Parent = API.findRecordForUSR(ParentUSR);
+ if (Decl->isTemplated()) {
+ FunctionTemplateDecl *TemplateDecl = Decl->getDescribedFunctionTemplate();
+ API.addCXXMethodTemplate(
+ API.findRecordForUSR(ParentUSR), Decl->getName(), USR, Loc,
+ AvailabilityInfo::createFromDecl(Decl), Comment,
+ DeclarationFragmentsBuilder::getFragmentsForFunctionTemplate(
+ TemplateDecl),
+ SubHeading, DeclarationFragmentsBuilder::getFunctionSignature(Decl),
+ DeclarationFragmentsBuilder::getAccessControl(TemplateDecl),
+ Template(TemplateDecl), isInSystemHeader(Decl));
+ } else if (Decl->getTemplateSpecializationInfo())
+ API.addCXXMethodTemplateSpec(
+ Parent, Decl->getName(), USR, Loc,
+ AvailabilityInfo::createFromDecl(Decl), Comment,
+ DeclarationFragmentsBuilder::
+ getFragmentsForFunctionTemplateSpecialization(Decl),
+ SubHeading, Signature, Access, isInSystemHeader(Decl));
+ else if (Decl->isOverloadedOperator())
+ API.addCXXInstanceMethod(
+ Parent, API.copyString(Decl->getNameAsString()), USR, Loc,
+ AvailabilityInfo::createFromDecl(Decl), Comment,
+ DeclarationFragmentsBuilder::getFragmentsForOverloadedOperator(Decl),
+ SubHeading, Signature, Access, isInSystemHeader(Decl));
+ else if (Decl->isStatic())
+ API.addCXXStaticMethod(
+ Parent, Decl->getName(), USR, Loc,
+ AvailabilityInfo::createFromDecl(Decl), Comment,
+ DeclarationFragmentsBuilder::getFragmentsForCXXMethod(Decl), SubHeading,
+ Signature, Access, isInSystemHeader(Decl));
+ else
+ API.addCXXInstanceMethod(
+ Parent, Decl->getName(), USR, Loc,
+ AvailabilityInfo::createFromDecl(Decl), Comment,
+ DeclarationFragmentsBuilder::getFragmentsForCXXMethod(Decl), SubHeading,
+ Signature, Access, isInSystemHeader(Decl));
+
+ return true;
+}
+
+template <typename Derived>
+bool ExtractAPIVisitorBase<Derived>::VisitCXXConstructorDecl(
+ const CXXConstructorDecl *Decl) {
+
+ StringRef Name = API.copyString(Decl->getNameAsString());
+ StringRef USR = API.recordUSR(Decl);
+ PresumedLoc Loc =
+ Context.getSourceManager().getPresumedLoc(Decl->getLocation());
+ DocComment Comment;
+ if (auto *RawComment =
+ getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
+ Comment = RawComment->getFormattedLines(Context.getSourceManager(),
+ Context.getDiagnostics());
+
+ // Build declaration fragments, sub-heading, and signature for the method.
+ DeclarationFragments Declaration =
+ DeclarationFragmentsBuilder::getFragmentsForSpecialCXXMethod(Decl);
+ DeclarationFragments SubHeading =
+ DeclarationFragmentsBuilder::getSubHeading(Decl);
+ FunctionSignature Signature =
+ DeclarationFragmentsBuilder::getFunctionSignature(Decl);
+ AccessControl Access = DeclarationFragmentsBuilder::getAccessControl(Decl);
+ SmallString<128> ParentUSR;
+ index::generateUSRForDecl(dyn_cast<CXXRecordDecl>(Decl->getDeclContext()),
+ ParentUSR);
+ API.addCXXInstanceMethod(API.findRecordForUSR(ParentUSR), Name, USR, Loc,
+ AvailabilityInfo::createFromDecl(Decl), Comment,
+ Declaration, SubHeading, Signature, Access,
+ isInSystemHeader(Decl));
+ return true;
+}
+
+template <typename Derived>
+bool ExtractAPIVisitorBase<Derived>::VisitCXXDestructorDecl(
+ const CXXDestructorDecl *Decl) {
+
+ StringRef Name = API.copyString(Decl->getNameAsString());
+ StringRef USR = API.recordUSR(Decl);
+ PresumedLoc Loc =
+ Context.getSourceManager().getPresumedLoc(Decl->getLocation());
+ DocComment Comment;
+ if (auto *RawComment =
+ getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
+ Comment = RawComment->getFormattedLines(Context.getSourceManager(),
+ Context.getDiagnostics());
+
+ // Build declaration fragments, sub-heading, and signature for the method.
+ DeclarationFragments Declaration =
+ DeclarationFragmentsBuilder::getFragmentsForSpecialCXXMethod(Decl);
+ DeclarationFragments SubHeading =
+ DeclarationFragmentsBuilder::getSubHeading(Decl);
+ FunctionSignature Signature =
+ DeclarationFragmentsBuilder::getFunctionSignature(Decl);
+ AccessControl Access = DeclarationFragmentsBuilder::getAccessControl(Decl);
+ SmallString<128> ParentUSR;
+ index::generateUSRForDecl(dyn_cast<CXXRecordDecl>(Decl->getDeclContext()),
+ ParentUSR);
+ API.addCXXInstanceMethod(API.findRecordForUSR(ParentUSR), Name, USR, Loc,
+ AvailabilityInfo::createFromDecl(Decl), Comment,
+ Declaration, SubHeading, Signature, Access,
+ isInSystemHeader(Decl));
+ return true;
+}
+
+template <typename Derived>
+bool ExtractAPIVisitorBase<Derived>::VisitConceptDecl(const ConceptDecl *Decl) {
+ if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
+ return true;
+
+ StringRef Name = Decl->getName();
+ StringRef USR = API.recordUSR(Decl);
+ PresumedLoc Loc =
+ Context.getSourceManager().getPresumedLoc(Decl->getLocation());
+ DocComment Comment;
+ if (auto *RawComment =
+ getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
+ Comment = RawComment->getFormattedLines(Context.getSourceManager(),
+ Context.getDiagnostics());
+ DeclarationFragments Declaration =
+ DeclarationFragmentsBuilder::getFragmentsForConcept(Decl);
+ DeclarationFragments SubHeading =
+ DeclarationFragmentsBuilder::getSubHeading(Decl);
+ API.addConcept(Name, USR, Loc, AvailabilityInfo::createFromDecl(Decl),
+ Comment, Declaration, SubHeading, Template(Decl),
+ isInSystemHeader(Decl));
+ return true;
+}
+
+template <typename Derived>
+bool ExtractAPIVisitorBase<Derived>::VisitClassTemplateSpecializationDecl(
+ const ClassTemplateSpecializationDecl *Decl) {
+ if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
+ return true;
+
+ StringRef Name = Decl->getName();
+ StringRef USR = API.recordUSR(Decl);
+ PresumedLoc Loc =
+ Context.getSourceManager().getPresumedLoc(Decl->getLocation());
+ DocComment Comment;
+ if (auto *RawComment =
+ getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
+ Comment = RawComment->getFormattedLines(Context.getSourceManager(),
+ Context.getDiagnostics());
+ DeclarationFragments Declaration =
+ DeclarationFragmentsBuilder::getFragmentsForClassTemplateSpecialization(
+ Decl);
+ DeclarationFragments SubHeading =
+ DeclarationFragmentsBuilder::getSubHeading(Decl);
+
+ APIRecord *Parent = determineParentRecord(Decl->getDeclContext());
+ auto *ClassTemplateSpecializationRecord = API.addClassTemplateSpecialization(
+ Parent, Name, USR, Loc, AvailabilityInfo::createFromDecl(Decl), Comment,
+ Declaration, SubHeading,
+ DeclarationFragmentsBuilder::getAccessControl(Decl),
+ isInSystemHeader(Decl));
+
+ ClassTemplateSpecializationRecord->Bases = getBases(Decl);
+
+ return true;
+}
+
+template <typename Derived>
+bool ExtractAPIVisitorBase<Derived>::
+ VisitClassTemplatePartialSpecializationDecl(
+ const ClassTemplatePartialSpecializationDecl *Decl) {
+ if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
+ return true;
+
+ StringRef Name = Decl->getName();
+ StringRef USR = API.recordUSR(Decl);
+ PresumedLoc Loc =
+ Context.getSourceManager().getPresumedLoc(Decl->getLocation());
+ DocComment Comment;
+ if (auto *RawComment =
+ getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
+ Comment = RawComment->getFormattedLines(Context.getSourceManager(),
+ Context.getDiagnostics());
+ DeclarationFragments Declaration = DeclarationFragmentsBuilder::
+ getFragmentsForClassTemplatePartialSpecialization(Decl);
+ DeclarationFragments SubHeading =
+ DeclarationFragmentsBuilder::getSubHeading(Decl);
+ APIRecord *Parent = determineParentRecord(Decl->getDeclContext());
+ auto *ClassTemplatePartialSpecRecord =
+ API.addClassTemplatePartialSpecialization(
+ Parent, Name, USR, Loc, AvailabilityInfo::createFromDecl(Decl),
+ Comment, Declaration, SubHeading, Template(Decl),
+ DeclarationFragmentsBuilder::getAccessControl(Decl),
+ isInSystemHeader(Decl));
+
+ ClassTemplatePartialSpecRecord->Bases = getBases(Decl);
+
+ return true;
+}
+
+template <typename Derived>
+bool ExtractAPIVisitorBase<Derived>::VisitVarTemplateDecl(
+ const VarTemplateDecl *Decl) {
+ if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
+ return true;
+
+ // Collect symbol information.
+ StringRef Name = Decl->getName();
+ StringRef USR = API.recordUSR(Decl);
+ PresumedLoc Loc =
+ Context.getSourceManager().getPresumedLoc(Decl->getLocation());
+ LinkageInfo Linkage = Decl->getLinkageAndVisibility();
+ DocComment Comment;
+ if (auto *RawComment =
+ getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
+ Comment = RawComment->getFormattedLines(Context.getSourceManager(),
+ Context.getDiagnostics());
+
+ // Build declaration fragments and sub-heading for the variable.
+ DeclarationFragments Declaration;
+ Declaration
+ .append(DeclarationFragmentsBuilder::getFragmentsForRedeclarableTemplate(
+ Decl))
+ .append(DeclarationFragmentsBuilder::getFragmentsForVarTemplate(
+ Decl->getTemplatedDecl()));
+ // Inject template fragments before var fragments.
+ DeclarationFragments SubHeading =
+ DeclarationFragmentsBuilder::getSubHeading(Decl);
+
+ SmallString<128> ParentUSR;
+ index::generateUSRForDecl(dyn_cast<CXXRecordDecl>(Decl->getDeclContext()),
+ ParentUSR);
+ if (Decl->getDeclContext()->getDeclKind() == Decl::CXXRecord)
+ API.addCXXFieldTemplate(API.findRecordForUSR(ParentUSR), Name, USR, Loc,
+ AvailabilityInfo::createFromDecl(Decl), Comment,
+ Declaration, SubHeading,
+ DeclarationFragmentsBuilder::getAccessControl(Decl),
+ Template(Decl), isInSystemHeader(Decl));
+ else
+ API.addGlobalVariableTemplate(Name, USR, Loc,
+ AvailabilityInfo::createFromDecl(Decl),
+ Linkage, Comment, Declaration, SubHeading,
+ Template(Decl), isInSystemHeader(Decl));
+ return true;
+}
+
+template <typename Derived>
+bool ExtractAPIVisitorBase<Derived>::VisitVarTemplateSpecializationDecl(
+ const VarTemplateSpecializationDecl *Decl) {
+ if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
+ return true;
+
+ // Collect symbol information.
+ StringRef Name = Decl->getName();
+ StringRef USR = API.recordUSR(Decl);
+ PresumedLoc Loc =
+ Context.getSourceManager().getPresumedLoc(Decl->getLocation());
+ LinkageInfo Linkage = Decl->getLinkageAndVisibility();
+ DocComment Comment;
+ if (auto *RawComment =
+ getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
+ Comment = RawComment->getFormattedLines(Context.getSourceManager(),
+ Context.getDiagnostics());
+
+ // Build declaration fragments and sub-heading for the variable.
+ DeclarationFragments Declaration =
+ DeclarationFragmentsBuilder::getFragmentsForVarTemplateSpecialization(
+ Decl);
+ DeclarationFragments SubHeading =
+ DeclarationFragmentsBuilder::getSubHeading(Decl);
+ API.addGlobalVariableTemplateSpecialization(
+ Name, USR, Loc, AvailabilityInfo::createFromDecl(Decl), Linkage, Comment,
+ Declaration, SubHeading, isInSystemHeader(Decl));
+ return true;
+}
+
+template <typename Derived>
+bool ExtractAPIVisitorBase<Derived>::VisitVarTemplatePartialSpecializationDecl(
+ const VarTemplatePartialSpecializationDecl *Decl) {
+ if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
+ return true;
+
+ // Collect symbol information.
+ StringRef Name = Decl->getName();
+ StringRef USR = API.recordUSR(Decl);
+ PresumedLoc Loc =
+ Context.getSourceManager().getPresumedLoc(Decl->getLocation());
+ LinkageInfo Linkage = Decl->getLinkageAndVisibility();
+ DocComment Comment;
+ if (auto *RawComment =
+ getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
+ Comment = RawComment->getFormattedLines(Context.getSourceManager(),
+ Context.getDiagnostics());
+
+ // Build declaration fragments and sub-heading for the variable.
+ DeclarationFragments Declaration = DeclarationFragmentsBuilder::
+ getFragmentsForVarTemplatePartialSpecialization(Decl);
+ DeclarationFragments SubHeading =
+ DeclarationFragmentsBuilder::getSubHeading(Decl);
+ API.addGlobalVariableTemplatePartialSpecialization(
+ Name, USR, Loc, AvailabilityInfo::createFromDecl(Decl), Linkage, Comment,
+ Declaration, SubHeading, Template(Decl), isInSystemHeader(Decl));
+ return true;
+}
+
+template <typename Derived>
+bool ExtractAPIVisitorBase<Derived>::VisitFunctionTemplateDecl(
+ const FunctionTemplateDecl *Decl) {
+ if (isa<CXXMethodDecl>(Decl->getTemplatedDecl()))
+ return true;
+ if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
+ return true;
+
+ // Collect symbol information.
+ StringRef Name = Decl->getName();
+ StringRef USR = API.recordUSR(Decl);
+ PresumedLoc Loc =
+ Context.getSourceManager().getPresumedLoc(Decl->getLocation());
+ LinkageInfo Linkage = Decl->getLinkageAndVisibility();
+ DocComment Comment;
+ if (auto *RawComment =
+ getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
+ Comment = RawComment->getFormattedLines(Context.getSourceManager(),
+ Context.getDiagnostics());
+
+ DeclarationFragments SubHeading =
+ DeclarationFragmentsBuilder::getSubHeading(Decl);
+ FunctionSignature Signature =
+ DeclarationFragmentsBuilder::getFunctionSignature(
+ Decl->getTemplatedDecl());
+ API.addGlobalFunctionTemplate(
+ Name, USR, Loc, AvailabilityInfo::createFromDecl(Decl), Linkage, Comment,
+ DeclarationFragmentsBuilder::getFragmentsForFunctionTemplate(Decl),
+ SubHeading, Signature, Template(Decl), isInSystemHeader(Decl));
+
+ return true;
+}
+
+template <typename Derived>
+bool ExtractAPIVisitorBase<Derived>::VisitObjCInterfaceDecl(
+ const ObjCInterfaceDecl *Decl) {
+ if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
+ return true;
+
+ // Collect symbol information.
+ StringRef Name = Decl->getName();
+ StringRef USR = API.recordUSR(Decl);
+ PresumedLoc Loc =
+ Context.getSourceManager().getPresumedLoc(Decl->getLocation());
+ LinkageInfo Linkage = Decl->getLinkageAndVisibility();
+ DocComment Comment;
+ if (auto *RawComment =
+ getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
+ Comment = RawComment->getFormattedLines(Context.getSourceManager(),
+ Context.getDiagnostics());
+
+ // Build declaration fragments and sub-heading for the interface.
+ DeclarationFragments Declaration =
+ DeclarationFragmentsBuilder::getFragmentsForObjCInterface(Decl);
+ DeclarationFragments SubHeading =
+ DeclarationFragmentsBuilder::getSubHeading(Decl);
+
+ // Collect super class information.
+ SymbolReference SuperClass;
+ if (const auto *SuperClassDecl = Decl->getSuperClass()) {
+ SuperClass.Name = SuperClassDecl->getObjCRuntimeNameAsString();
+ SuperClass.USR = API.recordUSR(SuperClassDecl);
+ }
+
+ ObjCInterfaceRecord *ObjCInterfaceRecord = API.addObjCInterface(
+ Name, USR, Loc, AvailabilityInfo::createFromDecl(Decl), Linkage, Comment,
+ Declaration, SubHeading, SuperClass, isInSystemHeader(Decl));
+
+ // Record all methods (selectors). This doesn't include automatically
+ // synthesized property methods.
+ getDerivedExtractAPIVisitor().recordObjCMethods(ObjCInterfaceRecord,
+ Decl->methods());
+ getDerivedExtractAPIVisitor().recordObjCProperties(ObjCInterfaceRecord,
+ Decl->properties());
+ getDerivedExtractAPIVisitor().recordObjCInstanceVariables(ObjCInterfaceRecord,
+ Decl->ivars());
+ getDerivedExtractAPIVisitor().recordObjCProtocols(ObjCInterfaceRecord,
+ Decl->protocols());
+
+ return true;
+}
+
+template <typename Derived>
+bool ExtractAPIVisitorBase<Derived>::VisitObjCProtocolDecl(
+ const ObjCProtocolDecl *Decl) {
+ if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
+ return true;
+
+ // Collect symbol information.
+ StringRef Name = Decl->getName();
+ StringRef USR = API.recordUSR(Decl);
+ PresumedLoc Loc =
+ Context.getSourceManager().getPresumedLoc(Decl->getLocation());
+ DocComment Comment;
+ if (auto *RawComment =
+ getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
+ Comment = RawComment->getFormattedLines(Context.getSourceManager(),
+ Context.getDiagnostics());
+
+ // Build declaration fragments and sub-heading for the protocol.
+ DeclarationFragments Declaration =
+ DeclarationFragmentsBuilder::getFragmentsForObjCProtocol(Decl);
+ DeclarationFragments SubHeading =
+ DeclarationFragmentsBuilder::getSubHeading(Decl);
+
+ ObjCProtocolRecord *ObjCProtocolRecord = API.addObjCProtocol(
+ Name, USR, Loc, AvailabilityInfo::createFromDecl(Decl), Comment,
+ Declaration, SubHeading, isInSystemHeader(Decl));
+
+ getDerivedExtractAPIVisitor().recordObjCMethods(ObjCProtocolRecord,
+ Decl->methods());
+ getDerivedExtractAPIVisitor().recordObjCProperties(ObjCProtocolRecord,
+ Decl->properties());
+ getDerivedExtractAPIVisitor().recordObjCProtocols(ObjCProtocolRecord,
+ Decl->protocols());
+
+ return true;
+}
+
+template <typename Derived>
+bool ExtractAPIVisitorBase<Derived>::VisitTypedefNameDecl(
+ const TypedefNameDecl *Decl) {
+ // Skip ObjC Type Parameter for now.
+ if (isa<ObjCTypeParamDecl>(Decl))
+ return true;
+
+ if (!Decl->isDefinedOutsideFunctionOrMethod())
+ return true;
+
+ if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
+ return true;
+
+ // Add the notion of typedef for tag type (struct or enum) of the same name.
+ if (const ElaboratedType *ET =
+ dyn_cast<ElaboratedType>(Decl->getUnderlyingType())) {
+ if (const TagType *TagTy = dyn_cast<TagType>(ET->desugar())) {
+ if (Decl->getName() == TagTy->getDecl()->getName()) {
+ if (isa<RecordDecl>(TagTy->getDecl())) {
+ modifyRecords(API.getRecords(), Decl->getName());
+ }
+ if (TagTy->getDecl()->isEnum()) {
+ modifyRecords(API.getEnums(), Decl->getName());
+ }
+ }
+ }
+ }
+
+ PresumedLoc Loc =
+ Context.getSourceManager().getPresumedLoc(Decl->getLocation());
+ StringRef Name = Decl->getName();
+ StringRef USR = API.recordUSR(Decl);
+ DocComment Comment;
+ if (auto *RawComment =
+ getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
+ Comment = RawComment->getFormattedLines(Context.getSourceManager(),
+ Context.getDiagnostics());
+
+ QualType Type = Decl->getUnderlyingType();
+ SymbolReference SymRef =
+ TypedefUnderlyingTypeResolver(Context).getSymbolReferenceForType(Type,
+ API);
+
+ API.addTypedef(Name, USR, Loc, AvailabilityInfo::createFromDecl(Decl),
+ Comment,
+ DeclarationFragmentsBuilder::getFragmentsForTypedef(Decl),
+ DeclarationFragmentsBuilder::getSubHeading(Decl), SymRef,
+ isInSystemHeader(Decl));
+
+ return true;
+}
+
+template <typename Derived>
+bool ExtractAPIVisitorBase<Derived>::VisitObjCCategoryDecl(
+ const ObjCCategoryDecl *Decl) {
+ if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
+ return true;
+
+ StringRef Name = Decl->getName();
+ StringRef USR = API.recordUSR(Decl);
+ PresumedLoc Loc =
+ Context.getSourceManager().getPresumedLoc(Decl->getLocation());
+ DocComment Comment;
+ if (auto *RawComment =
+ getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
+ Comment = RawComment->getFormattedLines(Context.getSourceManager(),
+ Context.getDiagnostics());
+ // Build declaration fragments and sub-heading for the category.
+ DeclarationFragments Declaration =
+ DeclarationFragmentsBuilder::getFragmentsForObjCCategory(Decl);
+ DeclarationFragments SubHeading =
+ DeclarationFragmentsBuilder::getSubHeading(Decl);
+
+ const ObjCInterfaceDecl *InterfaceDecl = Decl->getClassInterface();
+ SymbolReference Interface(InterfaceDecl->getName(),
+ API.recordUSR(InterfaceDecl));
+
+ bool IsFromExternalModule = true;
+ for (const auto &Interface : API.getObjCInterfaces()) {
+ if (InterfaceDecl->getName() == Interface.second.get()->Name) {
+ IsFromExternalModule = false;
+ break;
+ }
+ }
+
+ ObjCCategoryRecord *ObjCCategoryRecord = API.addObjCCategory(
+ Name, USR, Loc, AvailabilityInfo::createFromDecl(Decl), Comment,
+ Declaration, SubHeading, Interface, isInSystemHeader(Decl),
+ IsFromExternalModule);
+
+ getDerivedExtractAPIVisitor().recordObjCMethods(ObjCCategoryRecord,
+ Decl->methods());
+ getDerivedExtractAPIVisitor().recordObjCProperties(ObjCCategoryRecord,
+ Decl->properties());
+ getDerivedExtractAPIVisitor().recordObjCInstanceVariables(ObjCCategoryRecord,
+ Decl->ivars());
+ getDerivedExtractAPIVisitor().recordObjCProtocols(ObjCCategoryRecord,
+ Decl->protocols());
+
+ return true;
+}
+
+/// Collect API information for the enum constants and associate with the
+/// parent enum.
+template <typename Derived>
+void ExtractAPIVisitorBase<Derived>::recordEnumConstants(
+ EnumRecord *EnumRecord, const EnumDecl::enumerator_range Constants) {
+ for (const auto *Constant : Constants) {
+ // Collect symbol information.
+ StringRef Name = Constant->getName();
+ StringRef USR = API.recordUSR(Constant);
+ PresumedLoc Loc =
+ Context.getSourceManager().getPresumedLoc(Constant->getLocation());
+ DocComment Comment;
+ if (auto *RawComment =
+ getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Constant))
+ Comment = RawComment->getFormattedLines(Context.getSourceManager(),
+ Context.getDiagnostics());
+
+ // Build declaration fragments and sub-heading for the enum constant.
+ DeclarationFragments Declaration =
+ DeclarationFragmentsBuilder::getFragmentsForEnumConstant(Constant);
+ DeclarationFragments SubHeading =
+ DeclarationFragmentsBuilder::getSubHeading(Constant);
+
+ API.addEnumConstant(EnumRecord, Name, USR, Loc,
+ AvailabilityInfo::createFromDecl(Constant), Comment,
+ Declaration, SubHeading, isInSystemHeader(Constant));
+ }
+}
+
+/// Collect API information for the struct fields and associate with the
+/// parent struct.
+template <typename Derived>
+void ExtractAPIVisitorBase<Derived>::recordRecordFields(
+ RecordRecord *RecordRecord, APIRecord::RecordKind FieldKind,
+ const RecordDecl::field_range Fields) {
+ for (const auto *Field : Fields) {
+ // Collect symbol information.
+ StringRef Name = Field->getName();
+ StringRef USR = API.recordUSR(Field);
+ PresumedLoc Loc =
+ Context.getSourceManager().getPresumedLoc(Field->getLocation());
+ DocComment Comment;
+ if (auto *RawComment =
+ getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Field))
+ Comment = RawComment->getFormattedLines(Context.getSourceManager(),
+ Context.getDiagnostics());
+
+ // Build declaration fragments and sub-heading for the struct field.
+ DeclarationFragments Declaration =
+ DeclarationFragmentsBuilder::getFragmentsForField(Field);
+ DeclarationFragments SubHeading =
+ DeclarationFragmentsBuilder::getSubHeading(Field);
+
+ API.addRecordField(
+ RecordRecord, Name, USR, Loc, AvailabilityInfo::createFromDecl(Field),
+ Comment, Declaration, SubHeading, FieldKind, isInSystemHeader(Field));
+ }
+}
+
+template <typename Derived>
+bool ExtractAPIVisitorBase<Derived>::VisitFieldDecl(const FieldDecl *Decl) {
+ if (Decl->getDeclContext()->getDeclKind() == Decl::Record)
+ return true;
+ if (isa<ObjCIvarDecl>(Decl))
+ return true;
+ // Collect symbol information.
+ StringRef Name = Decl->getName();
+ StringRef USR = API.recordUSR(Decl);
+ PresumedLoc Loc =
+ Context.getSourceManager().getPresumedLoc(Decl->getLocation());
+ DocComment Comment;
+ if (auto *RawComment =
+ getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
+ Comment = RawComment->getFormattedLines(Context.getSourceManager(),
+ Context.getDiagnostics());
+
+ // Build declaration fragments and sub-heading for the struct field.
+ DeclarationFragments Declaration =
+ DeclarationFragmentsBuilder::getFragmentsForField(Decl);
+ DeclarationFragments SubHeading =
+ DeclarationFragmentsBuilder::getSubHeading(Decl);
+ AccessControl Access = DeclarationFragmentsBuilder::getAccessControl(Decl);
+
+ SmallString<128> ParentUSR;
+ index::generateUSRForDecl(dyn_cast<CXXRecordDecl>(Decl->getDeclContext()),
+ ParentUSR);
+ API.addCXXField(API.findRecordForUSR(ParentUSR), Name, USR, Loc,
+ AvailabilityInfo::createFromDecl(Decl), Comment, Declaration,
+ SubHeading, Access, isInSystemHeader(Decl));
+ return true;
+}
+
+template <typename Derived>
+bool ExtractAPIVisitorBase<Derived>::VisitCXXConversionDecl(
+ const CXXConversionDecl *Decl) {
+ StringRef Name = API.copyString(Decl->getNameAsString());
+ StringRef USR = API.recordUSR(Decl);
+ PresumedLoc Loc =
+ Context.getSourceManager().getPresumedLoc(Decl->getLocation());
+ DocComment Comment;
+ if (auto *RawComment =
+ getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
+ Comment = RawComment->getFormattedLines(Context.getSourceManager(),
+ Context.getDiagnostics());
+
+ // Build declaration fragments, sub-heading, and signature for the method.
+ DeclarationFragments Declaration =
+ DeclarationFragmentsBuilder::getFragmentsForConversionFunction(Decl);
+ DeclarationFragments SubHeading =
+ DeclarationFragmentsBuilder::getSubHeading(Decl);
+ FunctionSignature Signature =
+ DeclarationFragmentsBuilder::getFunctionSignature(Decl);
+ AccessControl Access = DeclarationFragmentsBuilder::getAccessControl(Decl);
+
+ SmallString<128> ParentUSR;
+ index::generateUSRForDecl(dyn_cast<CXXRecordDecl>(Decl->getDeclContext()),
+ ParentUSR);
+ if (Decl->isStatic())
+ API.addCXXStaticMethod(API.findRecordForUSR(ParentUSR), Name, USR, Loc,
+ AvailabilityInfo::createFromDecl(Decl), Comment,
+ Declaration, SubHeading, Signature, Access,
+ isInSystemHeader(Decl));
+ else
+ API.addCXXInstanceMethod(API.findRecordForUSR(ParentUSR), Name, USR, Loc,
+ AvailabilityInfo::createFromDecl(Decl), Comment,
+ Declaration, SubHeading, Signature, Access,
+ isInSystemHeader(Decl));
+ return true;
+}
+
+/// Collect API information for the Objective-C methods and associate with the
+/// parent container.
+template <typename Derived>
+void ExtractAPIVisitorBase<Derived>::recordObjCMethods(
+ ObjCContainerRecord *Container,
+ const ObjCContainerDecl::method_range Methods) {
+ for (const auto *Method : Methods) {
+ // Don't record selectors for properties.
+ if (Method->isPropertyAccessor())
+ continue;
+
+ StringRef Name = API.copyString(Method->getSelector().getAsString());
+ StringRef USR = API.recordUSR(Method);
+ PresumedLoc Loc =
+ Context.getSourceManager().getPresumedLoc(Method->getLocation());
+ DocComment Comment;
+ if (auto *RawComment =
+ getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Method))
+ Comment = RawComment->getFormattedLines(Context.getSourceManager(),
+ Context.getDiagnostics());
+
+ // Build declaration fragments, sub-heading, and signature for the method.
+ DeclarationFragments Declaration =
+ DeclarationFragmentsBuilder::getFragmentsForObjCMethod(Method);
+ DeclarationFragments SubHeading =
+ DeclarationFragmentsBuilder::getSubHeading(Method);
+ FunctionSignature Signature =
+ DeclarationFragmentsBuilder::getFunctionSignature(Method);
+
+ API.addObjCMethod(Container, Name, USR, Loc,
+ AvailabilityInfo::createFromDecl(Method), Comment,
+ Declaration, SubHeading, Signature,
+ Method->isInstanceMethod(), isInSystemHeader(Method));
+ }
+}
+
+template <typename Derived>
+void ExtractAPIVisitorBase<Derived>::recordObjCProperties(
+ ObjCContainerRecord *Container,
+ const ObjCContainerDecl::prop_range Properties) {
+ for (const auto *Property : Properties) {
+ StringRef Name = Property->getName();
+ StringRef USR = API.recordUSR(Property);
+ PresumedLoc Loc =
+ Context.getSourceManager().getPresumedLoc(Property->getLocation());
+ DocComment Comment;
+ if (auto *RawComment =
+ getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Property))
+ Comment = RawComment->getFormattedLines(Context.getSourceManager(),
+ Context.getDiagnostics());
+
+ // Build declaration fragments and sub-heading for the property.
+ DeclarationFragments Declaration =
+ DeclarationFragmentsBuilder::getFragmentsForObjCProperty(Property);
+ DeclarationFragments SubHeading =
+ DeclarationFragmentsBuilder::getSubHeading(Property);
+
+ StringRef GetterName =
+ API.copyString(Property->getGetterName().getAsString());
+ StringRef SetterName =
+ API.copyString(Property->getSetterName().getAsString());
+
+ // Get the attributes for property.
+ unsigned Attributes = ObjCPropertyRecord::NoAttr;
+ if (Property->getPropertyAttributes() &
+ ObjCPropertyAttribute::kind_readonly)
+ Attributes |= ObjCPropertyRecord::ReadOnly;
+
+ API.addObjCProperty(
+ Container, Name, USR, Loc, AvailabilityInfo::createFromDecl(Property),
+ Comment, Declaration, SubHeading,
+ static_cast<ObjCPropertyRecord::AttributeKind>(Attributes), GetterName,
+ SetterName, Property->isOptional(),
+ !(Property->getPropertyAttributes() &
+ ObjCPropertyAttribute::kind_class),
+ isInSystemHeader(Property));
+ }
+}
+
+template <typename Derived>
+void ExtractAPIVisitorBase<Derived>::recordObjCInstanceVariables(
+ ObjCContainerRecord *Container,
+ const llvm::iterator_range<
+ DeclContext::specific_decl_iterator<ObjCIvarDecl>>
+ Ivars) {
+ for (const auto *Ivar : Ivars) {
+ StringRef Name = Ivar->getName();
+ StringRef USR = API.recordUSR(Ivar);
+ PresumedLoc Loc =
+ Context.getSourceManager().getPresumedLoc(Ivar->getLocation());
+ DocComment Comment;
+ if (auto *RawComment =
+ getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Ivar))
+ Comment = RawComment->getFormattedLines(Context.getSourceManager(),
+ Context.getDiagnostics());
+
+ // Build declaration fragments and sub-heading for the instance variable.
+ DeclarationFragments Declaration =
+ DeclarationFragmentsBuilder::getFragmentsForField(Ivar);
+ DeclarationFragments SubHeading =
+ DeclarationFragmentsBuilder::getSubHeading(Ivar);
+
+ ObjCInstanceVariableRecord::AccessControl Access =
+ Ivar->getCanonicalAccessControl();
+
+ API.addObjCInstanceVariable(
+ Container, Name, USR, Loc, AvailabilityInfo::createFromDecl(Ivar),
+ Comment, Declaration, SubHeading, Access, isInSystemHeader(Ivar));
+ }
+}
+
+template <typename Derived>
+void ExtractAPIVisitorBase<Derived>::recordObjCProtocols(
+ ObjCContainerRecord *Container,
+ ObjCInterfaceDecl::protocol_range Protocols) {
+ for (const auto *Protocol : Protocols)
+ Container->Protocols.emplace_back(Protocol->getName(),
+ API.recordUSR(Protocol));
+}
+
+} // namespace impl
+
+/// The RecursiveASTVisitor to traverse symbol declarations and collect API
+/// information.
+template <typename Derived = void>
+class ExtractAPIVisitor
+ : public impl::ExtractAPIVisitorBase<std::conditional_t<
+ std::is_same_v<Derived, void>, ExtractAPIVisitor<>, Derived>> {
+ using Base = impl::ExtractAPIVisitorBase<std::conditional_t<
+ std::is_same_v<Derived, void>, ExtractAPIVisitor<>, Derived>>;
+
+public:
+ ExtractAPIVisitor(ASTContext &Context, APISet &API) : Base(Context, API) {}
+
+ bool shouldDeclBeIncluded(const Decl *D) const { return true; }
+ const RawComment *fetchRawCommentForDecl(const Decl *D) const {
+ return this->Context.getRawCommentForDeclNoCache(D);
+ }
+};
+
+} // namespace extractapi
+} // namespace clang
+
+#endif // LLVM_CLANG_EXTRACTAPI_EXTRACT_API_VISITOR_H
diff --git a/contrib/llvm-project/clang/include/clang/ExtractAPI/FrontendActions.h b/contrib/llvm-project/clang/include/clang/ExtractAPI/FrontendActions.h
new file mode 100644
index 000000000000..c67864aac9af
--- /dev/null
+++ b/contrib/llvm-project/clang/include/clang/ExtractAPI/FrontendActions.h
@@ -0,0 +1,95 @@
+//===- ExtractAPI/FrontendActions.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 defines the ExtractAPIAction and WrappingExtractAPIAction frontend
+/// actions.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_EXTRACTAPI_FRONTEND_ACTIONS_H
+#define LLVM_CLANG_EXTRACTAPI_FRONTEND_ACTIONS_H
+
+#include "clang/ExtractAPI/ExtractAPIActionBase.h"
+#include "clang/Frontend/FrontendAction.h"
+
+namespace clang {
+
+/// ExtractAPIAction sets up the output file and creates the ExtractAPIVisitor.
+class ExtractAPIAction : public ASTFrontendAction,
+ private ExtractAPIActionBase {
+protected:
+ std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
+ StringRef InFile) override;
+
+private:
+
+ /// The input file originally provided on the command line.
+ ///
+ /// This captures the spelling used to include the file and whether the
+ /// include is quoted or not.
+ SmallVector<std::pair<SmallString<32>, bool>> KnownInputFiles;
+
+ /// Prepare to execute the action on the given CompilerInstance.
+ ///
+ /// This is called before executing the action on any inputs. This generates a
+ /// single header that includes all of CI's inputs and replaces CI's input
+ /// list with it before actually executing the action.
+ bool PrepareToExecuteAction(CompilerInstance &CI) override;
+
+ /// Called after executing the action on the synthesized input buffer.
+ ///
+ /// Note: Now that we have gathered all the API definitions to surface we can
+ /// emit them in this callback.
+ void EndSourceFileAction() override;
+
+ static StringRef getInputBufferName() { return "<extract-api-includes>"; }
+
+ static std::unique_ptr<llvm::raw_pwrite_stream>
+ CreateOutputFile(CompilerInstance &CI, StringRef InFile);
+};
+
+/// Wrap ExtractAPIAction on top of a pre-existing action
+///
+/// Used when the ExtractAPI action needs to be executed as a side effect of a
+/// regular compilation job. Unlike ExtarctAPIAction, this is meant to be used
+/// on regular source files ( .m , .c files) instead of header files
+class WrappingExtractAPIAction : public WrapperFrontendAction,
+ private ExtractAPIActionBase {
+public:
+ WrappingExtractAPIAction(std::unique_ptr<FrontendAction> WrappedAction)
+ : WrapperFrontendAction(std::move(WrappedAction)) {}
+
+protected:
+ /// Create ExtractAPI consumer multiplexed on another consumer.
+ ///
+ /// This allows us to execute ExtractAPI action while on top of
+ std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
+ StringRef InFile) override;
+
+private:
+ /// Flag to check if the wrapper front end action's consumer is
+ /// craeted or not
+ bool CreatedASTConsumer = false;
+
+ void EndSourceFile() override { FrontendAction::EndSourceFile(); }
+
+ /// Called after executing the action on the synthesized input buffer.
+ ///
+ /// Executes both Wrapper and ExtractAPIBase end source file
+ /// actions. This is the place where all the gathered symbol graph
+ /// information is emited.
+ void EndSourceFileAction() override;
+
+ static std::unique_ptr<llvm::raw_pwrite_stream>
+ CreateOutputFile(CompilerInstance &CI, StringRef InFile);
+};
+
+} // namespace clang
+
+#endif // LLVM_CLANG_EXTRACTAPI_FRONTEND_ACTIONS_H
diff --git a/contrib/llvm-project/clang/include/clang/ExtractAPI/Serialization/SerializerBase.h b/contrib/llvm-project/clang/include/clang/ExtractAPI/Serialization/SerializerBase.h
new file mode 100644
index 000000000000..f0629a9ad56b
--- /dev/null
+++ b/contrib/llvm-project/clang/include/clang/ExtractAPI/Serialization/SerializerBase.h
@@ -0,0 +1,314 @@
+//===- ExtractAPI/Serialization/SerializerBase.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 defines the ExtractAPI APISetVisitor interface.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_EXTRACTAPI_SERIALIZATION_SERIALIZERBASE_H
+#define LLVM_CLANG_EXTRACTAPI_SERIALIZATION_SERIALIZERBASE_H
+
+#include "clang/ExtractAPI/API.h"
+
+namespace clang {
+namespace extractapi {
+
+/// The base interface of visitors for API information.
+template <typename Derived> class APISetVisitor {
+public:
+ void traverseAPISet() {
+ getDerived()->traverseNamespaces();
+
+ getDerived()->traverseGlobalVariableRecords();
+
+ getDerived()->traverseGlobalFunctionRecords();
+
+ getDerived()->traverseEnumRecords();
+
+ getDerived()->traverseStaticFieldRecords();
+
+ getDerived()->traverseCXXClassRecords();
+
+ getDerived()->traverseClassTemplateRecords();
+
+ getDerived()->traverseClassTemplateSpecializationRecords();
+
+ getDerived()->traverseClassTemplatePartialSpecializationRecords();
+
+ getDerived()->traverseCXXInstanceMethods();
+
+ getDerived()->traverseCXXStaticMethods();
+
+ getDerived()->traverseCXXMethodTemplates();
+
+ getDerived()->traverseCXXMethodTemplateSpecializations();
+
+ getDerived()->traverseCXXFields();
+
+ getDerived()->traverseCXXFieldTemplates();
+
+ getDerived()->traverseConcepts();
+
+ getDerived()->traverseGlobalVariableTemplateRecords();
+
+ getDerived()->traverseGlobalVariableTemplateSpecializationRecords();
+
+ getDerived()->traverseGlobalVariableTemplatePartialSpecializationRecords();
+
+ getDerived()->traverseGlobalFunctionTemplateRecords();
+
+ getDerived()->traverseGlobalFunctionTemplateSpecializationRecords();
+
+ getDerived()->traverseRecordRecords();
+
+ getDerived()->traverseObjCInterfaces();
+
+ getDerived()->traverseObjCProtocols();
+
+ getDerived()->traverseObjCCategories();
+
+ getDerived()->traverseMacroDefinitionRecords();
+
+ getDerived()->traverseTypedefRecords();
+ }
+
+ void traverseNamespaces() {
+ for (const auto &Namespace : API.getNamespaces())
+ getDerived()->visitNamespaceRecord(*Namespace.second);
+ }
+
+ void traverseGlobalFunctionRecords() {
+ for (const auto &GlobalFunction : API.getGlobalFunctions())
+ getDerived()->visitGlobalFunctionRecord(*GlobalFunction.second);
+ }
+
+ void traverseGlobalVariableRecords() {
+ for (const auto &GlobalVariable : API.getGlobalVariables())
+ getDerived()->visitGlobalVariableRecord(*GlobalVariable.second);
+ }
+
+ void traverseEnumRecords() {
+ for (const auto &Enum : API.getEnums())
+ getDerived()->visitEnumRecord(*Enum.second);
+ }
+
+ void traverseRecordRecords() {
+ for (const auto &Record : API.getRecords())
+ getDerived()->visitRecordRecord(*Record.second);
+ }
+
+ void traverseStaticFieldRecords() {
+ for (const auto &StaticField : API.getStaticFields())
+ getDerived()->visitStaticFieldRecord(*StaticField.second);
+ }
+
+ void traverseCXXClassRecords() {
+ for (const auto &Class : API.getCXXClasses())
+ getDerived()->visitCXXClassRecord(*Class.second);
+ }
+
+ void traverseCXXMethodTemplates() {
+ for (const auto &MethodTemplate : API.getCXXMethodTemplates())
+ getDerived()->visitMethodTemplateRecord(*MethodTemplate.second);
+ }
+
+ void traverseCXXMethodTemplateSpecializations() {
+ for (const auto &MethodTemplateSpecialization :
+ API.getCXXMethodTemplateSpecializations())
+ getDerived()->visitMethodTemplateSpecializationRecord(
+ *MethodTemplateSpecialization.second);
+ }
+
+ void traverseClassTemplateRecords() {
+ for (const auto &ClassTemplate : API.getClassTemplates())
+ getDerived()->visitClassTemplateRecord(*ClassTemplate.second);
+ }
+
+ void traverseClassTemplateSpecializationRecords() {
+ for (const auto &ClassTemplateSpecialization :
+ API.getClassTemplateSpecializations())
+ getDerived()->visitClassTemplateSpecializationRecord(
+ *ClassTemplateSpecialization.second);
+ }
+
+ void traverseClassTemplatePartialSpecializationRecords() {
+ for (const auto &ClassTemplatePartialSpecialization :
+ API.getClassTemplatePartialSpecializations())
+ getDerived()->visitClassTemplatePartialSpecializationRecord(
+ *ClassTemplatePartialSpecialization.second);
+ }
+
+ void traverseCXXInstanceMethods() {
+ for (const auto &InstanceMethod : API.getCXXInstanceMethods())
+ getDerived()->visitCXXInstanceMethodRecord(*InstanceMethod.second);
+ }
+
+ void traverseCXXStaticMethods() {
+ for (const auto &InstanceMethod : API.getCXXStaticMethods())
+ getDerived()->visitCXXStaticMethodRecord(*InstanceMethod.second);
+ }
+
+ void traverseCXXFields() {
+ for (const auto &CXXField : API.getCXXFields())
+ getDerived()->visitCXXFieldRecord(*CXXField.second);
+ }
+
+ void traverseCXXFieldTemplates() {
+ for (const auto &CXXFieldTemplate : API.getCXXFieldTemplates())
+ getDerived()->visitCXXFieldTemplateRecord(*CXXFieldTemplate.second);
+ }
+
+ void traverseGlobalVariableTemplateRecords() {
+ for (const auto &GlobalVariableTemplate : API.getGlobalVariableTemplates())
+ getDerived()->visitGlobalVariableTemplateRecord(
+ *GlobalVariableTemplate.second);
+ }
+
+ void traverseGlobalVariableTemplateSpecializationRecords() {
+ for (const auto &GlobalVariableTemplateSpecialization :
+ API.getGlobalVariableTemplateSpecializations())
+ getDerived()->visitGlobalVariableTemplateSpecializationRecord(
+ *GlobalVariableTemplateSpecialization.second);
+ }
+
+ void traverseGlobalVariableTemplatePartialSpecializationRecords() {
+ for (const auto &GlobalVariableTemplatePartialSpecialization :
+ API.getGlobalVariableTemplatePartialSpecializations())
+ getDerived()->visitGlobalVariableTemplatePartialSpecializationRecord(
+ *GlobalVariableTemplatePartialSpecialization.second);
+ }
+
+ void traverseGlobalFunctionTemplateRecords() {
+ for (const auto &GlobalFunctionTemplate : API.getGlobalFunctionTemplates())
+ getDerived()->visitGlobalFunctionTemplateRecord(
+ *GlobalFunctionTemplate.second);
+ }
+
+ void traverseGlobalFunctionTemplateSpecializationRecords() {
+ for (const auto &GlobalFunctionTemplateSpecialization :
+ API.getGlobalFunctionTemplateSpecializations())
+ getDerived()->visitGlobalFunctionTemplateSpecializationRecord(
+ *GlobalFunctionTemplateSpecialization.second);
+ }
+
+ void traverseConcepts() {
+ for (const auto &Concept : API.getConcepts())
+ getDerived()->visitConceptRecord(*Concept.second);
+ }
+
+ void traverseObjCInterfaces() {
+ for (const auto &Interface : API.getObjCInterfaces())
+ getDerived()->visitObjCContainerRecord(*Interface.second);
+ }
+
+ void traverseObjCProtocols() {
+ for (const auto &Protocol : API.getObjCProtocols())
+ getDerived()->visitObjCContainerRecord(*Protocol.second);
+ }
+
+ void traverseObjCCategories() {
+ for (const auto &Category : API.getObjCCategories())
+ getDerived()->visitObjCCategoryRecord(*Category.second);
+ }
+
+ void traverseMacroDefinitionRecords() {
+ for (const auto &Macro : API.getMacros())
+ getDerived()->visitMacroDefinitionRecord(*Macro.second);
+ }
+
+ void traverseTypedefRecords() {
+ for (const auto &Typedef : API.getTypedefs())
+ getDerived()->visitTypedefRecord(*Typedef.second);
+ }
+
+ void visitNamespaceRecord(const NamespaceRecord &Record){};
+
+ /// Visit a global function record.
+ void visitGlobalFunctionRecord(const GlobalFunctionRecord &Record){};
+
+ /// Visit a global variable record.
+ void visitGlobalVariableRecord(const GlobalVariableRecord &Record){};
+
+ /// Visit an enum record.
+ void visitEnumRecord(const EnumRecord &Record){};
+
+ /// Visit a record record.
+ void visitRecordRecord(const RecordRecord &Record){};
+
+ void visitStaticFieldRecord(const StaticFieldRecord &Record){};
+
+ void visitCXXClassRecord(const CXXClassRecord &Record){};
+
+ void visitClassTemplateRecord(const ClassTemplateRecord &Record){};
+
+ void visitClassTemplateSpecializationRecord(
+ const ClassTemplateSpecializationRecord &Record){};
+
+ void visitClassTemplatePartialSpecializationRecord(
+ const ClassTemplatePartialSpecializationRecord &Record){};
+
+ void visitCXXInstanceRecord(const CXXInstanceMethodRecord &Record){};
+
+ void visitCXXStaticRecord(const CXXStaticMethodRecord &Record){};
+
+ void visitMethodTemplateRecord(const CXXMethodTemplateRecord &Record){};
+
+ void visitMethodTemplateSpecializationRecord(
+ const CXXMethodTemplateSpecializationRecord &Record){};
+
+ void visitCXXFieldTemplateRecord(const CXXFieldTemplateRecord &Record){};
+
+ void visitGlobalVariableTemplateRecord(
+ const GlobalVariableTemplateRecord &Record) {}
+
+ void visitGlobalVariableTemplateSpecializationRecord(
+ const GlobalVariableTemplateSpecializationRecord &Record){};
+
+ void visitGlobalVariableTemplatePartialSpecializationRecord(
+ const GlobalVariableTemplatePartialSpecializationRecord &Record){};
+
+ void visitGlobalFunctionTemplateRecord(
+ const GlobalFunctionTemplateRecord &Record){};
+
+ void visitGlobalFunctionTemplateSpecializationRecord(
+ const GlobalFunctionTemplateSpecializationRecord &Record){};
+
+ /// Visit an Objective-C container record.
+ void visitObjCContainerRecord(const ObjCContainerRecord &Record){};
+
+ /// Visit an Objective-C category record.
+ void visitObjCCategoryRecord(const ObjCCategoryRecord &Record){};
+
+ /// Visit a macro definition record.
+ void visitMacroDefinitionRecord(const MacroDefinitionRecord &Record){};
+
+ /// Visit a typedef record.
+ void visitTypedefRecord(const TypedefRecord &Record){};
+
+protected:
+ const APISet &API;
+
+public:
+ APISetVisitor() = delete;
+ APISetVisitor(const APISetVisitor &) = delete;
+ APISetVisitor(APISetVisitor &&) = delete;
+ APISetVisitor &operator=(const APISetVisitor &) = delete;
+ APISetVisitor &operator=(APISetVisitor &&) = delete;
+
+protected:
+ APISetVisitor(const APISet &API) : API(API) {}
+ ~APISetVisitor() = default;
+
+ Derived *getDerived() { return static_cast<Derived *>(this); };
+};
+
+} // namespace extractapi
+} // namespace clang
+
+#endif // LLVM_CLANG_EXTRACTAPI_SERIALIZATION_SERIALIZERBASE_H
diff --git a/contrib/llvm-project/clang/include/clang/ExtractAPI/Serialization/SymbolGraphSerializer.h b/contrib/llvm-project/clang/include/clang/ExtractAPI/Serialization/SymbolGraphSerializer.h
new file mode 100644
index 000000000000..4249ac405fd2
--- /dev/null
+++ b/contrib/llvm-project/clang/include/clang/ExtractAPI/Serialization/SymbolGraphSerializer.h
@@ -0,0 +1,243 @@
+//===- ExtractAPI/Serialization/SymbolGraphSerializer.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 defines the SymbolGraphSerializer class.
+///
+/// Implement an APISetVisitor to serialize the APISet into the Symbol Graph
+/// format for ExtractAPI. See https://github.com/apple/swift-docc-symbolkit.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_EXTRACTAPI_SERIALIZATION_SYMBOLGRAPHSERIALIZER_H
+#define LLVM_CLANG_EXTRACTAPI_SERIALIZATION_SYMBOLGRAPHSERIALIZER_H
+
+#include "clang/ExtractAPI/API.h"
+#include "clang/ExtractAPI/APIIgnoresList.h"
+#include "clang/ExtractAPI/Serialization/SerializerBase.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringSet.h"
+#include "llvm/Support/JSON.h"
+#include "llvm/Support/VersionTuple.h"
+#include "llvm/Support/raw_ostream.h"
+#include <optional>
+
+namespace clang {
+namespace extractapi {
+
+using namespace llvm::json;
+
+/// Common options to customize the visitor output.
+struct SymbolGraphSerializerOption {
+ /// Do not include unnecessary whitespaces to save space.
+ bool Compact;
+};
+
+/// The visitor that organizes API information in the Symbol Graph format.
+///
+/// The Symbol Graph format (https://github.com/apple/swift-docc-symbolkit)
+/// models an API set as a directed graph, where nodes are symbol declarations,
+/// and edges are relationships between the connected symbols.
+class SymbolGraphSerializer : public APISetVisitor<SymbolGraphSerializer> {
+ /// A JSON array of formatted symbols in \c APISet.
+ Array Symbols;
+
+ /// A JSON array of formatted symbol relationships in \c APISet.
+ Array Relationships;
+
+ /// The Symbol Graph format version used by this serializer.
+ static const VersionTuple FormatVersion;
+
+ /// Indicates whether child symbols should be visited. This is mainly
+ /// useful for \c serializeSingleSymbolSGF.
+ bool ShouldRecurse;
+
+public:
+ /// Serialize the APIs in \c APISet in the Symbol Graph format.
+ ///
+ /// \returns a JSON object that contains the root of the formatted
+ /// Symbol Graph.
+ Object serialize();
+
+ /// Wrap serialize(void) and write out the serialized JSON object to \p os.
+ void serialize(raw_ostream &os);
+
+ /// Serialize a single symbol SGF. This is primarily used for libclang.
+ ///
+ /// \returns an optional JSON Object representing the payload that libclang
+ /// expects for providing symbol information for a single symbol. If this is
+ /// not a known symbol returns \c std::nullopt.
+ static std::optional<Object> serializeSingleSymbolSGF(StringRef USR,
+ const APISet &API);
+
+ /// The kind of a relationship between two symbols.
+ enum RelationshipKind {
+ /// The source symbol is a member of the target symbol.
+ /// For example enum constants are members of the enum, class/instance
+ /// methods are members of the class, etc.
+ MemberOf,
+
+ /// The source symbol is inherited from the target symbol.
+ InheritsFrom,
+
+ /// The source symbol conforms to the target symbol.
+ /// For example Objective-C protocol conformances.
+ ConformsTo,
+
+ /// The source symbol is an extension to the target symbol.
+ /// For example Objective-C categories extending an external type.
+ ExtensionTo,
+ };
+
+ /// Get the string representation of the relationship kind.
+ static StringRef getRelationshipString(RelationshipKind Kind);
+
+ enum ConstraintKind { Conformance, ConditionalConformance };
+
+ static StringRef getConstraintString(ConstraintKind Kind);
+
+private:
+ /// Just serialize the currently recorded objects in Symbol Graph format.
+ Object serializeCurrentGraph();
+
+ /// Synthesize the metadata section of the Symbol Graph format.
+ ///
+ /// The metadata section describes information about the Symbol Graph itself,
+ /// including the format version and the generator information.
+ Object serializeMetadata() const;
+
+ /// Synthesize the module section of the Symbol Graph format.
+ ///
+ /// The module section contains information about the product that is defined
+ /// by the given API set.
+ /// Note that "module" here is not to be confused with the Clang/C++ module
+ /// concept.
+ Object serializeModule() const;
+
+ /// Determine if the given \p Record should be skipped during serialization.
+ bool shouldSkip(const APIRecord &Record) const;
+
+ /// Format the common API information for \p Record.
+ ///
+ /// This handles the shared information of all kinds of API records,
+ /// for example identifier and source location. The resulting object is then
+ /// augmented with kind-specific symbol information by the caller.
+ /// This method also checks if the given \p Record should be skipped during
+ /// serialization.
+ ///
+ /// \returns \c std::nullopt if this \p Record should be skipped, or a JSON
+ /// object containing common symbol information of \p Record.
+ template <typename RecordTy>
+ std::optional<Object> serializeAPIRecord(const RecordTy &Record) const;
+
+ /// Helper method to serialize second-level member records of \p Record and
+ /// the member-of relationships.
+ template <typename MemberTy>
+ void serializeMembers(const APIRecord &Record,
+ const SmallVector<std::unique_ptr<MemberTy>> &Members);
+
+ /// Serialize the \p Kind relationship between \p Source and \p Target.
+ ///
+ /// Record the relationship between the two symbols in
+ /// SymbolGraphSerializer::Relationships.
+ void serializeRelationship(RelationshipKind Kind, SymbolReference Source,
+ SymbolReference Target);
+
+protected:
+ /// The list of symbols to ignore.
+ ///
+ /// Note: This should be consulted before emitting a symbol.
+ const APIIgnoresList &IgnoresList;
+
+ SymbolGraphSerializerOption Options;
+
+ llvm::StringSet<> visitedCategories;
+
+public:
+ void visitNamespaceRecord(const NamespaceRecord &Record);
+
+ /// Visit a global function record.
+ void visitGlobalFunctionRecord(const GlobalFunctionRecord &Record);
+
+ /// Visit a global variable record.
+ void visitGlobalVariableRecord(const GlobalVariableRecord &Record);
+
+ /// Visit an enum record.
+ void visitEnumRecord(const EnumRecord &Record);
+
+ /// Visit a record record.
+ void visitRecordRecord(const RecordRecord &Record);
+
+ void visitStaticFieldRecord(const StaticFieldRecord &Record);
+
+ void visitCXXClassRecord(const CXXClassRecord &Record);
+
+ void visitClassTemplateRecord(const ClassTemplateRecord &Record);
+
+ void visitClassTemplateSpecializationRecord(
+ const ClassTemplateSpecializationRecord &Record);
+
+ void visitClassTemplatePartialSpecializationRecord(
+ const ClassTemplatePartialSpecializationRecord &Record);
+
+ void visitCXXInstanceMethodRecord(const CXXInstanceMethodRecord &Record);
+
+ void visitCXXStaticMethodRecord(const CXXStaticMethodRecord &Record);
+
+ void visitMethodTemplateRecord(const CXXMethodTemplateRecord &Record);
+
+ void visitMethodTemplateSpecializationRecord(
+ const CXXMethodTemplateSpecializationRecord &Record);
+
+ void visitCXXFieldRecord(const CXXFieldRecord &Record);
+
+ void visitCXXFieldTemplateRecord(const CXXFieldTemplateRecord &Record);
+
+ void visitConceptRecord(const ConceptRecord &Record);
+
+ void
+ visitGlobalVariableTemplateRecord(const GlobalVariableTemplateRecord &Record);
+
+ void visitGlobalVariableTemplateSpecializationRecord(
+ const GlobalVariableTemplateSpecializationRecord &Record);
+
+ void visitGlobalVariableTemplatePartialSpecializationRecord(
+ const GlobalVariableTemplatePartialSpecializationRecord &Record);
+
+ void
+ visitGlobalFunctionTemplateRecord(const GlobalFunctionTemplateRecord &Record);
+
+ void visitGlobalFunctionTemplateSpecializationRecord(
+ const GlobalFunctionTemplateSpecializationRecord &Record);
+
+ /// Visit an Objective-C container record.
+ void visitObjCContainerRecord(const ObjCContainerRecord &Record);
+
+ /// Visit an Objective-C category record.
+ void visitObjCCategoryRecord(const ObjCCategoryRecord &Record);
+
+ /// Visit a macro definition record.
+ void visitMacroDefinitionRecord(const MacroDefinitionRecord &Record);
+
+ /// Visit a typedef record.
+ void visitTypedefRecord(const TypedefRecord &Record);
+
+ /// Serialize a single record.
+ void serializeSingleRecord(const APIRecord *Record);
+
+ SymbolGraphSerializer(const APISet &API, const APIIgnoresList &IgnoresList,
+ SymbolGraphSerializerOption Options = {},
+ bool ShouldRecurse = true)
+ : APISetVisitor(API), ShouldRecurse(ShouldRecurse),
+ IgnoresList(IgnoresList), Options(Options) {}
+};
+
+} // namespace extractapi
+} // namespace clang
+
+#endif // LLVM_CLANG_EXTRACTAPI_SERIALIZATION_SYMBOLGRAPHSERIALIZER_H
diff --git a/contrib/llvm-project/clang/include/clang/ExtractAPI/TypedefUnderlyingTypeResolver.h b/contrib/llvm-project/clang/include/clang/ExtractAPI/TypedefUnderlyingTypeResolver.h
new file mode 100644
index 000000000000..54aa11c354c0
--- /dev/null
+++ b/contrib/llvm-project/clang/include/clang/ExtractAPI/TypedefUnderlyingTypeResolver.h
@@ -0,0 +1,48 @@
+//===- ExtractAPI/TypedefUnderlyingTypeResolver.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 defines the UnderlyingTypeResolver which is a helper type for
+/// resolving the undelrying type for a given QualType and exposing that
+/// information in various forms.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_UNDERLYING_TYPE_RESOLVER_H
+#define LLVM_CLANG_UNDERLYING_TYPE_RESOLVER_H
+
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/Decl.h"
+#include "clang/ExtractAPI/API.h"
+
+#include <string>
+
+namespace clang {
+namespace extractapi {
+
+struct TypedefUnderlyingTypeResolver {
+ /// Gets the underlying type declaration.
+ const NamedDecl *getUnderlyingTypeDecl(QualType Type) const;
+
+ /// Get a SymbolReference for the given type.
+ SymbolReference getSymbolReferenceForType(QualType Type, APISet &API) const;
+
+ /// Get a USR for the given type.
+ std::string getUSRForType(QualType Type) const;
+
+ explicit TypedefUnderlyingTypeResolver(ASTContext &Context)
+ : Context(Context) {}
+
+private:
+ ASTContext &Context;
+};
+
+} // namespace extractapi
+} // namespace clang
+
+#endif // LLVM_CLANG_UNDERLYING_TYPE_RESOLVER_H
diff --git a/contrib/llvm-project/clang/include/clang/Format/Format.h b/contrib/llvm-project/clang/include/clang/Format/Format.h
index c424e79a971c..efcb4e1d87ea 100755
--- a/contrib/llvm-project/clang/include/clang/Format/Format.h
+++ b/contrib/llvm-project/clang/include/clang/Format/Format.h
@@ -20,6 +20,7 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/Support/Regex.h"
#include "llvm/Support/SourceMgr.h"
+#include <optional>
#include <system_error>
namespace llvm {
@@ -29,18 +30,17 @@ class FileSystem;
} // namespace llvm
namespace clang {
-
-class Lexer;
-class SourceManager;
-class DiagnosticConsumer;
-
namespace format {
enum class ParseError {
Success = 0,
Error,
Unsuitable,
- BinPackTrailingCommaConflict
+ BinPackTrailingCommaConflict,
+ InvalidQualifierSpecified,
+ DuplicateQualifierSpecified,
+ MissingQualifierType,
+ MissingQualifierOrder
};
class ParseErrorCategory final : public std::error_category {
public:
@@ -59,10 +59,11 @@ struct FormatStyle {
bool InheritsParentConfig;
/// The extra indent or outdent of access modifiers, e.g. ``public:``.
+ /// \version 3.3
int AccessModifierOffset;
/// Different styles for aligning after open brackets.
- enum BracketAlignmentStyle : unsigned char {
+ enum BracketAlignmentStyle : int8_t {
/// Align parameters on the open bracket, e.g.:
/// \code
/// someLongFunction(argument1,
@@ -82,16 +83,31 @@ 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
+ ///
+ /// \note
+ /// This currently only applies to braced initializer lists (when
+ /// ``Cpp11BracedListStyle`` is ``true``) and parentheses.
+ /// \endnote
+ BAS_BlockIndent,
};
/// If ``true``, horizontally aligns arguments after an open bracket.
///
/// This applies to round brackets (parentheses), angle brackets and square
/// brackets.
+ /// \version 3.8
BracketAlignmentStyle AlignAfterOpenBracket;
/// Different style for aligning array initializers.
- enum ArrayInitializerAlignmentStyle {
+ enum ArrayInitializerAlignmentStyle : int8_t {
/// Align array column and left justify the columns e.g.:
/// \code
/// struct test demo[] =
@@ -117,20 +133,143 @@ struct FormatStyle {
};
/// if not ``None``, when using initialization for an array of structs
/// aligns the fields into columns.
+ ///
+ /// \note
+ /// As of clang-format 15 this option only applied to arrays with equal
+ /// number of columns per row.
+ /// \endnote
+ ///
+ /// \version 13
ArrayInitializerAlignmentStyle AlignArrayOfStructures;
- /// Styles for alignment of consecutive tokens. Tokens can be assignment signs
- /// (see
- /// ``AlignConsecutiveAssignments``), bitfield member separators (see
- /// ``AlignConsecutiveBitFields``), names in declarations (see
- /// ``AlignConsecutiveDeclarations``) or macro definitions (see
- /// ``AlignConsecutiveMacros``).
- enum AlignConsecutiveStyle {
- ACS_None,
- ACS_Consecutive,
- ACS_AcrossEmptyLines,
- ACS_AcrossComments,
- ACS_AcrossEmptyLinesAndComments
+ /// Alignment options.
+ ///
+ /// They can also be read as a whole for compatibility. The choices are:
+ /// - None
+ /// - Consecutive
+ /// - AcrossEmptyLines
+ /// - AcrossComments
+ /// - AcrossEmptyLinesAndComments
+ ///
+ /// For example, to align across empty lines and not across comments, either
+ /// of these work.
+ /// \code
+ /// AlignConsecutiveMacros: AcrossEmptyLines
+ ///
+ /// AlignConsecutiveMacros:
+ /// Enabled: true
+ /// AcrossEmptyLines: true
+ /// AcrossComments: false
+ /// \endcode
+ struct AlignConsecutiveStyle {
+ /// Whether aligning is enabled.
+ /// \code
+ /// #define SHORT_NAME 42
+ /// #define LONGER_NAME 0x007f
+ /// #define EVEN_LONGER_NAME (2)
+ /// #define foo(x) (x * x)
+ /// #define bar(y, z) (y + z)
+ ///
+ /// int a = 1;
+ /// int somelongname = 2;
+ /// double c = 3;
+ ///
+ /// int aaaa : 1;
+ /// int b : 12;
+ /// int ccc : 8;
+ ///
+ /// int aaaa = 12;
+ /// float b = 23;
+ /// std::string ccc;
+ /// \endcode
+ bool Enabled;
+ /// Whether to align across empty lines.
+ /// \code
+ /// true:
+ /// int a = 1;
+ /// int somelongname = 2;
+ /// double c = 3;
+ ///
+ /// int d = 3;
+ ///
+ /// false:
+ /// int a = 1;
+ /// int somelongname = 2;
+ /// double c = 3;
+ ///
+ /// int d = 3;
+ /// \endcode
+ bool AcrossEmptyLines;
+ /// Whether to align across comments.
+ /// \code
+ /// true:
+ /// int d = 3;
+ /// /* A comment. */
+ /// double e = 4;
+ ///
+ /// false:
+ /// int d = 3;
+ /// /* A comment. */
+ /// double e = 4;
+ /// \endcode
+ bool AcrossComments;
+ /// Only for ``AlignConsecutiveAssignments``. Whether compound assignments
+ /// like ``+=`` are aligned along with ``=``.
+ /// \code
+ /// true:
+ /// a &= 2;
+ /// bbb = 2;
+ ///
+ /// false:
+ /// a &= 2;
+ /// bbb = 2;
+ /// \endcode
+ bool AlignCompound;
+ /// Only for ``AlignConsecutiveDeclarations``. Whether function pointers are
+ /// aligned.
+ /// \code
+ /// true:
+ /// unsigned i;
+ /// int &r;
+ /// int *p;
+ /// int (*f)();
+ ///
+ /// false:
+ /// unsigned i;
+ /// int &r;
+ /// int *p;
+ /// int (*f)();
+ /// \endcode
+ bool AlignFunctionPointers;
+ /// Only for ``AlignConsecutiveAssignments``. Whether short assignment
+ /// operators are left-padded to the same length as long ones in order to
+ /// put all assignment operators to the right of the left hand side.
+ /// \code
+ /// true:
+ /// a >>= 2;
+ /// bbb = 2;
+ ///
+ /// a = 2;
+ /// bbb >>= 2;
+ ///
+ /// false:
+ /// a >>= 2;
+ /// bbb = 2;
+ ///
+ /// a = 2;
+ /// bbb >>= 2;
+ /// \endcode
+ bool PadOperators;
+ bool operator==(const AlignConsecutiveStyle &R) const {
+ return Enabled == R.Enabled && AcrossEmptyLines == R.AcrossEmptyLines &&
+ AcrossComments == R.AcrossComments &&
+ AlignCompound == R.AlignCompound &&
+ AlignFunctionPointers == R.AlignFunctionPointers &&
+ PadOperators == R.PadOperators;
+ }
+ bool operator!=(const AlignConsecutiveStyle &R) const {
+ return !(*this == R);
+ }
};
/// Style of aligning consecutive macro definitions.
@@ -143,66 +282,8 @@ struct FormatStyle {
/// #define foo(x) (x * x)
/// #define bar(y, z) (y + z)
/// \endcode
- ///
- /// Possible values:
- ///
- /// * ``ACS_None`` (in configuration: ``None``)
- /// Do not align macro definitions on consecutive lines.
- ///
- /// * ``ACS_Consecutive`` (in configuration: ``Consecutive``)
- /// Align macro definitions on consecutive lines. This will result in
- /// formattings like:
- /// \code
- /// #define SHORT_NAME 42
- /// #define LONGER_NAME 0x007f
- /// #define EVEN_LONGER_NAME (2)
- ///
- /// #define foo(x) (x * x)
- /// /* some comment */
- /// #define bar(y, z) (y + z)
- /// \endcode
- ///
- /// * ``ACS_AcrossEmptyLines`` (in configuration: ``AcrossEmptyLines``)
- /// Same as ACS_Consecutive, but also spans over empty lines, e.g.
- /// \code
- /// #define SHORT_NAME 42
- /// #define LONGER_NAME 0x007f
- /// #define EVEN_LONGER_NAME (2)
- ///
- /// #define foo(x) (x * x)
- /// /* some comment */
- /// #define bar(y, z) (y + z)
- /// \endcode
- ///
- /// * ``ACS_AcrossComments`` (in configuration: ``AcrossComments``)
- /// Same as ACS_Consecutive, but also spans over lines only containing
- /// comments, e.g.
- /// \code
- /// #define SHORT_NAME 42
- /// #define LONGER_NAME 0x007f
- /// #define EVEN_LONGER_NAME (2)
- ///
- /// #define foo(x) (x * x)
- /// /* some comment */
- /// #define bar(y, z) (y + z)
- /// \endcode
- ///
- /// * ``ACS_AcrossEmptyLinesAndComments``
- /// (in configuration: ``AcrossEmptyLinesAndComments``)
- ///
- /// Same as ACS_Consecutive, but also spans over lines only containing
- /// comments and empty lines, e.g.
- /// \code
- /// #define SHORT_NAME 42
- /// #define LONGER_NAME 0x007f
- /// #define EVEN_LONGER_NAME (2)
- ///
- /// #define foo(x) (x * x)
- /// /* some comment */
- /// #define bar(y, z) (y + z)
- /// \endcode
+ /// \version 9
AlignConsecutiveStyle AlignConsecutiveMacros;
-
/// Style of aligning consecutive assignments.
///
/// ``Consecutive`` will result in formattings like:
@@ -211,67 +292,9 @@ struct FormatStyle {
/// int somelongname = 2;
/// double c = 3;
/// \endcode
- ///
- /// Possible values:
- ///
- /// * ``ACS_None`` (in configuration: ``None``)
- /// Do not align assignments on consecutive lines.
- ///
- /// * ``ACS_Consecutive`` (in configuration: ``Consecutive``)
- /// Align assignments on consecutive lines. This will result in
- /// formattings like:
- /// \code
- /// int a = 1;
- /// int somelongname = 2;
- /// double c = 3;
- ///
- /// int d = 3;
- /// /* A comment. */
- /// double e = 4;
- /// \endcode
- ///
- /// * ``ACS_AcrossEmptyLines`` (in configuration: ``AcrossEmptyLines``)
- /// Same as ACS_Consecutive, but also spans over empty lines, e.g.
- /// \code
- /// int a = 1;
- /// int somelongname = 2;
- /// double c = 3;
- ///
- /// int d = 3;
- /// /* A comment. */
- /// double e = 4;
- /// \endcode
- ///
- /// * ``ACS_AcrossComments`` (in configuration: ``AcrossComments``)
- /// Same as ACS_Consecutive, but also spans over lines only containing
- /// comments, e.g.
- /// \code
- /// int a = 1;
- /// int somelongname = 2;
- /// double c = 3;
- ///
- /// int d = 3;
- /// /* A comment. */
- /// double e = 4;
- /// \endcode
- ///
- /// * ``ACS_AcrossEmptyLinesAndComments``
- /// (in configuration: ``AcrossEmptyLinesAndComments``)
- ///
- /// Same as ACS_Consecutive, but also spans over lines only containing
- /// comments and empty lines, e.g.
- /// \code
- /// int a = 1;
- /// int somelongname = 2;
- /// double c = 3;
- ///
- /// int d = 3;
- /// /* A comment. */
- /// double e = 4;
- /// \endcode
+ /// \version 3.8
AlignConsecutiveStyle AlignConsecutiveAssignments;
-
- /// Style of aligning consecutive bit field.
+ /// Style of aligning consecutive bit fields.
///
/// ``Consecutive`` will align the bitfield separators of consecutive lines.
/// This will result in formattings like:
@@ -280,66 +303,8 @@ struct FormatStyle {
/// int b : 12;
/// int ccc : 8;
/// \endcode
- ///
- /// Possible values:
- ///
- /// * ``ACS_None`` (in configuration: ``None``)
- /// Do not align bit fields on consecutive lines.
- ///
- /// * ``ACS_Consecutive`` (in configuration: ``Consecutive``)
- /// Align bit fields on consecutive lines. This will result in
- /// formattings like:
- /// \code
- /// int aaaa : 1;
- /// int b : 12;
- /// int ccc : 8;
- ///
- /// int d : 2;
- /// /* A comment. */
- /// int ee : 3;
- /// \endcode
- ///
- /// * ``ACS_AcrossEmptyLines`` (in configuration: ``AcrossEmptyLines``)
- /// Same as ACS_Consecutive, but also spans over empty lines, e.g.
- /// \code
- /// int aaaa : 1;
- /// int b : 12;
- /// int ccc : 8;
- ///
- /// int d : 2;
- /// /* A comment. */
- /// int ee : 3;
- /// \endcode
- ///
- /// * ``ACS_AcrossComments`` (in configuration: ``AcrossComments``)
- /// Same as ACS_Consecutive, but also spans over lines only containing
- /// comments, e.g.
- /// \code
- /// int aaaa : 1;
- /// int b : 12;
- /// int ccc : 8;
- ///
- /// int d : 2;
- /// /* A comment. */
- /// int ee : 3;
- /// \endcode
- ///
- /// * ``ACS_AcrossEmptyLinesAndComments``
- /// (in configuration: ``AcrossEmptyLinesAndComments``)
- ///
- /// Same as ACS_Consecutive, but also spans over lines only containing
- /// comments and empty lines, e.g.
- /// \code
- /// int aaaa : 1;
- /// int b : 12;
- /// int ccc : 8;
- ///
- /// int d : 2;
- /// /* A comment. */
- /// int ee : 3;
- /// \endcode
+ /// \version 11
AlignConsecutiveStyle AlignConsecutiveBitFields;
-
/// Style of aligning consecutive declarations.
///
/// ``Consecutive`` will align the declaration names of consecutive lines.
@@ -349,68 +314,108 @@ struct FormatStyle {
/// float b = 23;
/// std::string ccc;
/// \endcode
- ///
- /// Possible values:
- ///
- /// * ``ACS_None`` (in configuration: ``None``)
- /// Do not align bit declarations on consecutive lines.
- ///
- /// * ``ACS_Consecutive`` (in configuration: ``Consecutive``)
- /// Align declarations on consecutive lines. This will result in
- /// formattings like:
- /// \code
- /// int aaaa = 12;
- /// float b = 23;
- /// std::string ccc;
- ///
- /// int a = 42;
- /// /* A comment. */
- /// bool c = false;
- /// \endcode
- ///
- /// * ``ACS_AcrossEmptyLines`` (in configuration: ``AcrossEmptyLines``)
- /// Same as ACS_Consecutive, but also spans over empty lines, e.g.
- /// \code
- /// int aaaa = 12;
- /// float b = 23;
- /// std::string ccc;
- ///
- /// int a = 42;
- /// /* A comment. */
- /// bool c = false;
- /// \endcode
- ///
- /// * ``ACS_AcrossComments`` (in configuration: ``AcrossComments``)
- /// Same as ACS_Consecutive, but also spans over lines only containing
- /// comments, e.g.
- /// \code
- /// int aaaa = 12;
- /// float b = 23;
- /// std::string ccc;
- ///
- /// int a = 42;
- /// /* A comment. */
- /// bool c = false;
- /// \endcode
- ///
- /// * ``ACS_AcrossEmptyLinesAndComments``
- /// (in configuration: ``AcrossEmptyLinesAndComments``)
- ///
- /// Same as ACS_Consecutive, but also spans over lines only containing
- /// comments and empty lines, e.g.
- /// \code
- /// int aaaa = 12;
- /// float b = 23;
- /// std::string ccc;
- ///
- /// int a = 42;
- /// /* A comment. */
- /// bool c = false;
- /// \endcode
+ /// \version 3.8
AlignConsecutiveStyle AlignConsecutiveDeclarations;
+ /// Alignment options.
+ ///
+ struct ShortCaseStatementsAlignmentStyle {
+ /// Whether aligning is enabled.
+ /// \code
+ /// true:
+ /// switch (level) {
+ /// case log::info: return "info:";
+ /// case log::warning: return "warning:";
+ /// default: return "";
+ /// }
+ ///
+ /// false:
+ /// switch (level) {
+ /// case log::info: return "info:";
+ /// case log::warning: return "warning:";
+ /// default: return "";
+ /// }
+ /// \endcode
+ bool Enabled;
+ /// Whether to align across empty lines.
+ /// \code
+ /// true:
+ /// switch (level) {
+ /// case log::info: return "info:";
+ /// case log::warning: return "warning:";
+ ///
+ /// default: return "";
+ /// }
+ ///
+ /// false:
+ /// switch (level) {
+ /// case log::info: return "info:";
+ /// case log::warning: return "warning:";
+ ///
+ /// default: return "";
+ /// }
+ /// \endcode
+ bool AcrossEmptyLines;
+ /// Whether to align across comments.
+ /// \code
+ /// true:
+ /// switch (level) {
+ /// case log::info: return "info:";
+ /// case log::warning: return "warning:";
+ /// /* A comment. */
+ /// default: return "";
+ /// }
+ ///
+ /// false:
+ /// switch (level) {
+ /// case log::info: return "info:";
+ /// case log::warning: return "warning:";
+ /// /* A comment. */
+ /// default: return "";
+ /// }
+ /// \endcode
+ bool AcrossComments;
+ /// Whether aligned case labels are aligned on the colon, or on the
+ /// , or on the tokens after the colon.
+ /// \code
+ /// true:
+ /// switch (level) {
+ /// case log::info : return "info:";
+ /// case log::warning: return "warning:";
+ /// default : return "";
+ /// }
+ ///
+ /// false:
+ /// switch (level) {
+ /// case log::info: return "info:";
+ /// case log::warning: return "warning:";
+ /// default: return "";
+ /// }
+ /// \endcode
+ bool AlignCaseColons;
+ bool operator==(const ShortCaseStatementsAlignmentStyle &R) const {
+ return Enabled == R.Enabled && AcrossEmptyLines == R.AcrossEmptyLines &&
+ AcrossComments == R.AcrossComments &&
+ AlignCaseColons == R.AlignCaseColons;
+ }
+ };
+
+ /// Style of aligning consecutive short case labels.
+ /// Only applies if ``AllowShortCaseLabelsOnASingleLine`` is ``true``.
+ ///
+ /// \code{.yaml}
+ /// # Example of usage:
+ /// AlignConsecutiveShortCaseStatements:
+ /// Enabled: true
+ /// AcrossEmptyLines: true
+ /// AcrossComments: true
+ /// AlignCaseColons: false
+ /// \endcode
+ /// \version 17
+ ShortCaseStatementsAlignmentStyle AlignConsecutiveShortCaseStatements;
+
/// Different styles for aligning escaped newlines.
- enum EscapedNewlineAlignmentStyle : unsigned char {
+ enum EscapedNewlineAlignmentStyle : int8_t {
/// Don't align escaped newlines.
/// \code
/// #define A \
@@ -441,10 +446,11 @@ struct FormatStyle {
};
/// Options for aligning backslashes in escaped newlines.
+ /// \version 5
EscapedNewlineAlignmentStyle AlignEscapedNewlines;
/// Different styles for aligning operands.
- enum OperandAlignmentStyle : unsigned char {
+ enum OperandAlignmentStyle : int8_t {
/// Do not align operands of binary and ternary expressions.
/// The wrapped lines are indented ``ContinuationIndentWidth`` spaces from
/// the start of the line.
@@ -479,15 +485,95 @@ struct FormatStyle {
/// If ``true``, horizontally align operands of binary and ternary
/// expressions.
+ /// \version 3.5
OperandAlignmentStyle AlignOperands;
- /// If ``true``, aligns trailing comments.
- /// \code
- /// true: false:
- /// int a; // My comment a vs. int a; // My comment a
- /// int b = 2; // comment b int b = 2; // comment about b
+ /// Enums for AlignTrailingComments
+ enum TrailingCommentsAlignmentKinds : int8_t {
+ /// Leave trailing comments as they are.
+ /// \code
+ /// int a; // comment
+ /// int ab; // comment
+ ///
+ /// int abc; // comment
+ /// int abcd; // comment
+ /// \endcode
+ TCAS_Leave,
+ /// Align trailing comments.
+ /// \code
+ /// int a; // comment
+ /// int ab; // comment
+ ///
+ /// int abc; // comment
+ /// int abcd; // comment
+ /// \endcode
+ TCAS_Always,
+ /// Don't align trailing comments but other formatter applies.
+ /// \code
+ /// int a; // comment
+ /// int ab; // comment
+ ///
+ /// int abc; // comment
+ /// int abcd; // comment
+ /// \endcode
+ TCAS_Never,
+ };
+
+ /// Alignment options
+ struct TrailingCommentsAlignmentStyle {
+ /// Specifies the way to align trailing comments.
+ TrailingCommentsAlignmentKinds Kind;
+ /// How many empty lines to apply alignment.
+ /// When both ``MaxEmptyLinesToKeep`` and ``OverEmptyLines`` are set to 2,
+ /// it formats like below.
+ /// \code
+ /// int a; // all these
+ ///
+ /// int ab; // comments are
+ ///
+ ///
+ /// int abcdef; // aligned
+ /// \endcode
+ ///
+ /// When ``MaxEmptyLinesToKeep`` is set to 2 and ``OverEmptyLines`` is set
+ /// to 1, it formats like below.
+ /// \code
+ /// int a; // these are
+ ///
+ /// int ab; // aligned
+ ///
+ ///
+ /// int abcdef; // but this isn't
+ /// \endcode
+ unsigned OverEmptyLines;
+
+ bool operator==(const TrailingCommentsAlignmentStyle &R) const {
+ return Kind == R.Kind && OverEmptyLines == R.OverEmptyLines;
+ }
+ bool operator!=(const TrailingCommentsAlignmentStyle &R) const {
+ return !(*this == R);
+ }
+ };
+
+ /// Control of trailing comments.
+ ///
+ /// The alignment stops at closing braces after a line break, and only
+ /// followed by other closing braces, a (``do-``) ``while``, a lambda call, or
+ /// a semicolon.
+ ///
+ /// \note
+ /// As of clang-format 16 this option is not a bool but can be set
+ /// to the options. Conventional bool options still can be parsed as before.
+ /// \endnote
+ ///
+ /// \code{.yaml}
+ /// # Example of usage:
+ /// AlignTrailingComments:
+ /// Kind: Always
+ /// OverEmptyLines: 2
/// \endcode
- bool AlignTrailingComments;
+ /// \version 3.7
+ TrailingCommentsAlignmentStyle AlignTrailingComments;
/// \brief If a function call or braced initializer list doesn't fit on a
/// line, allow putting all arguments onto the next line, even if
@@ -503,23 +589,13 @@ struct FormatStyle {
/// c,
/// d);
/// \endcode
+ /// \version 9
bool AllowAllArgumentsOnNextLine;
- /// \brief If a constructor definition with a member initializer list doesn't
- /// fit on a single line, allow putting all member initializers onto the next
- /// line, if ```ConstructorInitializerAllOnOneLineOrOnePerLine``` is true.
- /// Note that this parameter has no effect if
- /// ```ConstructorInitializerAllOnOneLineOrOnePerLine``` is false.
- /// \code
- /// true:
- /// MyClass::MyClass() :
- /// member0(0), member1(2) {}
- ///
- /// false:
- /// MyClass::MyClass() :
- /// member0(0),
- /// member1(2) {}
- bool AllowAllConstructorInitializersOnNextLine;
+ /// This option is **deprecated**. See ``NextLine`` of
+ /// ``PackConstructorInitializers``.
+ /// \version 9
+ // bool AllowAllConstructorInitializersOnNextLine;
/// If the function declaration doesn't fit on a line,
/// allow putting all parameters of a function declaration onto
@@ -536,25 +612,53 @@ struct FormatStyle {
/// int d,
/// int e);
/// \endcode
+ /// \version 3.3
bool AllowAllParametersOfDeclarationOnNextLine;
- /// Allow short enums on a single line.
- /// \code
- /// true:
- /// enum { A, B } myEnum;
- ///
- /// false:
- /// enum
- /// {
- /// A,
- /// B
- /// } myEnum;
- /// \endcode
- bool AllowShortEnumsOnASingleLine;
+ /// Different ways to break before a noexcept specifier.
+ enum BreakBeforeNoexceptSpecifierStyle : int8_t {
+ /// No line break allowed.
+ /// \code
+ /// void foo(int arg1,
+ /// double arg2) noexcept;
+ ///
+ /// void bar(int arg1, double arg2) noexcept(
+ /// noexcept(baz(arg1)) &&
+ /// noexcept(baz(arg2)));
+ /// \endcode
+ BBNSS_Never,
+ /// For a simple ``noexcept`` there is no line break allowed, but when we
+ /// have a condition it is.
+ /// \code
+ /// void foo(int arg1,
+ /// double arg2) noexcept;
+ ///
+ /// void bar(int arg1, double arg2)
+ /// noexcept(noexcept(baz(arg1)) &&
+ /// noexcept(baz(arg2)));
+ /// \endcode
+ BBNSS_OnlyWithParen,
+ /// Line breaks are allowed. But note that because of the associated
+ /// penalties ``clang-format`` often prefers not to break before the
+ /// ``noexcept``.
+ /// \code
+ /// void foo(int arg1,
+ /// double arg2) noexcept;
+ ///
+ /// void bar(int arg1, double arg2)
+ /// noexcept(noexcept(baz(arg1)) &&
+ /// noexcept(baz(arg2)));
+ /// \endcode
+ BBNSS_Always,
+ };
+
+ /// Controls if there could be a line break before a ``noexcept`` specifier.
+ /// \version 18
+ BreakBeforeNoexceptSpecifierStyle AllowBreakBeforeNoexceptSpecifier;
/// Different styles for merging short blocks containing at most one
/// statement.
- enum ShortBlockStyle : unsigned char {
+ enum ShortBlockStyle : int8_t {
/// Never merge blocks into a single line.
/// \code
/// while (true) {
@@ -582,6 +686,7 @@ struct FormatStyle {
/// Dependent on the value, ``while (true) { continue; }`` can be put on a
/// single line.
+ /// \version 3.5
ShortBlockStyle AllowShortBlocksOnASingleLine;
/// If ``true``, short case labels will be contracted to a single line.
@@ -595,11 +700,45 @@ struct FormatStyle {
/// return;
/// }
/// \endcode
+ /// \version 3.6
bool AllowShortCaseLabelsOnASingleLine;
+ /// Allow short compound requirement on a single line.
+ /// \code
+ /// true:
+ /// template <typename T>
+ /// concept c = requires(T x) {
+ /// { x + 1 } -> std::same_as<int>;
+ /// };
+ ///
+ /// false:
+ /// template <typename T>
+ /// concept c = requires(T x) {
+ /// {
+ /// x + 1
+ /// } -> std::same_as<int>;
+ /// };
+ /// \endcode
+ /// \version 18
+ bool AllowShortCompoundRequirementOnASingleLine;
+
+ /// Allow short enums on a single line.
+ /// \code
+ /// true:
+ /// enum { A, B } myEnum;
+ ///
+ /// false:
+ /// enum {
+ /// A,
+ /// B
+ /// } myEnum;
+ /// \endcode
+ /// \version 11
+ bool AllowShortEnumsOnASingleLine;
+
/// Different styles for merging short functions containing at most one
/// statement.
- enum ShortFunctionStyle : unsigned char {
+ enum ShortFunctionStyle : int8_t {
/// Never merge functions into a single line.
SFS_None,
/// Only merge functions defined inside a class. Same as "inline",
@@ -647,10 +786,11 @@ struct FormatStyle {
/// Dependent on the value, ``int f() { return 0; }`` can be put on a
/// single line.
+ /// \version 3.5
ShortFunctionStyle AllowShortFunctionsOnASingleLine;
/// Different styles for handling short if statements.
- enum ShortIfStyle : unsigned char {
+ enum ShortIfStyle : int8_t {
/// Never put short ifs on the same line.
/// \code
/// if (a)
@@ -717,32 +857,33 @@ struct FormatStyle {
};
/// Dependent on the value, ``if (a) return;`` can be put on a single line.
+ /// \version 3.3
ShortIfStyle AllowShortIfStatementsOnASingleLine;
/// Different styles for merging short lambdas containing at most one
/// statement.
- enum ShortLambdaStyle : unsigned char {
+ enum ShortLambdaStyle : int8_t {
/// Never merge lambdas into a single line.
SLS_None,
/// Only merge empty lambdas.
/// \code
- /// auto lambda = [](int a) {}
+ /// auto lambda = [](int a) {};
/// auto lambda2 = [](int a) {
/// return a;
/// };
/// \endcode
SLS_Empty,
- /// Merge lambda into a single line if argument of a function.
+ /// Merge lambda into a single line if the lambda is argument of a function.
/// \code
- /// auto lambda = [](int a) {
- /// return a;
+ /// auto lambda = [](int x, int y) {
+ /// return x < y;
/// };
- /// sort(a.begin(), a.end(), ()[] { return x < y; })
+ /// sort(a.begin(), a.end(), [](int x, int y) { return x < y; });
/// \endcode
SLS_Inline,
/// Merge all lambdas fitting on a single line.
/// \code
- /// auto lambda = [](int a) {}
+ /// auto lambda = [](int a) {};
/// auto lambda2 = [](int a) { return a; };
/// \endcode
SLS_All,
@@ -750,15 +891,17 @@ struct FormatStyle {
/// Dependent on the value, ``auto lambda []() { return 0; }`` can be put on a
/// single line.
+ /// \version 9
ShortLambdaStyle AllowShortLambdasOnASingleLine;
/// If ``true``, ``while (true) continue;`` can be put on a single
/// line.
+ /// \version 3.7
bool AllowShortLoopsOnASingleLine;
/// Different ways to break after the function definition return type.
/// This option is **deprecated** and is retained for backwards compatibility.
- enum DefinitionReturnTypeBreakingStyle : unsigned char {
+ enum DefinitionReturnTypeBreakingStyle : int8_t {
/// Break after return type automatically.
/// ``PenaltyReturnTypeOnItsOwnLine`` is taken into account.
DRTBS_None,
@@ -770,7 +913,7 @@ struct FormatStyle {
/// Different ways to break after the function definition or
/// declaration return type.
- enum ReturnTypeBreakingStyle : unsigned char {
+ enum ReturnTypeBreakingStyle : int8_t {
/// Break after return type automatically.
/// ``PenaltyReturnTypeOnItsOwnLine`` is taken into account.
/// \code
@@ -841,9 +984,11 @@ struct FormatStyle {
/// The function definition return type breaking style to use. This
/// option is **deprecated** and is retained for backwards compatibility.
+ /// \version 3.7
DefinitionReturnTypeBreakingStyle AlwaysBreakAfterDefinitionReturnType;
/// The function declaration return type breaking style to use.
+ /// \version 3.8
ReturnTypeBreakingStyle AlwaysBreakAfterReturnType;
/// If ``true``, always break before multiline string literals.
@@ -858,10 +1003,11 @@ struct FormatStyle {
/// "bbbb" "cccc";
/// "cccc";
/// \endcode
+ /// \version 3.4
bool AlwaysBreakBeforeMultilineStrings;
/// Different ways to break after the template declaration.
- enum BreakTemplateDeclarationsStyle : unsigned char {
+ enum BreakTemplateDeclarationsStyle : int8_t {
/// Do not force break before declaration.
/// ``PenaltyBreakTemplateDeclaration`` is taken into account.
/// \code
@@ -897,6 +1043,7 @@ struct FormatStyle {
};
/// The template declaration breaking style to use.
+ /// \version 3.4
BreakTemplateDeclarationsStyle AlwaysBreakTemplateDeclarations;
/// A vector of strings that should be interpreted as attributes/qualifiers
@@ -906,15 +1053,16 @@ struct FormatStyle {
/// For example:
/// \code
/// x = (char *__capability)&y;
- /// int function(void) __ununsed;
+ /// int function(void) __unused;
/// void only_writes_to_buffer(char *__output buffer);
/// \endcode
///
/// In the .clang-format configuration file, this can be configured like:
/// \code{.yaml}
- /// AttributeMacros: ['__capability', '__output', '__ununsed']
+ /// AttributeMacros: ['__capability', '__output', '__unused']
/// \endcode
///
+ /// \version 12
std::vector<std::string> AttributeMacros;
/// If ``false``, a function call's arguments will either be all on the
@@ -933,37 +1081,9 @@ struct FormatStyle {
/// aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa);
/// }
/// \endcode
+ /// \version 3.7
bool BinPackArguments;
- /// The style of inserting trailing commas into container literals.
- enum TrailingCommaStyle : unsigned char {
- /// Do not insert trailing commas.
- TCS_None,
- /// Insert trailing commas in container literals that were wrapped over
- /// multiple lines. Note that this is conceptually incompatible with
- /// bin-packing, because the trailing comma is used as an indicator
- /// that a container should be formatted one-per-line (i.e. not bin-packed).
- /// So inserting a trailing comma counteracts bin-packing.
- TCS_Wrapped,
- };
-
- /// If set to ``TCS_Wrapped`` will insert trailing commas in container
- /// literals (arrays and objects) that wrap across multiple lines.
- /// It is currently only available for JavaScript
- /// and disabled by default ``TCS_None``.
- /// ``InsertTrailingCommas`` cannot be used together with ``BinPackArguments``
- /// as inserting the comma disables bin-packing.
- /// \code
- /// TSC_Wrapped:
- /// const someArray = [
- /// aaaaaaaaaaaaaaaaaaaaaaaaaa,
- /// aaaaaaaaaaaaaaaaaaaaaaaaaa,
- /// aaaaaaaaaaaaaaaaaaaaaaaaaa,
- /// // ^ inserted
- /// ]
- /// \endcode
- TrailingCommaStyle InsertTrailingCommas;
-
/// If ``false``, a function declaration's or function definition's
/// parameters will either all be on the same line or will have one line each.
/// \code
@@ -976,11 +1096,474 @@ struct FormatStyle {
/// int aaaaaaaaaaaaaaaaaaaa,
/// int aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa) {}
/// \endcode
+ /// \version 3.7
bool BinPackParameters;
+ /// Styles for adding spacing around ``:`` in bitfield definitions.
+ enum BitFieldColonSpacingStyle : int8_t {
+ /// Add one space on each side of the ``:``
+ /// \code
+ /// unsigned bf : 2;
+ /// \endcode
+ BFCS_Both,
+ /// Add no space around the ``:`` (except when needed for
+ /// ``AlignConsecutiveBitFields``).
+ /// \code
+ /// unsigned bf:2;
+ /// \endcode
+ BFCS_None,
+ /// Add space before the ``:`` only
+ /// \code
+ /// unsigned bf :2;
+ /// \endcode
+ BFCS_Before,
+ /// Add space after the ``:`` only (space may be added before if
+ /// needed for ``AlignConsecutiveBitFields``).
+ /// \code
+ /// unsigned bf: 2;
+ /// \endcode
+ BFCS_After
+ };
+ /// The BitFieldColonSpacingStyle to use for bitfields.
+ /// \version 12
+ BitFieldColonSpacingStyle BitFieldColonSpacing;
+
+ /// The number of columns to use to indent the contents of braced init lists.
+ /// If unset, ``ContinuationIndentWidth`` is used.
+ /// \code
+ /// AlignAfterOpenBracket: AlwaysBreak
+ /// BracedInitializerIndentWidth: 2
+ ///
+ /// void f() {
+ /// SomeClass c{
+ /// "foo",
+ /// "bar",
+ /// "baz",
+ /// };
+ /// auto s = SomeStruct{
+ /// .foo = "foo",
+ /// .bar = "bar",
+ /// .baz = "baz",
+ /// };
+ /// SomeArrayT a[3] = {
+ /// {
+ /// foo,
+ /// bar,
+ /// },
+ /// {
+ /// foo,
+ /// bar,
+ /// },
+ /// SomeArrayT{},
+ /// };
+ /// }
+ /// \endcode
+ /// \version 17
+ std::optional<unsigned> BracedInitializerIndentWidth;
+
+ /// Different ways to wrap braces after control statements.
+ enum BraceWrappingAfterControlStatementStyle : int8_t {
+ /// Never wrap braces after a control statement.
+ /// \code
+ /// if (foo()) {
+ /// } else {
+ /// }
+ /// for (int i = 0; i < 10; ++i) {
+ /// }
+ /// \endcode
+ BWACS_Never,
+ /// Only wrap braces after a multi-line control statement.
+ /// \code
+ /// if (foo && bar &&
+ /// baz)
+ /// {
+ /// quux();
+ /// }
+ /// while (foo || bar) {
+ /// }
+ /// \endcode
+ BWACS_MultiLine,
+ /// Always wrap braces after a control statement.
+ /// \code
+ /// if (foo())
+ /// {
+ /// } else
+ /// {}
+ /// for (int i = 0; i < 10; ++i)
+ /// {}
+ /// \endcode
+ BWACS_Always
+ };
+
+ /// Precise control over the wrapping of braces.
+ /// \code
+ /// # Should be declared this way:
+ /// BreakBeforeBraces: Custom
+ /// BraceWrapping:
+ /// AfterClass: true
+ /// \endcode
+ struct BraceWrappingFlags {
+ /// Wrap case labels.
+ /// \code
+ /// false: true:
+ /// switch (foo) { vs. switch (foo) {
+ /// case 1: { case 1:
+ /// bar(); {
+ /// break; bar();
+ /// } break;
+ /// default: { }
+ /// plop(); default:
+ /// } {
+ /// } plop();
+ /// }
+ /// }
+ /// \endcode
+ bool AfterCaseLabel;
+ /// Wrap class definitions.
+ /// \code
+ /// true:
+ /// class foo
+ /// {};
+ ///
+ /// false:
+ /// class foo {};
+ /// \endcode
+ bool AfterClass;
+
+ /// Wrap control statements (``if``/``for``/``while``/``switch``/..).
+ BraceWrappingAfterControlStatementStyle AfterControlStatement;
+ /// Wrap enum definitions.
+ /// \code
+ /// true:
+ /// enum X : int
+ /// {
+ /// B
+ /// };
+ ///
+ /// false:
+ /// enum X : int { B };
+ /// \endcode
+ bool AfterEnum;
+ /// Wrap function definitions.
+ /// \code
+ /// true:
+ /// void foo()
+ /// {
+ /// bar();
+ /// bar2();
+ /// }
+ ///
+ /// false:
+ /// void foo() {
+ /// bar();
+ /// bar2();
+ /// }
+ /// \endcode
+ bool AfterFunction;
+ /// Wrap namespace definitions.
+ /// \code
+ /// true:
+ /// namespace
+ /// {
+ /// int foo();
+ /// int bar();
+ /// }
+ ///
+ /// false:
+ /// namespace {
+ /// int foo();
+ /// int bar();
+ /// }
+ /// \endcode
+ bool AfterNamespace;
+ /// Wrap ObjC definitions (interfaces, implementations...).
+ /// \note
+ /// @autoreleasepool and @synchronized blocks are wrapped
+ /// according to ``AfterControlStatement`` flag.
+ /// \endnote
+ bool AfterObjCDeclaration;
+ /// Wrap struct definitions.
+ /// \code
+ /// true:
+ /// struct foo
+ /// {
+ /// int x;
+ /// };
+ ///
+ /// false:
+ /// struct foo {
+ /// int x;
+ /// };
+ /// \endcode
+ bool AfterStruct;
+ /// Wrap union definitions.
+ /// \code
+ /// true:
+ /// union foo
+ /// {
+ /// int x;
+ /// }
+ ///
+ /// false:
+ /// union foo {
+ /// int x;
+ /// }
+ /// \endcode
+ bool AfterUnion;
+ /// Wrap extern blocks.
+ /// \code
+ /// true:
+ /// extern "C"
+ /// {
+ /// int foo();
+ /// }
+ ///
+ /// false:
+ /// extern "C" {
+ /// int foo();
+ /// }
+ /// \endcode
+ bool AfterExternBlock; // Partially superseded by IndentExternBlock
+ /// Wrap before ``catch``.
+ /// \code
+ /// true:
+ /// try {
+ /// foo();
+ /// }
+ /// catch () {
+ /// }
+ ///
+ /// false:
+ /// try {
+ /// foo();
+ /// } catch () {
+ /// }
+ /// \endcode
+ bool BeforeCatch;
+ /// Wrap before ``else``.
+ /// \code
+ /// true:
+ /// if (foo()) {
+ /// }
+ /// else {
+ /// }
+ ///
+ /// false:
+ /// if (foo()) {
+ /// } else {
+ /// }
+ /// \endcode
+ bool BeforeElse;
+ /// Wrap lambda block.
+ /// \code
+ /// true:
+ /// connect(
+ /// []()
+ /// {
+ /// foo();
+ /// bar();
+ /// });
+ ///
+ /// false:
+ /// connect([]() {
+ /// foo();
+ /// bar();
+ /// });
+ /// \endcode
+ bool BeforeLambdaBody;
+ /// Wrap before ``while``.
+ /// \code
+ /// true:
+ /// do {
+ /// foo();
+ /// }
+ /// while (1);
+ ///
+ /// false:
+ /// do {
+ /// foo();
+ /// } while (1);
+ /// \endcode
+ bool BeforeWhile;
+ /// Indent the wrapped braces themselves.
+ bool IndentBraces;
+ /// If ``false``, empty function body can be put on a single line.
+ /// This option is used only if the opening brace of the function has
+ /// already been wrapped, i.e. the ``AfterFunction`` brace wrapping mode is
+ /// set, and the function could/should not be put on a single line (as per
+ /// ``AllowShortFunctionsOnASingleLine`` and constructor formatting
+ /// options).
+ /// \code
+ /// false: true:
+ /// int f() vs. int f()
+ /// {} {
+ /// }
+ /// \endcode
+ ///
+ bool SplitEmptyFunction;
+ /// If ``false``, empty record (e.g. class, struct or union) body
+ /// can be put on a single line. This option is used only if the opening
+ /// brace of the record has already been wrapped, i.e. the ``AfterClass``
+ /// (for classes) brace wrapping mode is set.
+ /// \code
+ /// false: true:
+ /// class Foo vs. class Foo
+ /// {} {
+ /// }
+ /// \endcode
+ ///
+ bool SplitEmptyRecord;
+ /// If ``false``, empty namespace body can be put on a single line.
+ /// This option is used only if the opening brace of the namespace has
+ /// already been wrapped, i.e. the ``AfterNamespace`` brace wrapping mode is
+ /// set.
+ /// \code
+ /// false: true:
+ /// namespace Foo vs. namespace Foo
+ /// {} {
+ /// }
+ /// \endcode
+ ///
+ bool SplitEmptyNamespace;
+ };
+
+ /// Control of individual brace wrapping cases.
+ ///
+ /// If ``BreakBeforeBraces`` is set to ``BS_Custom``, use this to specify how
+ /// each individual brace case should be handled. Otherwise, this is ignored.
+ /// \code{.yaml}
+ /// # Example of usage:
+ /// BreakBeforeBraces: Custom
+ /// BraceWrapping:
+ /// AfterEnum: true
+ /// AfterStruct: false
+ /// SplitEmptyFunction: false
+ /// \endcode
+ /// \version 3.8
+ BraceWrappingFlags BraceWrapping;
+
+ /// Break between adjacent string literals.
+ /// \code
+ /// true:
+ /// return "Code"
+ /// "\0\52\26\55\55\0"
+ /// "x013"
+ /// "\02\xBA";
+ /// false:
+ /// return "Code" "\0\52\26\55\55\0" "x013" "\02\xBA";
+ /// \endcode
+ /// \version 18
+ bool BreakAdjacentStringLiterals;
+
+ /// Different ways to break after attributes.
+ enum AttributeBreakingStyle : int8_t {
+ /// Always break after attributes.
+ /// \code
+ /// [[maybe_unused]]
+ /// const int i;
+ /// [[gnu::const]] [[maybe_unused]]
+ /// int j;
+ ///
+ /// [[nodiscard]]
+ /// inline int f();
+ /// [[gnu::const]] [[nodiscard]]
+ /// int g();
+ ///
+ /// [[likely]]
+ /// if (a)
+ /// f();
+ /// else
+ /// g();
+ ///
+ /// switch (b) {
+ /// [[unlikely]]
+ /// case 1:
+ /// ++b;
+ /// break;
+ /// [[likely]]
+ /// default:
+ /// return;
+ /// }
+ /// \endcode
+ ABS_Always,
+ /// Leave the line breaking after attributes as is.
+ /// \code
+ /// [[maybe_unused]] const int i;
+ /// [[gnu::const]] [[maybe_unused]]
+ /// int j;
+ ///
+ /// [[nodiscard]] inline int f();
+ /// [[gnu::const]] [[nodiscard]]
+ /// int g();
+ ///
+ /// [[likely]] if (a)
+ /// f();
+ /// else
+ /// g();
+ ///
+ /// switch (b) {
+ /// [[unlikely]] case 1:
+ /// ++b;
+ /// break;
+ /// [[likely]]
+ /// default:
+ /// return;
+ /// }
+ /// \endcode
+ ABS_Leave,
+ /// Never break after attributes.
+ /// \code
+ /// [[maybe_unused]] const int i;
+ /// [[gnu::const]] [[maybe_unused]] int j;
+ ///
+ /// [[nodiscard]] inline int f();
+ /// [[gnu::const]] [[nodiscard]] int g();
+ ///
+ /// [[likely]] if (a)
+ /// f();
+ /// else
+ /// g();
+ ///
+ /// switch (b) {
+ /// [[unlikely]] case 1:
+ /// ++b;
+ /// break;
+ /// [[likely]] default:
+ /// return;
+ /// }
+ /// \endcode
+ ABS_Never,
+ };
+
+ /// Break after a group of C++11 attributes before variable or function
+ /// (including constructor/destructor) declaration/definition names or before
+ /// control statements, i.e. ``if``, ``switch`` (including ``case`` and
+ /// ``default`` labels), ``for``, and ``while`` statements.
+ /// \version 16
+ AttributeBreakingStyle BreakAfterAttributes;
+
+ /// If ``true``, clang-format will always break after a Json array ``[``
+ /// otherwise it will scan until the closing ``]`` to determine if it should
+ /// add newlines between elements (prettier compatible).
+ ///
+ /// \note
+ /// This is currently only for formatting JSON.
+ /// \endnote
+ /// \code
+ /// true: false:
+ /// [ vs. [1, 2, 3, 4]
+ /// 1,
+ /// 2,
+ /// 3,
+ /// 4
+ /// ]
+ /// \endcode
+ /// \version 16
+ bool BreakArrays;
+
/// The style of wrapping parameters on the same line (bin-packed) or
/// on one line each.
- enum BinPackStyle : unsigned char {
+ enum BinPackStyle : int8_t {
/// Automatically determine parameter bin-packing behavior.
BPS_Auto,
/// Always bin-pack parameters.
@@ -990,7 +1573,7 @@ struct FormatStyle {
};
/// The style of breaking before or after binary operators.
- enum BinaryOperatorStyle : unsigned char {
+ enum BinaryOperatorStyle : int8_t {
/// Break after operators.
/// \code
/// LooooooooooongType loooooooooooooooooooooongVariable =
@@ -1030,10 +1613,11 @@ struct FormatStyle {
};
/// The way to wrap binary operators.
+ /// \version 3.6
BinaryOperatorStyle BreakBeforeBinaryOperators;
/// Different ways to attach braces to their surrounding context.
- enum BraceBreakingStyle : unsigned char {
+ enum BraceBreakingStyle : int8_t {
/// Always attach braces to surrounding context.
/// \code
/// namespace N {
@@ -1459,297 +2043,66 @@ struct FormatStyle {
/// } // namespace N
/// \endcode
BS_WebKit,
- /// Configure each individual brace in `BraceWrapping`.
+ /// Configure each individual brace in ``BraceWrapping``.
BS_Custom
};
/// The brace breaking style to use.
+ /// \version 3.7
BraceBreakingStyle BreakBeforeBraces;
- /// Different ways to wrap braces after control statements.
- enum BraceWrappingAfterControlStatementStyle : unsigned char {
- /// Never wrap braces after a control statement.
+ /// Different ways to break before concept declarations.
+ enum BreakBeforeConceptDeclarationsStyle : int8_t {
+ /// Keep the template declaration line together with ``concept``.
/// \code
- /// if (foo()) {
- /// } else {
- /// }
- /// for (int i = 0; i < 10; ++i) {
- /// }
+ /// template <typename T> concept C = ...;
/// \endcode
- BWACS_Never,
- /// Only wrap braces after a multi-line control statement.
+ BBCDS_Never,
+ /// Breaking between template declaration and ``concept`` is allowed. The
+ /// actual behavior depends on the content and line breaking rules and
+ /// penalties.
+ BBCDS_Allowed,
+ /// Always break before ``concept``, putting it in the line after the
+ /// template declaration.
/// \code
- /// if (foo && bar &&
- /// baz)
- /// {
- /// quux();
- /// }
- /// while (foo || bar) {
- /// }
+ /// template <typename T>
+ /// concept C = ...;
/// \endcode
- BWACS_MultiLine,
- /// Always wrap braces after a control statement.
- /// \code
- /// if (foo())
- /// {
- /// } else
- /// {}
- /// for (int i = 0; i < 10; ++i)
- /// {}
- /// \endcode
- BWACS_Always
+ BBCDS_Always,
};
- /// Precise control over the wrapping of braces.
- /// \code
- /// # Should be declared this way:
- /// BreakBeforeBraces: Custom
- /// BraceWrapping:
- /// AfterClass: true
- /// \endcode
- struct BraceWrappingFlags {
- /// Wrap case labels.
- /// \code
- /// false: true:
- /// switch (foo) { vs. switch (foo) {
- /// case 1: { case 1:
- /// bar(); {
- /// break; bar();
- /// } break;
- /// default: { }
- /// plop(); default:
- /// } {
- /// } plop();
- /// }
- /// }
- /// \endcode
- bool AfterCaseLabel;
- /// Wrap class definitions.
- /// \code
- /// true:
- /// class foo {};
- ///
- /// false:
- /// class foo
- /// {};
- /// \endcode
- bool AfterClass;
+ /// The concept declaration style to use.
+ /// \version 12
+ BreakBeforeConceptDeclarationsStyle BreakBeforeConceptDeclarations;
- /// Wrap control statements (``if``/``for``/``while``/``switch``/..).
- BraceWrappingAfterControlStatementStyle AfterControlStatement;
- /// Wrap enum definitions.
- /// \code
- /// true:
- /// enum X : int
- /// {
- /// B
- /// };
- ///
- /// false:
- /// enum X : int { B };
- /// \endcode
- bool AfterEnum;
- /// Wrap function definitions.
- /// \code
- /// true:
- /// void foo()
- /// {
- /// bar();
- /// bar2();
- /// }
- ///
- /// false:
- /// void foo() {
- /// bar();
- /// bar2();
- /// }
- /// \endcode
- bool AfterFunction;
- /// Wrap namespace definitions.
- /// \code
- /// true:
- /// namespace
- /// {
- /// int foo();
- /// int bar();
- /// }
- ///
- /// false:
- /// namespace {
- /// int foo();
- /// int bar();
- /// }
- /// \endcode
- bool AfterNamespace;
- /// Wrap ObjC definitions (interfaces, implementations...).
- /// \note @autoreleasepool and @synchronized blocks are wrapped
- /// according to `AfterControlStatement` flag.
- bool AfterObjCDeclaration;
- /// Wrap struct definitions.
+ /// Different ways to break ASM parameters.
+ enum BreakBeforeInlineASMColonStyle : int8_t {
+ /// No break before inline ASM colon.
/// \code
- /// true:
- /// struct foo
- /// {
- /// int x;
- /// };
- ///
- /// false:
- /// struct foo {
- /// int x;
- /// };
+ /// asm volatile("string", : : val);
/// \endcode
- bool AfterStruct;
- /// Wrap union definitions.
+ BBIAS_Never,
+ /// Break before inline ASM colon if the line length is longer than column
+ /// limit.
/// \code
- /// true:
- /// union foo
- /// {
- /// int x;
- /// }
- ///
- /// false:
- /// union foo {
- /// int x;
- /// }
+ /// asm volatile("string", : : val);
+ /// asm("cmoveq %1, %2, %[result]"
+ /// : [result] "=r"(result)
+ /// : "r"(test), "r"(new), "[result]"(old));
/// \endcode
- bool AfterUnion;
- /// Wrap extern blocks.
+ BBIAS_OnlyMultiline,
+ /// Always break before inline ASM colon.
/// \code
- /// true:
- /// extern "C"
- /// {
- /// int foo();
- /// }
- ///
- /// false:
- /// extern "C" {
- /// int foo();
- /// }
+ /// asm volatile("string",
+ /// :
+ /// : val);
/// \endcode
- bool AfterExternBlock; // Partially superseded by IndentExternBlock
- /// Wrap before ``catch``.
- /// \code
- /// true:
- /// try {
- /// foo();
- /// }
- /// catch () {
- /// }
- ///
- /// false:
- /// try {
- /// foo();
- /// } catch () {
- /// }
- /// \endcode
- bool BeforeCatch;
- /// Wrap before ``else``.
- /// \code
- /// true:
- /// if (foo()) {
- /// }
- /// else {
- /// }
- ///
- /// false:
- /// if (foo()) {
- /// } else {
- /// }
- /// \endcode
- bool BeforeElse;
- /// Wrap lambda block.
- /// \code
- /// true:
- /// connect(
- /// []()
- /// {
- /// foo();
- /// bar();
- /// });
- ///
- /// false:
- /// connect([]() {
- /// foo();
- /// bar();
- /// });
- /// \endcode
- bool BeforeLambdaBody;
- /// Wrap before ``while``.
- /// \code
- /// true:
- /// do {
- /// foo();
- /// }
- /// while (1);
- ///
- /// false:
- /// do {
- /// foo();
- /// } while (1);
- /// \endcode
- bool BeforeWhile;
- /// Indent the wrapped braces themselves.
- bool IndentBraces;
- /// If ``false``, empty function body can be put on a single line.
- /// This option is used only if the opening brace of the function has
- /// already been wrapped, i.e. the `AfterFunction` brace wrapping mode is
- /// set, and the function could/should not be put on a single line (as per
- /// `AllowShortFunctionsOnASingleLine` and constructor formatting options).
- /// \code
- /// int f() vs. int f()
- /// {} {
- /// }
- /// \endcode
- ///
- bool SplitEmptyFunction;
- /// If ``false``, empty record (e.g. class, struct or union) body
- /// can be put on a single line. This option is used only if the opening
- /// brace of the record has already been wrapped, i.e. the `AfterClass`
- /// (for classes) brace wrapping mode is set.
- /// \code
- /// class Foo vs. class Foo
- /// {} {
- /// }
- /// \endcode
- ///
- bool SplitEmptyRecord;
- /// If ``false``, empty namespace body can be put on a single line.
- /// This option is used only if the opening brace of the namespace has
- /// already been wrapped, i.e. the `AfterNamespace` brace wrapping mode is
- /// set.
- /// \code
- /// namespace Foo vs. namespace Foo
- /// {} {
- /// }
- /// \endcode
- ///
- bool SplitEmptyNamespace;
+ BBIAS_Always,
};
- /// Control of individual brace wrapping cases.
- ///
- /// If ``BreakBeforeBraces`` is set to ``BS_Custom``, use this to specify how
- /// each individual brace case should be handled. Otherwise, this is ignored.
- /// \code{.yaml}
- /// # Example of usage:
- /// BreakBeforeBraces: Custom
- /// BraceWrapping:
- /// AfterEnum: true
- /// AfterStruct: false
- /// SplitEmptyFunction: false
- /// \endcode
- BraceWrappingFlags BraceWrapping;
-
- /// If ``true``, concept will be placed on a new line.
- /// \code
- /// true:
- /// template<typename T>
- /// concept ...
- ///
- /// false:
- /// template<typename T> concept ...
- /// \endcode
- bool BreakBeforeConceptDeclarations;
+ /// The inline ASM colon style to use.
+ /// \version 16
+ BreakBeforeInlineASMColonStyle BreakBeforeInlineASMColon;
/// If ``true``, ternary operators will be placed after line breaks.
/// \code
@@ -1763,10 +2116,11 @@ struct FormatStyle {
/// firstValue :
/// SecondValueVeryVeryVeryVeryLong;
/// \endcode
+ /// \version 3.7
bool BreakBeforeTernaryOperators;
/// Different ways to break initializers.
- enum BreakConstructorInitializersStyle : unsigned char {
+ enum BreakConstructorInitializersStyle : int8_t {
/// Break constructor initializers before the colon and after the commas.
/// \code
/// Constructor()
@@ -1791,7 +2145,8 @@ struct FormatStyle {
BCIS_AfterColon
};
- /// The constructor initializers style to use.
+ /// The break constructor initializers style to use.
+ /// \version 5
BreakConstructorInitializersStyle BreakConstructorInitializers;
/// Break after each annotation on a field in Java files.
@@ -1801,9 +2156,12 @@ struct FormatStyle {
/// @Mock
/// DataLoad loader;
/// \endcode
+ /// \version 3.8
bool BreakAfterJavaFieldAnnotations;
/// Allow breaking string literals when formatting.
+ ///
+ /// In C, C++, and Objective-C:
/// \code
/// true:
/// const char* x = "veryVeryVeryVeryVeryVe"
@@ -1812,8 +2170,36 @@ struct FormatStyle {
///
/// false:
/// const char* x =
- /// "veryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongString";
+ /// "veryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongString";
/// \endcode
+ ///
+ /// In C# and Java:
+ /// \code
+ /// true:
+ /// string x = "veryVeryVeryVeryVeryVe" +
+ /// "ryVeryVeryVeryVeryVery" +
+ /// "VeryLongString";
+ ///
+ /// false:
+ /// string x =
+ /// "veryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongString";
+ /// \endcode
+ ///
+ /// C# interpolated strings are not broken.
+ ///
+ /// In Verilog:
+ /// \code
+ /// true:
+ /// string x = {"veryVeryVeryVeryVeryVe",
+ /// "ryVeryVeryVeryVeryVery",
+ /// "VeryLongString"};
+ ///
+ /// false:
+ /// string x =
+ /// "veryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongString";
+ /// \endcode
+ ///
+ /// \version 3.9
bool BreakStringLiterals;
/// The column limit.
@@ -1821,6 +2207,7 @@ struct FormatStyle {
/// A column limit of ``0`` means that there is no column limit. In this case,
/// clang-format will respect the input's line breaking decisions within
/// statements unless they contradict other rules.
+ /// \version 3.7
unsigned ColumnLimit;
/// A regular expression that describes comments with special meaning,
@@ -1830,10 +2217,11 @@ struct FormatStyle {
/// // Will leave the following line unaffected
/// #include <vector> // FOOBAR pragma: keep
/// \endcode
+ /// \version 3.7
std::string CommentPragmas;
/// Different ways to break inheritance list.
- enum BreakInheritanceListStyle : unsigned char {
+ enum BreakInheritanceListStyle : int8_t {
/// Break inheritance list before the colon and after the commas.
/// \code
/// class Foo
@@ -1869,6 +2257,7 @@ struct FormatStyle {
};
/// The inheritance list style to use.
+ /// \version 7
BreakInheritanceListStyle BreakInheritanceList;
/// If ``true``, consecutive namespace declarations will be on the same
@@ -1892,30 +2281,17 @@ struct FormatStyle {
/// namespace Extra {
/// }}}
/// \endcode
+ /// \version 5
bool CompactNamespaces;
- // clang-format off
- /// If the constructor initializers don't fit on a line, put each
- /// initializer on its own line.
- /// \code
- /// true:
- /// SomeClass::Constructor()
- /// : aaaaaaaa(aaaaaaaa), aaaaaaaa(aaaaaaaa), aaaaaaaa(aaaaaaaaaaaaaaaaaaaaaaaaa) {
- /// return 0;
- /// }
- ///
- /// false:
- /// SomeClass::Constructor()
- /// : aaaaaaaa(aaaaaaaa), aaaaaaaa(aaaaaaaa),
- /// aaaaaaaa(aaaaaaaaaaaaaaaaaaaaaaaaa) {
- /// return 0;
- /// }
- /// \endcode
- bool ConstructorInitializerAllOnOneLineOrOnePerLine;
- // clang-format on
+ /// This option is **deprecated**. See ``CurrentLine`` of
+ /// ``PackConstructorInitializers``.
+ /// \version 3.7
+ // bool ConstructorInitializerAllOnOneLineOrOnePerLine;
/// The number of characters to use for indentation of constructor
/// initializer lists as well as inheritance lists.
+ /// \version 3.7
unsigned ConstructorInitializerIndentWidth;
/// Indent width for line continuations.
@@ -1926,6 +2302,7 @@ struct FormatStyle {
/// longFunction( // Again a long comment
/// arg);
/// \endcode
+ /// \version 3.7
unsigned ContinuationIndentWidth;
/// If ``true``, format braced lists as best suited for C++11 braced
@@ -1948,26 +2325,30 @@ struct FormatStyle {
/// f(MyMap[{composite, key}]); f(MyMap[{ composite, key }]);
/// new int[3]{1, 2, 3}; new int[3]{ 1, 2, 3 };
/// \endcode
+ /// \version 3.4
bool Cpp11BracedListStyle;
- /// \brief Analyze the formatted file for the most used line ending (``\r\n``
- /// or ``\n``). ``UseCRLF`` is only used as a fallback if none can be derived.
- bool DeriveLineEnding;
+ /// This option is **deprecated**. See ``DeriveLF`` and ``DeriveCRLF`` of
+ /// ``LineEnding``.
+ /// \version 10
+ // bool DeriveLineEnding;
/// If ``true``, analyze the formatted file for the most common
/// alignment of ``&`` and ``*``.
/// Pointer and reference alignment styles are going to be updated according
/// to the preferences found in the file.
/// ``PointerAlignment`` is then used only as fallback.
+ /// \version 3.7
bool DerivePointerAlignment;
/// Disables formatting completely.
+ /// \version 3.7
bool DisableFormat;
/// Different styles for empty line after access modifiers.
/// ``EmptyLineBeforeAccessModifier`` configuration handles the number of
/// empty lines between two access modifiers.
- enum EmptyLineAfterAccessModifierStyle : unsigned char {
+ enum EmptyLineAfterAccessModifierStyle : int8_t {
/// Remove all empty lines after access modifiers.
/// \code
/// struct foo {
@@ -2012,10 +2393,11 @@ struct FormatStyle {
/// Defines when to put an empty line after access modifiers.
/// ``EmptyLineBeforeAccessModifier`` configuration handles the number of
/// empty lines between two access modifiers.
+ /// \version 13
EmptyLineAfterAccessModifierStyle EmptyLineAfterAccessModifier;
/// Different styles for empty line before access modifiers.
- enum EmptyLineBeforeAccessModifierStyle : unsigned char {
+ enum EmptyLineBeforeAccessModifierStyle : int8_t {
/// Remove all empty lines before access modifiers.
/// \code
/// struct foo {
@@ -2074,6 +2456,7 @@ struct FormatStyle {
};
/// Defines in which cases to put empty line before access modifiers.
+ /// \version 12
EmptyLineBeforeAccessModifierStyle EmptyLineBeforeAccessModifier;
/// If ``true``, clang-format detects whether function calls and
@@ -2084,20 +2467,27 @@ struct FormatStyle {
/// made, clang-format analyzes whether there are other bin-packed cases in
/// the input file and act accordingly.
///
- /// NOTE: This is an experimental flag, that might go away or be renamed. Do
- /// not use this in config files, etc. Use at your own risk.
+ /// \note
+ /// This is an experimental flag, that might go away or be renamed. Do
+ /// not use this in config files, etc. Use at your own risk.
+ /// \endnote
+ /// \version 3.7
bool ExperimentalAutoDetectBinPacking;
/// If ``true``, clang-format adds missing namespace end comments for
- /// short namespaces and fixes invalid existing ones. Short ones are
- /// controlled by "ShortNamespaceLines".
+ /// namespaces and fixes invalid existing ones. This doesn't affect short
+ /// namespaces, which are controlled by ``ShortNamespaceLines``.
/// \code
/// true: false:
- /// namespace a { vs. namespace a {
- /// foo(); foo();
- /// bar(); bar();
+ /// namespace longNamespace { vs. namespace longNamespace {
+ /// void foo(); void foo();
+ /// void bar(); void bar();
/// } // namespace a }
+ /// namespace shortNamespace { namespace shortNamespace {
+ /// void baz(); void baz();
+ /// } }
/// \endcode
+ /// \version 5
bool FixNamespaceComments;
/// A vector of macros that should be interpreted as foreach loops
@@ -2115,8 +2505,11 @@ struct FormatStyle {
/// \endcode
///
/// For example: BOOST_FOREACH.
+ /// \version 3.7
std::vector<std::string> ForEachMacros;
+ tooling::IncludeStyle IncludeStyle;
+
/// A vector of macros that should be interpreted as conditionals
/// instead of as function calls.
///
@@ -2135,64 +2528,9 @@ struct FormatStyle {
///
/// For example: `KJ_IF_MAYBE
/// <https://github.com/capnproto/capnproto/blob/master/kjdoc/tour.md#maybes>`_
+ /// \version 13
std::vector<std::string> IfMacros;
- /// \brief A vector of macros that should be interpreted as type declarations
- /// instead of as function calls.
- ///
- /// These are expected to be macros of the form:
- /// \code
- /// STACK_OF(...)
- /// \endcode
- ///
- /// In the .clang-format configuration file, this can be configured like:
- /// \code{.yaml}
- /// TypenameMacros: ['STACK_OF', 'LIST']
- /// \endcode
- ///
- /// For example: OpenSSL STACK_OF, BSD LIST_ENTRY.
- std::vector<std::string> TypenameMacros;
-
- /// A vector of macros that should be interpreted as complete
- /// statements.
- ///
- /// Typical macros are expressions, and require a semi-colon to be
- /// added; sometimes this is not the case, and this allows to make
- /// clang-format aware of such cases.
- ///
- /// For example: Q_UNUSED
- std::vector<std::string> StatementMacros;
-
- /// A vector of macros which are used to open namespace blocks.
- ///
- /// These are expected to be macros of the form:
- /// \code
- /// NAMESPACE(<namespace-name>, ...) {
- /// <namespace-content>
- /// }
- /// \endcode
- ///
- /// For example: TESTSUITE
- std::vector<std::string> NamespaceMacros;
-
- /// A vector of macros which are whitespace-sensitive and should not
- /// be touched.
- ///
- /// These are expected to be macros of the form:
- /// \code
- /// STRINGIZE(...)
- /// \endcode
- ///
- /// In the .clang-format configuration file, this can be configured like:
- /// \code{.yaml}
- /// WhitespaceSensitiveMacros: ['STRINGIZE', 'PP_STRINGIZE']
- /// \endcode
- ///
- /// For example: BOOST_PP_STRINGIZE
- std::vector<std::string> WhitespaceSensitiveMacros;
-
- tooling::IncludeStyle IncludeStyle;
-
/// Specify whether access modifiers should have their own indentation level.
///
/// When ``false``, access modifiers are indented (or outdented) relative to
@@ -2217,26 +2555,9 @@ struct FormatStyle {
/// return 1; return 1;
/// } }
/// \endcode
+ /// \version 13
bool IndentAccessModifiers;
- /// Indent case labels one level from the switch statement.
- ///
- /// When ``false``, use the same indentation level as for the switch
- /// statement. Switch statement body is always indented one level more than
- /// case labels (except the first block following the case label, which
- /// itself indents the code - unless IndentCaseBlocks is enabled).
- /// \code
- /// false: true:
- /// switch (fool) { vs. switch (fool) {
- /// case 1: case 1:
- /// bar(); bar();
- /// break; break;
- /// default: default:
- /// plop(); plop();
- /// } }
- /// \endcode
- bool IndentCaseLabels;
-
/// Indent case label blocks one level from the case label.
///
/// When ``false``, the block following the case label uses the same
@@ -2257,8 +2578,28 @@ struct FormatStyle {
/// }
/// }
/// \endcode
+ /// \version 11
bool IndentCaseBlocks;
+ /// Indent case labels one level from the switch statement.
+ ///
+ /// When ``false``, use the same indentation level as for the switch
+ /// statement. Switch statement body is always indented one level more than
+ /// case labels (except the first block following the case label, which
+ /// itself indents the code - unless IndentCaseBlocks is enabled).
+ /// \code
+ /// false: true:
+ /// switch (fool) { vs. switch (fool) {
+ /// case 1: case 1:
+ /// bar(); bar();
+ /// break; break;
+ /// default: default:
+ /// plop(); plop();
+ /// } }
+ /// \endcode
+ /// \version 3.3
+ bool IndentCaseLabels;
+
/// Indent goto labels.
///
/// When ``false``, goto labels are flushed left.
@@ -2273,44 +2614,11 @@ struct FormatStyle {
/// return 1; return 1;
/// } }
/// \endcode
+ /// \version 10
bool IndentGotoLabels;
- /// Options for indenting preprocessor directives.
- enum PPDirectiveIndentStyle : unsigned char {
- /// Does not indent any directives.
- /// \code
- /// #if FOO
- /// #if BAR
- /// #include <foo>
- /// #endif
- /// #endif
- /// \endcode
- PPDIS_None,
- /// Indents directives after the hash.
- /// \code
- /// #if FOO
- /// # if BAR
- /// # include <foo>
- /// # endif
- /// #endif
- /// \endcode
- PPDIS_AfterHash,
- /// Indents directives before the hash.
- /// \code
- /// #if FOO
- /// #if BAR
- /// #include <foo>
- /// #endif
- /// #endif
- /// \endcode
- PPDIS_BeforeHash
- };
-
- /// The preprocessor directive indenting style to use.
- PPDirectiveIndentStyle IndentPPDirectives;
-
/// Indents extern blocks
- enum IndentExternBlockStyle : unsigned char {
+ enum IndentExternBlockStyle : int8_t {
/// Backwards compatible with AfterExternBlock's indenting.
/// \code
/// IndentExternBlock: AfterExternBlock
@@ -2346,9 +2654,48 @@ struct FormatStyle {
};
/// IndentExternBlockStyle is the type of indenting of extern blocks.
+ /// \version 11
IndentExternBlockStyle IndentExternBlock;
- /// Indent the requires clause in a template
+ /// Options for indenting preprocessor directives.
+ enum PPDirectiveIndentStyle : int8_t {
+ /// Does not indent any directives.
+ /// \code
+ /// #if FOO
+ /// #if BAR
+ /// #include <foo>
+ /// #endif
+ /// #endif
+ /// \endcode
+ PPDIS_None,
+ /// Indents directives after the hash.
+ /// \code
+ /// #if FOO
+ /// # if BAR
+ /// # include <foo>
+ /// # endif
+ /// #endif
+ /// \endcode
+ PPDIS_AfterHash,
+ /// Indents directives before the hash.
+ /// \code
+ /// #if FOO
+ /// #if BAR
+ /// #include <foo>
+ /// #endif
+ /// #endif
+ /// \endcode
+ PPDIS_BeforeHash
+ };
+
+ /// The preprocessor directive indenting style to use.
+ /// \version 6
+ PPDirectiveIndentStyle IndentPPDirectives;
+
+ /// Indent the requires clause in a template. This only applies when
+ /// ``RequiresClausePosition`` is ``OwnLine``, or ``WithFollowing``.
+ ///
+ /// In clang-format 12, 13 and 14 it was named ``IndentRequires``.
/// \code
/// true:
/// template <typename It>
@@ -2364,7 +2711,8 @@ struct FormatStyle {
/// //....
/// }
/// \endcode
- bool IndentRequires;
+ /// \version 15
+ bool IndentRequiresClause;
/// The number of columns to use for indentation.
/// \code
@@ -2377,6 +2725,7 @@ struct FormatStyle {
/// }
/// }
/// \endcode
+ /// \version 3.7
unsigned IndentWidth;
/// Indent if a function definition or declaration is wrapped after the
@@ -2390,8 +2739,154 @@ struct FormatStyle {
/// LoooooooooooooooooooooooooooooooooooooooongReturnType
/// LoooooooooooooooooooooooooooooooongFunctionDeclaration();
/// \endcode
+ /// \version 3.7
bool IndentWrappedFunctionNames;
+ /// Insert braces after control statements (``if``, ``else``, ``for``, ``do``,
+ /// and ``while``) in C++ unless the control statements are inside macro
+ /// definitions or the braces would enclose preprocessor directives.
+ /// \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);
+ /// else } else {
+ /// return; return;
+ /// }
+ ///
+ /// while (i--) vs. while (i--) {
+ /// for (auto *A : D.attrs()) for (auto *A : D.attrs()) {
+ /// handleAttr(A); handleAttr(A);
+ /// }
+ /// }
+ ///
+ /// do vs. do {
+ /// --i; --i;
+ /// while (i); } while (i);
+ /// \endcode
+ /// \version 15
+ bool InsertBraces;
+
+ /// Insert a newline at end of file if missing.
+ /// \version 16
+ bool InsertNewlineAtEOF;
+
+ /// The style of inserting trailing commas into container literals.
+ enum TrailingCommaStyle : int8_t {
+ /// Do not insert trailing commas.
+ TCS_None,
+ /// Insert trailing commas in container literals that were wrapped over
+ /// multiple lines. Note that this is conceptually incompatible with
+ /// bin-packing, because the trailing comma is used as an indicator
+ /// that a container should be formatted one-per-line (i.e. not bin-packed).
+ /// So inserting a trailing comma counteracts bin-packing.
+ TCS_Wrapped,
+ };
+
+ /// If set to ``TCS_Wrapped`` will insert trailing commas in container
+ /// literals (arrays and objects) that wrap across multiple lines.
+ /// It is currently only available for JavaScript
+ /// and disabled by default ``TCS_None``.
+ /// ``InsertTrailingCommas`` cannot be used together with ``BinPackArguments``
+ /// as inserting the comma disables bin-packing.
+ /// \code
+ /// TSC_Wrapped:
+ /// const someArray = [
+ /// aaaaaaaaaaaaaaaaaaaaaaaaaa,
+ /// aaaaaaaaaaaaaaaaaaaaaaaaaa,
+ /// aaaaaaaaaaaaaaaaaaaaaaaaaa,
+ /// // ^ inserted
+ /// ]
+ /// \endcode
+ /// \version 11
+ TrailingCommaStyle InsertTrailingCommas;
+
+ /// Separator format of integer literals of different bases.
+ ///
+ /// If negative, remove separators. If ``0``, leave the literal as is. If
+ /// positive, insert separators between digits starting from the rightmost
+ /// digit.
+ ///
+ /// For example, the config below will leave separators in binary literals
+ /// alone, insert separators in decimal literals to separate the digits into
+ /// groups of 3, and remove separators in hexadecimal literals.
+ /// \code
+ /// IntegerLiteralSeparator:
+ /// Binary: 0
+ /// Decimal: 3
+ /// Hex: -1
+ /// \endcode
+ ///
+ /// You can also specify a minimum number of digits (``BinaryMinDigits``,
+ /// ``DecimalMinDigits``, and ``HexMinDigits``) the integer literal must
+ /// have in order for the separators to be inserted.
+ struct IntegerLiteralSeparatorStyle {
+ /// Format separators in binary literals.
+ /// \code{.text}
+ /// /* -1: */ b = 0b100111101101;
+ /// /* 0: */ b = 0b10011'11'0110'1;
+ /// /* 3: */ b = 0b100'111'101'101;
+ /// /* 4: */ b = 0b1001'1110'1101;
+ /// \endcode
+ int8_t Binary;
+ /// Format separators in binary literals with a minimum number of digits.
+ /// \code{.text}
+ /// // Binary: 3
+ /// // BinaryMinDigits: 7
+ /// b1 = 0b101101;
+ /// b2 = 0b1'101'101;
+ /// \endcode
+ int8_t BinaryMinDigits;
+ /// Format separators in decimal literals.
+ /// \code{.text}
+ /// /* -1: */ d = 18446744073709550592ull;
+ /// /* 0: */ d = 184467'440737'0'95505'92ull;
+ /// /* 3: */ d = 18'446'744'073'709'550'592ull;
+ /// \endcode
+ int8_t Decimal;
+ /// Format separators in decimal literals with a minimum number of digits.
+ /// \code{.text}
+ /// // Decimal: 3
+ /// // DecimalMinDigits: 5
+ /// d1 = 2023;
+ /// d2 = 10'000;
+ /// \endcode
+ int8_t DecimalMinDigits;
+ /// Format separators in hexadecimal literals.
+ /// \code{.text}
+ /// /* -1: */ h = 0xDEADBEEFDEADBEEFuz;
+ /// /* 0: */ h = 0xDEAD'BEEF'DE'AD'BEE'Fuz;
+ /// /* 2: */ h = 0xDE'AD'BE'EF'DE'AD'BE'EFuz;
+ /// \endcode
+ int8_t Hex;
+ /// Format separators in hexadecimal literals with a minimum number of
+ /// digits.
+ /// \code{.text}
+ /// // Hex: 2
+ /// // HexMinDigits: 6
+ /// h1 = 0xABCDE;
+ /// h2 = 0xAB'CD'EF;
+ /// \endcode
+ int8_t HexMinDigits;
+ bool operator==(const IntegerLiteralSeparatorStyle &R) const {
+ return Binary == R.Binary && BinaryMinDigits == R.BinaryMinDigits &&
+ Decimal == R.Decimal && DecimalMinDigits == R.DecimalMinDigits &&
+ Hex == R.Hex && HexMinDigits == R.HexMinDigits;
+ }
+ };
+
+ /// Format integer literal separators (``'`` for C++ and ``_`` for C#, Java,
+ /// and JavaScript).
+ /// \version 16
+ IntegerLiteralSeparatorStyle IntegerLiteralSeparator;
+
/// A vector of prefixes ordered by the desired groups for Java imports.
///
/// One group's prefix can be a subset of another - the longest prefix is
@@ -2423,11 +2918,12 @@ struct FormatStyle {
///
/// import org.example.ClassD;
/// \endcode
+ /// \version 8
std::vector<std::string> JavaImportGroups;
/// Quotation styles for JavaScript strings. Does not affect template
/// strings.
- enum JavaScriptQuoteStyle : unsigned char {
+ enum JavaScriptQuoteStyle : int8_t {
/// Leave string quotes as they are.
/// \code{.js}
/// string1 = "foo";
@@ -2449,6 +2945,7 @@ struct FormatStyle {
};
/// The JavaScriptQuoteStyle to use for JavaScript strings.
+ /// \version 3.9
JavaScriptQuoteStyle JavaScriptQuotes;
// clang-format off
@@ -2464,9 +2961,14 @@ struct FormatStyle {
/// false:
/// import {VeryLongImportsAreAnnoying, VeryLongImportsAreAnnoying, VeryLongImportsAreAnnoying,} from "some/module.js"
/// \endcode
+ /// \version 3.9
bool JavaScriptWrapImports;
// clang-format on
+ /// Keep empty lines (up to ``MaxEmptyLinesToKeep``) at end of file.
+ /// \version 17
+ bool KeepEmptyLinesAtEOF;
+
/// If true, the empty line at the start of blocks is kept.
/// \code
/// true: false:
@@ -2475,14 +2977,49 @@ struct FormatStyle {
/// bar(); }
/// }
/// \endcode
+ /// \version 3.7
bool KeepEmptyLinesAtTheStartOfBlocks;
+ /// Indentation logic for lambda bodies.
+ enum LambdaBodyIndentationKind : int8_t {
+ /// Align lambda body relative to the lambda signature. This is the default.
+ /// \code
+ /// someMethod(
+ /// [](SomeReallyLongLambdaSignatureArgument foo) {
+ /// return;
+ /// });
+ /// \endcode
+ LBI_Signature,
+ /// For statements within block scope, align lambda body relative to the
+ /// indentation level of the outer scope the lambda signature resides in.
+ /// \code
+ /// someMethod(
+ /// [](SomeReallyLongLambdaSignatureArgument foo) {
+ /// return;
+ /// });
+ ///
+ /// someMethod(someOtherMethod(
+ /// [](SomeReallyLongLambdaSignatureArgument foo) {
+ /// return;
+ /// }));
+ /// \endcode
+ LBI_OuterScope,
+ };
+
+ /// The indentation style of lambda bodies. ``Signature`` (the default)
+ /// causes the lambda body to be indented one additional level relative to
+ /// the indentation level of the signature. ``OuterScope`` forces the lambda
+ /// body to be indented one additional level relative to the parent scope
+ /// containing the lambda signature.
+ /// \version 13
+ LambdaBodyIndentationKind LambdaBodyIndentation;
+
/// Supported languages.
///
/// When stored in a configuration file, specifies the language, that the
/// configuration targets. When passed to the ``reformat()`` function, enables
/// syntax features specific to the language.
- enum LanguageKind : unsigned char {
+ enum LanguageKind : int8_t {
/// Do not use.
LK_None,
/// Should be used for C, C++.
@@ -2504,46 +3041,41 @@ struct FormatStyle {
LK_TableGen,
/// Should be used for Protocol Buffer messages in text format
/// (https://developers.google.com/protocol-buffers/).
- LK_TextProto
+ LK_TextProto,
+ /// Should be used for Verilog and SystemVerilog.
+ /// https://standards.ieee.org/ieee/1800/6700/
+ /// https://sci-hub.st/10.1109/IEEESTD.2018.8299595
+ LK_Verilog
};
bool isCpp() const { return Language == LK_Cpp || Language == LK_ObjC; }
bool isCSharp() const { return Language == LK_CSharp; }
bool isJson() const { return Language == LK_Json; }
+ bool isJavaScript() const { return Language == LK_JavaScript; }
+ bool isVerilog() const { return Language == LK_Verilog; }
+ bool isProto() const {
+ return Language == LK_Proto || Language == LK_TextProto;
+ }
+ bool isTableGen() const { return Language == LK_TableGen; }
/// Language, this format style is targeted at.
+ /// \version 3.5
LanguageKind Language;
- /// Indentation logic for lambda bodies.
- enum LambdaBodyIndentationKind : unsigned char {
- /// Align lambda body relative to the lambda signature. This is the default.
- /// \code
- /// someMethod(
- /// [](SomeReallyLongLambdaSignatureArgument foo) {
- /// return;
- /// });
- /// \endcode
- LBI_Signature,
- /// Align lambda body relative to the indentation level of the outer scope
- /// the lambda signature resides in.
- /// \code
- /// someMethod(
- /// [](SomeReallyLongLambdaSignatureArgument foo) {
- /// return;
- /// });
- /// \endcode
- LBI_OuterScope,
+ /// Line ending style.
+ enum LineEndingStyle : int8_t {
+ /// Use ``\n``.
+ LE_LF,
+ /// Use ``\r\n``.
+ LE_CRLF,
+ /// Use ``\n`` unless the input has more lines ending in ``\r\n``.
+ LE_DeriveLF,
+ /// Use ``\r\n`` unless the input has more lines ending in ``\n``.
+ LE_DeriveCRLF,
};
- /// The indentation style of lambda bodies. ``Signature`` (the default)
- /// causes the lambda body to be indented one additional level relative to
- /// the indentation level of the signature. ``OuterScope`` forces the lambda
- /// body to be indented one additional level relative to the parent scope
- /// containing the lambda signature. For callback-heavy code, it may improve
- /// 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>`_
- LambdaBodyIndentationKind LambdaBodyIndentation;
+ /// Line ending style (``\n`` or ``\r\n``) to use.
+ /// \version 16
+ LineEndingStyle LineEnding;
/// A regular expression matching macros that start a block.
/// \code
@@ -2571,11 +3103,53 @@ struct FormatStyle {
/// bar();
/// NS_TABLE_FOO_END
/// \endcode
+ /// \version 3.7
std::string MacroBlockBegin;
/// A regular expression matching macros that end a block.
+ /// \version 3.7
std::string MacroBlockEnd;
+ /// A list of macros of the form \c <definition>=<expansion> .
+ ///
+ /// Code will be parsed with macros expanded, in order to determine how to
+ /// interpret and format the macro arguments.
+ ///
+ /// For example, the code:
+ /// \code
+ /// A(a*b);
+ /// \endcode
+ ///
+ /// will usually be interpreted as a call to a function A, and the
+ /// multiplication expression will be formatted as ``a * b``.
+ ///
+ /// If we specify the macro definition:
+ /// \code{.yaml}
+ /// Macros:
+ /// - A(x)=x
+ /// \endcode
+ ///
+ /// the code will now be parsed as a declaration of the variable b of type a*,
+ /// and formatted as ``a* b`` (depending on pointer-binding rules).
+ ///
+ /// Features and restrictions:
+ /// * Both function-like macros and object-like macros are supported.
+ /// * Macro arguments must be used exactly once in the expansion.
+ /// * No recursive expansion; macros referencing other macros will be
+ /// ignored.
+ /// * Overloading by arity is supported: for example, given the macro
+ /// definitions A=x, A()=y, A(a)=a
+ ///
+ /// \code
+ /// A; -> x;
+ /// A(); -> y;
+ /// A(z); -> z;
+ /// A(a, b); // will not be expanded.
+ /// \endcode
+ ///
+ /// \version 17
+ std::vector<std::string> Macros;
+
/// The maximum number of consecutive empty lines to keep.
/// \code
/// MaxEmptyLinesToKeep: 1 vs. MaxEmptyLinesToKeep: 0
@@ -2587,10 +3161,11 @@ struct FormatStyle {
/// return i;
/// }
/// \endcode
+ /// \version 3.7
unsigned MaxEmptyLinesToKeep;
/// Different ways to indent namespace contents.
- enum NamespaceIndentationKind : unsigned char {
+ enum NamespaceIndentationKind : int8_t {
/// Don't indent in namespaces.
/// \code
/// namespace out {
@@ -2624,8 +3199,22 @@ struct FormatStyle {
};
/// The indentation used for namespaces.
+ /// \version 3.7
NamespaceIndentationKind NamespaceIndentation;
+ /// A vector of macros which are used to open namespace blocks.
+ ///
+ /// These are expected to be macros of the form:
+ /// \code
+ /// NAMESPACE(<namespace-name>, ...) {
+ /// <namespace-content>
+ /// }
+ /// \endcode
+ ///
+ /// For example: TESTSUITE
+ /// \version 9
+ std::vector<std::string> NamespaceMacros;
+
/// Controls bin-packing Objective-C protocol conformance list
/// items into as few lines as possible when they go over ``ColumnLimit``.
///
@@ -2656,6 +3245,7 @@ struct FormatStyle {
/// ddddddddddddd> {
/// }
/// \endcode
+ /// \version 7
BinPackStyle ObjCBinPackProtocolList;
/// The number of characters to use for indentation of ObjC blocks.
@@ -2666,12 +3256,9 @@ struct FormatStyle {
/// [self onOperationDone];
/// }];
/// \endcode
+ /// \version 3.7
unsigned ObjCBlockIndentWidth;
- /// Add a space after ``@property`` in Objective-C, i.e. use
- /// ``@property (readonly)`` instead of ``@property(readonly)``.
- bool ObjCSpaceAfterProperty;
-
/// Break parameters list into lines when there is nested block
/// parameters in a function call.
/// \code
@@ -2693,43 +3280,151 @@ struct FormatStyle {
/// }]
/// }
/// \endcode
+ /// \version 11
bool ObjCBreakBeforeNestedBlockParam;
+ /// The order in which ObjC property attributes should appear.
+ ///
+ /// Attributes in code will be sorted in the order specified. Any attributes
+ /// encountered that are not mentioned in this array will be sorted last, in
+ /// stable order. Comments between attributes will leave the attributes
+ /// untouched.
+ /// \warning
+ /// Using this option 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{.yaml}
+ /// ObjCPropertyAttributeOrder: [
+ /// class, direct,
+ /// atomic, nonatomic,
+ /// assign, retain, strong, copy, weak, unsafe_unretained,
+ /// readonly, readwrite, getter, setter,
+ /// nullable, nonnull, null_resettable, null_unspecified
+ /// ]
+ /// \endcode
+ /// \version 18
+ std::vector<std::string> ObjCPropertyAttributeOrder;
+
+ /// Add a space after ``@property`` in Objective-C, i.e. use
+ /// ``@property (readonly)`` instead of ``@property(readonly)``.
+ /// \version 3.7
+ bool ObjCSpaceAfterProperty;
+
/// Add a space in front of an Objective-C protocol list, i.e. use
/// ``Foo <Protocol>`` instead of ``Foo<Protocol>``.
+ /// \version 3.7
bool ObjCSpaceBeforeProtocolList;
+ /// Different ways to try to fit all constructor initializers on a line.
+ enum PackConstructorInitializersStyle : int8_t {
+ /// Always put each constructor initializer on its own line.
+ /// \code
+ /// Constructor()
+ /// : a(),
+ /// b()
+ /// \endcode
+ PCIS_Never,
+ /// Bin-pack constructor initializers.
+ /// \code
+ /// Constructor()
+ /// : aaaaaaaaaaaaaaaaaaaa(), bbbbbbbbbbbbbbbbbbbb(),
+ /// cccccccccccccccccccc()
+ /// \endcode
+ PCIS_BinPack,
+ /// Put all constructor initializers on the current line if they fit.
+ /// Otherwise, put each one on its own line.
+ /// \code
+ /// Constructor() : a(), b()
+ ///
+ /// Constructor()
+ /// : aaaaaaaaaaaaaaaaaaaa(),
+ /// bbbbbbbbbbbbbbbbbbbb(),
+ /// ddddddddddddd()
+ /// \endcode
+ PCIS_CurrentLine,
+ /// Same as ``PCIS_CurrentLine`` except that if all constructor initializers
+ /// do not fit on the current line, try to fit them on the next line.
+ /// \code
+ /// Constructor() : a(), b()
+ ///
+ /// Constructor()
+ /// : aaaaaaaaaaaaaaaaaaaa(), bbbbbbbbbbbbbbbbbbbb(), ddddddddddddd()
+ ///
+ /// Constructor()
+ /// : aaaaaaaaaaaaaaaaaaaa(),
+ /// bbbbbbbbbbbbbbbbbbbb(),
+ /// cccccccccccccccccccc()
+ /// \endcode
+ PCIS_NextLine,
+ /// Put all constructor initializers on the next line if they fit.
+ /// Otherwise, put each one on its own line.
+ /// \code
+ /// Constructor()
+ /// : a(), b()
+ ///
+ /// Constructor()
+ /// : aaaaaaaaaaaaaaaaaaaa(), bbbbbbbbbbbbbbbbbbbb(), ddddddddddddd()
+ ///
+ /// Constructor()
+ /// : aaaaaaaaaaaaaaaaaaaa(),
+ /// bbbbbbbbbbbbbbbbbbbb(),
+ /// cccccccccccccccccccc()
+ /// \endcode
+ PCIS_NextLineOnly,
+ };
+
+ /// The pack constructor initializers style to use.
+ /// \version 14
+ PackConstructorInitializersStyle PackConstructorInitializers;
+
/// The penalty for breaking around an assignment operator.
+ /// \version 5
unsigned PenaltyBreakAssignment;
/// The penalty for breaking a function call after ``call(``.
+ /// \version 3.7
unsigned PenaltyBreakBeforeFirstCallParameter;
/// The penalty for each line break introduced inside a comment.
+ /// \version 3.7
unsigned PenaltyBreakComment;
/// The penalty for breaking before the first ``<<``.
+ /// \version 3.7
unsigned PenaltyBreakFirstLessLess;
+ /// The penalty for breaking after ``(``.
+ /// \version 14
+ unsigned PenaltyBreakOpenParenthesis;
+
+ /// The penalty for breaking after ``::``.
+ /// \version 18
+ unsigned PenaltyBreakScopeResolution;
+
/// The penalty for each line break introduced inside a string literal.
+ /// \version 3.7
unsigned PenaltyBreakString;
/// The penalty for breaking after template declaration.
+ /// \version 7
unsigned PenaltyBreakTemplateDeclaration;
/// The penalty for each character outside of the column limit.
+ /// \version 3.7
unsigned PenaltyExcessCharacter;
- /// Penalty for putting the return type of a function onto its own
- /// line.
- unsigned PenaltyReturnTypeOnItsOwnLine;
-
/// Penalty for each character of whitespace indentation
/// (counted relative to leading non-whitespace column).
+ /// \version 12
unsigned PenaltyIndentedWhitespace;
+ /// Penalty for putting the return type of a function onto its own line.
+ /// \version 3.7
+ unsigned PenaltyReturnTypeOnItsOwnLine;
+
/// The ``&``, ``&&`` and ``*`` alignment style.
- enum PointerAlignmentStyle : unsigned char {
+ enum PointerAlignmentStyle : int8_t {
/// Align pointer to the left.
/// \code
/// int* a;
@@ -2748,6 +3443,7 @@ struct FormatStyle {
};
/// Pointer and reference alignment style.
+ /// \version 3.7
PointerAlignmentStyle PointerAlignment;
/// The number of columns to use for indentation of preprocessor statements.
@@ -2762,8 +3458,81 @@ struct FormatStyle {
/// # define BAR
/// #endif
/// \endcode
+ /// \version 13
int PPIndentWidth;
+ /// Different specifiers and qualifiers alignment styles.
+ enum QualifierAlignmentStyle : int8_t {
+ /// Don't change specifiers/qualifiers to either Left or Right alignment
+ /// (default).
+ /// \code
+ /// int const a;
+ /// const int *a;
+ /// \endcode
+ QAS_Leave,
+ /// Change specifiers/qualifiers to be left-aligned.
+ /// \code
+ /// const int a;
+ /// const int *a;
+ /// \endcode
+ QAS_Left,
+ /// Change specifiers/qualifiers to be right-aligned.
+ /// \code
+ /// int const a;
+ /// int const *a;
+ /// \endcode
+ QAS_Right,
+ /// Change specifiers/qualifiers to be aligned based on ``QualifierOrder``.
+ /// With:
+ /// \code{.yaml}
+ /// QualifierOrder: ['inline', 'static', 'type', 'const']
+ /// \endcode
+ ///
+ /// \code
+ ///
+ /// int const a;
+ /// int const *a;
+ /// \endcode
+ QAS_Custom
+ };
+
+ /// Different ways to arrange specifiers and qualifiers (e.g. const/volatile).
+ /// \warning
+ /// Setting ``QualifierAlignment`` to something other than ``Leave``, COULD
+ /// lead to incorrect code formatting due to incorrect decisions made due to
+ /// clang-formats lack of complete semantic information.
+ /// As such extra care should be taken to review code changes made by the use
+ /// of this option.
+ /// \endwarning
+ /// \version 14
+ QualifierAlignmentStyle QualifierAlignment;
+
+ /// The order in which the qualifiers appear.
+ /// Order is an array that can contain any of the following:
+ ///
+ /// * const
+ /// * inline
+ /// * static
+ /// * friend
+ /// * constexpr
+ /// * volatile
+ /// * restrict
+ /// * type
+ ///
+ /// \note
+ /// it MUST contain 'type'.
+ /// \endnote
+ ///
+ /// Items to the left of 'type' will be placed to the left of the type and
+ /// aligned in the order supplied. Items to the right of 'type' will be
+ /// placed to the right of the type and aligned in the order supplied.
+ ///
+ /// \code{.yaml}
+ /// QualifierOrder: ['inline', 'static', 'type', 'const', 'volatile' ]
+ /// \endcode
+ /// \version 14
+ std::vector<std::string> QualifierOrder;
+
/// See documentation of ``RawStringFormats``.
struct RawStringFormat {
/// The language of this raw string.
@@ -2821,10 +3590,11 @@ struct FormatStyle {
/// BasedOnStyle: llvm
/// CanonicalDelimiter: 'cc'
/// \endcode
+ /// \version 6
std::vector<RawStringFormat> RawStringFormats;
/// \brief The ``&`` and ``&&`` alignment style.
- enum ReferenceAlignmentStyle {
+ enum ReferenceAlignmentStyle : int8_t {
/// Align reference like ``PointerAlignment``.
RAS_Pointer,
/// Align reference to the left.
@@ -2846,10 +3616,13 @@ struct FormatStyle {
/// \brief Reference alignment style (overrides ``PointerAlignment`` for
/// references).
+ /// \version 13
ReferenceAlignmentStyle ReferenceAlignment;
// clang-format off
- /// If ``true``, clang-format will attempt to re-flow comments.
+ /// If ``true``, clang-format will attempt to re-flow comments. That is it
+ /// will touch a comment and *reflow* long comments into new lines, trying to
+ /// obey the ``ColumnLimit``.
/// \code
/// false:
/// // veryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongComment with plenty of information
@@ -2861,9 +3634,282 @@ struct FormatStyle {
/// /* second veryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongComment with plenty of
/// * information */
/// \endcode
+ /// \version 3.8
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;
+
+ /// Types of redundant parentheses to remove.
+ enum RemoveParenthesesStyle : int8_t {
+ /// Do not remove parentheses.
+ /// \code
+ /// class __declspec((dllimport)) X {};
+ /// co_return (((0)));
+ /// return ((a + b) - ((c + d)));
+ /// \endcode
+ RPS_Leave,
+ /// Replace multiple parentheses with single parentheses.
+ /// \code
+ /// class __declspec(dllimport) X {};
+ /// co_return (0);
+ /// return ((a + b) - (c + d));
+ /// \endcode
+ RPS_MultipleParentheses,
+ /// Also remove parentheses enclosing the expression in a
+ /// ``return``/``co_return`` statement.
+ /// \code
+ /// class __declspec(dllimport) X {};
+ /// co_return 0;
+ /// return (a + b) - (c + d);
+ /// \endcode
+ RPS_ReturnStatement,
+ };
+
+ /// Remove redundant parentheses.
+ /// \warning
+ /// Setting this option to any value other than ``Leave`` 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
+ /// \version 17
+ RemoveParenthesesStyle RemoveParentheses;
+
+ /// Remove semicolons after the closing brace of a non-empty function.
+ /// \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:
+ ///
+ /// int max(int a, int b) { int max(int a, int b) {
+ /// return a > b ? a : b; return a > b ? a : b;
+ /// }; }
+ ///
+ /// \endcode
+ /// \version 16
+ bool RemoveSemicolon;
+
+ /// \brief The possible positions for the requires clause. The
+ /// ``IndentRequires`` option is only used if the ``requires`` is put on the
+ /// start of a line.
+ enum RequiresClausePositionStyle : int8_t {
+ /// Always put the ``requires`` clause on its own line.
+ /// \code
+ /// template <typename T>
+ /// requires C<T>
+ /// struct Foo {...
+ ///
+ /// template <typename T>
+ /// requires C<T>
+ /// void bar(T t) {...
+ ///
+ /// template <typename T>
+ /// void baz(T t)
+ /// requires C<T>
+ /// {...
+ /// \endcode
+ RCPS_OwnLine,
+ /// Try to put the clause together with the preceding part of a declaration.
+ /// For class templates: stick to the template declaration.
+ /// For function templates: stick to the template declaration.
+ /// For function declaration followed by a requires clause: stick to the
+ /// parameter list.
+ /// \code
+ /// template <typename T> requires C<T>
+ /// struct Foo {...
+ ///
+ /// template <typename T> requires C<T>
+ /// void bar(T t) {...
+ ///
+ /// template <typename T>
+ /// void baz(T t) requires C<T>
+ /// {...
+ /// \endcode
+ RCPS_WithPreceding,
+ /// Try to put the ``requires`` clause together with the class or function
+ /// declaration.
+ /// \code
+ /// template <typename T>
+ /// requires C<T> struct Foo {...
+ ///
+ /// template <typename T>
+ /// requires C<T> void bar(T t) {...
+ ///
+ /// template <typename T>
+ /// void baz(T t)
+ /// requires C<T> {...
+ /// \endcode
+ RCPS_WithFollowing,
+ /// Try to put everything in the same line if possible. Otherwise normal
+ /// line breaking rules take over.
+ /// \code
+ /// // Fitting:
+ /// template <typename T> requires C<T> struct Foo {...
+ ///
+ /// template <typename T> requires C<T> void bar(T t) {...
+ ///
+ /// template <typename T> void bar(T t) requires C<T> {...
+ ///
+ /// // Not fitting, one possible example:
+ /// template <typename LongName>
+ /// requires C<LongName>
+ /// struct Foo {...
+ ///
+ /// template <typename LongName>
+ /// requires C<LongName>
+ /// void bar(LongName ln) {
+ ///
+ /// template <typename LongName>
+ /// void bar(LongName ln)
+ /// requires C<LongName> {
+ /// \endcode
+ RCPS_SingleLine,
+ };
+
+ /// \brief The position of the ``requires`` clause.
+ /// \version 15
+ RequiresClausePositionStyle RequiresClausePosition;
+
+ /// Indentation logic for requires expression bodies.
+ enum RequiresExpressionIndentationKind : int8_t {
+ /// Align requires expression body relative to the indentation level of the
+ /// outer scope the requires expression resides in.
+ /// This is the default.
+ /// \code
+ /// template <typename T>
+ /// concept C = requires(T t) {
+ /// ...
+ /// }
+ /// \endcode
+ REI_OuterScope,
+ /// Align requires expression body relative to the ``requires`` keyword.
+ /// \code
+ /// template <typename T>
+ /// concept C = requires(T t) {
+ /// ...
+ /// }
+ /// \endcode
+ REI_Keyword,
+ };
+
+ /// The indentation used for requires expression bodies.
+ /// \version 16
+ RequiresExpressionIndentationKind RequiresExpressionIndentation;
+
+ /// \brief The style if definition blocks should be separated.
+ enum SeparateDefinitionStyle : int8_t {
+ /// 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.
///
@@ -2883,10 +3929,15 @@ struct FormatStyle {
/// int bar; int bar;
/// } // namespace b } // namespace b
/// \endcode
+ /// \version 13
unsigned ShortNamespaceLines;
+ /// Do not format macro definition body.
+ /// \version 18
+ bool SkipMacroDefinitionBody;
+
/// Include sorting options.
- enum SortIncludesOptions : unsigned char {
+ enum SortIncludesOptions : int8_t {
/// Includes are never sorted.
/// \code
/// #include "B/A.h"
@@ -2917,15 +3968,11 @@ struct FormatStyle {
};
/// Controls if and how clang-format will sort ``#includes``.
- /// If ``Never``, includes are never sorted.
- /// If ``CaseInsensitive``, includes are sorted in an ASCIIbetical or case
- /// insensitive fashion.
- /// If ``CaseSensitive``, includes are sorted in an alphabetical or case
- /// sensitive fashion.
+ /// \version 3.8
SortIncludesOptions SortIncludes;
/// Position for Java Static imports.
- enum SortJavaStaticImportOptions : unsigned char {
+ enum SortJavaStaticImportOptions : int8_t {
/// Static imports are placed before non-static imports.
/// \code{.java}
/// import static org.example.function1;
@@ -2945,29 +3992,59 @@ struct FormatStyle {
/// When sorting Java imports, by default static imports are placed before
/// non-static imports. If ``JavaStaticImportAfterImport`` is ``After``,
/// static imports are placed after non-static imports.
+ /// \version 12
SortJavaStaticImportOptions SortJavaStaticImport;
- /// If ``true``, clang-format will sort using declarations.
- ///
- /// The order of using declarations is defined as follows:
- /// Split the strings by "::" and discard any initial empty strings. The last
- /// element of each list is a non-namespace name; all others are namespace
- /// names. Sort the lists of names lexicographically, where the sort order of
- /// individual names is that all non-namespace names come before all namespace
- /// names, and within those groups, names are in case-insensitive
- /// lexicographic order.
- /// \code
- /// false: true:
- /// using std::cout; vs. using std::cin;
- /// using std::cin; using std::cout;
- /// \endcode
- bool SortUsingDeclarations;
+ /// Using declaration sorting options.
+ enum SortUsingDeclarationsOptions : int8_t {
+ /// Using declarations are never sorted.
+ /// \code
+ /// using std::chrono::duration_cast;
+ /// using std::move;
+ /// using boost::regex;
+ /// using boost::regex_constants::icase;
+ /// using std::string;
+ /// \endcode
+ SUD_Never,
+ /// Using declarations are sorted in the order defined as follows:
+ /// Split the strings by "::" and discard any initial empty strings. Sort
+ /// the lists of names lexicographically, and within those groups, names are
+ /// in case-insensitive lexicographic order.
+ /// \code
+ /// using boost::regex;
+ /// using boost::regex_constants::icase;
+ /// using std::chrono::duration_cast;
+ /// using std::move;
+ /// using std::string;
+ /// \endcode
+ SUD_Lexicographic,
+ /// Using declarations are sorted in the order defined as follows:
+ /// Split the strings by "::" and discard any initial empty strings. The
+ /// last element of each list is a non-namespace name; all others are
+ /// namespace names. Sort the lists of names lexicographically, where the
+ /// sort order of individual names is that all non-namespace names come
+ /// before all namespace names, and within those groups, names are in
+ /// case-insensitive lexicographic order.
+ /// \code
+ /// using boost::regex;
+ /// using boost::regex_constants::icase;
+ /// using std::move;
+ /// using std::string;
+ /// using std::chrono::duration_cast;
+ /// \endcode
+ SUD_LexicographicNumeric,
+ };
+
+ /// Controls if and how clang-format will sort using declarations.
+ /// \version 5
+ SortUsingDeclarationsOptions SortUsingDeclarations;
/// If ``true``, a space is inserted after C style casts.
/// \code
/// true: false:
/// (int) i; vs. (int)i;
/// \endcode
+ /// \version 3.5
bool SpaceAfterCStyleCast;
/// If ``true``, a space is inserted after the logical not operator (``!``).
@@ -2975,6 +4052,7 @@ struct FormatStyle {
/// true: false:
/// ! someExpression(); vs. !someExpression();
/// \endcode
+ /// \version 9
bool SpaceAfterLogicalNot;
/// If \c true, a space will be inserted after the 'template' keyword.
@@ -2982,10 +4060,11 @@ struct FormatStyle {
/// true: false:
/// template <int> void foo(); vs. template<int> void foo();
/// \endcode
+ /// \version 4
bool SpaceAfterTemplateKeyword;
/// Different ways to put a space before opening parentheses.
- enum SpaceAroundPointerQualifiersStyle : unsigned char {
+ enum SpaceAroundPointerQualifiersStyle : int8_t {
/// Don't ensure spaces around pointer qualifiers and use PointerAlignment
/// instead.
/// \code
@@ -3014,6 +4093,7 @@ struct FormatStyle {
};
/// Defines in which cases to put a space before or after pointer qualifiers
+ /// \version 12
SpaceAroundPointerQualifiersStyle SpaceAroundPointerQualifiers;
/// If ``false``, spaces will be removed before assignment operators.
@@ -3022,6 +4102,7 @@ struct FormatStyle {
/// int a = 5; vs. int a= 5;
/// a += 42; a+= 42;
/// \endcode
+ /// \version 3.7
bool SpaceBeforeAssignmentOperators;
/// If ``false``, spaces will be removed before case colon.
@@ -3031,6 +4112,7 @@ struct FormatStyle {
/// case 1 : break; case 1: break;
/// } }
/// \endcode
+ /// \version 12
bool SpaceBeforeCaseColon;
/// If ``true``, a space will be inserted before a C++11 braced list
@@ -3042,6 +4124,7 @@ struct FormatStyle {
/// vector<int> { 1, 2, 3 }; vector<int>{ 1, 2, 3 };
/// new int[3] { 1, 2, 3 }; new int[3]{ 1, 2, 3 };
/// \endcode
+ /// \version 7
bool SpaceBeforeCpp11BracedList;
/// If ``false``, spaces will be removed before constructor initializer
@@ -3050,6 +4133,7 @@ struct FormatStyle {
/// true: false:
/// Foo::Foo() : a(a) {} Foo::Foo(): a(a) {}
/// \endcode
+ /// \version 7
bool SpaceBeforeCtorInitializerColon;
/// If ``false``, spaces will be removed before inheritance colon.
@@ -3057,18 +4141,25 @@ struct FormatStyle {
/// true: false:
/// class Foo : Bar {} vs. class Foo: Bar {}
/// \endcode
+ /// \version 7
bool SpaceBeforeInheritanceColon;
+ /// If ``true``, a space will be added before a JSON colon. For other
+ /// languages, e.g. JavaScript, use ``SpacesInContainerLiterals`` instead.
+ /// \code
+ /// true: false:
+ /// { {
+ /// "key" : "value" vs. "key": "value"
+ /// } }
+ /// \endcode
+ /// \version 17
+ bool SpaceBeforeJsonColon;
+
/// Different ways to put a space before opening parentheses.
- enum SpaceBeforeParensOptions : unsigned char {
- /// Never put a space before opening parentheses.
- /// \code
- /// void f() {
- /// if(true) {
- /// f();
- /// }
- /// }
- /// \endcode
+ enum SpaceBeforeParensStyle : int8_t {
+ /// This is **deprecated** and replaced by ``Custom`` below, with all
+ /// ``SpaceBeforeParensOptions`` but ``AfterPlacementOperator`` set to
+ /// ``false``.
SBPO_Never,
/// Put a space before opening parentheses only after control statement
/// keywords (``for/if/while...``).
@@ -3084,7 +4175,7 @@ struct FormatStyle {
/// ForEach and If macros. This is useful in projects where ForEach/If
/// macros are treated as function calls instead of control statements.
/// ``SBPO_ControlStatementsExceptForEachMacros`` remains an alias for
- /// backward compatability.
+ /// backward compatibility.
/// \code
/// void f() {
/// Q_FOREACH(...) {
@@ -3115,11 +4206,151 @@ struct FormatStyle {
/// }
/// }
/// \endcode
- SBPO_Always
+ SBPO_Always,
+ /// Configure each individual space before parentheses in
+ /// ``SpaceBeforeParensOptions``.
+ SBPO_Custom,
};
/// Defines in which cases to put a space before opening parentheses.
- SpaceBeforeParensOptions SpaceBeforeParens;
+ /// \version 3.5
+ SpaceBeforeParensStyle SpaceBeforeParens;
+
+ /// Precise control over the spacing before parentheses.
+ /// \code
+ /// # Should be declared this way:
+ /// SpaceBeforeParens: Custom
+ /// SpaceBeforeParensOptions:
+ /// AfterControlStatements: true
+ /// AfterFunctionDefinitionName: true
+ /// \endcode
+ struct SpaceBeforeParensCustom {
+ /// If ``true``, put space between control statement keywords
+ /// (for/if/while...) and opening parentheses.
+ /// \code
+ /// true: false:
+ /// if (...) {} vs. if(...) {}
+ /// \endcode
+ bool AfterControlStatements;
+ /// If ``true``, put space between foreach macros and opening parentheses.
+ /// \code
+ /// true: false:
+ /// FOREACH (...) vs. FOREACH(...)
+ /// <loop-body> <loop-body>
+ /// \endcode
+ bool AfterForeachMacros;
+ /// If ``true``, put a space between function declaration name and opening
+ /// parentheses.
+ /// \code
+ /// true: false:
+ /// void f (); vs. void f();
+ /// \endcode
+ bool AfterFunctionDeclarationName;
+ /// If ``true``, put a space between function definition name and opening
+ /// parentheses.
+ /// \code
+ /// true: false:
+ /// void f () {} vs. void f() {}
+ /// \endcode
+ bool AfterFunctionDefinitionName;
+ /// If ``true``, put space between if macros and opening parentheses.
+ /// \code
+ /// true: false:
+ /// IF (...) vs. IF(...)
+ /// <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 between operator ``new``/``delete`` and opening
+ /// parenthesis.
+ /// \code
+ /// true: false:
+ /// new (buf) T; vs. new(buf) T;
+ /// delete (buf) T; delete(buf) T;
+ /// \endcode
+ bool AfterPlacementOperator;
+ /// If ``true``, put space between requires keyword in a requires clause and
+ /// opening parentheses, if there is one.
+ /// \code
+ /// true: false:
+ /// template<typename T> vs. template<typename T>
+ /// requires (A<T> && B<T>) requires(A<T> && B<T>)
+ /// ... ...
+ /// \endcode
+ bool AfterRequiresInClause;
+ /// If ``true``, put space between requires keyword in a requires expression
+ /// and opening parentheses.
+ /// \code
+ /// true: false:
+ /// template<typename T> vs. template<typename T>
+ /// concept C = requires (T t) { concept C = requires(T t) {
+ /// ... ...
+ /// } }
+ /// \endcode
+ bool AfterRequiresInExpression;
+ /// If ``true``, put a space before opening parentheses only if the
+ /// parentheses are not empty.
+ /// \code
+ /// true: false:
+ /// void f (int a); vs. void f();
+ /// f (a); f();
+ /// \endcode
+ bool BeforeNonEmptyParentheses;
+
+ SpaceBeforeParensCustom()
+ : AfterControlStatements(false), AfterForeachMacros(false),
+ AfterFunctionDeclarationName(false),
+ AfterFunctionDefinitionName(false), AfterIfMacros(false),
+ AfterOverloadedOperator(false), AfterPlacementOperator(true),
+ AfterRequiresInClause(false), AfterRequiresInExpression(false),
+ BeforeNonEmptyParentheses(false) {}
+
+ bool operator==(const SpaceBeforeParensCustom &Other) const {
+ return AfterControlStatements == Other.AfterControlStatements &&
+ AfterForeachMacros == Other.AfterForeachMacros &&
+ AfterFunctionDeclarationName ==
+ Other.AfterFunctionDeclarationName &&
+ AfterFunctionDefinitionName == Other.AfterFunctionDefinitionName &&
+ AfterIfMacros == Other.AfterIfMacros &&
+ AfterOverloadedOperator == Other.AfterOverloadedOperator &&
+ AfterPlacementOperator == Other.AfterPlacementOperator &&
+ AfterRequiresInClause == Other.AfterRequiresInClause &&
+ AfterRequiresInExpression == Other.AfterRequiresInExpression &&
+ BeforeNonEmptyParentheses == Other.BeforeNonEmptyParentheses;
+ }
+ };
+
+ /// Control of individual space before parentheses.
+ ///
+ /// If ``SpaceBeforeParens`` is set to ``Custom``, use this to specify
+ /// how each individual space before parentheses case should be handled.
+ /// Otherwise, this is ignored.
+ /// \code{.yaml}
+ /// # Example of usage:
+ /// SpaceBeforeParens: Custom
+ /// SpaceBeforeParensOptions:
+ /// AfterControlStatements: true
+ /// AfterFunctionDefinitionName: true
+ /// \endcode
+ /// \version 14
+ SpaceBeforeParensCustom SpaceBeforeParensOptions;
+
+ /// If ``true``, spaces will be before ``[``.
+ /// Lambdas will not be affected. Only the first ``[`` will get a space added.
+ /// \code
+ /// true: false:
+ /// int a [5]; vs. int a[5];
+ /// int a [5][5]; vs. int a[5][5];
+ /// \endcode
+ /// \version 10
+ bool SpaceBeforeSquareBrackets;
/// If ``false``, spaces will be removed before range-based for loop
/// colon.
@@ -3127,6 +4358,7 @@ struct FormatStyle {
/// true: false:
/// for (auto v : values) {} vs. for(auto v: values) {}
/// \endcode
+ /// \version 7
bool SpaceBeforeRangeBasedForLoopColon;
/// If ``true``, spaces will be inserted into ``{}``.
@@ -3135,26 +4367,24 @@ struct FormatStyle {
/// void f() { } vs. void f() {}
/// while (true) { } while (true) {}
/// \endcode
+ /// \version 10
bool SpaceInEmptyBlock;
/// If ``true``, spaces may be inserted into ``()``.
- /// \code
- /// true: false:
- /// void f( ) { vs. void f() {
- /// int x[] = {foo( ), bar( )}; int x[] = {foo(), bar()};
- /// if (true) { if (true) {
- /// f( ); f();
- /// } }
- /// } }
- /// \endcode
- bool SpaceInEmptyParentheses;
+ /// This option is **deprecated**. See ``InEmptyParentheses`` of
+ /// ``SpacesInParensOptions``.
+ /// \version 3.7
+ // bool SpaceInEmptyParentheses;
/// The number of spaces before trailing line comments
/// (``//`` - comments).
///
- /// This does not affect trailing block comments (``/*`` - comments) as
- /// those commonly have different usage patterns and a number of special
- /// cases.
+ /// This does not affect trailing block comments (``/*`` - comments) as those
+ /// commonly have different usage patterns and a number of special cases. In
+ /// the case of Verilog, it doesn't affect a comment right after the opening
+ /// parenthesis in the port or parameter list in a module header, because it
+ /// is probably for the port on the following line instead of the parenthesis
+ /// it follows.
/// \code
/// SpacesBeforeTrailingComments: 3
/// void f() {
@@ -3163,11 +4393,12 @@ struct FormatStyle {
/// } // foo
/// }
/// \endcode
+ /// \version 3.7
unsigned SpacesBeforeTrailingComments;
- /// Styles for adding spacing after ``<`` and before ``>`
+ /// Styles for adding spacing after ``<`` and before ``>``
/// in template argument lists.
- enum SpacesInAnglesStyle : unsigned char {
+ enum SpacesInAnglesStyle : int8_t {
/// Remove spaces after ``<`` and before ``>``.
/// \code
/// static_cast<int>(arg);
@@ -3185,34 +4416,34 @@ struct FormatStyle {
SIAS_Leave
};
/// The SpacesInAnglesStyle to use for template argument lists.
+ /// \version 3.4
SpacesInAnglesStyle SpacesInAngles;
/// If ``true``, spaces will be inserted around if/for/switch/while
/// conditions.
- /// \code
- /// true: false:
- /// if ( a ) { ... } vs. if (a) { ... }
- /// while ( i < 5 ) { ... } while (i < 5) { ... }
- /// \endcode
- bool SpacesInConditionalStatement;
-
- /// If ``true``, spaces are inserted inside container literals (e.g.
- /// ObjC and Javascript array and dict literals).
+ /// This option is **deprecated**. See ``InConditionalStatements`` of
+ /// ``SpacesInParensOptions``.
+ /// \version 10
+ // bool SpacesInConditionalStatement;
+
+ /// If ``true``, spaces are inserted inside container literals (e.g. ObjC and
+ /// Javascript array and dict literals). For JSON, use
+ /// ``SpaceBeforeJsonColon`` instead.
/// \code{.js}
/// true: false:
/// var arr = [ 1, 2, 3 ]; vs. var arr = [1, 2, 3];
/// f({a : 1, b : 2, c : 3}); f({a: 1, b: 2, c: 3});
/// \endcode
+ /// \version 3.7
bool SpacesInContainerLiterals;
/// If ``true``, spaces may be inserted into C style casts.
- /// \code
- /// true: false:
- /// x = ( int32 )y vs. x = (int32)y
- /// \endcode
- bool SpacesInCStyleCastParentheses;
+ /// This option is **deprecated**. See ``InCStyleCasts`` of
+ /// ``SpacesInParensOptions``.
+ /// \version 3.7
+ // bool SpacesInCStyleCastParentheses;
- /// Control of spaces within a single line comment
+ /// Control of spaces within a single line comment.
struct SpacesInLineComment {
/// The minimum number of spaces at the start of the comment.
unsigned Minimum;
@@ -3223,38 +4454,141 @@ struct FormatStyle {
/// How many spaces are allowed at the start of a line comment. To disable the
/// maximum set it to ``-1``, apart from that the maximum takes precedence
/// over the minimum.
- /// \code Minimum = 1 Maximum = -1
- /// // One space is forced
+ /// \code
+ /// Minimum = 1
+ /// Maximum = -1
+ /// // One space is forced
///
- /// // but more spaces are possible
+ /// // but more spaces are possible
///
- /// Minimum = 0
- /// Maximum = 0
- /// //Forces to start every comment directly after the slashes
+ /// Minimum = 0
+ /// Maximum = 0
+ /// //Forces to start every comment directly after the slashes
/// \endcode
///
/// Note that in line comment sections the relative indent of the subsequent
/// lines is kept, that means the following:
/// \code
- /// before: after:
- /// Minimum: 1
- /// //if (b) { // if (b) {
- /// // return true; // return true;
- /// //} // }
- ///
- /// Maximum: 0
- /// /// List: ///List:
- /// /// - Foo /// - Foo
- /// /// - Bar /// - Bar
+ /// before: after:
+ /// Minimum: 1
+ /// //if (b) { // if (b) {
+ /// // return true; // return true;
+ /// //} // }
+ ///
+ /// Maximum: 0
+ /// /// List: ///List:
+ /// /// - Foo /// - Foo
+ /// /// - Bar /// - Bar
/// \endcode
+ ///
+ /// This option has only effect if ``ReflowComments`` is set to ``true``.
+ /// \version 13
SpacesInLineComment SpacesInLineCommentPrefix;
+ /// Different ways to put a space before opening and closing parentheses.
+ enum SpacesInParensStyle : int8_t {
+ /// Never put a space in parentheses.
+ /// \code
+ /// void f() {
+ /// if(true) {
+ /// f();
+ /// }
+ /// }
+ /// \endcode
+ SIPO_Never,
+ /// Configure each individual space in parentheses in
+ /// `SpacesInParensOptions`.
+ SIPO_Custom,
+ };
+
/// If ``true``, spaces will be inserted after ``(`` and before ``)``.
+ /// This option is **deprecated**. The previous behavior is preserved by using
+ /// ``SpacesInParens`` with ``Custom`` and by setting all
+ /// ``SpacesInParensOptions`` to ``true`` except for ``InCStyleCasts`` and
+ /// ``InEmptyParentheses``.
+ /// \version 3.7
+ // bool SpacesInParentheses;
+
+ /// Defines in which cases spaces will be inserted after ``(`` and before
+ /// ``)``.
+ /// \version 17
+ SpacesInParensStyle SpacesInParens;
+
+ /// Precise control over the spacing in parentheses.
/// \code
- /// true: false:
- /// t f( Deleted & ) & = delete; vs. t f(Deleted &) & = delete;
+ /// # Should be declared this way:
+ /// SpacesInParens: Custom
+ /// SpacesInParensOptions:
+ /// InConditionalStatements: true
+ /// Other: true
/// \endcode
- bool SpacesInParentheses;
+ struct SpacesInParensCustom {
+ /// Put a space in parentheses only inside conditional statements
+ /// (``for/if/while/switch...``).
+ /// \code
+ /// true: false:
+ /// if ( a ) { ... } vs. if (a) { ... }
+ /// while ( i < 5 ) { ... } while (i < 5) { ... }
+ /// \endcode
+ bool InConditionalStatements;
+ /// Put a space in C style casts.
+ /// \code
+ /// true: false:
+ /// x = ( int32 )y vs. x = (int32)y
+ /// \endcode
+ bool InCStyleCasts;
+ /// Put a space in parentheses only if the parentheses are empty i.e. '()'
+ /// \code
+ /// true: false:
+ /// void f( ) { vs. void f() {
+ /// int x[] = {foo( ), bar( )}; int x[] = {foo(), bar()};
+ /// if (true) { if (true) {
+ /// f( ); f();
+ /// } }
+ /// } }
+ /// \endcode
+ bool InEmptyParentheses;
+ /// Put a space in parentheses not covered by preceding options.
+ /// \code
+ /// true: false:
+ /// t f( Deleted & ) & = delete; vs. t f(Deleted &) & = delete;
+ /// \endcode
+ bool Other;
+
+ SpacesInParensCustom()
+ : InConditionalStatements(false), InCStyleCasts(false),
+ InEmptyParentheses(false), Other(false) {}
+
+ SpacesInParensCustom(bool InConditionalStatements, bool InCStyleCasts,
+ bool InEmptyParentheses, bool Other)
+ : InConditionalStatements(InConditionalStatements),
+ InCStyleCasts(InCStyleCasts), InEmptyParentheses(InEmptyParentheses),
+ Other(Other) {}
+
+ bool operator==(const SpacesInParensCustom &R) const {
+ return InConditionalStatements == R.InConditionalStatements &&
+ InCStyleCasts == R.InCStyleCasts &&
+ InEmptyParentheses == R.InEmptyParentheses && Other == R.Other;
+ }
+ bool operator!=(const SpacesInParensCustom &R) const {
+ return !(*this == R);
+ }
+ };
+
+ /// Control of individual spaces in parentheses.
+ ///
+ /// If ``SpacesInParens`` is set to ``Custom``, use this to specify
+ /// how each individual space in parentheses case should be handled.
+ /// Otherwise, this is ignored.
+ /// \code{.yaml}
+ /// # Example of usage:
+ /// SpacesInParens: Custom
+ /// SpacesInParensOptions:
+ /// InConditionalStatements: true
+ /// InEmptyParentheses: true
+ /// \endcode
+ /// \version 17
+ SpacesInParensCustom SpacesInParensOptions;
/// If ``true``, spaces will be inserted after ``[`` and before ``]``.
/// Lambdas without arguments or unspecified size array declarations will not
@@ -3264,45 +4598,9 @@ struct FormatStyle {
/// int a[ 5 ]; vs. int a[5];
/// std::unique_ptr<int[]> foo() {} // Won't be affected
/// \endcode
+ /// \version 3.7
bool SpacesInSquareBrackets;
- /// If ``true``, spaces will be before ``[``.
- /// Lambdas will not be affected. Only the first ``[`` will get a space added.
- /// \code
- /// true: false:
- /// int a [5]; vs. int a[5];
- /// int a [5][5]; vs. int a[5][5];
- /// \endcode
- bool SpaceBeforeSquareBrackets;
-
- /// Styles for adding spacing around ``:`` in bitfield definitions.
- enum BitFieldColonSpacingStyle : unsigned char {
- /// Add one space on each side of the ``:``
- /// \code
- /// unsigned bf : 2;
- /// \endcode
- BFCS_Both,
- /// Add no space around the ``:`` (except when needed for
- /// ``AlignConsecutiveBitFields``).
- /// \code
- /// unsigned bf:2;
- /// \endcode
- BFCS_None,
- /// Add space before the ``:`` only
- /// \code
- /// unsigned bf :2;
- /// \endcode
- BFCS_Before,
- /// Add space after the ``:`` only (space may be added before if
- /// needed for ``AlignConsecutiveBitFields``).
- /// \code
- /// unsigned bf: 2;
- /// \endcode
- BFCS_After
- };
- /// The BitFieldColonSpacingStyle to use for bitfields.
- BitFieldColonSpacingStyle BitFieldColonSpacing;
-
/// Supported language standards for parsing and formatting C++ constructs.
/// \code
/// Latest: vector<set<int>>
@@ -3311,7 +4609,7 @@ struct FormatStyle {
///
/// The correct way to spell a specific language version is e.g. ``c++11``.
/// The historical aliases ``Cpp03`` and ``Cpp11`` are deprecated.
- enum LanguageStandard : unsigned char {
+ enum LanguageStandard : int8_t {
/// Parse and format as C++03.
/// ``Cpp03`` is a deprecated alias for ``c++03``
LS_Cpp03, // c++03
@@ -3335,6 +4633,7 @@ struct FormatStyle {
/// c++03: latest:
/// vector<set<int> > x; vs. vector<set<int>> x;
/// \endcode
+ /// \version 3.7
LanguageStandard Standard;
/// Macros which are ignored in front of a statement, as if they were an
@@ -3351,13 +4650,57 @@ struct FormatStyle {
/// unsigned char data = 'x';
/// emit signal(data); // Now it's fine again.
/// \endcode
+ /// \version 12
std::vector<std::string> StatementAttributeLikeMacros;
+ /// A vector of macros that should be interpreted as complete
+ /// statements.
+ ///
+ /// Typical macros are expressions, and require a semi-colon to be
+ /// added; sometimes this is not the case, and this allows to make
+ /// clang-format aware of such cases.
+ ///
+ /// For example: Q_UNUSED
+ /// \version 8
+ std::vector<std::string> StatementMacros;
+
/// The number of columns used for tab stops.
+ /// \version 3.7
unsigned TabWidth;
+ /// A vector of non-keyword identifiers that should be interpreted as type
+ /// names.
+ ///
+ /// A ``*``, ``&``, or ``&&`` between a type name and another non-keyword
+ /// identifier is annotated as a pointer or reference token instead of a
+ /// binary operator.
+ ///
+ /// \version 17
+ std::vector<std::string> TypeNames;
+
+ /// \brief A vector of macros that should be interpreted as type declarations
+ /// instead of as function calls.
+ ///
+ /// These are expected to be macros of the form:
+ /// \code
+ /// STACK_OF(...)
+ /// \endcode
+ ///
+ /// In the .clang-format configuration file, this can be configured like:
+ /// \code{.yaml}
+ /// TypenameMacros: ['STACK_OF', 'LIST']
+ /// \endcode
+ ///
+ /// For example: OpenSSL STACK_OF, BSD LIST_ENTRY.
+ /// \version 9
+ std::vector<std::string> TypenameMacros;
+
+ /// This option is **deprecated**. See ``LF`` and ``CRLF`` of ``LineEnding``.
+ /// \version 10
+ // bool UseCRLF;
+
/// Different ways to use tab in formatting.
- enum UseTabStyle : unsigned char {
+ enum UseTabStyle : int8_t {
/// Never use tab.
UT_Never,
/// Use tabs only for indentation.
@@ -3373,13 +4716,41 @@ struct FormatStyle {
UT_Always
};
- /// \brief Use ``\r\n`` instead of ``\n`` for line breaks.
- /// Also used as fallback if ``DeriveLineEnding`` is true.
- bool UseCRLF;
-
/// The way to use tab characters in the resulting file.
+ /// \version 3.7
UseTabStyle UseTab;
+ /// For Verilog, put each port on its own line in module instantiations.
+ /// \code
+ /// true:
+ /// ffnand ff1(.q(),
+ /// .qbar(out1),
+ /// .clear(in1),
+ /// .preset(in2));
+ ///
+ /// false:
+ /// ffnand ff1(.q(), .qbar(out1), .clear(in1), .preset(in2));
+ /// \endcode
+ /// \version 17
+ bool VerilogBreakBetweenInstancePorts;
+
+ /// A vector of macros which are whitespace-sensitive and should not
+ /// be touched.
+ ///
+ /// These are expected to be macros of the form:
+ /// \code
+ /// STRINGIZE(...)
+ /// \endcode
+ ///
+ /// In the .clang-format configuration file, this can be configured like:
+ /// \code{.yaml}
+ /// WhitespaceSensitiveMacros: ['STRINGIZE', 'PP_STRINGIZE']
+ /// \endcode
+ ///
+ /// For example: BOOST_PP_STRINGIZE
+ /// \version 11
+ std::vector<std::string> WhitespaceSensitiveMacros;
+
bool operator==(const FormatStyle &R) const {
return AccessModifierOffset == R.AccessModifierOffset &&
AlignAfterOpenBracket == R.AlignAfterOpenBracket &&
@@ -3388,18 +4759,22 @@ struct FormatStyle {
AlignConsecutiveBitFields == R.AlignConsecutiveBitFields &&
AlignConsecutiveDeclarations == R.AlignConsecutiveDeclarations &&
AlignConsecutiveMacros == R.AlignConsecutiveMacros &&
+ AlignConsecutiveShortCaseStatements ==
+ R.AlignConsecutiveShortCaseStatements &&
AlignEscapedNewlines == R.AlignEscapedNewlines &&
AlignOperands == R.AlignOperands &&
AlignTrailingComments == R.AlignTrailingComments &&
AllowAllArgumentsOnNextLine == R.AllowAllArgumentsOnNextLine &&
- AllowAllConstructorInitializersOnNextLine ==
- R.AllowAllConstructorInitializersOnNextLine &&
AllowAllParametersOfDeclarationOnNextLine ==
R.AllowAllParametersOfDeclarationOnNextLine &&
- AllowShortEnumsOnASingleLine == R.AllowShortEnumsOnASingleLine &&
+ AllowBreakBeforeNoexceptSpecifier ==
+ R.AllowBreakBeforeNoexceptSpecifier &&
AllowShortBlocksOnASingleLine == R.AllowShortBlocksOnASingleLine &&
AllowShortCaseLabelsOnASingleLine ==
R.AllowShortCaseLabelsOnASingleLine &&
+ AllowShortCompoundRequirementOnASingleLine ==
+ R.AllowShortCompoundRequirementOnASingleLine &&
+ AllowShortEnumsOnASingleLine == R.AllowShortEnumsOnASingleLine &&
AllowShortFunctionsOnASingleLine ==
R.AllowShortFunctionsOnASingleLine &&
AllowShortIfStatementsOnASingleLine ==
@@ -3414,23 +4789,26 @@ struct FormatStyle {
AttributeMacros == R.AttributeMacros &&
BinPackArguments == R.BinPackArguments &&
BinPackParameters == R.BinPackParameters &&
+ BitFieldColonSpacing == R.BitFieldColonSpacing &&
+ BracedInitializerIndentWidth == R.BracedInitializerIndentWidth &&
+ BreakAdjacentStringLiterals == R.BreakAdjacentStringLiterals &&
+ BreakAfterAttributes == R.BreakAfterAttributes &&
+ BreakAfterJavaFieldAnnotations == R.BreakAfterJavaFieldAnnotations &&
+ BreakArrays == R.BreakArrays &&
BreakBeforeBinaryOperators == R.BreakBeforeBinaryOperators &&
BreakBeforeBraces == R.BreakBeforeBraces &&
BreakBeforeConceptDeclarations == R.BreakBeforeConceptDeclarations &&
+ BreakBeforeInlineASMColon == R.BreakBeforeInlineASMColon &&
BreakBeforeTernaryOperators == R.BreakBeforeTernaryOperators &&
BreakConstructorInitializers == R.BreakConstructorInitializers &&
- CompactNamespaces == R.CompactNamespaces &&
- BreakAfterJavaFieldAnnotations == R.BreakAfterJavaFieldAnnotations &&
+ BreakInheritanceList == R.BreakInheritanceList &&
BreakStringLiterals == R.BreakStringLiterals &&
ColumnLimit == R.ColumnLimit && CommentPragmas == R.CommentPragmas &&
- BreakInheritanceList == R.BreakInheritanceList &&
- ConstructorInitializerAllOnOneLineOrOnePerLine ==
- R.ConstructorInitializerAllOnOneLineOrOnePerLine &&
+ CompactNamespaces == R.CompactNamespaces &&
ConstructorInitializerIndentWidth ==
R.ConstructorInitializerIndentWidth &&
ContinuationIndentWidth == R.ContinuationIndentWidth &&
Cpp11BracedListStyle == R.Cpp11BracedListStyle &&
- DeriveLineEnding == R.DeriveLineEnding &&
DerivePointerAlignment == R.DerivePointerAlignment &&
DisableFormat == R.DisableFormat &&
EmptyLineAfterAccessModifier == R.EmptyLineAfterAccessModifier &&
@@ -3446,22 +4824,27 @@ struct FormatStyle {
IncludeStyle.IncludeIsMainSourceRegex ==
R.IncludeStyle.IncludeIsMainSourceRegex &&
IndentAccessModifiers == R.IndentAccessModifiers &&
- IndentCaseLabels == R.IndentCaseLabels &&
IndentCaseBlocks == R.IndentCaseBlocks &&
+ IndentCaseLabels == R.IndentCaseLabels &&
+ IndentExternBlock == R.IndentExternBlock &&
IndentGotoLabels == R.IndentGotoLabels &&
IndentPPDirectives == R.IndentPPDirectives &&
- IndentExternBlock == R.IndentExternBlock &&
- IndentRequires == R.IndentRequires && IndentWidth == R.IndentWidth &&
- Language == R.Language &&
+ IndentRequiresClause == R.IndentRequiresClause &&
+ IndentWidth == R.IndentWidth &&
IndentWrappedFunctionNames == R.IndentWrappedFunctionNames &&
+ InsertBraces == R.InsertBraces &&
+ InsertNewlineAtEOF == R.InsertNewlineAtEOF &&
+ IntegerLiteralSeparator == R.IntegerLiteralSeparator &&
JavaImportGroups == R.JavaImportGroups &&
JavaScriptQuotes == R.JavaScriptQuotes &&
JavaScriptWrapImports == R.JavaScriptWrapImports &&
+ KeepEmptyLinesAtEOF == R.KeepEmptyLinesAtEOF &&
KeepEmptyLinesAtTheStartOfBlocks ==
R.KeepEmptyLinesAtTheStartOfBlocks &&
+ Language == R.Language &&
LambdaBodyIndentation == R.LambdaBodyIndentation &&
- MacroBlockBegin == R.MacroBlockBegin &&
- MacroBlockEnd == R.MacroBlockEnd &&
+ LineEnding == R.LineEnding && MacroBlockBegin == R.MacroBlockBegin &&
+ MacroBlockEnd == R.MacroBlockEnd && Macros == R.Macros &&
MaxEmptyLinesToKeep == R.MaxEmptyLinesToKeep &&
NamespaceIndentation == R.NamespaceIndentation &&
NamespaceMacros == R.NamespaceMacros &&
@@ -3469,22 +4852,35 @@ struct FormatStyle {
ObjCBlockIndentWidth == R.ObjCBlockIndentWidth &&
ObjCBreakBeforeNestedBlockParam ==
R.ObjCBreakBeforeNestedBlockParam &&
+ ObjCPropertyAttributeOrder == R.ObjCPropertyAttributeOrder &&
ObjCSpaceAfterProperty == R.ObjCSpaceAfterProperty &&
ObjCSpaceBeforeProtocolList == R.ObjCSpaceBeforeProtocolList &&
+ PackConstructorInitializers == R.PackConstructorInitializers &&
PenaltyBreakAssignment == R.PenaltyBreakAssignment &&
PenaltyBreakBeforeFirstCallParameter ==
R.PenaltyBreakBeforeFirstCallParameter &&
PenaltyBreakComment == R.PenaltyBreakComment &&
PenaltyBreakFirstLessLess == R.PenaltyBreakFirstLessLess &&
+ PenaltyBreakOpenParenthesis == R.PenaltyBreakOpenParenthesis &&
+ PenaltyBreakScopeResolution == R.PenaltyBreakScopeResolution &&
PenaltyBreakString == R.PenaltyBreakString &&
- PenaltyExcessCharacter == R.PenaltyExcessCharacter &&
- PenaltyReturnTypeOnItsOwnLine == R.PenaltyReturnTypeOnItsOwnLine &&
PenaltyBreakTemplateDeclaration ==
R.PenaltyBreakTemplateDeclaration &&
+ PenaltyExcessCharacter == R.PenaltyExcessCharacter &&
+ PenaltyReturnTypeOnItsOwnLine == R.PenaltyReturnTypeOnItsOwnLine &&
PointerAlignment == R.PointerAlignment &&
+ QualifierAlignment == R.QualifierAlignment &&
+ QualifierOrder == R.QualifierOrder &&
RawStringFormats == R.RawStringFormats &&
ReferenceAlignment == R.ReferenceAlignment &&
+ RemoveBracesLLVM == R.RemoveBracesLLVM &&
+ RemoveParentheses == R.RemoveParentheses &&
+ RemoveSemicolon == R.RemoveSemicolon &&
+ RequiresClausePosition == R.RequiresClausePosition &&
+ RequiresExpressionIndentation == R.RequiresExpressionIndentation &&
+ SeparateDefinitionBlocks == R.SeparateDefinitionBlocks &&
ShortNamespaceLines == R.ShortNamespaceLines &&
+ SkipMacroDefinitionBody == R.SkipMacroDefinitionBody &&
SortIncludes == R.SortIncludes &&
SortJavaStaticImport == R.SortJavaStaticImport &&
SpaceAfterCStyleCast == R.SpaceAfterCStyleCast &&
@@ -3496,33 +4892,35 @@ struct FormatStyle {
SpaceBeforeCtorInitializerColon ==
R.SpaceBeforeCtorInitializerColon &&
SpaceBeforeInheritanceColon == R.SpaceBeforeInheritanceColon &&
+ SpaceBeforeJsonColon == R.SpaceBeforeJsonColon &&
SpaceBeforeParens == R.SpaceBeforeParens &&
+ SpaceBeforeParensOptions == R.SpaceBeforeParensOptions &&
SpaceAroundPointerQualifiers == R.SpaceAroundPointerQualifiers &&
SpaceBeforeRangeBasedForLoopColon ==
R.SpaceBeforeRangeBasedForLoopColon &&
+ SpaceBeforeSquareBrackets == R.SpaceBeforeSquareBrackets &&
SpaceInEmptyBlock == R.SpaceInEmptyBlock &&
- SpaceInEmptyParentheses == R.SpaceInEmptyParentheses &&
SpacesBeforeTrailingComments == R.SpacesBeforeTrailingComments &&
SpacesInAngles == R.SpacesInAngles &&
- SpacesInConditionalStatement == R.SpacesInConditionalStatement &&
SpacesInContainerLiterals == R.SpacesInContainerLiterals &&
- SpacesInCStyleCastParentheses == R.SpacesInCStyleCastParentheses &&
SpacesInLineCommentPrefix.Minimum ==
R.SpacesInLineCommentPrefix.Minimum &&
SpacesInLineCommentPrefix.Maximum ==
R.SpacesInLineCommentPrefix.Maximum &&
- SpacesInParentheses == R.SpacesInParentheses &&
+ SpacesInParens == R.SpacesInParens &&
+ SpacesInParensOptions == R.SpacesInParensOptions &&
SpacesInSquareBrackets == R.SpacesInSquareBrackets &&
- SpaceBeforeSquareBrackets == R.SpaceBeforeSquareBrackets &&
- BitFieldColonSpacing == R.BitFieldColonSpacing &&
Standard == R.Standard &&
StatementAttributeLikeMacros == R.StatementAttributeLikeMacros &&
StatementMacros == R.StatementMacros && TabWidth == R.TabWidth &&
- UseTab == R.UseTab && UseCRLF == R.UseCRLF &&
- TypenameMacros == R.TypenameMacros;
+ TypeNames == R.TypeNames && TypenameMacros == R.TypenameMacros &&
+ UseTab == R.UseTab &&
+ VerilogBreakBetweenInstancePorts ==
+ R.VerilogBreakBetweenInstancePorts &&
+ WhitespaceSensitiveMacros == R.WhitespaceSensitiveMacros;
}
- llvm::Optional<FormatStyle> GetLanguageStyle(LanguageKind Language) const;
+ std::optional<FormatStyle> GetLanguageStyle(LanguageKind Language) const;
// Stores per-language styles. A FormatStyle instance inside has an empty
// StyleSet. A FormatStyle instance returned by the Get method has its
@@ -3534,7 +4932,7 @@ struct FormatStyle {
struct FormatStyleSet {
typedef std::map<FormatStyle::LanguageKind, FormatStyle> MapType;
- llvm::Optional<FormatStyle> Get(FormatStyle::LanguageKind Language) const;
+ std::optional<FormatStyle> Get(FormatStyle::LanguageKind Language) const;
// Adds \p Style to this FormatStyleSet. Style must not have an associated
// FormatStyleSet.
@@ -3580,7 +4978,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:
@@ -3595,6 +4993,8 @@ FormatStyle getGNUStyle();
/// https://docs.microsoft.com/en-us/visualstudio/ide/editorconfig-code-style-settings-reference?view=vs-2017
FormatStyle getMicrosoftStyle(FormatStyle::LanguageKind Language);
+FormatStyle getClangFormatStyle();
+
/// Returns style indicating formatting should be not applied at all.
FormatStyle getNoStyle();
@@ -3618,7 +5018,7 @@ bool getPredefinedStyle(StringRef Name, FormatStyle::LanguageKind Language,
/// document, are retained in \p Style.
///
/// If AllowUnknownOptions is true, no errors are emitted if unknown
-/// format options are occured.
+/// format options are occurred.
///
/// If set all diagnostics are emitted through the DiagHandler.
std::error_code
@@ -3661,7 +5061,7 @@ formatReplacements(StringRef Code, const tooling::Replacements &Replaces,
/// - If a replacement has offset UINT_MAX, length 1, and a replacement text
/// that is the name of the header to be removed, the header will be removed
/// from \p Code if it exists.
-/// The include manipulation is done via `tooling::HeaderInclude`, see its
+/// The include manipulation is done via ``tooling::HeaderInclude``, see its
/// documentation for more details on how include insertion points are found and
/// what edits are produced.
llvm::Expected<tooling::Replacements>
@@ -3720,6 +5120,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.
///
@@ -3741,11 +5152,11 @@ LangOptions getFormattingLangOpts(const FormatStyle &Style = getLLVMStyle());
extern const char *StyleOptionHelpDescription;
/// The suggested format style to use by default. This allows tools using
-/// `getStyle` to have a consistent default style.
+/// ``getStyle`` to have a consistent default style.
/// Different builds can modify the value to the preferred styles.
extern const char *DefaultFormatStyle;
-/// The suggested predefined style to use as the fallback style in `getStyle`.
+/// The suggested predefined style to use as the fallback style in ``getStyle``.
/// Different builds can modify the value to the preferred styles.
extern const char *DefaultFallbackStyle;
@@ -3758,6 +5169,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.
@@ -3807,11 +5220,16 @@ inline StringRef getLanguageName(FormatStyle::LanguageKind Language) {
return "TableGen";
case FormatStyle::LK_TextProto:
return "TextProto";
+ case FormatStyle::LK_Verilog:
+ return "Verilog";
default:
return "Unknown";
}
}
+bool isClangFormatOn(StringRef Comment);
+bool isClangFormatOff(StringRef Comment);
+
} // end namespace format
} // end namespace clang
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/ASTUnit.h b/contrib/llvm-project/clang/include/clang/Frontend/ASTUnit.h
index 6cf9f3ff936f..6af712afdcb6 100644
--- a/contrib/llvm-project/clang/include/clang/Frontend/ASTUnit.h
+++ b/contrib/llvm-project/clang/include/clang/Frontend/ASTUnit.h
@@ -31,8 +31,6 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/IntrusiveRefCntPtr.h"
-#include "llvm/ADT/None.h"
-#include "llvm/ADT/Optional.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringMap.h"
@@ -42,6 +40,7 @@
#include <cstddef>
#include <cstdint>
#include <memory>
+#include <optional>
#include <string>
#include <utility>
#include <vector>
@@ -78,6 +77,7 @@ class Preprocessor;
class PreprocessorOptions;
class Sema;
class TargetInfo;
+class SyntaxOnlyAction;
/// \brief Enumerates the available scopes for skipping function bodies.
enum class SkipFunctionBodiesScope { None, Preamble, PreambleAndMainFile };
@@ -120,11 +120,13 @@ private:
std::shared_ptr<PreprocessorOptions> PPOpts;
IntrusiveRefCntPtr<ASTReader> Reader;
bool HadModuleLoaderFatalFailure = false;
+ bool StorePreamblesInMemory = false;
struct ASTWriterData;
std::unique_ptr<ASTWriterData> WriterData;
FileSystemOptions FileSystemOpts;
+ std::string PreambleStoragePath;
/// The AST consumer that received information about the translation
/// unit as it was parsed or loaded.
@@ -222,7 +224,7 @@ private:
llvm::StringMap<SourceLocation> PreambleSrcLocCache;
/// The contents of the preamble.
- llvm::Optional<PrecompiledPreamble> Preamble;
+ std::optional<PrecompiledPreamble> Preamble;
/// When non-NULL, this is the buffer used to store the contents of
/// the main file when it has been padded for use with the precompiled
@@ -353,6 +355,7 @@ private:
/// Bit used by CIndex to mark when a translation unit may be in an
/// inconsistent state, and is not safe to free.
+ LLVM_PREFERRED_TYPE(bool)
unsigned UnsafeToFree : 1;
/// \brief Enumerator specifying the scope for skipping function bodies.
@@ -642,7 +645,7 @@ public:
bool visitLocalTopLevelDecls(void *context, DeclVisitorFn Fn);
/// Get the PCH file if one was included.
- const FileEntry *getPCHFile();
+ OptionalFileEntryRef getPCHFile();
/// Returns true if the ASTUnit was constructed from a serialized
/// module file.
@@ -688,15 +691,16 @@ public:
/// lifetime is expected to extend past that of the returned ASTUnit.
///
/// \returns - The initialized ASTUnit or null if the AST failed to load.
- static std::unique_ptr<ASTUnit>
- LoadFromASTFile(const std::string &Filename,
- const PCHContainerReader &PCHContainerRdr, WhatToLoad ToLoad,
- IntrusiveRefCntPtr<DiagnosticsEngine> Diags,
- const FileSystemOptions &FileSystemOpts,
- bool UseDebugInfo = false, bool OnlyLocalDecls = false,
- CaptureDiagsKind CaptureDiagnostics = CaptureDiagsKind::None,
- bool AllowASTWithCompilerErrors = false,
- bool UserFilesAreVolatile = false);
+ static std::unique_ptr<ASTUnit> LoadFromASTFile(
+ const std::string &Filename, const PCHContainerReader &PCHContainerRdr,
+ WhatToLoad ToLoad, IntrusiveRefCntPtr<DiagnosticsEngine> Diags,
+ const FileSystemOptions &FileSystemOpts,
+ std::shared_ptr<HeaderSearchOptions> HSOpts, bool OnlyLocalDecls = false,
+ CaptureDiagsKind CaptureDiagnostics = CaptureDiagsKind::None,
+ bool AllowASTWithCompilerErrors = false,
+ bool UserFilesAreVolatile = false,
+ IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS =
+ llvm::vfs::getRealFileSystem());
private:
/// Helper function for \c LoadFromCompilerInvocation() and
@@ -801,6 +805,13 @@ public:
///
/// \param ResourceFilesPath - The path to the compiler resource files.
///
+ /// \param StorePreamblesInMemory - Whether to store PCH in memory. If false,
+ /// PCH are stored in temporary files.
+ ///
+ /// \param PreambleStoragePath - The path to a directory, in which to create
+ /// temporary PCH files. If empty, the default system temporary directory is
+ /// used. This parameter is ignored if \p StorePreamblesInMemory is true.
+ ///
/// \param ModuleFormat - If provided, uses the specific module format.
///
/// \param ErrAST - If non-null and parsing failed without any AST to return
@@ -815,13 +826,14 @@ public:
///
// FIXME: Move OnlyLocalDecls, UseBumpAllocator to setters on the ASTUnit, we
// shouldn't need to specify them at construction time.
- static ASTUnit *LoadFromCommandLine(
+ static std::unique_ptr<ASTUnit> LoadFromCommandLine(
const char **ArgBegin, const char **ArgEnd,
std::shared_ptr<PCHContainerOperations> PCHContainerOps,
IntrusiveRefCntPtr<DiagnosticsEngine> Diags, StringRef ResourceFilesPath,
- bool OnlyLocalDecls = false,
+ bool StorePreamblesInMemory = false,
+ StringRef PreambleStoragePath = StringRef(), bool OnlyLocalDecls = false,
CaptureDiagsKind CaptureDiagnostics = CaptureDiagsKind::None,
- ArrayRef<RemappedFile> RemappedFiles = None,
+ ArrayRef<RemappedFile> RemappedFiles = std::nullopt,
bool RemappedFilesKeepOriginalName = true,
unsigned PrecompilePreambleAfterNParses = 0,
TranslationUnitKind TUKind = TU_Complete,
@@ -833,7 +845,7 @@ public:
bool SingleFileParse = false, bool UserFilesAreVolatile = false,
bool ForSerialization = false,
bool RetainExcludedConditionalBlocks = false,
- llvm::Optional<StringRef> ModuleFormat = llvm::None,
+ std::optional<StringRef> ModuleFormat = std::nullopt,
std::unique_ptr<ASTUnit> *ErrAST = nullptr,
IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS = nullptr);
@@ -849,7 +861,7 @@ public:
/// \returns True if a failure occurred that causes the ASTUnit not to
/// contain any translation-unit information, false otherwise.
bool Reparse(std::shared_ptr<PCHContainerOperations> PCHContainerOps,
- ArrayRef<RemappedFile> RemappedFiles = None,
+ ArrayRef<RemappedFile> RemappedFiles = std::nullopt,
IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS = nullptr);
/// Free data that will be re-generated on the next parse.
@@ -875,6 +887,10 @@ public:
/// \param IncludeBriefComments Whether to include brief documentation within
/// the set of code completions returned.
///
+ /// \param Act If supplied, this argument is used to parse the input file,
+ /// allowing customized parsing by overriding SyntaxOnlyAction lifecycle
+ /// methods.
+ ///
/// FIXME: The Diag, LangOpts, SourceMgr, FileMgr, StoredDiagnostics, and
/// OwnedBuffers parameters are all disgusting hacks. They will go away.
void CodeComplete(StringRef File, unsigned Line, unsigned Column,
@@ -885,7 +901,8 @@ public:
DiagnosticsEngine &Diag, LangOptions &LangOpts,
SourceManager &SourceMgr, FileManager &FileMgr,
SmallVectorImpl<StoredDiagnostic> &StoredDiagnostics,
- SmallVectorImpl<const llvm::MemoryBuffer *> &OwnedBuffers);
+ SmallVectorImpl<const llvm::MemoryBuffer *> &OwnedBuffers,
+ std::unique_ptr<SyntaxOnlyAction> Act);
/// Save this translation unit to a file with the given name.
///
diff --git a/contrib/llvm-project/clang/include/clang/Frontend/CommandLineSourceLoc.h b/contrib/llvm-project/clang/include/clang/Frontend/CommandLineSourceLoc.h
index dfc4454b4baf..074800a881a8 100644
--- a/contrib/llvm-project/clang/include/clang/Frontend/CommandLineSourceLoc.h
+++ b/contrib/llvm-project/clang/include/clang/Frontend/CommandLineSourceLoc.h
@@ -17,6 +17,7 @@
#include "clang/Basic/LLVM.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/raw_ostream.h"
+#include <optional>
namespace clang {
@@ -67,8 +68,8 @@ struct ParsedSourceRange {
/// second element is the column.
std::pair<unsigned, unsigned> End;
- /// Returns a parsed source range from a string or None if the string is
- /// invalid.
+ /// Returns a parsed source range from a string or std::nullopt if the string
+ /// is invalid.
///
/// These source string has the following format:
///
@@ -76,7 +77,7 @@ struct ParsedSourceRange {
///
/// If the end line and column are omitted, the starting line and columns
/// are used as the end values.
- static Optional<ParsedSourceRange> fromString(StringRef Str) {
+ static std::optional<ParsedSourceRange> fromString(StringRef Str) {
std::pair<StringRef, StringRef> RangeSplit = Str.rsplit('-');
unsigned EndLine, EndColumn;
bool HasEndLoc = false;
@@ -93,7 +94,7 @@ struct ParsedSourceRange {
}
auto Begin = ParsedSourceLocation::FromString(RangeSplit.first);
if (Begin.FileName.empty())
- return None;
+ return std::nullopt;
if (!HasEndLoc) {
EndLine = Begin.Line;
EndColumn = Begin.Column;
diff --git a/contrib/llvm-project/clang/include/clang/Frontend/CompilerInstance.h b/contrib/llvm-project/clang/include/clang/Frontend/CompilerInstance.h
index 861b15020329..ac2f940769fb 100644
--- a/contrib/llvm-project/clang/include/clang/Frontend/CompilerInstance.h
+++ b/contrib/llvm-project/clang/include/clang/Frontend/CompilerInstance.h
@@ -12,6 +12,7 @@
#include "clang/AST/ASTConsumer.h"
#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/SourceManager.h"
+#include "clang/Basic/TargetInfo.h"
#include "clang/Frontend/CompilerInvocation.h"
#include "clang/Frontend/PCHContainerOperations.h"
#include "clang/Frontend/Utils.h"
@@ -26,6 +27,7 @@
#include <cassert>
#include <list>
#include <memory>
+#include <optional>
#include <string>
#include <utility>
@@ -38,11 +40,14 @@ class TimerGroup;
namespace clang {
class ASTContext;
class ASTReader;
+
+namespace serialization {
+class ModuleFile;
+}
+
class CodeCompleteConsumer;
class DiagnosticsEngine;
class DiagnosticConsumer;
-class ExternalASTSource;
-class FileEntry;
class FileManager;
class FrontendAction;
class InMemoryModuleCache;
@@ -166,9 +171,10 @@ class CompilerInstance : public ModuleLoader {
/// failed.
struct OutputFile {
std::string Filename;
- Optional<llvm::sys::fs::TempFile> File;
+ std::optional<llvm::sys::fs::TempFile> File;
- OutputFile(std::string filename, Optional<llvm::sys::fs::TempFile> file)
+ OutputFile(std::string filename,
+ std::optional<llvm::sys::fs::TempFile> file)
: Filename(std::move(filename)), File(std::move(file)) {}
};
@@ -188,7 +194,7 @@ public:
~CompilerInstance() override;
/// @name High-Level Operations
- /// {
+ /// @{
/// ExecuteAction - Execute the provided action against the compiler's
/// CompilerInvocation object.
@@ -219,9 +225,12 @@ public:
// of the context or else not CompilerInstance specific.
bool ExecuteAction(FrontendAction &Act);
- /// }
+ /// Load the list of plugins requested in the \c FrontendOptions.
+ void LoadRequestedPlugins();
+
+ /// @}
/// @name Compiler Invocation and Options
- /// {
+ /// @{
bool hasInvocation() const { return Invocation != nullptr; }
@@ -230,6 +239,8 @@ public:
return *Invocation;
}
+ std::shared_ptr<CompilerInvocation> getInvocationPtr() { return Invocation; }
+
/// setInvocation - Replace the current invocation.
void setInvocation(std::shared_ptr<CompilerInvocation> Value);
@@ -242,13 +253,11 @@ public:
BuildGlobalModuleIndex = Build;
}
- /// }
+ /// @}
/// @name Forwarding Methods
- /// {
+ /// @{
- AnalyzerOptionsRef getAnalyzerOpts() {
- return Invocation->getAnalyzerOpts();
- }
+ AnalyzerOptions &getAnalyzerOpts() { return Invocation->getAnalyzerOpts(); }
CodeGenOptions &getCodeGenOpts() {
return Invocation->getCodeGenOpts();
@@ -295,13 +304,14 @@ public:
return Invocation->getHeaderSearchOptsPtr();
}
- LangOptions &getLangOpts() {
- return *Invocation->getLangOpts();
- }
- const LangOptions &getLangOpts() const {
- return *Invocation->getLangOpts();
+ APINotesOptions &getAPINotesOpts() { return Invocation->getAPINotesOpts(); }
+ const APINotesOptions &getAPINotesOpts() const {
+ return Invocation->getAPINotesOpts();
}
+ LangOptions &getLangOpts() { return Invocation->getLangOpts(); }
+ const LangOptions &getLangOpts() const { return Invocation->getLangOpts(); }
+
PreprocessorOptions &getPreprocessorOpts() {
return Invocation->getPreprocessorOpts();
}
@@ -323,9 +333,9 @@ public:
return Invocation->getTargetOpts();
}
- /// }
+ /// @}
/// @name Diagnostics Engine
- /// {
+ /// @{
bool hasDiagnostics() const { return Diagnostics != nullptr; }
@@ -335,6 +345,11 @@ public:
return *Diagnostics;
}
+ IntrusiveRefCntPtr<DiagnosticsEngine> getDiagnosticsPtr() const {
+ assert(Diagnostics && "Compiler instance has no diagnostics!");
+ return Diagnostics;
+ }
+
/// setDiagnostics - Replace the current diagnostics engine.
void setDiagnostics(DiagnosticsEngine *Value);
@@ -344,9 +359,9 @@ public:
return *Diagnostics->getClient();
}
- /// }
+ /// @}
/// @name VerboseOutputStream
- /// }
+ /// @{
/// Replace the current stream for verbose output.
void setVerboseOutputStream(raw_ostream &Value);
@@ -359,9 +374,9 @@ public:
return *VerboseOutputStream;
}
- /// }
+ /// @}
/// @name Target Info
- /// {
+ /// @{
bool hasTarget() const { return Target != nullptr; }
@@ -370,12 +385,17 @@ public:
return *Target;
}
+ IntrusiveRefCntPtr<TargetInfo> getTargetPtr() const {
+ assert(Target && "Compiler instance has no target!");
+ return Target;
+ }
+
/// Replace the current Target.
void setTarget(TargetInfo *Value);
- /// }
+ /// @}
/// @name AuxTarget Info
- /// {
+ /// @{
TargetInfo *getAuxTarget() const { return AuxTarget.get(); }
@@ -385,15 +405,15 @@ public:
// Create Target and AuxTarget based on current options
bool createTarget();
- /// }
+ /// @}
/// @name Virtual File System
- /// {
+ /// @{
llvm::vfs::FileSystem &getVirtualFileSystem() const;
- /// }
+ /// @}
/// @name File Manager
- /// {
+ /// @{
bool hasFileManager() const { return FileMgr != nullptr; }
@@ -403,6 +423,11 @@ public:
return *FileMgr;
}
+ IntrusiveRefCntPtr<FileManager> getFileManagerPtr() const {
+ assert(FileMgr && "Compiler instance has no file manager!");
+ return FileMgr;
+ }
+
void resetAndLeakFileManager() {
llvm::BuryPointer(FileMgr.get());
FileMgr.resetWithoutRelease();
@@ -411,9 +436,9 @@ public:
/// Replace the current file manager and virtual file system.
void setFileManager(FileManager *Value);
- /// }
+ /// @}
/// @name Source Manager
- /// {
+ /// @{
bool hasSourceManager() const { return SourceMgr != nullptr; }
@@ -423,6 +448,11 @@ public:
return *SourceMgr;
}
+ IntrusiveRefCntPtr<SourceManager> getSourceManagerPtr() const {
+ assert(SourceMgr && "Compiler instance has no source manager!");
+ return SourceMgr;
+ }
+
void resetAndLeakSourceManager() {
llvm::BuryPointer(SourceMgr.get());
SourceMgr.resetWithoutRelease();
@@ -431,9 +461,9 @@ public:
/// setSourceManager - Replace the current source manager.
void setSourceManager(SourceManager *Value);
- /// }
+ /// @}
/// @name Preprocessor
- /// {
+ /// @{
bool hasPreprocessor() const { return PP != nullptr; }
@@ -452,9 +482,9 @@ public:
/// Replace the current preprocessor.
void setPreprocessor(std::shared_ptr<Preprocessor> Value);
- /// }
+ /// @}
/// @name ASTContext
- /// {
+ /// @{
bool hasASTContext() const { return Context != nullptr; }
@@ -463,6 +493,11 @@ public:
return *Context;
}
+ IntrusiveRefCntPtr<ASTContext> getASTContextPtr() const {
+ assert(Context && "Compiler instance has no AST context!");
+ return Context;
+ }
+
void resetAndLeakASTContext() {
llvm::BuryPointer(Context.get());
Context.resetWithoutRelease();
@@ -475,9 +510,9 @@ public:
/// of S.
void setSema(Sema *S);
- /// }
+ /// @}
/// @name ASTConsumer
- /// {
+ /// @{
bool hasASTConsumer() const { return (bool)Consumer; }
@@ -494,9 +529,9 @@ public:
/// takes ownership of \p Value.
void setASTConsumer(std::unique_ptr<ASTConsumer> Value);
- /// }
+ /// @}
/// @name Semantic analysis
- /// {
+ /// @{
bool hasSema() const { return (bool)TheSema; }
Sema &getSema() const {
@@ -507,9 +542,9 @@ public:
std::unique_ptr<Sema> takeSema();
void resetAndLeakSema();
- /// }
+ /// @}
/// @name Module Management
- /// {
+ /// @{
IntrusiveRefCntPtr<ASTReader> getASTReader() const;
void setASTReader(IntrusiveRefCntPtr<ASTReader> Reader);
@@ -550,9 +585,9 @@ public:
return *Reader;
}
- /// }
+ /// @}
/// @name Code Completion
- /// {
+ /// @{
bool hasCodeCompletionConsumer() const { return (bool)CompletionConsumer; }
@@ -566,9 +601,9 @@ public:
/// the compiler instance takes ownership of \p Value.
void setCodeCompletionConsumer(CodeCompleteConsumer *Value);
- /// }
+ /// @}
/// @name Frontend timer
- /// {
+ /// @{
bool hasFrontendTimer() const { return (bool)FrontendTimer; }
@@ -577,9 +612,9 @@ public:
return *FrontendTimer;
}
- /// }
+ /// @}
/// @name Output Files
- /// {
+ /// @{
/// clearOutputFiles - Clear the output file list. The underlying output
/// streams must have been closed beforehand.
@@ -587,9 +622,9 @@ public:
/// \param EraseFiles - If true, attempt to erase the files from disk.
void clearOutputFiles(bool EraseFiles);
- /// }
+ /// @}
/// @name Construction Utility Methods
- /// {
+ /// @{
/// Create the diagnostics engine using the invocation's diagnostic options
/// and replace any existing one with it.
@@ -738,9 +773,9 @@ private:
public:
std::unique_ptr<raw_pwrite_stream> createNullOutputFile();
- /// }
+ /// @}
/// @name Initialization Utility Methods
- /// {
+ /// @{
/// InitializeSourceManager - Initialize the source manager to set InputFile
/// as the main file.
@@ -757,7 +792,7 @@ public:
FileManager &FileMgr,
SourceManager &SourceMgr);
- /// }
+ /// @}
void setOutputStream(std::unique_ptr<llvm::raw_pwrite_stream> OutStream) {
OutputStream = std::move(OutStream);
@@ -769,7 +804,8 @@ public:
void createASTReader();
- bool loadModuleFile(StringRef FileName);
+ bool loadModuleFile(StringRef FileName,
+ serialization::ModuleFile *&LoadedModuleFile);
private:
/// Find a module, potentially compiling it, before reading its AST. This is
diff --git a/contrib/llvm-project/clang/include/clang/Frontend/CompilerInvocation.h b/contrib/llvm-project/clang/include/clang/Frontend/CompilerInvocation.h
index 2245439d0632..c6528779bde7 100644
--- a/contrib/llvm-project/clang/include/clang/Frontend/CompilerInvocation.h
+++ b/contrib/llvm-project/clang/include/clang/Frontend/CompilerInvocation.h
@@ -9,6 +9,7 @@
#ifndef LLVM_CLANG_FRONTEND_COMPILERINVOCATION_H
#define LLVM_CLANG_FRONTEND_COMPILERINVOCATION_H
+#include "clang/APINotes/APINotesOptions.h"
#include "clang/Basic/CodeGenOptions.h"
#include "clang/Basic/DiagnosticOptions.h"
#include "clang/Basic/FileSystemOptions.h"
@@ -50,6 +51,11 @@ class HeaderSearchOptions;
class PreprocessorOptions;
class TargetOptions;
+// This lets us create the DiagnosticsEngine with a properly-filled-out
+// DiagnosticOptions instance.
+std::unique_ptr<DiagnosticOptions>
+CreateAndPopulateDiagOpts(ArrayRef<const char *> Argv);
+
/// Fill out Opts based on the options given in Args.
///
/// Args must have been created from the OptTable returned by
@@ -61,16 +67,12 @@ bool ParseDiagnosticArgs(DiagnosticOptions &Opts, llvm::opt::ArgList &Args,
DiagnosticsEngine *Diags = nullptr,
bool DefaultDiagColor = true);
-/// The base class of CompilerInvocation with reference semantics.
-///
-/// This class stores option objects behind reference-counted pointers. This is
-/// useful for clients that want to keep some option object around even after
-/// CompilerInvocation gets destroyed, without making a copy.
-///
-/// This is a separate class so that we can implement the copy constructor and
-/// assignment here and leave them defaulted in the rest of CompilerInvocation.
-class CompilerInvocationRefBase {
-public:
+/// The base class of CompilerInvocation. It keeps individual option objects
+/// behind reference-counted pointers, which is useful for clients that want to
+/// keep select option objects alive (even after CompilerInvocation gets
+/// destroyed) without making a copy.
+class CompilerInvocationBase {
+protected:
/// Options controlling the language variant.
std::shared_ptr<LangOptions> LangOpts;
@@ -81,103 +83,122 @@ public:
IntrusiveRefCntPtr<DiagnosticOptions> DiagnosticOpts;
/// Options controlling the \#include directive.
- std::shared_ptr<HeaderSearchOptions> HeaderSearchOpts;
+ std::shared_ptr<HeaderSearchOptions> HSOpts;
/// Options controlling the preprocessor (aside from \#include handling).
- std::shared_ptr<PreprocessorOptions> PreprocessorOpts;
+ std::shared_ptr<PreprocessorOptions> PPOpts;
/// Options controlling the static analyzer.
AnalyzerOptionsRef AnalyzerOpts;
- CompilerInvocationRefBase();
- CompilerInvocationRefBase(const CompilerInvocationRefBase &X);
- CompilerInvocationRefBase(CompilerInvocationRefBase &&X);
- CompilerInvocationRefBase &operator=(CompilerInvocationRefBase X);
- CompilerInvocationRefBase &operator=(CompilerInvocationRefBase &&X);
- ~CompilerInvocationRefBase();
-
- LangOptions *getLangOpts() { return LangOpts.get(); }
- const LangOptions *getLangOpts() const { return LangOpts.get(); }
-
- TargetOptions &getTargetOpts() { return *TargetOpts.get(); }
- const TargetOptions &getTargetOpts() const { return *TargetOpts.get(); }
+ std::shared_ptr<MigratorOptions> MigratorOpts;
- DiagnosticOptions &getDiagnosticOpts() const { return *DiagnosticOpts; }
-
- HeaderSearchOptions &getHeaderSearchOpts() { return *HeaderSearchOpts; }
-
- const HeaderSearchOptions &getHeaderSearchOpts() const {
- return *HeaderSearchOpts;
- }
-
- std::shared_ptr<HeaderSearchOptions> getHeaderSearchOptsPtr() const {
- return HeaderSearchOpts;
- }
-
- std::shared_ptr<PreprocessorOptions> getPreprocessorOptsPtr() {
- return PreprocessorOpts;
- }
-
- PreprocessorOptions &getPreprocessorOpts() { return *PreprocessorOpts; }
-
- const PreprocessorOptions &getPreprocessorOpts() const {
- return *PreprocessorOpts;
- }
-
- AnalyzerOptionsRef getAnalyzerOpts() const { return AnalyzerOpts; }
-};
-
-/// The base class of CompilerInvocation with value semantics.
-class CompilerInvocationValueBase {
-protected:
- MigratorOptions MigratorOpts;
+ /// Options controlling API notes.
+ std::shared_ptr<APINotesOptions> APINotesOpts;
/// Options controlling IRgen and the backend.
- CodeGenOptions CodeGenOpts;
-
- /// Options controlling dependency output.
- DependencyOutputOptions DependencyOutputOpts;
+ std::shared_ptr<CodeGenOptions> CodeGenOpts;
/// Options controlling file system operations.
- FileSystemOptions FileSystemOpts;
+ std::shared_ptr<FileSystemOptions> FSOpts;
/// Options controlling the frontend itself.
- FrontendOptions FrontendOpts;
+ std::shared_ptr<FrontendOptions> FrontendOpts;
+
+ /// Options controlling dependency output.
+ std::shared_ptr<DependencyOutputOptions> DependencyOutputOpts;
/// Options controlling preprocessed output.
- PreprocessorOutputOptions PreprocessorOutputOpts;
+ std::shared_ptr<PreprocessorOutputOptions> PreprocessorOutputOpts;
+
+ /// Dummy tag type whose instance can be passed into the constructor to
+ /// prevent creation of the reference-counted option objects.
+ struct EmptyConstructor {};
+
+ CompilerInvocationBase();
+ CompilerInvocationBase(EmptyConstructor) {}
+ CompilerInvocationBase(const CompilerInvocationBase &X) = delete;
+ CompilerInvocationBase(CompilerInvocationBase &&X) = default;
+ CompilerInvocationBase &operator=(const CompilerInvocationBase &X) = delete;
+ CompilerInvocationBase &deep_copy_assign(const CompilerInvocationBase &X);
+ CompilerInvocationBase &shallow_copy_assign(const CompilerInvocationBase &X);
+ CompilerInvocationBase &operator=(CompilerInvocationBase &&X) = default;
+ ~CompilerInvocationBase() = default;
public:
- MigratorOptions &getMigratorOpts() { return MigratorOpts; }
- const MigratorOptions &getMigratorOpts() const { return MigratorOpts; }
-
- CodeGenOptions &getCodeGenOpts() { return CodeGenOpts; }
- const CodeGenOptions &getCodeGenOpts() const { return CodeGenOpts; }
-
- DependencyOutputOptions &getDependencyOutputOpts() {
- return DependencyOutputOpts;
+ /// Const getters.
+ /// @{
+ const LangOptions &getLangOpts() const { return *LangOpts; }
+ const TargetOptions &getTargetOpts() const { return *TargetOpts; }
+ const DiagnosticOptions &getDiagnosticOpts() const { return *DiagnosticOpts; }
+ const HeaderSearchOptions &getHeaderSearchOpts() const { return *HSOpts; }
+ const PreprocessorOptions &getPreprocessorOpts() const { return *PPOpts; }
+ const AnalyzerOptions &getAnalyzerOpts() const { return *AnalyzerOpts; }
+ const MigratorOptions &getMigratorOpts() const { return *MigratorOpts; }
+ const APINotesOptions &getAPINotesOpts() const { return *APINotesOpts; }
+ const CodeGenOptions &getCodeGenOpts() const { return *CodeGenOpts; }
+ const FileSystemOptions &getFileSystemOpts() const { return *FSOpts; }
+ const FrontendOptions &getFrontendOpts() const { return *FrontendOpts; }
+ const DependencyOutputOptions &getDependencyOutputOpts() const {
+ return *DependencyOutputOpts;
+ }
+ const PreprocessorOutputOptions &getPreprocessorOutputOpts() const {
+ return *PreprocessorOutputOpts;
}
+ /// @}
- const DependencyOutputOptions &getDependencyOutputOpts() const {
- return DependencyOutputOpts;
+ /// Command line generation.
+ /// @{
+ using StringAllocator = llvm::function_ref<const char *(const Twine &)>;
+ /// Generate cc1-compatible command line arguments from this instance.
+ ///
+ /// \param [out] Args - The generated arguments. Note that the caller is
+ /// responsible for inserting the path to the clang executable and "-cc1" if
+ /// desired.
+ /// \param SA - A function that given a Twine can allocate storage for a given
+ /// command line argument and return a pointer to the newly allocated string.
+ /// The returned pointer is what gets appended to Args.
+ void generateCC1CommandLine(llvm::SmallVectorImpl<const char *> &Args,
+ StringAllocator SA) const {
+ generateCC1CommandLine([&](const Twine &Arg) {
+ // No need to allocate static string literals.
+ Args.push_back(Arg.isSingleStringLiteral()
+ ? Arg.getSingleStringRef().data()
+ : SA(Arg));
+ });
}
- FileSystemOptions &getFileSystemOpts() { return FileSystemOpts; }
+ using ArgumentConsumer = llvm::function_ref<void(const Twine &)>;
+ /// Generate cc1-compatible command line arguments from this instance.
+ ///
+ /// \param Consumer - Callback that gets invoked for every single generated
+ /// command line argument.
+ void generateCC1CommandLine(ArgumentConsumer Consumer) const;
- const FileSystemOptions &getFileSystemOpts() const {
- return FileSystemOpts;
- }
+ /// Generate cc1-compatible command line arguments from this instance,
+ /// wrapping the result as a std::vector<std::string>.
+ ///
+ /// This is a (less-efficient) wrapper over generateCC1CommandLine().
+ std::vector<std::string> getCC1CommandLine() const;
- FrontendOptions &getFrontendOpts() { return FrontendOpts; }
- const FrontendOptions &getFrontendOpts() const { return FrontendOpts; }
+private:
+ /// Generate command line options from DiagnosticOptions.
+ static void GenerateDiagnosticArgs(const DiagnosticOptions &Opts,
+ ArgumentConsumer Consumer,
+ bool DefaultDiagColor);
- PreprocessorOutputOptions &getPreprocessorOutputOpts() {
- return PreprocessorOutputOpts;
- }
+ /// Generate command line options from LangOptions.
+ static void GenerateLangArgs(const LangOptions &Opts,
+ ArgumentConsumer Consumer, const llvm::Triple &T,
+ InputKind IK);
- const PreprocessorOutputOptions &getPreprocessorOutputOpts() const {
- return PreprocessorOutputOpts;
- }
+ // Generate command line options from CodeGenOptions.
+ static void GenerateCodeGenArgs(const CodeGenOptions &Opts,
+ ArgumentConsumer Consumer,
+ const llvm::Triple &T,
+ const std::string &OutputFile,
+ const LangOptions *LangOpts);
+ /// @}
};
/// Helper class for holding the data necessary to invoke the compiler.
@@ -185,9 +206,73 @@ public:
/// This class is designed to represent an abstract "invocation" of the
/// compiler, including data such as the include paths, the code generation
/// options, the warning flags, and so on.
-class CompilerInvocation : public CompilerInvocationRefBase,
- public CompilerInvocationValueBase {
+class CompilerInvocation : public CompilerInvocationBase {
public:
+ CompilerInvocation() = default;
+ CompilerInvocation(const CompilerInvocation &X)
+ : CompilerInvocationBase(EmptyConstructor{}) {
+ deep_copy_assign(X);
+ }
+ CompilerInvocation(CompilerInvocation &&) = default;
+ CompilerInvocation &operator=(const CompilerInvocation &X) {
+ deep_copy_assign(X);
+ return *this;
+ }
+ ~CompilerInvocation() = default;
+
+ /// Const getters.
+ /// @{
+ // Note: These need to be pulled in manually. Otherwise, they get hidden by
+ // the mutable getters with the same names.
+ using CompilerInvocationBase::getLangOpts;
+ using CompilerInvocationBase::getTargetOpts;
+ using CompilerInvocationBase::getDiagnosticOpts;
+ using CompilerInvocationBase::getHeaderSearchOpts;
+ using CompilerInvocationBase::getPreprocessorOpts;
+ using CompilerInvocationBase::getAnalyzerOpts;
+ using CompilerInvocationBase::getMigratorOpts;
+ using CompilerInvocationBase::getAPINotesOpts;
+ using CompilerInvocationBase::getCodeGenOpts;
+ using CompilerInvocationBase::getFileSystemOpts;
+ using CompilerInvocationBase::getFrontendOpts;
+ using CompilerInvocationBase::getDependencyOutputOpts;
+ using CompilerInvocationBase::getPreprocessorOutputOpts;
+ /// @}
+
+ /// Mutable getters.
+ /// @{
+ LangOptions &getLangOpts() { return *LangOpts; }
+ TargetOptions &getTargetOpts() { return *TargetOpts; }
+ DiagnosticOptions &getDiagnosticOpts() { return *DiagnosticOpts; }
+ HeaderSearchOptions &getHeaderSearchOpts() { return *HSOpts; }
+ PreprocessorOptions &getPreprocessorOpts() { return *PPOpts; }
+ AnalyzerOptions &getAnalyzerOpts() { return *AnalyzerOpts; }
+ MigratorOptions &getMigratorOpts() { return *MigratorOpts; }
+ APINotesOptions &getAPINotesOpts() { return *APINotesOpts; }
+ CodeGenOptions &getCodeGenOpts() { return *CodeGenOpts; }
+ FileSystemOptions &getFileSystemOpts() { return *FSOpts; }
+ FrontendOptions &getFrontendOpts() { return *FrontendOpts; }
+ DependencyOutputOptions &getDependencyOutputOpts() {
+ return *DependencyOutputOpts;
+ }
+ PreprocessorOutputOptions &getPreprocessorOutputOpts() {
+ return *PreprocessorOutputOpts;
+ }
+ /// @}
+
+ /// Base class internals.
+ /// @{
+ using CompilerInvocationBase::LangOpts;
+ using CompilerInvocationBase::TargetOpts;
+ using CompilerInvocationBase::DiagnosticOpts;
+ std::shared_ptr<HeaderSearchOptions> getHeaderSearchOptsPtr() {
+ return HSOpts;
+ }
+ std::shared_ptr<PreprocessorOptions> getPreprocessorOptsPtr() {
+ return PPOpts;
+ }
+ /// @}
+
/// Create a compiler invocation from a list of input options.
/// \returns true on success.
///
@@ -214,70 +299,89 @@ public:
/// executable), for finding the builtin compiler path.
static std::string GetResourcesPath(const char *Argv0, void *MainAddr);
- /// Set language defaults for the given input language and
- /// language standard in the given LangOptions object.
- ///
- /// \param Opts - The LangOptions object to set up.
- /// \param IK - The input language.
- /// \param T - The target triple.
- /// \param Includes - The affected list of included files.
- /// \param LangStd - The input language standard.
- static void
- setLangDefaults(LangOptions &Opts, InputKind IK, const llvm::Triple &T,
- std::vector<std::string> &Includes,
- LangStandard::Kind LangStd = LangStandard::lang_unspecified);
-
/// Retrieve a module hash string that is suitable for uniquely
/// identifying the conditions under which the module was built.
std::string getModuleHash() const;
- using StringAllocator = llvm::function_ref<const char *(const llvm::Twine &)>;
- /// Generate a cc1-compatible command line arguments from this instance.
+ /// Check that \p Args can be parsed and re-serialized without change,
+ /// emiting diagnostics for any differences.
///
- /// \param [out] Args - The generated arguments. Note that the caller is
- /// responsible for inserting the path to the clang executable and "-cc1" if
- /// desired.
- /// \param SA - A function that given a Twine can allocate storage for a given
- /// command line argument and return a pointer to the newly allocated string.
- /// The returned pointer is what gets appended to Args.
- void generateCC1CommandLine(llvm::SmallVectorImpl<const char *> &Args,
- StringAllocator SA) const;
+ /// This check is only suitable for command-lines that are expected to already
+ /// be canonical.
+ ///
+ /// \return false if there are any errors.
+ static bool checkCC1RoundTrip(ArrayRef<const char *> Args,
+ DiagnosticsEngine &Diags,
+ const char *Argv0 = nullptr);
+
+ /// Reset all of the options that are not considered when building a
+ /// module.
+ void resetNonModularOptions();
+
+ /// Disable implicit modules and canonicalize options that are only used by
+ /// implicit modules.
+ void clearImplicitModuleBuildOptions();
private:
static bool CreateFromArgsImpl(CompilerInvocation &Res,
ArrayRef<const char *> CommandLineArgs,
DiagnosticsEngine &Diags, const char *Argv0);
- /// Generate command line options from DiagnosticOptions.
- static void GenerateDiagnosticArgs(const DiagnosticOptions &Opts,
- SmallVectorImpl<const char *> &Args,
- StringAllocator SA, bool DefaultDiagColor);
-
/// Parse command line options that map to LangOptions.
static bool ParseLangArgs(LangOptions &Opts, llvm::opt::ArgList &Args,
InputKind IK, const llvm::Triple &T,
std::vector<std::string> &Includes,
DiagnosticsEngine &Diags);
- /// Generate command line options from LangOptions.
- static void GenerateLangArgs(const LangOptions &Opts,
- SmallVectorImpl<const char *> &Args,
- StringAllocator SA, const llvm::Triple &T,
- InputKind IK);
-
/// Parse command line options that map to CodeGenOptions.
static bool ParseCodeGenArgs(CodeGenOptions &Opts, llvm::opt::ArgList &Args,
InputKind IK, DiagnosticsEngine &Diags,
const llvm::Triple &T,
const std::string &OutputFile,
const LangOptions &LangOptsRef);
+};
- // Generate command line options from CodeGenOptions.
- static void GenerateCodeGenArgs(const CodeGenOptions &Opts,
- SmallVectorImpl<const char *> &Args,
- StringAllocator SA, const llvm::Triple &T,
- const std::string &OutputFile,
- const LangOptions *LangOpts);
+/// Same as \c CompilerInvocation, but with copy-on-write optimization.
+class CowCompilerInvocation : public CompilerInvocationBase {
+public:
+ CowCompilerInvocation() = default;
+ CowCompilerInvocation(const CowCompilerInvocation &X)
+ : CompilerInvocationBase(EmptyConstructor{}) {
+ shallow_copy_assign(X);
+ }
+ CowCompilerInvocation(CowCompilerInvocation &&) = default;
+ CowCompilerInvocation &operator=(const CowCompilerInvocation &X) {
+ shallow_copy_assign(X);
+ return *this;
+ }
+ ~CowCompilerInvocation() = default;
+
+ CowCompilerInvocation(const CompilerInvocation &X)
+ : CompilerInvocationBase(EmptyConstructor{}) {
+ deep_copy_assign(X);
+ }
+
+ CowCompilerInvocation(CompilerInvocation &&X)
+ : CompilerInvocationBase(std::move(X)) {}
+
+ // Const getters are inherited from the base class.
+
+ /// Mutable getters.
+ /// @{
+ LangOptions &getMutLangOpts();
+ TargetOptions &getMutTargetOpts();
+ DiagnosticOptions &getMutDiagnosticOpts();
+ HeaderSearchOptions &getMutHeaderSearchOpts();
+ PreprocessorOptions &getMutPreprocessorOpts();
+ AnalyzerOptions &getMutAnalyzerOpts();
+ MigratorOptions &getMutMigratorOpts();
+ APINotesOptions &getMutAPINotesOpts();
+ CodeGenOptions &getMutCodeGenOpts();
+ FileSystemOptions &getMutFileSystemOpts();
+ FrontendOptions &getMutFrontendOpts();
+ DependencyOutputOptions &getMutDependencyOutputOpts();
+ PreprocessorOutputOptions &getMutPreprocessorOutputOpts();
+ /// @}
};
IntrusiveRefCntPtr<llvm::vfs::FileSystem>
@@ -288,6 +392,11 @@ IntrusiveRefCntPtr<llvm::vfs::FileSystem> createVFSFromCompilerInvocation(
const CompilerInvocation &CI, DiagnosticsEngine &Diags,
IntrusiveRefCntPtr<llvm::vfs::FileSystem> BaseFS);
+IntrusiveRefCntPtr<llvm::vfs::FileSystem>
+createVFSFromOverlayFiles(ArrayRef<std::string> VFSOverlayFiles,
+ DiagnosticsEngine &Diags,
+ IntrusiveRefCntPtr<llvm::vfs::FileSystem> BaseFS);
+
} // namespace clang
#endif // LLVM_CLANG_FRONTEND_COMPILERINVOCATION_H
diff --git a/contrib/llvm-project/clang/include/clang/Frontend/DependencyOutputOptions.h b/contrib/llvm-project/clang/include/clang/Frontend/DependencyOutputOptions.h
index 78a2841d1e10..d92a87d78d7c 100644
--- a/contrib/llvm-project/clang/include/clang/Frontend/DependencyOutputOptions.h
+++ b/contrib/llvm-project/clang/include/clang/Frontend/DependencyOutputOptions.h
@@ -9,6 +9,7 @@
#ifndef LLVM_CLANG_FRONTEND_DEPENDENCYOUTPUTOPTIONS_H
#define LLVM_CLANG_FRONTEND_DEPENDENCYOUTPUTOPTIONS_H
+#include "clang/Basic/HeaderInclude.h"
#include <string>
#include <vector>
@@ -32,18 +33,30 @@ enum ExtraDepKind {
/// file generation.
class DependencyOutputOptions {
public:
+ LLVM_PREFERRED_TYPE(bool)
unsigned IncludeSystemHeaders : 1; ///< Include system header dependencies.
+ LLVM_PREFERRED_TYPE(bool)
unsigned ShowHeaderIncludes : 1; ///< Show header inclusions (-H).
+ LLVM_PREFERRED_TYPE(bool)
unsigned UsePhonyTargets : 1; ///< Include phony targets for each
/// dependency, which can avoid some 'make'
/// problems.
+ LLVM_PREFERRED_TYPE(bool)
unsigned AddMissingHeaderDeps : 1; ///< Add missing headers to dependency list
+ LLVM_PREFERRED_TYPE(bool)
unsigned IncludeModuleFiles : 1; ///< Include module file dependencies.
+ LLVM_PREFERRED_TYPE(bool)
unsigned ShowSkippedHeaderIncludes : 1; ///< With ShowHeaderIncludes, show
/// also includes that were skipped
/// due to the "include guard
/// optimization" or #pragma once.
+ /// The format of header information.
+ HeaderIncludeFormatKind HeaderIncludeFormat = HIFMT_Textual;
+
+ /// Determine whether header information should be filtered.
+ HeaderIncludeFilteringKind HeaderIncludeFiltering = HIFIL_None;
+
/// Destination of cl.exe style /showIncludes info.
ShowIncludesDestination ShowIncludesDest = ShowIncludesDestination::None;
@@ -67,9 +80,6 @@ public:
/// target.
std::vector<std::pair<std::string, ExtraDepKind>> ExtraDeps;
- /// In /showIncludes mode, pretend the main TU is a header with this name.
- std::string ShowIncludesPretendHeader;
-
/// The file to write GraphViz-formatted header dependencies to.
std::string DOTOutputFile;
@@ -80,7 +90,8 @@ public:
DependencyOutputOptions()
: IncludeSystemHeaders(0), ShowHeaderIncludes(0), UsePhonyTargets(0),
AddMissingHeaderDeps(0), IncludeModuleFiles(0),
- ShowSkippedHeaderIncludes(0) {}
+ ShowSkippedHeaderIncludes(0), HeaderIncludeFormat(HIFMT_Textual),
+ HeaderIncludeFiltering(HIFIL_None) {}
};
} // end namespace clang
diff --git a/contrib/llvm-project/clang/include/clang/Frontend/FrontendAction.h b/contrib/llvm-project/clang/include/clang/Frontend/FrontendAction.h
index dfefddfb4527..039f6f247b6d 100644
--- a/contrib/llvm-project/clang/include/clang/Frontend/FrontendAction.h
+++ b/contrib/llvm-project/clang/include/clang/Frontend/FrontendAction.h
@@ -270,17 +270,18 @@ public:
const std::vector<std::string> &arg) = 0;
enum ActionType {
- Cmdline, ///< Action is determined by the cc1 command-line
- ReplaceAction, ///< Replace the main action
- AddBeforeMainAction, ///< Execute the action before the main action
- AddAfterMainAction ///< Execute the action after the main action
+ CmdlineBeforeMainAction, ///< Execute the action before the main action if
+ ///< on the command line
+ CmdlineAfterMainAction, ///< Execute the action after the main action if on
+ ///< the command line
+ ReplaceAction, ///< Replace the main action
+ AddBeforeMainAction, ///< Execute the action before the main action
+ AddAfterMainAction ///< Execute the action after the main action
};
/// Get the action type for this plugin
///
- /// \return The action type. If the type is Cmdline then by default the
- /// plugin does nothing and what it does is determined by the cc1
- /// command-line.
- virtual ActionType getActionType() { return Cmdline; }
+ /// \return The action type. By default we use CmdlineAfterMainAction.
+ virtual ActionType getActionType() { return CmdlineAfterMainAction; }
};
/// Abstract base class to use for preprocessor-based frontend actions.
diff --git a/contrib/llvm-project/clang/include/clang/Frontend/FrontendActions.h b/contrib/llvm-project/clang/include/clang/Frontend/FrontendActions.h
index ff8d4417eaa4..fcce31ac0590 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
//===----------------------------------------------------------------------===//
@@ -153,17 +151,16 @@ class GenerateModuleInterfaceAction : public GenerateModuleAction {
private:
bool BeginSourceFileAction(CompilerInstance &CI) override;
+ std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
+ StringRef InFile) override;
+
std::unique_ptr<raw_pwrite_stream>
CreateOutputFile(CompilerInstance &CI, StringRef InFile) override;
};
-class GenerateHeaderModuleAction : public GenerateModuleAction {
- /// The synthesized module input buffer for the current compilation.
- std::unique_ptr<llvm::MemoryBuffer> Buffer;
- std::vector<std::string> ModuleHeaders;
+class GenerateHeaderUnitAction : public GenerateModuleAction {
private:
- bool PrepareToExecuteAction(CompilerInstance &CI) override;
bool BeginSourceFileAction(CompilerInstance &CI) override;
std::unique_ptr<raw_pwrite_stream>
@@ -183,6 +180,9 @@ public:
/// Dump information about the given module file, to be used for
/// basic debugging and discovery.
class DumpModuleInfoAction : public ASTFrontendAction {
+ // Allow other tools (ex lldb) to direct output for their use.
+ std::shared_ptr<llvm::raw_ostream> OutputStream;
+
protected:
std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
StringRef InFile) override;
@@ -190,6 +190,9 @@ protected:
void ExecuteAction() override;
public:
+ DumpModuleInfoAction() = default;
+ explicit DumpModuleInfoAction(std::shared_ptr<llvm::raw_ostream> Out)
+ : OutputStream(Out) {}
bool hasPCHSupport() const override { return false; }
bool hasASTFileSupport() const override { return true; }
bool hasIRSupport() const override { return false; }
@@ -299,6 +302,15 @@ protected:
bool hasPCHSupport() const override { return true; }
};
+class GetDependenciesByModuleNameAction : public PreprocessOnlyAction {
+ StringRef ModuleName;
+ void ExecuteAction() override;
+
+public:
+ GetDependenciesByModuleNameAction(StringRef ModuleName)
+ : ModuleName(ModuleName) {}
+};
+
} // end namespace clang
#endif
diff --git a/contrib/llvm-project/clang/include/clang/Frontend/FrontendOptions.h b/contrib/llvm-project/clang/include/clang/Frontend/FrontendOptions.h
index 15c905d712a3..53a8681cfdbb 100644
--- a/contrib/llvm-project/clang/include/clang/Frontend/FrontendOptions.h
+++ b/contrib/llvm-project/clang/include/clang/Frontend/FrontendOptions.h
@@ -19,6 +19,7 @@
#include <cassert>
#include <map>
#include <memory>
+#include <optional>
#include <string>
#include <vector>
@@ -75,6 +76,9 @@ enum ActionKind {
/// Emit a .o file.
EmitObj,
+ // Extract API information
+ ExtractAPI,
+
/// Parse and apply any fixits to the source.
FixIt,
@@ -84,8 +88,8 @@ enum ActionKind {
/// Generate pre-compiled module from a C++ module interface file.
GenerateModuleInterface,
- /// Generate pre-compiled module from a set of header files.
- GenerateHeaderModule,
+ /// Generate a C++20 header unit module from a header file.
+ GenerateHeaderUnit,
/// Generate pre-compiled header.
GeneratePCH,
@@ -143,11 +147,6 @@ enum ActionKind {
/// The kind of a file that we've been handed as an input.
class InputKind {
-private:
- Language Lang;
- unsigned Fmt : 3;
- unsigned Preprocessed : 1;
-
public:
/// The input file format.
enum Format {
@@ -156,13 +155,41 @@ public:
Precompiled
};
+ // If we are building a header unit, what kind it is; this affects whether
+ // we look for the file in the user or system include search paths before
+ // flagging a missing input.
+ enum HeaderUnitKind {
+ HeaderUnit_None,
+ HeaderUnit_User,
+ HeaderUnit_System,
+ HeaderUnit_Abs
+ };
+
+private:
+ Language Lang;
+ LLVM_PREFERRED_TYPE(Format)
+ unsigned Fmt : 3;
+ LLVM_PREFERRED_TYPE(bool)
+ unsigned Preprocessed : 1;
+ LLVM_PREFERRED_TYPE(HeaderUnitKind)
+ unsigned HeaderUnit : 3;
+ LLVM_PREFERRED_TYPE(bool)
+ unsigned IsHeader : 1;
+
+public:
constexpr InputKind(Language L = Language::Unknown, Format F = Source,
- bool PP = false)
- : Lang(L), Fmt(F), Preprocessed(PP) {}
+ bool PP = false, HeaderUnitKind HU = HeaderUnit_None,
+ bool HD = false)
+ : Lang(L), Fmt(F), Preprocessed(PP), HeaderUnit(HU), IsHeader(HD) {}
Language getLanguage() const { return static_cast<Language>(Lang); }
Format getFormat() const { return static_cast<Format>(Fmt); }
+ HeaderUnitKind getHeaderUnitKind() const {
+ return static_cast<HeaderUnitKind>(HeaderUnit);
+ }
bool isPreprocessed() const { return Preprocessed; }
+ bool isHeader() const { return IsHeader; }
+ bool isHeaderUnit() const { return HeaderUnit != HeaderUnit_None; }
/// Is the input kind fully-unknown?
bool isUnknown() const { return Lang == Language::Unknown && Fmt == Source; }
@@ -173,11 +200,23 @@ public:
}
InputKind getPreprocessed() const {
- return InputKind(getLanguage(), getFormat(), true);
+ return InputKind(getLanguage(), getFormat(), true, getHeaderUnitKind(),
+ isHeader());
+ }
+
+ InputKind getHeader() const {
+ return InputKind(getLanguage(), getFormat(), isPreprocessed(),
+ getHeaderUnitKind(), true);
+ }
+
+ InputKind withHeaderUnit(HeaderUnitKind HU) const {
+ return InputKind(getLanguage(), getFormat(), isPreprocessed(), HU,
+ isHeader());
}
InputKind withFormat(Format F) const {
- return InputKind(getLanguage(), F, isPreprocessed());
+ return InputKind(getLanguage(), F, isPreprocessed(), getHeaderUnitKind(),
+ isHeader());
}
};
@@ -189,7 +228,7 @@ class FrontendInputFile {
/// The input, if it comes from a buffer rather than a file. This object
/// does not own the buffer, and the caller is responsible for ensuring
/// that it outlives any users.
- llvm::Optional<llvm::MemoryBufferRef> Buffer;
+ std::optional<llvm::MemoryBufferRef> Buffer;
/// The kind of input, e.g., C source, AST file, LLVM IR.
InputKind Kind;
@@ -208,10 +247,14 @@ public:
InputKind getKind() const { return Kind; }
bool isSystem() const { return IsSystem; }
- bool isEmpty() const { return File.empty() && Buffer == None; }
+ bool isEmpty() const { return File.empty() && Buffer == std::nullopt; }
bool isFile() const { return !isBuffer(); }
- bool isBuffer() const { return Buffer != None; }
+ bool isBuffer() const { return Buffer != std::nullopt; }
bool isPreprocessed() const { return Kind.isPreprocessed(); }
+ bool isHeader() const { return Kind.isHeader(); }
+ InputKind::HeaderUnitKind getHeaderUnitKind() const {
+ return Kind.getHeaderUnitKind();
+ }
StringRef getFile() const {
assert(isFile());
@@ -228,82 +271,118 @@ public:
class FrontendOptions {
public:
/// Disable memory freeing on exit.
+ LLVM_PREFERRED_TYPE(bool)
unsigned DisableFree : 1;
/// When generating PCH files, instruct the AST writer to create relocatable
/// PCH files.
+ LLVM_PREFERRED_TYPE(bool)
unsigned RelocatablePCH : 1;
/// Show the -help text.
+ LLVM_PREFERRED_TYPE(bool)
unsigned ShowHelp : 1;
/// Show frontend performance metrics and statistics.
+ LLVM_PREFERRED_TYPE(bool)
unsigned ShowStats : 1;
+ LLVM_PREFERRED_TYPE(bool)
+ unsigned AppendStats : 1;
+
/// print the supported cpus for the current target
+ LLVM_PREFERRED_TYPE(bool)
unsigned PrintSupportedCPUs : 1;
- /// Output time trace profile.
- unsigned TimeTrace : 1;
+ /// Print the supported extensions for the current target.
+ LLVM_PREFERRED_TYPE(bool)
+ unsigned PrintSupportedExtensions : 1;
/// Show the -version text.
+ LLVM_PREFERRED_TYPE(bool)
unsigned ShowVersion : 1;
/// Apply fixes even if there are unfixable errors.
+ LLVM_PREFERRED_TYPE(bool)
unsigned FixWhatYouCan : 1;
/// Apply fixes only for warnings.
+ LLVM_PREFERRED_TYPE(bool)
unsigned FixOnlyWarnings : 1;
/// Apply fixes and recompile.
+ LLVM_PREFERRED_TYPE(bool)
unsigned FixAndRecompile : 1;
/// Apply fixes to temporary files.
+ LLVM_PREFERRED_TYPE(bool)
unsigned FixToTemporaries : 1;
/// Emit ARC errors even if the migrator can fix them.
+ LLVM_PREFERRED_TYPE(bool)
unsigned ARCMTMigrateEmitARCErrors : 1;
/// Skip over function bodies to speed up parsing in cases you do not need
/// them (e.g. with code completion).
+ LLVM_PREFERRED_TYPE(bool)
unsigned SkipFunctionBodies : 1;
/// Whether we can use the global module index if available.
+ LLVM_PREFERRED_TYPE(bool)
unsigned UseGlobalModuleIndex : 1;
/// Whether we can generate the global module index if needed.
+ LLVM_PREFERRED_TYPE(bool)
unsigned GenerateGlobalModuleIndex : 1;
/// Whether we include declaration dumps in AST dumps.
+ LLVM_PREFERRED_TYPE(bool)
unsigned ASTDumpDecls : 1;
/// Whether we deserialize all decls when forming AST dumps.
+ LLVM_PREFERRED_TYPE(bool)
unsigned ASTDumpAll : 1;
/// Whether we include lookup table dumps in AST dumps.
+ LLVM_PREFERRED_TYPE(bool)
unsigned ASTDumpLookups : 1;
/// Whether we include declaration type dumps in AST dumps.
+ LLVM_PREFERRED_TYPE(bool)
unsigned ASTDumpDeclTypes : 1;
/// Whether we are performing an implicit module build.
+ LLVM_PREFERRED_TYPE(bool)
unsigned BuildingImplicitModule : 1;
+ /// Whether to use a filesystem lock when building implicit modules.
+ LLVM_PREFERRED_TYPE(bool)
+ unsigned BuildingImplicitModuleUsesLock : 1;
+
/// Whether we should embed all used files into the PCM file.
+ LLVM_PREFERRED_TYPE(bool)
unsigned ModulesEmbedAllFiles : 1;
/// Whether timestamps should be written to the produced PCH file.
+ LLVM_PREFERRED_TYPE(bool)
unsigned IncludeTimestamps : 1;
/// Should a temporary file be used during compilation.
+ LLVM_PREFERRED_TYPE(bool)
unsigned UseTemporary : 1;
/// When using -emit-module, treat the modulemap as a system module.
+ LLVM_PREFERRED_TYPE(bool)
unsigned IsSystemModule : 1;
/// Output (and read) PCM files regardless of compiler errors.
+ LLVM_PREFERRED_TYPE(bool)
unsigned AllowPCMWithCompilerErrors : 1;
+ /// Whether to share the FileManager when building modules.
+ LLVM_PREFERRED_TYPE(bool)
+ unsigned ModulesShareFileManager : 1;
+
CodeCompleteOptions CodeCompleteOpts;
/// Specifies the output format of the AST.
@@ -370,7 +449,7 @@ public:
ObjCMT_MigrateDecls | ObjCMT_PropertyDotSyntax)
};
unsigned ObjCMTAction = ObjCMT_None;
- std::string ObjCMTWhiteListPath;
+ std::string ObjCMTAllowListPath;
std::string MTMigrateDir;
std::string ARCMTMigrateReportOut;
@@ -404,6 +483,21 @@ public:
/// The name of the action to run when using a plugin action.
std::string ActionName;
+ // Currently this is only used as part of the `-extract-api` action.
+ /// The name of the product the input files belong too.
+ std::string ProductName;
+
+ // Currently this is only used as part of the `-extract-api` action.
+ // A comma seperated list of files providing a list of APIs to
+ // ignore when extracting documentation.
+ std::vector<std::string> ExtractAPIIgnoresFileList;
+
+ // Currently this is only used as part of the `-emit-symbol-graph`
+ // action.
+ // Location of output directory where symbol graph information would
+ // be dumped
+ std::string SymbolGraphOutputDir;
+
/// Args to pass to the plugins
std::map<std::string, std::vector<std::string>> PluginArgs;
@@ -441,10 +535,10 @@ public:
std::string AuxTriple;
/// Auxiliary target CPU for CUDA/HIP compilation.
- Optional<std::string> AuxTargetCPU;
+ std::optional<std::string> AuxTargetCPU;
/// Auxiliary target features for CUDA/HIP compilation.
- Optional<std::vector<std::string>> AuxTargetFeatures;
+ std::optional<std::vector<std::string>> AuxTargetFeatures;
/// Filename to write statistics to.
std::string StatsFile;
@@ -452,17 +546,21 @@ public:
/// Minimum time granularity (in microseconds) traced by time profiler.
unsigned TimeTraceGranularity;
+ /// Path which stores the output files for -ftime-trace
+ std::string TimeTracePath;
+
public:
FrontendOptions()
: DisableFree(false), RelocatablePCH(false), ShowHelp(false),
- ShowStats(false), TimeTrace(false), ShowVersion(false),
+ ShowStats(false), AppendStats(false), ShowVersion(false),
FixWhatYouCan(false), FixOnlyWarnings(false), FixAndRecompile(false),
FixToTemporaries(false), ARCMTMigrateEmitARCErrors(false),
SkipFunctionBodies(false), UseGlobalModuleIndex(true),
GenerateGlobalModuleIndex(true), ASTDumpDecls(false),
ASTDumpLookups(false), BuildingImplicitModule(false),
- ModulesEmbedAllFiles(false), IncludeTimestamps(true),
- UseTemporary(true), AllowPCMWithCompilerErrors(false),
+ BuildingImplicitModuleUsesLock(true), ModulesEmbedAllFiles(false),
+ IncludeTimestamps(true), UseTemporary(true),
+ AllowPCMWithCompilerErrors(false), ModulesShareFileManager(true),
TimeTraceGranularity(500) {}
/// getInputKindForExtension - Return the appropriate input kind for a file
diff --git a/contrib/llvm-project/clang/include/clang/Frontend/LayoutOverrideSource.h b/contrib/llvm-project/clang/include/clang/Frontend/LayoutOverrideSource.h
index ea1611470a76..c6e2d7311183 100644
--- a/contrib/llvm-project/clang/include/clang/Frontend/LayoutOverrideSource.h
+++ b/contrib/llvm-project/clang/include/clang/Frontend/LayoutOverrideSource.h
@@ -30,6 +30,12 @@ namespace clang {
/// The alignment of the record.
uint64_t Align;
+ /// The offsets of non-virtual base classes in the record.
+ SmallVector<CharUnits, 8> BaseOffsets;
+
+ /// The offsets of virtual base classes in the record.
+ SmallVector<CharUnits, 8> VBaseOffsets;
+
/// The offsets of the fields, in source order.
SmallVector<uint64_t, 8> FieldOffsets;
};
diff --git a/contrib/llvm-project/clang/include/clang/Frontend/MigratorOptions.h b/contrib/llvm-project/clang/include/clang/Frontend/MigratorOptions.h
index cf50ffcf0c4f..da899643f0b4 100644
--- a/contrib/llvm-project/clang/include/clang/Frontend/MigratorOptions.h
+++ b/contrib/llvm-project/clang/include/clang/Frontend/MigratorOptions.h
@@ -14,11 +14,15 @@
#ifndef LLVM_CLANG_FRONTEND_MIGRATOROPTIONS_H
#define LLVM_CLANG_FRONTEND_MIGRATOROPTIONS_H
+#include "llvm/Support/Compiler.h"
+
namespace clang {
class MigratorOptions {
public:
+ LLVM_PREFERRED_TYPE(bool)
unsigned NoNSAllocReallocError : 1;
+ LLVM_PREFERRED_TYPE(bool)
unsigned NoFinalizeRemoval : 1;
MigratorOptions() {
NoNSAllocReallocError = 0;
diff --git a/contrib/llvm-project/clang/include/clang/Frontend/MultiplexConsumer.h b/contrib/llvm-project/clang/include/clang/Frontend/MultiplexConsumer.h
index 3054e1842811..7f8d2858b386 100644
--- a/contrib/llvm-project/clang/include/clang/Frontend/MultiplexConsumer.h
+++ b/contrib/llvm-project/clang/include/clang/Frontend/MultiplexConsumer.h
@@ -40,6 +40,8 @@ public:
void MacroDefinitionRead(serialization::PreprocessedEntityID,
MacroDefinitionRecord *MD) override;
void ModuleRead(serialization::SubmoduleID ID, Module *Mod) override;
+ void ModuleImportRead(serialization::SubmoduleID ID,
+ SourceLocation ImportLoc) override;
private:
std::vector<ASTDeserializationListener *> Listeners;
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 bb7fd97fe5df..798870bf24fe 100644
--- a/contrib/llvm-project/clang/include/clang/Frontend/PrecompiledPreamble.h
+++ b/contrib/llvm-project/clang/include/clang/Frontend/PrecompiledPreamble.h
@@ -10,14 +10,13 @@
//
//===----------------------------------------------------------------------===//
-#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"
#include "llvm/ADT/IntrusiveRefCntPtr.h"
#include "llvm/ADT/StringRef.h"
-#include "llvm/Support/AlignOf.h"
#include "llvm/Support/MD5.h"
#include <cstddef>
#include <memory>
@@ -76,6 +75,10 @@ public:
/// \param StoreInMemory Store PCH in memory. If false, PCH will be stored in
/// a temporary file.
///
+ /// \param StoragePath The path to a directory, in which to create a temporary
+ /// file to store PCH in. If empty, the default system temporary directory is
+ /// used. This parameter is ignored if \p StoreInMemory is true.
+ ///
/// \param Callbacks A set of callbacks to be executed when building
/// the preamble.
static llvm::ErrorOr<PrecompiledPreamble>
@@ -84,10 +87,12 @@ public:
DiagnosticsEngine &Diagnostics,
IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS,
std::shared_ptr<PCHContainerOperations> PCHContainerOps,
- bool StoreInMemory, PreambleCallbacks &Callbacks);
+ bool StoreInMemory, StringRef StoragePath,
+ PreambleCallbacks &Callbacks);
- PrecompiledPreamble(PrecompiledPreamble &&) = default;
- PrecompiledPreamble &operator=(PrecompiledPreamble &&) = default;
+ PrecompiledPreamble(PrecompiledPreamble &&);
+ PrecompiledPreamble &operator=(PrecompiledPreamble &&);
+ ~PrecompiledPreamble();
/// PreambleBounds used to build the preamble.
PreambleBounds getBounds() const;
@@ -128,79 +133,12 @@ public:
llvm::MemoryBuffer *MainFileBuffer) const;
private:
- PrecompiledPreamble(PCHStorage Storage, std::vector<char> PreambleBytes,
+ PrecompiledPreamble(std::unique_ptr<PCHStorage> Storage,
+ std::vector<char> PreambleBytes,
bool PreambleEndsAtStartOfLine,
llvm::StringMap<PreambleFileHash> FilesInPreamble,
llvm::StringSet<> MissingFiles);
- /// A temp file that would be deleted on destructor call. If destructor is not
- /// called for any reason, the file will be deleted at static objects'
- /// destruction.
- /// An assertion will fire if two TempPCHFiles are created with the same name,
- /// so it's not intended to be used outside preamble-handling.
- class TempPCHFile {
- public:
- // A main method used to construct TempPCHFile.
- static llvm::ErrorOr<TempPCHFile> CreateNewPreamblePCHFile();
-
- private:
- TempPCHFile(std::string FilePath);
-
- public:
- TempPCHFile(TempPCHFile &&Other);
- TempPCHFile &operator=(TempPCHFile &&Other);
-
- TempPCHFile(const TempPCHFile &) = delete;
- ~TempPCHFile();
-
- /// A path where temporary file is stored.
- llvm::StringRef getFilePath() const;
-
- private:
- void RemoveFileIfPresent();
-
- private:
- llvm::Optional<std::string> FilePath;
- };
-
- class InMemoryPreamble {
- public:
- std::string Data;
- };
-
- class PCHStorage {
- public:
- enum class Kind { Empty, InMemory, TempFile };
-
- PCHStorage() = default;
- PCHStorage(TempPCHFile File);
- PCHStorage(InMemoryPreamble Memory);
-
- PCHStorage(const PCHStorage &) = delete;
- PCHStorage &operator=(const PCHStorage &) = delete;
-
- PCHStorage(PCHStorage &&Other);
- PCHStorage &operator=(PCHStorage &&Other);
-
- ~PCHStorage();
-
- Kind getKind() const;
-
- TempPCHFile &asFile();
- const TempPCHFile &asFile() const;
-
- InMemoryPreamble &asMemory();
- const InMemoryPreamble &asMemory() const;
-
- private:
- void destroy();
- void setEmpty();
-
- private:
- Kind StorageKind = Kind::Empty;
- llvm::AlignedCharArrayUnion<TempPCHFile, InMemoryPreamble> Storage = {};
- };
-
/// Data used to determine if a file used in the preamble has been changed.
struct PreambleFileHash {
/// All files have size set.
@@ -245,7 +183,7 @@ private:
IntrusiveRefCntPtr<llvm::vfs::FileSystem> &VFS);
/// Manages the memory buffer or temporary file that stores the PCH.
- PCHStorage Storage;
+ std::unique_ptr<PCHStorage> Storage;
/// Keeps track of the files that were used when computing the
/// preamble, with both their buffer size and their modification time.
///
@@ -274,7 +212,7 @@ class PreambleCallbacks {
public:
virtual ~PreambleCallbacks() = default;
- /// Called before FrontendAction::BeginSourceFile.
+ /// Called before FrontendAction::Execute.
/// Can be used to store references to various CompilerInstance fields
/// (e.g. SourceManager) that may be interesting to the consumers of other
/// callbacks.
@@ -291,7 +229,7 @@ public:
/// used instead, but having only this method allows a simpler API.
virtual void HandleTopLevelDecl(DeclGroupRef DG);
/// Creates wrapper class for PPCallbacks so we can also process information
- /// about includes that are inside of a preamble
+ /// about includes that are inside of a preamble. Called after BeforeExecute.
virtual std::unique_ptr<PPCallbacks> createPPCallbacks();
/// The returned CommentHandler will be added to the preprocessor if not null.
virtual CommentHandler *getCommentHandler();
diff --git a/contrib/llvm-project/clang/include/clang/Frontend/PreprocessorOutputOptions.h b/contrib/llvm-project/clang/include/clang/Frontend/PreprocessorOutputOptions.h
index 72e5ad1137fb..6e19cae33cf2 100644
--- a/contrib/llvm-project/clang/include/clang/Frontend/PreprocessorOutputOptions.h
+++ b/contrib/llvm-project/clang/include/clang/Frontend/PreprocessorOutputOptions.h
@@ -9,21 +9,38 @@
#ifndef LLVM_CLANG_FRONTEND_PREPROCESSOROUTPUTOPTIONS_H
#define LLVM_CLANG_FRONTEND_PREPROCESSOROUTPUTOPTIONS_H
+#include <llvm/Support/Compiler.h>
+
namespace clang {
/// PreprocessorOutputOptions - Options for controlling the C preprocessor
/// output (e.g., -E).
class PreprocessorOutputOptions {
public:
+ LLVM_PREFERRED_TYPE(bool)
unsigned ShowCPP : 1; ///< Print normal preprocessed output.
+ LLVM_PREFERRED_TYPE(bool)
unsigned ShowComments : 1; ///< Show comments.
+ LLVM_PREFERRED_TYPE(bool)
unsigned ShowLineMarkers : 1; ///< Show \#line markers.
+ LLVM_PREFERRED_TYPE(bool)
unsigned UseLineDirectives : 1; ///< Use \#line instead of GCC-style \# N.
+ LLVM_PREFERRED_TYPE(bool)
unsigned ShowMacroComments : 1; ///< Show comments, even in macros.
+ LLVM_PREFERRED_TYPE(bool)
unsigned ShowMacros : 1; ///< Print macro definitions.
+ LLVM_PREFERRED_TYPE(bool)
unsigned ShowIncludeDirectives : 1; ///< Print includes, imports etc. within preprocessed output.
+ LLVM_PREFERRED_TYPE(bool)
unsigned RewriteIncludes : 1; ///< Preprocess include directives only.
+ LLVM_PREFERRED_TYPE(bool)
unsigned RewriteImports : 1; ///< Include contents of transitively-imported modules.
+ LLVM_PREFERRED_TYPE(bool)
+ unsigned MinimizeWhitespace : 1; ///< Ignore whitespace from input.
+ LLVM_PREFERRED_TYPE(bool)
+ unsigned DirectivesOnly : 1; ///< Process directives but do not expand macros.
+ LLVM_PREFERRED_TYPE(bool)
+ unsigned KeepSystemIncludes : 1; ///< Do not expand system headers.
public:
PreprocessorOutputOptions() {
@@ -36,6 +53,9 @@ public:
ShowIncludeDirectives = 0;
RewriteIncludes = 0;
RewriteImports = 0;
+ MinimizeWhitespace = 0;
+ DirectivesOnly = 0;
+ KeepSystemIncludes = 0;
}
};
diff --git a/contrib/llvm-project/clang/include/clang/Frontend/SARIFDiagnostic.h b/contrib/llvm-project/clang/include/clang/Frontend/SARIFDiagnostic.h
new file mode 100644
index 000000000000..ec1d0b8e6a7c
--- /dev/null
+++ b/contrib/llvm-project/clang/include/clang/Frontend/SARIFDiagnostic.h
@@ -0,0 +1,74 @@
+//===--- SARIFDiagnostic.h - SARIF Diagnostic Formatting -----*- 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 is a utility class that provides support for constructing a SARIF object
+// containing diagnostics.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_FRONTEND_SARIFDIAGNOSTIC_H
+#define LLVM_CLANG_FRONTEND_SARIFDIAGNOSTIC_H
+
+#include "clang/Basic/Sarif.h"
+#include "clang/Frontend/DiagnosticRenderer.h"
+#include "llvm/ADT/StringRef.h"
+
+namespace clang {
+
+class SARIFDiagnostic : public DiagnosticRenderer {
+public:
+ SARIFDiagnostic(raw_ostream &OS, const LangOptions &LangOpts,
+ DiagnosticOptions *DiagOpts, SarifDocumentWriter *Writer);
+
+ ~SARIFDiagnostic() = default;
+
+ SARIFDiagnostic &operator=(const SARIFDiagnostic &&) = delete;
+ SARIFDiagnostic(SARIFDiagnostic &&) = delete;
+ SARIFDiagnostic &operator=(const SARIFDiagnostic &) = delete;
+ SARIFDiagnostic(const SARIFDiagnostic &) = delete;
+
+protected:
+ void emitDiagnosticMessage(FullSourceLoc Loc, PresumedLoc PLoc,
+ DiagnosticsEngine::Level Level, StringRef Message,
+ ArrayRef<CharSourceRange> Ranges,
+ DiagOrStoredDiag D) override;
+
+ void emitDiagnosticLoc(FullSourceLoc Loc, PresumedLoc PLoc,
+ DiagnosticsEngine::Level Level,
+ ArrayRef<CharSourceRange> Ranges) override;
+
+ void emitCodeContext(FullSourceLoc Loc, DiagnosticsEngine::Level Level,
+ SmallVectorImpl<CharSourceRange> &Ranges,
+ ArrayRef<FixItHint> Hints) override {}
+
+ void emitIncludeLocation(FullSourceLoc Loc, PresumedLoc PLoc) override;
+
+ void emitImportLocation(FullSourceLoc Loc, PresumedLoc PLoc,
+ StringRef ModuleName) override;
+
+ void emitBuildingModuleLocation(FullSourceLoc Loc, PresumedLoc PLoc,
+ StringRef ModuleName) override;
+
+private:
+ // Shared between SARIFDiagnosticPrinter and this renderer.
+ SarifDocumentWriter *Writer;
+
+ SarifResult addLocationToResult(SarifResult Result, FullSourceLoc Loc,
+ PresumedLoc PLoc,
+ ArrayRef<CharSourceRange> Ranges,
+ const Diagnostic &Diag);
+
+ SarifRule addDiagnosticLevelToRule(SarifRule Rule,
+ DiagnosticsEngine::Level Level);
+
+ llvm::StringRef emitFilename(StringRef Filename, const SourceManager &SM);
+};
+
+} // end namespace clang
+
+#endif
diff --git a/contrib/llvm-project/clang/include/clang/Frontend/SARIFDiagnosticPrinter.h b/contrib/llvm-project/clang/include/clang/Frontend/SARIFDiagnosticPrinter.h
new file mode 100644
index 000000000000..f2652833b3c1
--- /dev/null
+++ b/contrib/llvm-project/clang/include/clang/Frontend/SARIFDiagnosticPrinter.h
@@ -0,0 +1,76 @@
+//===-- SARIFDiagnosticPrinter.h - SARIF Diagnostic Client -------*- 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 is a concrete diagnostic client, which prints the diagnostics to
+// standard error in SARIF format.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_FRONTEND_SARIFDIAGNOSTICPRINTER_H
+#define LLVM_CLANG_FRONTEND_SARIFDIAGNOSTICPRINTER_H
+
+#include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/LLVM.h"
+#include "clang/Basic/Sarif.h"
+#include "llvm/ADT/IntrusiveRefCntPtr.h"
+#include "llvm/ADT/StringRef.h"
+#include <memory>
+
+namespace clang {
+class DiagnosticOptions;
+class LangOptions;
+class SARIFDiagnostic;
+class SarifDocumentWriter;
+
+class SARIFDiagnosticPrinter : public DiagnosticConsumer {
+public:
+ SARIFDiagnosticPrinter(raw_ostream &OS, DiagnosticOptions *Diags);
+ ~SARIFDiagnosticPrinter() = default;
+
+ SARIFDiagnosticPrinter &operator=(const SARIFDiagnosticPrinter &&) = delete;
+ SARIFDiagnosticPrinter(SARIFDiagnosticPrinter &&) = delete;
+ SARIFDiagnosticPrinter &operator=(const SARIFDiagnosticPrinter &) = delete;
+ SARIFDiagnosticPrinter(const SARIFDiagnosticPrinter &) = delete;
+
+ /// setPrefix - Set the diagnostic printer prefix string, which will be
+ /// printed at the start of any diagnostics. If empty, no prefix string is
+ /// used.
+ void setPrefix(llvm::StringRef Value) { Prefix = Value; }
+
+ bool hasSarifWriter() const { return Writer != nullptr; }
+
+ SarifDocumentWriter &getSarifWriter() const {
+ assert(Writer && "SarifWriter not set!");
+ return *Writer;
+ }
+
+ void setSarifWriter(std::unique_ptr<SarifDocumentWriter> SarifWriter) {
+ Writer = std::move(SarifWriter);
+ }
+
+ void BeginSourceFile(const LangOptions &LO, const Preprocessor *PP) override;
+ void EndSourceFile() override;
+ void HandleDiagnostic(DiagnosticsEngine::Level Level,
+ const Diagnostic &Info) override;
+
+private:
+ raw_ostream &OS;
+ IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts;
+
+ /// Handle to the currently active SARIF diagnostic emitter.
+ std::unique_ptr<SARIFDiagnostic> SARIFDiag;
+
+ /// A string to prefix to error messages.
+ std::string Prefix;
+
+ std::unique_ptr<SarifDocumentWriter> Writer;
+};
+
+} // end namespace clang
+
+#endif
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/TextDiagnostic.h b/contrib/llvm-project/clang/include/clang/Frontend/TextDiagnostic.h
index a2eec46beccd..7eb0ab0cdc9b 100644
--- a/contrib/llvm-project/clang/include/clang/Frontend/TextDiagnostic.h
+++ b/contrib/llvm-project/clang/include/clang/Frontend/TextDiagnostic.h
@@ -103,7 +103,8 @@ private:
SmallVectorImpl<CharSourceRange> &Ranges,
ArrayRef<FixItHint> Hints);
- void emitSnippet(StringRef SourceLine);
+ void emitSnippet(StringRef SourceLine, unsigned MaxLineNoDisplayWidth,
+ unsigned LineNo);
void emitParseableFixits(ArrayRef<FixItHint> Hints, const SourceManager &SM);
};
diff --git a/contrib/llvm-project/clang/include/clang/Frontend/TextDiagnosticPrinter.h b/contrib/llvm-project/clang/include/clang/Frontend/TextDiagnosticPrinter.h
index ba756fa18c30..2610bde7513a 100644
--- a/contrib/llvm-project/clang/include/clang/Frontend/TextDiagnosticPrinter.h
+++ b/contrib/llvm-project/clang/include/clang/Frontend/TextDiagnosticPrinter.h
@@ -34,6 +34,7 @@ class TextDiagnosticPrinter : public DiagnosticConsumer {
/// A string to prefix to error messages.
std::string Prefix;
+ LLVM_PREFERRED_TYPE(bool)
unsigned OwnsOutputStream : 1;
public:
diff --git a/contrib/llvm-project/clang/include/clang/Frontend/Utils.h b/contrib/llvm-project/clang/include/clang/Frontend/Utils.h
index da2d79af2eba..604e42067a3f 100644
--- a/contrib/llvm-project/clang/include/clang/Frontend/Utils.h
+++ b/contrib/llvm-project/clang/include/clang/Frontend/Utils.h
@@ -22,7 +22,6 @@
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/StringSet.h"
-#include "llvm/Option/OptSpecifier.h"
#include "llvm/Support/FileCollector.h"
#include "llvm/Support/VirtualFileSystem.h"
#include <cstdint>
@@ -32,12 +31,6 @@
#include <utility>
#include <vector>
-namespace llvm {
-
-class Triple;
-
-} // namespace llvm
-
namespace clang {
class ASTReader;
@@ -46,25 +39,18 @@ 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);
+class CodeGenOptions;
/// InitializePreprocessor - Initialize the preprocessor getting it and the
/// environment ready to process a single file.
void InitializePreprocessor(Preprocessor &PP, const PreprocessorOptions &PPOpts,
const PCHContainerReader &PCHContainerRdr,
- const FrontendOptions &FEOpts);
+ const FrontendOptions &FEOpts,
+ const CodeGenOptions &CodeGenOpts);
/// DoPrintPreprocessedInput - Implement -E mode.
void DoPrintPreprocessedInput(Preprocessor &PP, raw_ostream *OS,
@@ -123,10 +109,10 @@ public:
void finishedMainFile(DiagnosticsEngine &Diags) override;
- bool needSystemDependencies() final override { return IncludeSystemHeaders; }
+ bool needSystemDependencies() final { return IncludeSystemHeaders; }
bool sawDependency(StringRef Filename, bool FromModule, bool IsSystem,
- bool IsModuleFile, bool IsMissing) final override;
+ bool IsModuleFile, bool IsMissing) final;
protected:
void outputDependencyFile(llvm::raw_ostream &OS);
@@ -205,27 +191,50 @@ IntrusiveRefCntPtr<ExternalSemaSource>
createChainedIncludesSource(CompilerInstance &CI,
IntrusiveRefCntPtr<ExternalSemaSource> &Reader);
-/// createInvocationFromCommandLine - Construct a compiler invocation object for
-/// a command line argument vector.
+/// Optional inputs to createInvocation.
+struct CreateInvocationOptions {
+ /// Receives diagnostics encountered while parsing command-line flags.
+ /// If not provided, these are printed to stderr.
+ IntrusiveRefCntPtr<DiagnosticsEngine> Diags = nullptr;
+ /// Used e.g. to probe for system headers locations.
+ /// If not provided, the real filesystem is used.
+ /// FIXME: the driver does perform some non-virtualized IO.
+ IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS = nullptr;
+ /// Whether to attempt to produce a non-null (possibly incorrect) invocation
+ /// if any errors were encountered.
+ /// By default, always return null on errors.
+ bool RecoverOnError = false;
+ /// Allow the driver to probe the filesystem for PCH files.
+ /// This is used to replace -include with -include-pch in the cc1 args.
+ /// FIXME: ProbePrecompiled=true is a poor, historical default.
+ /// It misbehaves if the PCH file is from GCC, has the wrong version, etc.
+ bool ProbePrecompiled = false;
+ /// If set, the target is populated with the cc1 args produced by the driver.
+ /// This may be populated even if createInvocation returns nullptr.
+ std::vector<std::string> *CC1Args = nullptr;
+};
+
+/// Interpret clang arguments in preparation to parse a file.
+///
+/// This simulates a number of steps Clang takes when its driver is invoked:
+/// - choosing actions (e.g compile + link) to run
+/// - probing the system for settings like standard library locations
+/// - spawning a cc1 subprocess to compile code, with more explicit arguments
+/// - in the cc1 process, assembling those arguments into a CompilerInvocation
+/// which is used to configure the parser
///
-/// \param ShouldRecoverOnErrors - whether we should attempt to return a
-/// non-null (and possibly incorrect) CompilerInvocation if any errors were
-/// encountered. When this flag is false, always return null on errors.
+/// This simulation is lossy, e.g. in some situations one driver run would
+/// result in multiple parses. (Multi-arch, CUDA, ...).
+/// This function tries to select a reasonable invocation that tools should use.
///
-/// \param CC1Args - if non-null, will be populated with the args to cc1
-/// expanded from \p Args. May be set even if nullptr is returned.
+/// Args[0] should be the driver name, such as "clang" or "/usr/bin/g++".
+/// Absolute path is preferred - this affects searching for system headers.
///
-/// \return A CompilerInvocation, or nullptr if none was built for the given
-/// argument vector.
-std::unique_ptr<CompilerInvocation> createInvocationFromCommandLine(
- ArrayRef<const char *> Args,
- IntrusiveRefCntPtr<DiagnosticsEngine> Diags =
- IntrusiveRefCntPtr<DiagnosticsEngine>(),
- IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS = nullptr,
- bool ShouldRecoverOnErrors = false,
- std::vector<std::string> *CC1Args = nullptr);
-
-// Frontend timing utils
+/// May return nullptr if an invocation could not be determined.
+/// See CreateInvocationOptions::ShouldRecoverOnErrors to try harder!
+std::unique_ptr<CompilerInvocation>
+createInvocation(ArrayRef<const char *> Args,
+ CreateInvocationOptions Opts = {});
} // namespace clang
diff --git a/contrib/llvm-project/clang/include/clang/Frontend/VerifyDiagnosticConsumer.h b/contrib/llvm-project/clang/include/clang/Frontend/VerifyDiagnosticConsumer.h
index a97cd138d159..ddfae2666c4c 100644
--- a/contrib/llvm-project/clang/include/clang/Frontend/VerifyDiagnosticConsumer.h
+++ b/contrib/llvm-project/clang/include/clang/Frontend/VerifyDiagnosticConsumer.h
@@ -32,156 +32,8 @@ class TextDiagnosticBuffer;
/// VerifyDiagnosticConsumer - Create a diagnostic client which will use
/// markers in the input source to check that all the emitted diagnostics match
-/// those expected.
-///
-/// INVOKING THE DIAGNOSTIC CHECKER:
-///
-/// VerifyDiagnosticConsumer is typically invoked via the "-verify" option to
-/// "clang -cc1". "-verify" is equivalent to "-verify=expected", so all
-/// diagnostics are typically specified with the prefix "expected". For
-/// example:
-///
-/// \code
-/// int A = B; // expected-error {{use of undeclared identifier 'B'}}
-/// \endcode
-///
-/// Custom prefixes can be specified as a comma-separated sequence. Each
-/// prefix must start with a letter and contain only alphanumeric characters,
-/// hyphens, and underscores. For example, given just "-verify=foo,bar",
-/// the above diagnostic would be ignored, but the following diagnostics would
-/// be recognized:
-///
-/// \code
-/// int A = B; // foo-error {{use of undeclared identifier 'B'}}
-/// int C = D; // bar-error {{use of undeclared identifier 'D'}}
-/// \endcode
-///
-/// Multiple occurrences accumulate prefixes. For example,
-/// "-verify -verify=foo,bar -verify=baz" is equivalent to
-/// "-verify=expected,foo,bar,baz".
-///
-/// SPECIFYING DIAGNOSTICS:
-///
-/// Indicating that a line expects an error or a warning is simple. Put a
-/// comment on the line that has the diagnostic, use:
-///
-/// \code
-/// expected-{error,warning,remark,note}
-/// \endcode
-///
-/// to tag if it's an expected error, remark or warning, and place the expected
-/// text between {{ and }} markers. The full text doesn't have to be included,
-/// only enough to ensure that the correct diagnostic was emitted.
-///
-/// Here's an example:
-///
-/// \code
-/// int A = B; // expected-error {{use of undeclared identifier 'B'}}
-/// \endcode
-///
-/// You can place as many diagnostics on one line as you wish. To make the code
-/// more readable, you can use slash-newline to separate out the diagnostics.
-///
-/// Alternatively, it is possible to specify the line on which the diagnostic
-/// should appear by appending "@<line>" to "expected-<type>", for example:
-///
-/// \code
-/// #warning some text
-/// // expected-warning@10 {{some text}}
-/// \endcode
-///
-/// The line number may be absolute (as above), or relative to the current
-/// line by prefixing the number with either '+' or '-'.
-///
-/// If the diagnostic is generated in a separate file, for example in a shared
-/// header file, it may be beneficial to be able to declare the file in which
-/// the diagnostic will appear, rather than placing the expected-* directive in
-/// the actual file itself. This can be done using the following syntax:
-///
-/// \code
-/// // expected-error@path/include.h:15 {{error message}}
-/// \endcode
-///
-/// The path can be absolute or relative and the same search paths will be used
-/// as for #include directives. The line number in an external file may be
-/// substituted with '*' meaning that any line number will match (useful where
-/// the included file is, for example, a system header where the actual line
-/// number may change and is not critical).
-///
-/// As an alternative to specifying a fixed line number, the location of a
-/// diagnostic can instead be indicated by a marker of the form "#<marker>".
-/// Markers are specified by including them in a comment, and then referenced
-/// by appending the marker to the diagnostic with "@#<marker>":
-///
-/// \code
-/// #warning some text // #1
-/// // expected-warning@#1 {{some text}}
-/// \endcode
-///
-/// The name of a marker used in a directive must be unique within the
-/// compilation.
-///
-/// The simple syntax above allows each specification to match exactly one
-/// error. You can use the extended syntax to customize this. The extended
-/// syntax is "expected-<type> <n> {{diag text}}", where \<type> is one of
-/// "error", "warning" or "note", and \<n> is a positive integer. This allows
-/// the diagnostic to appear as many times as specified. Example:
-///
-/// \code
-/// void f(); // expected-note 2 {{previous declaration is here}}
-/// \endcode
-///
-/// Where the diagnostic is expected to occur a minimum number of times, this
-/// can be specified by appending a '+' to the number. Example:
-///
-/// \code
-/// void f(); // expected-note 0+ {{previous declaration is here}}
-/// void g(); // expected-note 1+ {{previous declaration is here}}
-/// \endcode
-///
-/// In the first example, the diagnostic becomes optional, i.e. it will be
-/// swallowed if it occurs, but will not generate an error if it does not
-/// occur. In the second example, the diagnostic must occur at least once.
-/// As a short-hand, "one or more" can be specified simply by '+'. Example:
-///
-/// \code
-/// void g(); // expected-note + {{previous declaration is here}}
-/// \endcode
-///
-/// A range can also be specified by "<n>-<m>". Example:
-///
-/// \code
-/// void f(); // expected-note 0-1 {{previous declaration is here}}
-/// \endcode
-///
-/// In this example, the diagnostic may appear only once, if at all.
-///
-/// Regex matching mode may be selected by appending '-re' to type and
-/// including regexes wrapped in double curly braces in the directive, such as:
-///
-/// \code
-/// expected-error-re {{format specifies type 'wchar_t **' (aka '{{.+}}')}}
-/// \endcode
-///
-/// Examples matching error: "variable has incomplete type 'struct s'"
-///
-/// \code
-/// // expected-error {{variable has incomplete type 'struct s'}}
-/// // expected-error {{variable has incomplete type}}
-///
-/// // expected-error-re {{variable has type 'struct {{.}}'}}
-/// // expected-error-re {{variable has type 'struct {{.*}}'}}
-/// // expected-error-re {{variable has type 'struct {{(.*)}}'}}
-/// // expected-error-re {{variable has type 'struct{{[[:space:]](.*)}}'}}
-/// \endcode
-///
-/// VerifyDiagnosticConsumer expects at least one expected-* directive to
-/// be found inside the source code. If no diagnostics are expected the
-/// following directive can be used to indicate this:
-///
-/// \code
-/// // expected-no-diagnostics
-/// \endcode
+/// those expected. See clang/docs/InternalsManual.rst for details about how to
+/// write tests to verify diagnostics.
///
class VerifyDiagnosticConsumer: public DiagnosticConsumer,
public CommentHandler {
@@ -278,14 +130,15 @@ private:
// These facilities are used for validation in debug builds.
class UnparsedFileStatus {
- llvm::PointerIntPair<const FileEntry *, 1, bool> Data;
+ OptionalFileEntryRef File;
+ bool FoundDirectives;
public:
- UnparsedFileStatus(const FileEntry *File, bool FoundDirectives)
- : Data(File, FoundDirectives) {}
+ UnparsedFileStatus(OptionalFileEntryRef File, bool FoundDirectives)
+ : File(File), FoundDirectives(FoundDirectives) {}
- const FileEntry *getFile() const { return Data.getPointer(); }
- bool foundDirectives() const { return Data.getInt(); }
+ OptionalFileEntryRef getFile() const { return File; }
+ bool foundDirectives() const { return FoundDirectives; }
};
using ParsedFilesMap = llvm::DenseMap<FileID, const FileEntry *>;
diff --git a/contrib/llvm-project/clang/include/clang/Index/IndexSymbol.h b/contrib/llvm-project/clang/include/clang/Index/IndexSymbol.h
index 2ba81986c2fe..59e90fced3dd 100644
--- a/contrib/llvm-project/clang/include/clang/Index/IndexSymbol.h
+++ b/contrib/llvm-project/clang/include/clang/Index/IndexSymbol.h
@@ -57,6 +57,8 @@ enum class SymbolKind : uint8_t {
TemplateTypeParm,
TemplateTemplateParm,
NonTypeTemplateParm,
+
+ Concept, /// C++20 concept.
};
enum class SymbolLanguage : uint8_t {
diff --git a/contrib/llvm-project/clang/include/clang/Index/IndexingOptions.h b/contrib/llvm-project/clang/include/clang/Index/IndexingOptions.h
index d19653848d59..97847dd7d5d8 100644
--- a/contrib/llvm-project/clang/include/clang/Index/IndexingOptions.h
+++ b/contrib/llvm-project/clang/include/clang/Index/IndexingOptions.h
@@ -29,9 +29,9 @@ struct IndexingOptions {
bool IndexFunctionLocals = false;
bool IndexImplicitInstantiation = false;
bool IndexMacros = true;
- // Whether to index macro definitions in the Preprocesor when preprocessor
+ // Whether to index macro definitions in the Preprocessor when preprocessor
// callback is not available (e.g. after parsing has finished). Note that
- // macro references are not available in Proprocessor.
+ // macro references are not available in Preprocessor.
bool IndexMacrosInPreprocessor = false;
// Has no effect if IndexFunctionLocals are false.
bool IndexParametersInDeclarations = false;
diff --git a/contrib/llvm-project/clang/include/clang/IndexSerialization/SerializablePathCollection.h b/contrib/llvm-project/clang/include/clang/IndexSerialization/SerializablePathCollection.h
index 20cf8fbdad96..6337a8119668 100644
--- a/contrib/llvm-project/clang/include/clang/IndexSerialization/SerializablePathCollection.h
+++ b/contrib/llvm-project/clang/include/clang/IndexSerialization/SerializablePathCollection.h
@@ -6,13 +6,12 @@
//
//===----------------------------------------------------------------------===//
-#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"
#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/Optional.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
@@ -111,7 +110,7 @@ public:
/// Stores path to \p FE if it hasn't been stored yet.
/// \returns index to array exposed by getPathsBuffer().
- size_t tryStoreFilePath(const clang::FileEntry &FE);
+ size_t tryStoreFilePath(FileEntryRef FE);
private:
/// Stores \p Path if it is non-empty.
@@ -126,4 +125,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/CodeCompletion.h b/contrib/llvm-project/clang/include/clang/Interpreter/CodeCompletion.h
new file mode 100644
index 000000000000..c64aa899759f
--- /dev/null
+++ b/contrib/llvm-project/clang/include/clang/Interpreter/CodeCompletion.h
@@ -0,0 +1,49 @@
+//===----- CodeCompletion.h - Code Completion for ClangRepl ---===//
+//
+// 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 the classes which performs code completion at the REPL.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_INTERPRETER_CODE_COMPLETION_H
+#define LLVM_CLANG_INTERPRETER_CODE_COMPLETION_H
+#include <string>
+#include <vector>
+
+namespace llvm {
+class StringRef;
+} // namespace llvm
+
+namespace clang {
+class CodeCompletionResult;
+class CompilerInstance;
+
+struct ReplCodeCompleter {
+ ReplCodeCompleter() = default;
+ std::string Prefix;
+
+ /// \param InterpCI [in] The compiler instance that is used to trigger code
+ /// completion
+
+ /// \param Content [in] The string where code completion is triggered.
+
+ /// \param Line [in] The line number of the code completion point.
+
+ /// \param Col [in] The column number of the code completion point.
+
+ /// \param ParentCI [in] The running interpreter compiler instance that
+ /// provides ASTContexts.
+
+ /// \param CCResults [out] The completion results.
+ void codeComplete(CompilerInstance *InterpCI, llvm::StringRef Content,
+ unsigned Line, unsigned Col,
+ const CompilerInstance *ParentCI,
+ std::vector<std::string> &CCResults);
+};
+} // namespace clang
+#endif
diff --git a/contrib/llvm-project/clang/include/clang/Interpreter/Interpreter.h b/contrib/llvm-project/clang/include/clang/Interpreter/Interpreter.h
index 020cbe2db3d0..292fa566ae70 100644
--- a/contrib/llvm-project/clang/include/clang/Interpreter/Interpreter.h
+++ b/contrib/llvm-project/clang/include/clang/Interpreter/Interpreter.h
@@ -14,32 +14,62 @@
#ifndef LLVM_CLANG_INTERPRETER_INTERPRETER_H
#define LLVM_CLANG_INTERPRETER_INTERPRETER_H
+#include "clang/AST/Decl.h"
+#include "clang/AST/GlobalDecl.h"
#include "clang/Interpreter/PartialTranslationUnit.h"
+#include "clang/Interpreter/Value.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ExecutionEngine/JITSymbol.h"
+#include "llvm/ExecutionEngine/Orc/Shared/ExecutorAddress.h"
#include "llvm/Support/Error.h"
-
#include <memory>
#include <vector>
namespace llvm {
namespace orc {
+class LLJIT;
class ThreadSafeContext;
-}
-class Module;
+} // namespace orc
} // namespace llvm
namespace clang {
class CompilerInstance;
-class DeclGroupRef;
class IncrementalExecutor;
class IncrementalParser;
/// Create a pre-configured \c CompilerInstance for incremental processing.
class IncrementalCompilerBuilder {
public:
+ IncrementalCompilerBuilder() {}
+
+ void SetCompilerArgs(const std::vector<const char *> &Args) {
+ UserArgs = Args;
+ }
+
+ // General C++
+ llvm::Expected<std::unique_ptr<CompilerInstance>> CreateCpp();
+
+ // Offload options
+ void SetOffloadArch(llvm::StringRef Arch) { OffloadArch = Arch; };
+
+ // CUDA specific
+ void SetCudaSDK(llvm::StringRef path) { CudaSDKPath = path; };
+
+ llvm::Expected<std::unique_ptr<CompilerInstance>> CreateCudaHost();
+ llvm::Expected<std::unique_ptr<CompilerInstance>> CreateCudaDevice();
+
+private:
static llvm::Expected<std::unique_ptr<CompilerInstance>>
create(std::vector<const char *> &ClangArgv);
+
+ llvm::Expected<std::unique_ptr<CompilerInstance>> createCuda(bool device);
+
+ std::vector<const char *> UserArgs;
+
+ llvm::StringRef OffloadArch;
+ llvm::StringRef CudaSDKPath;
};
/// Provides top-level interfaces for incremental compilation and execution.
@@ -48,23 +78,73 @@ class Interpreter {
std::unique_ptr<IncrementalParser> IncrParser;
std::unique_ptr<IncrementalExecutor> IncrExecutor;
+ // An optional parser for CUDA offloading
+ std::unique_ptr<IncrementalParser> DeviceParser;
+
Interpreter(std::unique_ptr<CompilerInstance> CI, llvm::Error &Err);
+ llvm::Error CreateExecutor();
+ unsigned InitPTUSize = 0;
+
+ // This member holds the last result of the value printing. It's a class
+ // member because we might want to access it after more inputs. If no value
+ // printing happens, it's in an invalid state.
+ Value LastValue;
+
public:
~Interpreter();
static llvm::Expected<std::unique_ptr<Interpreter>>
create(std::unique_ptr<CompilerInstance> CI);
+ static llvm::Expected<std::unique_ptr<Interpreter>>
+ createWithCUDA(std::unique_ptr<CompilerInstance> CI,
+ std::unique_ptr<CompilerInstance> DCI);
+ const ASTContext &getASTContext() const;
+ ASTContext &getASTContext();
const CompilerInstance *getCompilerInstance() const;
+ CompilerInstance *getCompilerInstance();
+ llvm::Expected<llvm::orc::LLJIT &> getExecutionEngine();
+
llvm::Expected<PartialTranslationUnit &> Parse(llvm::StringRef Code);
llvm::Error Execute(PartialTranslationUnit &T);
- llvm::Error ParseAndExecute(llvm::StringRef Code) {
- auto PTU = Parse(Code);
- if (!PTU)
- return PTU.takeError();
- if (PTU->TheModule)
- return Execute(*PTU);
- return llvm::Error::success();
+ llvm::Error ParseAndExecute(llvm::StringRef Code, Value *V = nullptr);
+ llvm::Expected<llvm::orc::ExecutorAddr> CompileDtorCall(CXXRecordDecl *CXXRD);
+
+ /// Undo N previous incremental inputs.
+ llvm::Error Undo(unsigned N = 1);
+
+ /// Link a dynamic library
+ llvm::Error LoadDynamicLibrary(const char *name);
+
+ /// \returns the \c ExecutorAddr of a \c GlobalDecl. This interface uses
+ /// the CodeGenModule's internal mangling cache to avoid recomputing the
+ /// mangled name.
+ llvm::Expected<llvm::orc::ExecutorAddr> getSymbolAddress(GlobalDecl GD) const;
+
+ /// \returns the \c ExecutorAddr of a given name as written in the IR.
+ llvm::Expected<llvm::orc::ExecutorAddr>
+ getSymbolAddress(llvm::StringRef IRName) const;
+
+ /// \returns the \c ExecutorAddr of a given name as written in the object
+ /// file.
+ llvm::Expected<llvm::orc::ExecutorAddr>
+ getSymbolAddressFromLinkerName(llvm::StringRef LinkerName) const;
+
+ enum InterfaceKind { NoAlloc, WithAlloc, CopyArray, NewTag };
+
+ const llvm::SmallVectorImpl<Expr *> &getValuePrintingInfo() const {
+ return ValuePrintingInfo;
}
+
+ Expr *SynthesizeExpr(Expr *E);
+
+private:
+ size_t getEffectivePTUSize() const;
+
+ bool FindRuntimeInterface();
+
+ llvm::DenseMap<CXXRecordDecl *, llvm::orc::ExecutorAddr> Dtors;
+
+ llvm::SmallVector<Expr *, 4> ValuePrintingInfo;
};
} // namespace clang
diff --git a/contrib/llvm-project/clang/include/clang/Interpreter/Value.h b/contrib/llvm-project/clang/include/clang/Interpreter/Value.h
new file mode 100644
index 000000000000..c380cd91550d
--- /dev/null
+++ b/contrib/llvm-project/clang/include/clang/Interpreter/Value.h
@@ -0,0 +1,208 @@
+//===--- Value.h - Definition of interpreter value --------------*- 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
+//
+//===----------------------------------------------------------------------===//
+//
+// Value is a lightweight struct that is used for carrying execution results in
+// clang-repl. It's a special runtime that acts like a messager between compiled
+// code and interpreted code. This makes it possible to exchange interesting
+// information between the compiled & interpreted world.
+//
+// A typical usage is like the below:
+//
+// Value V;
+// Interp.ParseAndExecute("int x = 42;");
+// Interp.ParseAndExecute("x", &V);
+// V.getType(); // <-- Yields a clang::QualType.
+// V.getInt(); // <-- Yields 42.
+//
+// The current design is still highly experimental and nobody should rely on the
+// API being stable because we're hopefully going to make significant changes to
+// it in the relatively near future. For example, Value also intends to be used
+// as an exchange token for JIT support enabling remote execution on the embed
+// devices where the JIT infrastructure cannot fit. To support that we will need
+// to split the memory storage in a different place and perhaps add a resource
+// header is similar to intrinsics headers which have stricter performance
+// constraints.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_INTERPRETER_VALUE_H
+#define LLVM_CLANG_INTERPRETER_VALUE_H
+
+#include "llvm/Support/Compiler.h"
+#include <cstdint>
+
+// NOTE: Since the REPL itself could also include this runtime, extreme caution
+// should be taken when MAKING CHANGES to this file, especially when INCLUDE NEW
+// HEADERS, like <string>, <memory> and etc. (That pulls a large number of
+// tokens and will impact the runtime performance of the REPL)
+
+namespace llvm {
+class raw_ostream;
+
+} // namespace llvm
+
+namespace clang {
+
+class ASTContext;
+class Interpreter;
+class QualType;
+
+#if defined(_WIN32)
+// REPL_EXTERNAL_VISIBILITY are symbols that we need to be able to locate
+// at runtime. On Windows, this requires them to be exported from any of the
+// modules loaded at runtime. Marking them as dllexport achieves this; both
+// for DLLs (that normally export symbols as part of their interface) and for
+// EXEs (that normally don't export anything).
+// For a build with libclang-cpp.dll, this doesn't make any difference - the
+// functions would have been exported anyway. But for cases when these are
+// statically linked into an EXE, it makes sure that they're exported.
+#define REPL_EXTERNAL_VISIBILITY __declspec(dllexport)
+#elif __has_attribute(visibility)
+#if defined(LLVM_BUILD_LLVM_DYLIB) || defined(LLVM_BUILD_SHARED_LIBS)
+#define REPL_EXTERNAL_VISIBILITY __attribute__((visibility("default")))
+#else
+#define REPL_EXTERNAL_VISIBILITY
+#endif
+#else
+#define REPL_EXTERNAL_VISIBILITY
+#endif
+
+#define REPL_BUILTIN_TYPES \
+ X(bool, Bool) \
+ X(char, Char_S) \
+ X(signed char, SChar) \
+ X(unsigned char, UChar) \
+ X(short, Short) \
+ X(unsigned short, UShort) \
+ X(int, Int) \
+ X(unsigned int, UInt) \
+ X(long, Long) \
+ X(unsigned long, ULong) \
+ X(long long, LongLong) \
+ X(unsigned long long, ULongLong) \
+ X(float, Float) \
+ X(double, Double) \
+ X(long double, LongDouble)
+
+class REPL_EXTERNAL_VISIBILITY Value {
+ union Storage {
+#define X(type, name) type m_##name;
+ REPL_BUILTIN_TYPES
+#undef X
+ void *m_Ptr;
+ };
+
+public:
+ enum Kind {
+#define X(type, name) K_##name,
+ REPL_BUILTIN_TYPES
+#undef X
+
+ K_Void,
+ K_PtrOrObj,
+ K_Unspecified
+ };
+
+ Value() = default;
+ Value(Interpreter *In, void *Ty);
+ Value(const Value &RHS);
+ Value(Value &&RHS) noexcept;
+ Value &operator=(const Value &RHS);
+ Value &operator=(Value &&RHS) noexcept;
+ ~Value();
+
+ void printType(llvm::raw_ostream &Out) const;
+ void printData(llvm::raw_ostream &Out) const;
+ void print(llvm::raw_ostream &Out) const;
+ void dump() const;
+ void clear();
+
+ ASTContext &getASTContext();
+ const ASTContext &getASTContext() const;
+ Interpreter &getInterpreter();
+ const Interpreter &getInterpreter() const;
+ QualType getType() const;
+
+ bool isValid() const { return ValueKind != K_Unspecified; }
+ bool isVoid() const { return ValueKind == K_Void; }
+ bool hasValue() const { return isValid() && !isVoid(); }
+ bool isManuallyAlloc() const { return IsManuallyAlloc; }
+ Kind getKind() const { return ValueKind; }
+ void setKind(Kind K) { ValueKind = K; }
+ void setOpaqueType(void *Ty) { OpaqueType = Ty; }
+
+ void *getPtr() const;
+ void setPtr(void *Ptr) { Data.m_Ptr = Ptr; }
+
+#define X(type, name) \
+ void set##name(type Val) { Data.m_##name = Val; } \
+ type get##name() const { return Data.m_##name; }
+ REPL_BUILTIN_TYPES
+#undef X
+
+ /// \brief Get the value with cast.
+ //
+ /// Get the value cast to T. This is similar to reinterpret_cast<T>(value),
+ /// casting the value of builtins (except void), enums and pointers.
+ /// Values referencing an object are treated as pointers to the object.
+ template <typename T> T convertTo() const {
+ return convertFwd<T>::cast(*this);
+ }
+
+protected:
+ bool isPointerOrObjectType() const { return ValueKind == K_PtrOrObj; }
+
+ /// \brief Get to the value with type checking casting the underlying
+ /// stored value to T.
+ template <typename T> T as() const {
+ switch (ValueKind) {
+ default:
+ return T();
+#define X(type, name) \
+ case Value::K_##name: \
+ return (T)Data.m_##name;
+ REPL_BUILTIN_TYPES
+#undef X
+ }
+ }
+
+ // Allow convertTo to be partially specialized.
+ template <typename T> struct convertFwd {
+ static T cast(const Value &V) {
+ if (V.isPointerOrObjectType())
+ return (T)(uintptr_t)V.as<void *>();
+ if (!V.isValid() || V.isVoid()) {
+ return T();
+ }
+ return V.as<T>();
+ }
+ };
+
+ template <typename T> struct convertFwd<T *> {
+ static T *cast(const Value &V) {
+ if (V.isPointerOrObjectType())
+ return (T *)(uintptr_t)V.as<void *>();
+ return nullptr;
+ }
+ };
+
+ Interpreter *Interp = nullptr;
+ void *OpaqueType = nullptr;
+ Storage Data;
+ Kind ValueKind = K_Unspecified;
+ bool IsManuallyAlloc = false;
+};
+
+template <> inline void *Value::as() const {
+ if (isPointerOrObjectType())
+ return Data.m_Ptr;
+ return (void *)as<uintptr_t>();
+}
+
+} // namespace clang
+#endif
diff --git a/contrib/llvm-project/clang/include/clang/Lex/DependencyDirectivesScanner.h b/contrib/llvm-project/clang/include/clang/Lex/DependencyDirectivesScanner.h
new file mode 100644
index 000000000000..0e115906fbfe
--- /dev/null
+++ b/contrib/llvm-project/clang/include/clang/Lex/DependencyDirectivesScanner.h
@@ -0,0 +1,140 @@
+//===- clang/Lex/DependencyDirectivesScanner.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 is the interface for scanning header and source files to get the
+/// minimum necessary preprocessor directives for evaluating includes. It
+/// reduces the source down to #define, #include, #import, @import, and any
+/// conditional preprocessor logic that contains one of those.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_LEX_DEPENDENCYDIRECTIVESSCANNER_H
+#define LLVM_CLANG_LEX_DEPENDENCYDIRECTIVESSCANNER_H
+
+#include "clang/Basic/SourceLocation.h"
+#include "llvm/ADT/ArrayRef.h"
+
+namespace clang {
+
+namespace tok {
+enum TokenKind : unsigned short;
+}
+
+class DiagnosticsEngine;
+
+namespace dependency_directives_scan {
+
+/// Token lexed as part of dependency directive scanning.
+struct Token {
+ /// Offset into the original source input.
+ unsigned Offset;
+ unsigned Length;
+ tok::TokenKind Kind;
+ unsigned short Flags;
+
+ Token(unsigned Offset, unsigned Length, tok::TokenKind Kind,
+ unsigned short Flags)
+ : Offset(Offset), Length(Length), Kind(Kind), Flags(Flags) {}
+
+ unsigned getEnd() const { return Offset + Length; }
+
+ bool is(tok::TokenKind K) const { return Kind == K; }
+ bool isNot(tok::TokenKind K) const { return Kind != K; }
+ bool isOneOf(tok::TokenKind K1, tok::TokenKind K2) const {
+ return is(K1) || is(K2);
+ }
+ template <typename... Ts> bool isOneOf(tok::TokenKind K1, Ts... Ks) const {
+ return is(K1) || isOneOf(Ks...);
+ }
+};
+
+/// Represents the kind of preprocessor directive or a module declaration that
+/// is tracked by the scanner in its token output.
+enum DirectiveKind : uint8_t {
+ pp_none,
+ pp_include,
+ pp___include_macros,
+ pp_define,
+ pp_undef,
+ pp_import,
+ pp_pragma_import,
+ pp_pragma_once,
+ pp_pragma_push_macro,
+ pp_pragma_pop_macro,
+ pp_pragma_include_alias,
+ pp_pragma_system_header,
+ pp_include_next,
+ pp_if,
+ pp_ifdef,
+ pp_ifndef,
+ pp_elif,
+ pp_elifdef,
+ pp_elifndef,
+ pp_else,
+ pp_endif,
+ decl_at_import,
+ cxx_module_decl,
+ cxx_import_decl,
+ cxx_export_module_decl,
+ cxx_export_import_decl,
+ /// Indicates that there are tokens present between the last scanned directive
+ /// and eof. The \p Directive::Tokens array will be empty for this kind.
+ tokens_present_before_eof,
+ pp_eof,
+};
+
+/// Represents a directive that's lexed as part of the dependency directives
+/// scanning. It's used to track various preprocessor directives that could
+/// potentially have an effect on the dependencies.
+struct Directive {
+ ArrayRef<Token> Tokens;
+
+ /// The kind of token.
+ DirectiveKind Kind = pp_none;
+
+ Directive() = default;
+ Directive(DirectiveKind K, ArrayRef<Token> Tokens)
+ : Tokens(Tokens), Kind(K) {}
+};
+
+} // end namespace dependency_directives_scan
+
+/// Scan the input for the preprocessor directives that might have
+/// an effect on the dependencies for a compilation unit.
+///
+/// This function ignores all non-preprocessor code and anything that
+/// can't affect what gets included.
+///
+/// \returns false on success, true on error. If the diagnostic engine is not
+/// null, an appropriate error is reported using the given input location
+/// with the offset that corresponds to the \p Input buffer offset.
+bool scanSourceForDependencyDirectives(
+ StringRef Input, SmallVectorImpl<dependency_directives_scan::Token> &Tokens,
+ SmallVectorImpl<dependency_directives_scan::Directive> &Directives,
+ DiagnosticsEngine *Diags = nullptr,
+ SourceLocation InputSourceLoc = SourceLocation());
+
+/// Print the previously scanned dependency directives as minimized source text.
+///
+/// \param Source The original source text that the dependency directives were
+/// scanned from.
+/// \param Directives The previously scanned dependency
+/// directives.
+/// \param OS the stream to print the dependency directives on.
+///
+/// This is used primarily for testing purposes, during dependency scanning the
+/// \p Lexer uses the tokens directly, not their printed version.
+void printDependencyDirectivesAsSource(
+ StringRef Source,
+ ArrayRef<dependency_directives_scan::Directive> Directives,
+ llvm::raw_ostream &OS);
+
+} // end namespace clang
+
+#endif // LLVM_CLANG_LEX_DEPENDENCYDIRECTIVESSCANNER_H
diff --git a/contrib/llvm-project/clang/include/clang/Lex/DependencyDirectivesSourceMinimizer.h b/contrib/llvm-project/clang/include/clang/Lex/DependencyDirectivesSourceMinimizer.h
deleted file mode 100644
index 9bb820156c25..000000000000
--- a/contrib/llvm-project/clang/include/clang/Lex/DependencyDirectivesSourceMinimizer.h
+++ /dev/null
@@ -1,112 +0,0 @@
-//===- clang/Lex/DependencyDirectivesSourceMinimizer.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 is the interface for minimizing header and source files to the
-/// minimum necessary preprocessor directives for evaluating includes. It
-/// reduces the source down to #define, #include, #import, @import, and any
-/// conditional preprocessor logic that contains one of those.
-///
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_LEX_DEPENDENCY_DIRECTIVES_SOURCE_MINIMIZER_H
-#define LLVM_CLANG_LEX_DEPENDENCY_DIRECTIVES_SOURCE_MINIMIZER_H
-
-#include "clang/Basic/SourceLocation.h"
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/StringRef.h"
-
-namespace clang {
-
-class DiagnosticsEngine;
-
-namespace minimize_source_to_dependency_directives {
-
-/// Represents the kind of preprocessor directive or a module declaration that
-/// is tracked by the source minimizer in its token output.
-enum TokenKind {
- pp_none,
- pp_include,
- pp___include_macros,
- pp_define,
- pp_undef,
- pp_import,
- pp_pragma_import,
- pp_pragma_once,
- pp_include_next,
- pp_if,
- pp_ifdef,
- pp_ifndef,
- pp_elif,
- pp_elifdef,
- pp_elifndef,
- pp_else,
- pp_endif,
- decl_at_import,
- cxx_export_decl,
- cxx_module_decl,
- cxx_import_decl,
- pp_eof,
-};
-
-/// Represents a simplified token that's lexed as part of the source
-/// minimization. It's used to track the location of various preprocessor
-/// directives that could potentially have an effect on the depedencies.
-struct Token {
- /// The kind of token.
- TokenKind K = pp_none;
-
- /// Offset into the output byte stream of where the directive begins.
- int Offset = -1;
-
- Token(TokenKind K, int Offset) : K(K), Offset(Offset) {}
-};
-
-/// Simplified token range to track the range of a potentially skippable PP
-/// directive.
-struct SkippedRange {
- /// Offset into the output byte stream of where the skipped directive begins.
- int Offset;
-
- /// The number of bytes that can be skipped before the preprocessing must
- /// resume.
- int Length;
-};
-
-/// Computes the potential source ranges that can be skipped by the preprocessor
-/// when skipping a directive like #if, #ifdef or #elsif.
-///
-/// \returns false on success, true on error.
-bool computeSkippedRanges(ArrayRef<Token> Input,
- llvm::SmallVectorImpl<SkippedRange> &Range);
-
-} // end namespace minimize_source_to_dependency_directives
-
-/// Minimize the input down to the preprocessor directives that might have
-/// an effect on the dependencies for a compilation unit.
-///
-/// This function deletes all non-preprocessor code, and strips anything that
-/// can't affect what gets included. It canonicalizes whitespace where
-/// convenient to stabilize the output against formatting changes in the input.
-///
-/// Clears the output vectors at the beginning of the call.
-///
-/// \returns false on success, true on error. If the diagnostic engine is not
-/// null, an appropriate error is reported using the given input location
-/// with the offset that corresponds to the minimizer's current buffer offset.
-bool minimizeSourceToDependencyDirectives(
- llvm::StringRef Input, llvm::SmallVectorImpl<char> &Output,
- llvm::SmallVectorImpl<minimize_source_to_dependency_directives::Token>
- &Tokens,
- DiagnosticsEngine *Diags = nullptr,
- SourceLocation InputSourceLoc = SourceLocation());
-
-} // end namespace clang
-
-#endif // LLVM_CLANG_LEX_DEPENDENCY_DIRECTIVES_SOURCE_MINIMIZER_H
diff --git a/contrib/llvm-project/clang/include/clang/Lex/DirectoryLookup.h b/contrib/llvm-project/clang/include/clang/Lex/DirectoryLookup.h
index da2ae9fce1aa..81680d3b271e 100644
--- a/contrib/llvm-project/clang/include/clang/Lex/DirectoryLookup.h
+++ b/contrib/llvm-project/clang/include/clang/Lex/DirectoryLookup.h
@@ -50,17 +50,21 @@ private:
/// DirCharacteristic - The type of directory this is: this is an instance of
/// SrcMgr::CharacteristicKind.
- unsigned DirCharacteristic : 2;
+ LLVM_PREFERRED_TYPE(SrcMgr::CharacteristicKind)
+ unsigned DirCharacteristic : 3;
/// LookupType - This indicates whether this DirectoryLookup object is a
/// normal directory, a framework, or a headermap.
+ LLVM_PREFERRED_TYPE(LookupType_t)
unsigned LookupType : 2;
/// Whether this is a header map used when building a framework.
+ LLVM_PREFERRED_TYPE(bool)
unsigned IsIndexHeaderMap : 1;
/// Whether we've performed an exhaustive search for module maps
/// within the subdirectories of this directory.
+ LLVM_PREFERRED_TYPE(bool)
unsigned SearchedAllModuleMaps : 1;
public:
@@ -91,14 +95,18 @@ public:
return isNormalDir() ? &u.Dir.getDirEntry() : nullptr;
}
+ OptionalDirectoryEntryRef getDirRef() const {
+ return isNormalDir() ? OptionalDirectoryEntryRef(u.Dir) : std::nullopt;
+ }
+
/// getFrameworkDir - Return the directory that this framework refers to.
///
const DirectoryEntry *getFrameworkDir() const {
return isFramework() ? &u.Dir.getDirEntry() : nullptr;
}
- Optional<DirectoryEntryRef> getFrameworkDirRef() const {
- return isFramework() ? Optional<DirectoryEntryRef>(u.Dir) : None;
+ OptionalDirectoryEntryRef getFrameworkDirRef() const {
+ return isFramework() ? OptionalDirectoryEntryRef(u.Dir) : std::nullopt;
}
/// getHeaderMap - Return the directory that this entry refers to.
@@ -176,16 +184,17 @@ public:
/// \param [out] MappedName if this is a headermap which maps the filename to
/// a framework include ("Foo.h" -> "Foo/Foo.h"), set the new name to this
/// vector and point Filename to it.
- Optional<FileEntryRef>
+ OptionalFileEntryRef
LookupFile(StringRef &Filename, HeaderSearch &HS, SourceLocation IncludeLoc,
SmallVectorImpl<char> *SearchPath,
SmallVectorImpl<char> *RelativePath, Module *RequestingModule,
ModuleMap::KnownHeader *SuggestedModule,
bool &InUserSpecifiedSystemFramework, bool &IsFrameworkFound,
- bool &IsInHeaderMap, SmallVectorImpl<char> &MappedName) const;
+ bool &IsInHeaderMap, SmallVectorImpl<char> &MappedName,
+ bool OpenFile = true) const;
private:
- Optional<FileEntryRef> DoFrameworkLookup(
+ OptionalFileEntryRef DoFrameworkLookup(
StringRef Filename, HeaderSearch &HS, SmallVectorImpl<char> *SearchPath,
SmallVectorImpl<char> *RelativePath, Module *RequestingModule,
ModuleMap::KnownHeader *SuggestedModule,
diff --git a/contrib/llvm-project/clang/include/clang/Lex/HeaderMap.h b/contrib/llvm-project/clang/include/clang/Lex/HeaderMap.h
index 53108b00bd16..9d88b36bfd8e 100644
--- a/contrib/llvm-project/clang/include/clang/Lex/HeaderMap.h
+++ b/contrib/llvm-project/clang/include/clang/Lex/HeaderMap.h
@@ -15,11 +15,12 @@
#include "clang/Basic/FileManager.h"
#include "clang/Basic/LLVM.h"
-#include "llvm/ADT/Optional.h"
+#include "clang/Lex/HeaderMapTypes.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/MemoryBuffer.h"
#include <memory>
+#include <optional>
namespace clang {
@@ -39,6 +40,19 @@ public:
// Check for a valid header and extract the byte swap.
static bool checkHeader(const llvm::MemoryBuffer &File, bool &NeedsByteSwap);
+ // Make a call for every Key in the map.
+ template <typename Func> void forEachKey(Func Callback) const {
+ const HMapHeader &Hdr = getHeader();
+ unsigned NumBuckets = getEndianAdjustedWord(Hdr.NumBuckets);
+
+ for (unsigned Bucket = 0; Bucket < NumBuckets; ++Bucket) {
+ HMapBucket B = getBucket(Bucket);
+ if (B.Key != HMAP_EmptyBucketKey)
+ if (std::optional<StringRef> Key = getString(B.Key))
+ Callback(*Key);
+ }
+ }
+
/// If the specified relative filename is located in this HeaderMap return
/// the filename it is mapped to, otherwise return an empty StringRef.
StringRef lookupFilename(StringRef Filename,
@@ -59,8 +73,8 @@ private:
HMapBucket getBucket(unsigned BucketNo) const;
/// Look up the specified string in the string table. If the string index is
- /// not valid, return None.
- Optional<StringRef> getString(unsigned StrTabIdx) const;
+ /// not valid, return std::nullopt.
+ std::optional<StringRef> getString(unsigned StrTabIdx) const;
};
/// This class represents an Apple concept known as a 'header map'. To the
@@ -74,17 +88,10 @@ class HeaderMap : private HeaderMapImpl {
public:
/// This attempts to load the specified file as a header map. If it doesn't
/// look like a HeaderMap, it gives up and returns null.
- static std::unique_ptr<HeaderMap> Create(const FileEntry *FE,
- FileManager &FM);
-
- /// Check to see if the specified relative filename is located in this
- /// HeaderMap. If so, open it and return its FileEntry. If RawPath is not
- /// NULL and the file is found, RawPath will be set to the raw path at which
- /// the file was found in the file system. For example, for a search path
- /// ".." and a filename "../file.h" this would be "../../file.h".
- Optional<FileEntryRef> LookupFile(StringRef Filename, FileManager &FM) const;
+ static std::unique_ptr<HeaderMap> Create(FileEntryRef FE, FileManager &FM);
using HeaderMapImpl::dump;
+ using HeaderMapImpl::forEachKey;
using HeaderMapImpl::getFileName;
using HeaderMapImpl::lookupFilename;
using HeaderMapImpl::reverseLookupFilename;
diff --git a/contrib/llvm-project/clang/include/clang/Lex/HeaderSearch.h b/contrib/llvm-project/clang/include/clang/Lex/HeaderSearch.h
index a35a394f719b..a2c33842924b 100644
--- a/contrib/llvm-project/clang/include/clang/Lex/HeaderSearch.h
+++ b/contrib/llvm-project/clang/include/clang/Lex/HeaderSearch.h
@@ -20,8 +20,6 @@
#include "clang/Lex/ModuleMap.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/SetVector.h"
-#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
@@ -34,6 +32,12 @@
#include <utility>
#include <vector>
+namespace llvm {
+
+class Triple;
+
+} // namespace llvm
+
namespace clang {
class DiagnosticsEngine;
@@ -41,6 +45,7 @@ class DirectoryEntry;
class ExternalPreprocessorSource;
class FileEntry;
class FileManager;
+class HeaderSearch;
class HeaderSearchOptions;
class IdentifierInfo;
class LangOptions;
@@ -51,30 +56,39 @@ class TargetInfo;
/// The preprocessor keeps track of this information for each
/// file that is \#included.
struct HeaderFileInfo {
- /// True if this is a \#import'd or \#pragma once file.
+ // 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.
+ LLVM_PREFERRED_TYPE(bool)
unsigned isImport : 1;
/// True if this is a \#pragma once file.
+ LLVM_PREFERRED_TYPE(bool)
unsigned isPragmaOnce : 1;
/// Keep track of whether this is a system header, and if so,
/// whether it is C++ clean or not. This can be set by the include paths or
/// by \#pragma gcc system_header. This is an instance of
/// SrcMgr::CharacteristicKind.
+ LLVM_PREFERRED_TYPE(SrcMgr::CharacteristicKind)
unsigned DirInfo : 3;
/// Whether this header file info was supplied by an external source,
/// and has not changed since.
+ LLVM_PREFERRED_TYPE(bool)
unsigned External : 1;
/// Whether this header is part of a module.
+ LLVM_PREFERRED_TYPE(bool)
unsigned isModuleHeader : 1;
/// Whether this header is part of the module that we are building.
+ LLVM_PREFERRED_TYPE(bool)
unsigned isCompilingModuleHeader : 1;
/// Whether this structure is considered to already have been
/// "resolved", meaning that it was loaded from the external source.
+ LLVM_PREFERRED_TYPE(bool)
unsigned Resolved : 1;
/// Whether this is a header inside a framework that is currently
@@ -84,14 +98,13 @@ struct HeaderFileInfo {
/// into the appropriate framework subdirectories, and therefore are
/// provided via a header map. This bit indicates when this is one of
/// those framework headers.
+ LLVM_PREFERRED_TYPE(bool)
unsigned IndexHeaderMapHeader : 1;
/// Whether this file has been looked up as a header.
+ LLVM_PREFERRED_TYPE(bool)
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
@@ -113,14 +126,6 @@ struct HeaderFileInfo {
/// of the framework.
StringRef Framework;
- /// List of aliases that this header is known as.
- /// Most headers should only have at most one alias, but a handful
- /// have two.
- llvm::SetVector<llvm::SmallString<32>,
- llvm::SmallVector<llvm::SmallString<32>, 2>,
- llvm::SmallSet<llvm::SmallString<32>, 2>>
- Aliases;
-
HeaderFileInfo()
: isImport(false), isPragmaOnce(false), DirInfo(SrcMgr::C_User),
External(false), isModuleHeader(false), isCompilingModuleHeader(false),
@@ -130,13 +135,6 @@ struct HeaderFileInfo {
/// any.
const IdentifierInfo *
getControllingMacro(ExternalPreprocessorSource *External);
-
- /// Determine whether this is a non-default header file info, e.g.,
- /// it corresponds to an actual header we've included or tried to include.
- bool isNonDefault() const {
- return isImport || isPragmaOnce || NumIncludes || ControllingMacro ||
- ControllingMacroID;
- }
};
/// An external source of header file information, which may supply
@@ -150,13 +148,13 @@ public:
/// \returns Header file information for the given file entry, with the
/// \c External bit set. If the file entry is not known, return a
/// default-constructed \c HeaderFileInfo.
- virtual HeaderFileInfo GetHeaderFileInfo(const FileEntry *FE) = 0;
+ virtual HeaderFileInfo GetHeaderFileInfo(FileEntryRef FE) = 0;
};
/// This structure is used to record entries in our framework cache.
struct FrameworkCacheEntry {
/// The directory entry which should be used for the cached framework.
- const DirectoryEntry *Directory;
+ OptionalDirectoryEntryRef Directory;
/// Whether this framework has been "user-specified" to be treated as if it
/// were a system framework (even if it was found outside a system framework
@@ -164,27 +162,106 @@ struct FrameworkCacheEntry {
bool IsUserSpecifiedSystemFramework;
};
+namespace detail {
+template <bool Const, typename T>
+using Qualified = std::conditional_t<Const, const T, T>;
+
+/// Forward iterator over the search directories of \c HeaderSearch.
+template <bool IsConst>
+struct SearchDirIteratorImpl
+ : llvm::iterator_facade_base<SearchDirIteratorImpl<IsConst>,
+ std::forward_iterator_tag,
+ Qualified<IsConst, DirectoryLookup>> {
+ /// Const -> non-const iterator conversion.
+ template <typename Enable = std::enable_if<IsConst, bool>>
+ SearchDirIteratorImpl(const SearchDirIteratorImpl<false> &Other)
+ : HS(Other.HS), Idx(Other.Idx) {}
+
+ SearchDirIteratorImpl(const SearchDirIteratorImpl &) = default;
+
+ SearchDirIteratorImpl &operator=(const SearchDirIteratorImpl &) = default;
+
+ bool operator==(const SearchDirIteratorImpl &RHS) const {
+ return HS == RHS.HS && Idx == RHS.Idx;
+ }
+
+ SearchDirIteratorImpl &operator++() {
+ assert(*this && "Invalid iterator.");
+ ++Idx;
+ return *this;
+ }
+
+ Qualified<IsConst, DirectoryLookup> &operator*() const {
+ assert(*this && "Invalid iterator.");
+ return HS->SearchDirs[Idx];
+ }
+
+ /// Creates an invalid iterator.
+ SearchDirIteratorImpl(std::nullptr_t) : HS(nullptr), Idx(0) {}
+
+ /// Checks whether the iterator is valid.
+ explicit operator bool() const { return HS != nullptr; }
+
+private:
+ /// The parent \c HeaderSearch. This is \c nullptr for invalid iterator.
+ Qualified<IsConst, HeaderSearch> *HS;
+
+ /// The index of the current element.
+ size_t Idx;
+
+ /// The constructor that creates a valid iterator.
+ SearchDirIteratorImpl(Qualified<IsConst, HeaderSearch> &HS, size_t Idx)
+ : HS(&HS), Idx(Idx) {}
+
+ /// Only HeaderSearch is allowed to instantiate valid iterators.
+ friend HeaderSearch;
+
+ /// Enables const -> non-const conversion.
+ friend SearchDirIteratorImpl<!IsConst>;
+};
+} // namespace detail
+
+using ConstSearchDirIterator = detail::SearchDirIteratorImpl<true>;
+using SearchDirIterator = detail::SearchDirIteratorImpl<false>;
+
+using ConstSearchDirRange = llvm::iterator_range<ConstSearchDirIterator>;
+using SearchDirRange = llvm::iterator_range<SearchDirIterator>;
+
/// Encapsulates the information needed to find the file referenced
/// by a \#include or \#include_next, (sub-)framework lookup, etc.
class HeaderSearch {
friend class DirectoryLookup;
+ friend ConstSearchDirIterator;
+ friend SearchDirIterator;
+
/// Header-search options used to initialize this header search.
std::shared_ptr<HeaderSearchOptions> HSOpts;
+ /// Mapping from SearchDir to HeaderSearchOptions::UserEntries indices.
+ llvm::DenseMap<unsigned, unsigned> SearchDirToHSEntry;
+
DiagnosticsEngine &Diags;
FileManager &FileMgr;
/// \#include search path information. Requests for \#include "x" search the
/// directory of the \#including file first, then each directory in SearchDirs
/// consecutively. Requests for <x> search the current dir first, then each
- /// directory in SearchDirs, starting at AngledDirIdx, consecutively. If
- /// NoCurDirSearch is true, then the check for the file in the current
- /// directory is suppressed.
+ /// directory in SearchDirs, starting at AngledDirIdx, consecutively.
std::vector<DirectoryLookup> SearchDirs;
+ /// Whether the DirectoryLookup at the corresponding index in SearchDirs has
+ /// been successfully used to lookup a file.
+ std::vector<bool> SearchDirsUsage;
unsigned AngledDirIdx = 0;
unsigned SystemDirIdx = 0;
- bool NoCurDirSearch = false;
+
+ /// Maps HeaderMap keys to SearchDir indices. When HeaderMaps are used
+ /// heavily, SearchDirs can start with thousands of HeaderMaps, so this Index
+ /// lets us avoid scanning them all to find a match.
+ llvm::StringMap<unsigned, llvm::BumpPtrAllocator> SearchDirHeaderMapIndex;
+
+ /// The index of the first SearchDir that isn't a header map.
+ unsigned FirstNonHeaderMapSearchDirIdx = 0;
/// \#include prefixes for which the 'system header' property is
/// overridden.
@@ -206,13 +283,16 @@ class HeaderSearch {
/// Keeps track of each lookup performed by LookupFile.
struct LookupFileCacheInfo {
- /// Starting index in SearchDirs that the cached search was performed from.
- /// If there is a hit and this value doesn't match the current query, the
- /// cache has to be ignored.
- unsigned StartIdx = 0;
+ // The requesting module for the lookup we cached.
+ const Module *RequestingModule = nullptr;
+
+ /// Starting search directory iterator that the cached search was performed
+ /// from. If there is a hit and this value doesn't match the current query,
+ /// the cache has to be ignored.
+ ConstSearchDirIterator StartIt = nullptr;
- /// The entry in SearchDirs that satisfied the query.
- unsigned HitIdx = 0;
+ /// The search directory iterator that satisfied the query.
+ ConstSearchDirIterator HitIt = nullptr;
/// This is non-null if the original filename was mapped to a framework
/// include via a headermap.
@@ -221,9 +301,11 @@ class HeaderSearch {
/// Default constructor -- Initialize all members with zero.
LookupFileCacheInfo() = default;
- void reset(unsigned StartIdx) {
- this->StartIdx = StartIdx;
- this->MappedName = nullptr;
+ void reset(const Module *NewRequestingModule,
+ ConstSearchDirIterator NewStartIt) {
+ RequestingModule = NewRequestingModule;
+ StartIt = NewStartIt;
+ MappedName = nullptr;
}
};
llvm::StringMap<LookupFileCacheInfo, llvm::BumpPtrAllocator> LookupFileCache;
@@ -240,7 +322,7 @@ class HeaderSearch {
std::unique_ptr<IncludeAliasMap> IncludeAliases;
/// This is a mapping from FileEntry -> HeaderMap, uniquing headermaps.
- std::vector<std::pair<const FileEntry *, std::unique_ptr<HeaderMap>>> HeaderMaps;
+ std::vector<std::pair<FileEntryRef, std::unique_ptr<HeaderMap>>> HeaderMaps;
/// The mapping between modules and headers.
mutable ModuleMap ModMap;
@@ -252,6 +334,9 @@ class HeaderSearch {
/// whether they were valid or not.
llvm::DenseMap<const FileEntry *, bool> LoadedModuleMaps;
+ // A map of discovered headers with their associated include file name.
+ llvm::DenseMap<const FileEntry *, llvm::SmallString<64>> IncludeNames;
+
/// Uniqued set of framework names, which is used to track which
/// headers were included as framework headers.
llvm::StringSet<llvm::BumpPtrAllocator> FrameworkNames;
@@ -264,6 +349,10 @@ class HeaderSearch {
/// Entity used to look up stored header file information.
ExternalHeaderFileInfoSource *ExternalSource = nullptr;
+ /// Scan all of the header maps at the beginning of SearchDirs and
+ /// map their keys to the SearchDir index of their header map.
+ void indexInitialHeaderMaps();
+
public:
HeaderSearch(std::shared_ptr<HeaderSearchOptions> HSOpts,
SourceManager &SourceMgr, DiagnosticsEngine &Diags,
@@ -280,25 +369,17 @@ public:
DiagnosticsEngine &getDiags() const { return Diags; }
/// Interface for setting the file search paths.
- void SetSearchPaths(const std::vector<DirectoryLookup> &dirs,
- unsigned angledDirIdx, unsigned systemDirIdx,
- bool noCurDirSearch) {
- assert(angledDirIdx <= systemDirIdx && systemDirIdx <= dirs.size() &&
- "Directory indices are unordered");
- SearchDirs = dirs;
- AngledDirIdx = angledDirIdx;
- SystemDirIdx = systemDirIdx;
- NoCurDirSearch = noCurDirSearch;
- //LookupFileCache.clear();
- }
+ void SetSearchPaths(std::vector<DirectoryLookup> dirs, unsigned angledDirIdx,
+ unsigned systemDirIdx,
+ 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);
- 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.
@@ -409,14 +490,15 @@ public:
/// found in any of searched SearchDirs. Will be set to false if a framework
/// is found only through header maps. Doesn't guarantee the requested file is
/// found.
- Optional<FileEntryRef> LookupFile(
+ OptionalFileEntryRef LookupFile(
StringRef Filename, SourceLocation IncludeLoc, bool isAngled,
- const DirectoryLookup *FromDir, const DirectoryLookup *&CurDir,
- ArrayRef<std::pair<const FileEntry *, const DirectoryEntry *>> Includers,
+ ConstSearchDirIterator FromDir, ConstSearchDirIterator *CurDir,
+ ArrayRef<std::pair<OptionalFileEntryRef, DirectoryEntryRef>> Includers,
SmallVectorImpl<char> *SearchPath, SmallVectorImpl<char> *RelativePath,
Module *RequestingModule, ModuleMap::KnownHeader *SuggestedModule,
bool *IsMapped, bool *IsFrameworkFound, bool SkipCache = false,
- bool BuildSystemModule = false);
+ bool BuildSystemModule = false, bool OpenFile = true,
+ bool CacheFailures = true);
/// Look up a subframework for the specified \#include file.
///
@@ -424,8 +506,8 @@ public:
/// within ".../Carbon.framework/Headers/Carbon.h", check to see if
/// HIToolbox is a subframework within Carbon.framework. If so, return
/// the FileEntry for the designated file, otherwise return null.
- Optional<FileEntryRef> LookupSubframeworkHeader(
- StringRef Filename, const FileEntry *ContextFileEnt,
+ OptionalFileEntryRef LookupSubframeworkHeader(
+ StringRef Filename, FileEntryRef ContextFileEnt,
SmallVectorImpl<char> *SearchPath, SmallVectorImpl<char> *RelativePath,
Module *RequestingModule, ModuleMap::KnownHeader *SuggestedModule);
@@ -440,76 +522,63 @@ public:
///
/// \return false if \#including the file will have no effect or true
/// if we should include it.
- bool ShouldEnterIncludeFile(Preprocessor &PP, const FileEntry *File,
- bool isImport, bool ModulesEnabled,
- Module *M);
+ bool ShouldEnterIncludeFile(Preprocessor &PP, FileEntryRef File,
+ bool isImport, bool ModulesEnabled, Module *M,
+ bool &IsFirstIncludeOfFile);
/// Return whether the specified file is a normal header,
/// a system header, or a C++ friendly system header.
- SrcMgr::CharacteristicKind getFileDirFlavor(const FileEntry *File) {
+ SrcMgr::CharacteristicKind getFileDirFlavor(FileEntryRef File) {
return (SrcMgr::CharacteristicKind)getFileInfo(File).DirInfo;
}
- /// Mark the specified file as a "once only" file, e.g. due to
+ /// Mark the specified file as a "once only" file due to
/// \#pragma once.
- void MarkFileIncludeOnce(const FileEntry *File) {
+ void MarkFileIncludeOnce(FileEntryRef File) {
HeaderFileInfo &FI = getFileInfo(File);
- FI.isImport = true;
FI.isPragmaOnce = true;
}
/// Mark the specified file as a system header, e.g. due to
/// \#pragma GCC system_header.
- void MarkFileSystemHeader(const FileEntry *File) {
+ void MarkFileSystemHeader(FileEntryRef File) {
getFileInfo(File).DirInfo = SrcMgr::C_System;
}
- void AddFileAlias(const FileEntry *File, StringRef Alias) {
- getFileInfo(File).Aliases.insert(Alias);
- }
-
/// Mark the specified file as part of a module.
- void MarkFileModuleHeader(const FileEntry *FE,
- ModuleMap::ModuleHeaderRole Role,
+ void MarkFileModuleHeader(FileEntryRef FE, 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
/// no-op \#includes.
- void SetFileControllingMacro(const FileEntry *File,
+ void SetFileControllingMacro(FileEntryRef File,
const IdentifierInfo *ControllingMacro) {
getFileInfo(File).ControllingMacro = ControllingMacro;
}
- /// Return true if this is the first time encountering this header.
- bool FirstTimeLexingFile(const FileEntry *File) {
- return getFileInfo(File).NumIncludes == 1;
- }
-
/// Determine whether this file is intended to be safe from
/// multiple inclusions, e.g., it has \#pragma once or a controlling
/// macro.
///
/// This routine does not consider the effect of \#import
- bool isFileMultipleIncludeGuarded(const FileEntry *File);
+ bool isFileMultipleIncludeGuarded(FileEntryRef File) const;
- /// Determine whether the given file is known to have ever been \#imported
- /// (or if it has been \#included and we've encountered a \#pragma once).
- bool hasFileBeenImported(const FileEntry *File) {
+ /// Determine whether the given file is known to have ever been \#imported.
+ bool hasFileBeenImported(FileEntryRef File) const {
const HeaderFileInfo *FI = getExistingFileInfo(File);
return FI && FI->isImport;
}
+ /// Determine which HeaderSearchOptions::UserEntries have been successfully
+ /// used so far and mark their index with 'true' in the resulting bit vector.
+ /// Note: implicit module maps don't contribute to entry usage.
+ std::vector<bool> computeUserEntryUsage() const;
+
/// This method returns a HeaderMap for the specified
/// FileEntry, uniquing them through the 'HeaderMaps' datastructure.
- const HeaderMap *CreateHeaderMap(const FileEntry *FE);
+ const HeaderMap *CreateHeaderMap(FileEntryRef FE);
/// Get filenames for all registered header maps.
void getHeaderMapFileNames(SmallVectorImpl<std::string> &Names) const;
@@ -562,6 +631,8 @@ public:
///
/// \param ModuleName The name of the module we're looking for.
///
+ /// \param ImportLoc Location of the module include/import.
+ ///
/// \param AllowSearch Whether we are allowed to search in the various
/// search directories to produce a module definition. If not, this lookup
/// will only return an already-known module.
@@ -570,13 +641,15 @@ public:
/// in subdirectories.
///
/// \returns The module with the given name.
- Module *lookupModule(StringRef ModuleName, bool AllowSearch = true,
+ Module *lookupModule(StringRef ModuleName,
+ SourceLocation ImportLoc = SourceLocation(),
+ bool AllowSearch = true,
bool AllowExtraModuleMapSearch = false);
/// Try to find a module map file in the given directory, returning
- /// \c nullptr if none is found.
- const FileEntry *lookupModuleMapFile(const DirectoryEntry *Dir,
- bool IsFramework);
+ /// \c nullopt if none is found.
+ OptionalFileEntryRef lookupModuleMapFile(DirectoryEntryRef Dir,
+ bool IsFramework);
/// Determine whether there is a module map that may map the header
/// with the given file name to a (sub)module.
@@ -596,14 +669,20 @@ public:
///
/// \param File The header that we wish to map to a module.
/// \param AllowTextual Whether we want to find textual headers too.
- ModuleMap::KnownHeader findModuleForHeader(const FileEntry *File,
- bool AllowTextual = false) const;
+ ModuleMap::KnownHeader findModuleForHeader(FileEntryRef File,
+ bool AllowTextual = false,
+ bool AllowExcluded = false) const;
/// Retrieve all the modules corresponding to the given file.
///
/// \ref findModuleForHeader should typically be used instead of this.
ArrayRef<ModuleMap::KnownHeader>
- findAllModulesForHeader(const FileEntry *File) const;
+ findAllModulesForHeader(FileEntryRef File) const;
+
+ /// Like \ref findAllModulesForHeader, but do not attempt to infer module
+ /// ownership from umbrella headers if we've not already done so.
+ ArrayRef<ModuleMap::KnownHeader>
+ findResolvedModulesForHeader(FileEntryRef File) const;
/// Read the contents of the given module map file.
///
@@ -618,8 +697,8 @@ public:
/// used to resolve paths within the module (this is required when
/// building the module from preprocessed source).
/// \returns true if an error occurred, false otherwise.
- bool loadModuleMapFile(const FileEntry *File, bool IsSystem,
- FileID ID = FileID(), unsigned *Offset = nullptr,
+ bool loadModuleMapFile(FileEntryRef File, bool IsSystem, FileID ID = FileID(),
+ unsigned *Offset = nullptr,
StringRef OriginalModuleMapFile = StringRef());
/// Collect the set of all known, top-level modules.
@@ -640,11 +719,14 @@ private:
/// but for compatibility with some buggy frameworks, additional attempts
/// may be made to find the module under a related-but-different search-name.
///
+ /// \param ImportLoc Location of the module include/import.
+ ///
/// \param AllowExtraModuleMapSearch Whether we allow to search modulemaps
/// in subdirectories.
///
/// \returns The module named ModuleName.
Module *lookupModule(StringRef ModuleName, StringRef SearchName,
+ SourceLocation ImportLoc,
bool AllowExtraModuleMapSearch = false);
/// Retrieve the name of the (to-be-)cached module file that should
@@ -674,8 +756,7 @@ private:
/// frameworks.
///
/// \returns The module, if found; otherwise, null.
- Module *loadFrameworkModule(StringRef Name,
- const DirectoryEntry *Dir,
+ Module *loadFrameworkModule(StringRef Name, DirectoryEntryRef Dir,
bool IsSystem);
/// Load all of the module maps within the immediate subdirectories
@@ -686,8 +767,7 @@ private:
///
/// \return \c true if the file can be used, \c false if we are not permitted to
/// find this file due to requirements from \p RequestingModule.
- bool findUsableModuleForHeader(const FileEntry *File,
- const DirectoryEntry *Root,
+ bool findUsableModuleForHeader(FileEntryRef File, const DirectoryEntry *Root,
Module *RequestingModule,
ModuleMap::KnownHeader *SuggestedModule,
bool IsSystemHeaderDir);
@@ -698,16 +778,27 @@ private:
/// \return \c true if the file can be used, \c false if we are not permitted to
/// find this file due to requirements from \p RequestingModule.
bool findUsableModuleForFrameworkHeader(
- const FileEntry *File, StringRef FrameworkName, Module *RequestingModule,
+ FileEntryRef File, StringRef FrameworkName, Module *RequestingModule,
ModuleMap::KnownHeader *SuggestedModule, bool IsSystemFramework);
/// Look up the file with the specified name and determine its owning
/// module.
- Optional<FileEntryRef>
+ OptionalFileEntryRef
getFileAndSuggestModule(StringRef FileName, SourceLocation IncludeLoc,
const DirectoryEntry *Dir, bool IsSystemHeaderDir,
Module *RequestingModule,
- ModuleMap::KnownHeader *SuggestedModule);
+ ModuleMap::KnownHeader *SuggestedModule,
+ bool OpenFile = true, bool CacheFailures = true);
+
+ /// Cache the result of a successful lookup at the given include location
+ /// using the search path at \c HitIt.
+ void cacheLookupSuccess(LookupFileCacheInfo &CacheLookup,
+ ConstSearchDirIterator HitIt,
+ SourceLocation IncludeLoc);
+
+ /// Note that a lookup at the given include location was successful using the
+ /// search path at index `HitIdx`.
+ void noteLookupUsage(unsigned HitIdx, SourceLocation IncludeLoc);
public:
/// Retrieve the module map.
@@ -720,47 +811,61 @@ public:
/// Return the HeaderFileInfo structure for the specified FileEntry,
/// in preparation for updating it in some way.
- HeaderFileInfo &getFileInfo(const FileEntry *FE);
+ HeaderFileInfo &getFileInfo(FileEntryRef FE);
/// Return the HeaderFileInfo structure for the specified FileEntry,
/// if it has ever been filled in.
/// \param WantExternal Whether the caller wants purely-external header file
/// info (where \p External is true).
- const HeaderFileInfo *getExistingFileInfo(const FileEntry *FE,
+ const HeaderFileInfo *getExistingFileInfo(FileEntryRef FE,
bool WantExternal = true) const;
- // Used by external tools
- using search_dir_iterator = std::vector<DirectoryLookup>::const_iterator;
-
- search_dir_iterator search_dir_begin() const { return SearchDirs.begin(); }
- search_dir_iterator search_dir_end() const { return SearchDirs.end(); }
- unsigned search_dir_size() const { return SearchDirs.size(); }
-
- search_dir_iterator quoted_dir_begin() const {
- return SearchDirs.begin();
+ SearchDirIterator search_dir_begin() { return {*this, 0}; }
+ SearchDirIterator search_dir_end() { return {*this, SearchDirs.size()}; }
+ SearchDirRange search_dir_range() {
+ return {search_dir_begin(), search_dir_end()};
}
- search_dir_iterator quoted_dir_end() const {
- return SearchDirs.begin() + AngledDirIdx;
+ ConstSearchDirIterator search_dir_begin() const { return quoted_dir_begin(); }
+ ConstSearchDirIterator search_dir_nth(size_t n) const {
+ assert(n < SearchDirs.size());
+ return {*this, n};
}
-
- search_dir_iterator angled_dir_begin() const {
- return SearchDirs.begin() + AngledDirIdx;
+ ConstSearchDirIterator search_dir_end() const { return system_dir_end(); }
+ ConstSearchDirRange search_dir_range() const {
+ return {search_dir_begin(), search_dir_end()};
}
- search_dir_iterator angled_dir_end() const {
- return SearchDirs.begin() + SystemDirIdx;
+ unsigned search_dir_size() const { return SearchDirs.size(); }
+
+ ConstSearchDirIterator quoted_dir_begin() const { return {*this, 0}; }
+ ConstSearchDirIterator quoted_dir_end() const { return angled_dir_begin(); }
+
+ ConstSearchDirIterator angled_dir_begin() const {
+ return {*this, AngledDirIdx};
}
+ ConstSearchDirIterator angled_dir_end() const { return system_dir_begin(); }
- search_dir_iterator system_dir_begin() const {
- return SearchDirs.begin() + SystemDirIdx;
+ ConstSearchDirIterator system_dir_begin() const {
+ return {*this, SystemDirIdx};
+ }
+ ConstSearchDirIterator system_dir_end() const {
+ return {*this, SearchDirs.size()};
}
- search_dir_iterator system_dir_end() const { return SearchDirs.end(); }
+ /// Get the index of the given search directory.
+ unsigned searchDirIdx(const DirectoryLookup &DL) const;
/// Retrieve a uniqued framework name.
StringRef getUniqueFrameworkName(StringRef Framework);
+ /// Retrieve the include name for the header.
+ ///
+ /// \param File The entry for a given header.
+ /// \returns The name of how the file was included when the header's location
+ /// was resolved.
+ StringRef getIncludeNameForHeader(const FileEntry *File) const;
+
/// Suggest a path by which the specified file could be found, for use in
/// diagnostics to suggest a #include. Returned path will only contain forward
/// slashes as separators. MainFile is the absolute path of the file that we
@@ -768,11 +873,11 @@ public:
/// MainFile location, if none of the include search directories were prefix
/// of File.
///
- /// \param IsSystem If non-null, filled in to indicate whether the suggested
- /// path is relative to a system header directory.
- std::string suggestPathToFileForDiagnostics(const FileEntry *File,
+ /// \param IsAngled If non-null, filled in to indicate whether the suggested
+ /// path should be referenced as <Header.h> instead of "Header.h".
+ std::string suggestPathToFileForDiagnostics(FileEntryRef File,
llvm::StringRef MainFile,
- bool *IsSystem = nullptr);
+ bool *IsAngled = nullptr) const;
/// Suggest a path by which the specified file could be found, for use in
/// diagnostics to suggest a #include. Returned path will only contain forward
@@ -786,7 +891,7 @@ public:
std::string suggestPathToFileForDiagnostics(llvm::StringRef File,
llvm::StringRef WorkingDir,
llvm::StringRef MainFile,
- bool *IsSystem = nullptr);
+ bool *IsAngled = nullptr) const;
void PrintStats();
@@ -809,9 +914,8 @@ private:
LMM_InvalidModuleMap
};
- LoadModuleMapResult loadModuleMapFileImpl(const FileEntry *File,
- bool IsSystem,
- const DirectoryEntry *Dir,
+ LoadModuleMapResult loadModuleMapFileImpl(FileEntryRef File, bool IsSystem,
+ DirectoryEntryRef Dir,
FileID ID = FileID(),
unsigned *Offset = nullptr);
@@ -835,10 +939,16 @@ private:
///
/// \returns The result of attempting to load the module map file from the
/// named directory.
- LoadModuleMapResult loadModuleMapFile(const DirectoryEntry *Dir,
- bool IsSystem, bool IsFramework);
+ LoadModuleMapResult loadModuleMapFile(DirectoryEntryRef Dir, 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/HeaderSearchOptions.h b/contrib/llvm-project/clang/include/clang/Lex/HeaderSearchOptions.h
index 42f3cff8c57a..fa2d0b502d72 100644
--- a/contrib/llvm-project/clang/include/clang/Lex/HeaderSearchOptions.h
+++ b/contrib/llvm-project/clang/include/clang/Lex/HeaderSearchOptions.h
@@ -14,10 +14,11 @@
#include "llvm/ADT/Hashing.h"
#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/HashBuilder.h"
#include <cstdint>
+#include <map>
#include <string>
#include <vector>
-#include <map>
namespace clang {
@@ -69,11 +70,13 @@ public:
struct Entry {
std::string Path;
frontend::IncludeDirGroup Group;
+ LLVM_PREFERRED_TYPE(bool)
unsigned IsFramework : 1;
/// IgnoreSysRoot - This is false if an absolute path should be treated
/// relative to the sysroot, or true if it should always be the absolute
/// path.
+ LLVM_PREFERRED_TYPE(bool)
unsigned IgnoreSysRoot : 1;
Entry(StringRef path, frontend::IncludeDirGroup group, bool isFramework,
@@ -127,10 +130,12 @@ public:
/// module cache.
///
/// Note: Only used for testing!
+ LLVM_PREFERRED_TYPE(bool)
unsigned DisableModuleHash : 1;
/// Implicit module maps. This option is enabld by default when
/// modules is enabled.
+ LLVM_PREFERRED_TYPE(bool)
unsigned ImplicitModuleMaps : 1;
/// Set the 'home directory' of a module map file to the current
@@ -140,10 +145,19 @@ public:
//
/// The home directory is where we look for files named in the module map
/// file.
+ LLVM_PREFERRED_TYPE(bool)
unsigned ModuleMapFileHomeIsCwd : 1;
+ /// Set the base path of a built module file to be the current working
+ /// directory. This is useful for sharing module files across machines
+ /// that build with different paths without having to rewrite all
+ /// modulemap files to have working directory relative paths.
+ LLVM_PREFERRED_TYPE(bool)
+ unsigned ModuleFileHomeIsCwd : 1;
+
/// Also search for prebuilt implicit modules in the prebuilt module cache
/// path.
+ LLVM_PREFERRED_TYPE(bool)
unsigned EnablePrebuiltImplicitModules : 1;
/// The interval (in seconds) between pruning operations.
@@ -178,37 +192,67 @@ public:
std::vector<std::string> VFSOverlayFiles;
/// Include the compiler builtin includes.
+ LLVM_PREFERRED_TYPE(bool)
unsigned UseBuiltinIncludes : 1;
/// Include the system standard include search directories.
+ LLVM_PREFERRED_TYPE(bool)
unsigned UseStandardSystemIncludes : 1;
/// Include the system standard C++ library include search directories.
+ LLVM_PREFERRED_TYPE(bool)
unsigned UseStandardCXXIncludes : 1;
/// Use libc++ instead of the default libstdc++.
+ LLVM_PREFERRED_TYPE(bool)
unsigned UseLibcxx : 1;
/// Whether header search information should be output as for -v.
+ LLVM_PREFERRED_TYPE(bool)
unsigned Verbose : 1;
/// If true, skip verifying input files used by modules if the
/// module was already verified during this build session (see
/// \c BuildSessionTimestamp).
+ LLVM_PREFERRED_TYPE(bool)
unsigned ModulesValidateOncePerBuildSession : 1;
/// Whether to validate system input files when a module is loaded.
+ LLVM_PREFERRED_TYPE(bool)
unsigned ModulesValidateSystemHeaders : 1;
// Whether the content of input files should be hashed and used to
// validate consistency.
+ LLVM_PREFERRED_TYPE(bool)
unsigned ValidateASTInputFilesContent : 1;
+ // Whether the input files from C++20 Modules should be checked.
+ LLVM_PREFERRED_TYPE(bool)
+ unsigned ForceCheckCXX20ModulesInputFiles : 1;
+
/// Whether the module includes debug information (-gmodules).
+ LLVM_PREFERRED_TYPE(bool)
unsigned UseDebugInfo : 1;
+ LLVM_PREFERRED_TYPE(bool)
unsigned ModulesValidateDiagnosticOptions : 1;
+ /// Whether to entirely skip writing diagnostic options.
+ /// Primarily used to speed up deserialization during dependency scanning.
+ LLVM_PREFERRED_TYPE(bool)
+ unsigned ModulesSkipDiagnosticOptions : 1;
+
+ /// Whether to entirely skip writing header search paths.
+ /// Primarily used to speed up deserialization during dependency scanning.
+ LLVM_PREFERRED_TYPE(bool)
+ unsigned ModulesSkipHeaderSearchPaths : 1;
+
+ /// Whether to entirely skip writing pragma diagnostic mappings.
+ /// Primarily used to speed up deserialization during dependency scanning.
+ LLVM_PREFERRED_TYPE(bool)
+ unsigned ModulesSkipPragmaDiagnosticMappings : 1;
+
+ LLVM_PREFERRED_TYPE(bool)
unsigned ModulesHashContent : 1;
/// Whether we should include all things that could impact the module in the
@@ -216,18 +260,23 @@ public:
///
/// This includes things like the full header search path, and enabled
/// diagnostics.
+ LLVM_PREFERRED_TYPE(bool)
unsigned ModulesStrictContextHash : 1;
HeaderSearchOptions(StringRef _Sysroot = "/")
: Sysroot(_Sysroot), ModuleFormat("raw"), DisableModuleHash(false),
ImplicitModuleMaps(false), ModuleMapFileHomeIsCwd(false),
- EnablePrebuiltImplicitModules(false), UseBuiltinIncludes(true),
- UseStandardSystemIncludes(true), UseStandardCXXIncludes(true),
- UseLibcxx(false), Verbose(false),
+ ModuleFileHomeIsCwd(false), EnablePrebuiltImplicitModules(false),
+ UseBuiltinIncludes(true), UseStandardSystemIncludes(true),
+ UseStandardCXXIncludes(true), UseLibcxx(false), Verbose(false),
ModulesValidateOncePerBuildSession(false),
ModulesValidateSystemHeaders(false),
- ValidateASTInputFilesContent(false), UseDebugInfo(false),
- ModulesValidateDiagnosticOptions(true), ModulesHashContent(false),
+ ValidateASTInputFilesContent(false),
+ ForceCheckCXX20ModulesInputFiles(false), UseDebugInfo(false),
+ ModulesValidateDiagnosticOptions(true),
+ ModulesSkipDiagnosticOptions(false),
+ ModulesSkipHeaderSearchPaths(false),
+ ModulesSkipPragmaDiagnosticMappings(false), ModulesHashContent(false),
ModulesStrictContextHash(false) {}
/// AddPath - Add the \p Path path to the specified \p Group list.
@@ -256,11 +305,23 @@ inline llvm::hash_code hash_value(const HeaderSearchOptions::Entry &E) {
return llvm::hash_combine(E.Path, E.Group, E.IsFramework, E.IgnoreSysRoot);
}
+template <typename HasherT, llvm::endianness Endianness>
+inline void addHash(llvm::HashBuilder<HasherT, Endianness> &HBuilder,
+ const HeaderSearchOptions::Entry &E) {
+ HBuilder.add(E.Path, E.Group, E.IsFramework, E.IgnoreSysRoot);
+}
+
inline llvm::hash_code
hash_value(const HeaderSearchOptions::SystemHeaderPrefix &SHP) {
return llvm::hash_combine(SHP.Prefix, SHP.IsSystemHeader);
}
+template <typename HasherT, llvm::endianness Endianness>
+inline void addHash(llvm::HashBuilder<HasherT, Endianness> &HBuilder,
+ const HeaderSearchOptions::SystemHeaderPrefix &SHP) {
+ HBuilder.add(SHP.Prefix, SHP.IsSystemHeader);
+}
+
} // namespace clang
#endif // LLVM_CLANG_LEX_HEADERSEARCHOPTIONS_H
diff --git a/contrib/llvm-project/clang/include/clang/Lex/Lexer.h b/contrib/llvm-project/clang/include/clang/Lex/Lexer.h
index a291520ae5ca..b6ecc7e5ded9 100644
--- a/contrib/llvm-project/clang/include/clang/Lex/Lexer.h
+++ b/contrib/llvm-project/clang/include/clang/Lex/Lexer.h
@@ -16,13 +16,14 @@
#include "clang/Basic/LangOptions.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Basic/TokenKinds.h"
+#include "clang/Lex/DependencyDirectivesScanner.h"
#include "clang/Lex/PreprocessorLexer.h"
#include "clang/Lex/Token.h"
-#include "llvm/ADT/Optional.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
#include <cassert>
#include <cstdint>
+#include <optional>
#include <string>
namespace llvm {
@@ -36,6 +37,7 @@ namespace clang {
class DiagnosticBuilder;
class Preprocessor;
class SourceManager;
+class LangOptions;
/// ConflictMarkerKind - Kinds of conflict marker which the lexer might be
/// recovering from.
@@ -90,8 +92,18 @@ class Lexer : public PreprocessorLexer {
// Location for start of file.
SourceLocation FileLoc;
- // LangOpts enabled by this language (cache).
- LangOptions LangOpts;
+ // LangOpts enabled by this language.
+ // Storing LangOptions as reference here is important from performance point
+ // of view. Lack of reference means that LangOptions copy constructor would be
+ // called by Lexer(..., const LangOptions &LangOpts,...). Given that local
+ // Lexer objects are created thousands times (in Lexer::getRawToken,
+ // Preprocessor::EnterSourceFile and other places) during single module
+ // processing in frontend it would make std::vector<std::string> copy
+ // constructors surprisingly hot.
+ const LangOptions &LangOpts;
+
+ // True if '//' line comments are enabled.
+ bool LineComment;
// True if lexer for _Pragma handling.
bool Is_PragmaLexer;
@@ -128,6 +140,9 @@ class Lexer : public PreprocessorLexer {
bool HasLeadingEmptyMacro;
+ /// True if this is the first time we're lexing the input file.
+ bool IsFirstTimeLexingFile;
+
// NewLinePtr - A pointer to new line character '\n' being lexed. For '\r\n',
// it also points to '\n.'
const char *NewLinePtr;
@@ -135,6 +150,13 @@ class Lexer : public PreprocessorLexer {
// CurrentConflictMarkerState - The kind of conflict marker we are handling.
ConflictMarkerKind CurrentConflictMarkerState;
+ /// Non-empty if this \p Lexer is \p isDependencyDirectivesLexer().
+ ArrayRef<dependency_directives_scan::Directive> DepDirectives;
+
+ /// If this \p Lexer is \p isDependencyDirectivesLexer(), it represents the
+ /// next token to use from the current dependency directive.
+ unsigned NextDepDirectiveTokenIndex = 0;
+
void InitLexer(const char *BufStart, const char *BufPtr, const char *BufEnd);
public:
@@ -142,19 +164,22 @@ public:
/// with the specified preprocessor managing the lexing process. This lexer
/// assumes that the associated file buffer and Preprocessor objects will
/// outlive it, so it doesn't take ownership of either of them.
- Lexer(FileID FID, const llvm::MemoryBufferRef &InputFile, Preprocessor &PP);
+ Lexer(FileID FID, const llvm::MemoryBufferRef &InputFile, Preprocessor &PP,
+ bool IsFirstIncludeOfFile = true);
/// Lexer constructor - Create a new raw lexer object. This object is only
/// suitable for calls to 'LexFromRawLexer'. This lexer assumes that the
/// text range will outlive it, so it doesn't take ownership of it.
Lexer(SourceLocation FileLoc, const LangOptions &LangOpts,
- const char *BufStart, const char *BufPtr, const char *BufEnd);
+ const char *BufStart, const char *BufPtr, const char *BufEnd,
+ bool IsFirstIncludeOfFile = true);
/// Lexer constructor - Create a new raw lexer object. This object is only
/// suitable for calls to 'LexFromRawLexer'. This lexer assumes that the
/// text range will outlive it, so it doesn't take ownership of it.
Lexer(FileID FID, const llvm::MemoryBufferRef &FromFile,
- const SourceManager &SM, const LangOptions &LangOpts);
+ const SourceManager &SM, const LangOptions &LangOpts,
+ bool IsFirstIncludeOfFile = true);
Lexer(const Lexer &) = delete;
Lexer &operator=(const Lexer &) = delete;
@@ -167,21 +192,34 @@ public:
SourceLocation ExpansionLocEnd,
unsigned TokLen, Preprocessor &PP);
- /// getLangOpts - Return the language features currently enabled.
- /// NOTE: this lexer modifies features as a file is parsed!
- const LangOptions &getLangOpts() const { return LangOpts; }
-
/// getFileLoc - Return the File Location for the file we are lexing out of.
/// The physical location encodes the location where the characters come from,
/// the virtual location encodes where we should *claim* the characters came
/// from. Currently this is only used by _Pragma handling.
SourceLocation getFileLoc() const { return FileLoc; }
-private:
/// Lex - Return the next token in the file. If this is the end of file, it
/// return the tok::eof token. This implicitly involves the preprocessor.
bool Lex(Token &Result);
+private:
+ /// Called when the preprocessor is in 'dependency scanning lexing mode'.
+ bool LexDependencyDirectiveToken(Token &Result);
+
+ /// Called when the preprocessor is in 'dependency scanning lexing mode' and
+ /// is skipping a conditional block.
+ bool LexDependencyDirectiveTokenWhileSkipping(Token &Result);
+
+ /// True when the preprocessor is in 'dependency scanning lexing mode' and
+ /// created this \p Lexer for lexing a set of dependency directive tokens.
+ bool isDependencyDirectivesLexer() const { return !DepDirectives.empty(); }
+
+ /// Initializes \p Result with data from \p DDTok and advances \p BufferPtr to
+ /// the position just after the token.
+ /// \returns the buffer pointer at the beginning of the token.
+ const char *convertDependencyDirectiveToken(
+ const dependency_directives_scan::Token &DDTok, Token &Result);
+
public:
/// isPragmaLexer - Returns true if this Lexer is being used to lex a pragma.
bool isPragmaLexer() const { return Is_PragmaLexer; }
@@ -275,14 +313,8 @@ public:
return BufferPtr - BufferStart;
}
- /// Skip over \p NumBytes bytes.
- ///
- /// If the skip is successful, the next token will be lexed from the new
- /// offset. The lexer also assumes that we skipped to the start of the line.
- ///
- /// \returns true if the skip failed (new offset would have been past the
- /// end of the buffer), false otherwise.
- bool skipOver(unsigned NumBytes);
+ /// Set the lexer's buffer pointer to \p Offset.
+ void seek(unsigned Offset, bool IsAtStartOfLine);
/// Stringify - Convert the specified string into a C string by i) escaping
/// '\\' and " characters and ii) replacing newline character(s) with "\\n".
@@ -519,10 +551,10 @@ public:
/// Finds the token that comes right after the given location.
///
- /// Returns the next token, or none if the location is inside a macro.
- static Optional<Token> findNextToken(SourceLocation Loc,
- const SourceManager &SM,
- const LangOptions &LangOpts);
+ /// Returns the next token, or std::nullopt if the location is inside a macro.
+ static std::optional<Token> findNextToken(SourceLocation Loc,
+ const SourceManager &SM,
+ const LangOptions &LangOpts);
/// Checks that the given token is the first token that occurs after
/// the given location (this excludes comments and whitespace). Returns the
@@ -536,25 +568,30 @@ public:
bool SkipTrailingWhitespaceAndNewLine);
/// Returns true if the given character could appear in an identifier.
- static bool isIdentifierBodyChar(char c, const LangOptions &LangOpts);
+ static bool isAsciiIdentifierContinueChar(char c,
+ const LangOptions &LangOpts);
/// Checks whether new line pointed by Str is preceded by escape
/// sequence.
static bool isNewLineEscaped(const char *BufferStart, const char *Str);
+ /// Represents a char and the number of bytes parsed to produce it.
+ struct SizedChar {
+ char Char;
+ unsigned Size;
+ };
+
/// getCharAndSizeNoWarn - Like the getCharAndSize method, but does not ever
/// emit a warning.
- static inline char getCharAndSizeNoWarn(const char *Ptr, unsigned &Size,
- const LangOptions &LangOpts) {
+ static inline SizedChar getCharAndSizeNoWarn(const char *Ptr,
+ const LangOptions &LangOpts) {
// If this is not a trigraph and not a UCN or escaped newline, return
// quickly.
if (isObviouslySimpleCharacter(Ptr[0])) {
- Size = 1;
- return *Ptr;
+ return {*Ptr, 1u};
}
- Size = 0;
- return getCharAndSizeSlowNoWarn(Ptr, Size, LangOpts);
+ return getCharAndSizeSlowNoWarn(Ptr, LangOpts);
}
/// Returns the leading whitespace for line that corresponds to the given
@@ -562,6 +599,9 @@ public:
static StringRef getIndentationForLine(SourceLocation Loc,
const SourceManager &SM);
+ /// Check if this is the first time we're lexing the input file.
+ bool isFirstTimeLexingFile() const { return IsFirstTimeLexingFile; }
+
private:
//===--------------------------------------------------------------------===//
// Internal implementation interfaces.
@@ -573,10 +613,7 @@ private:
bool CheckUnicodeWhitespace(Token &Result, uint32_t C, const char *CurPtr);
- /// Given that a token begins with the Unicode character \p C, figure out
- /// what kind of token it is and dispatch to the appropriate lexing helper
- /// function.
- bool LexUnicode(Token &Result, uint32_t C, const char *CurPtr);
+ bool LexUnicodeIdentifierStart(Token &Result, uint32_t C, const char *CurPtr);
/// FormTokenWithChars - When we lex a token, we have identified a span
/// starting at BufferPtr, going to TokEnd that forms the token. This method
@@ -632,8 +669,7 @@ private:
// quickly.
if (isObviouslySimpleCharacter(Ptr[0])) return *Ptr++;
- unsigned Size = 0;
- char C = getCharAndSizeSlow(Ptr, Size, &Tok);
+ auto [C, Size] = getCharAndSizeSlow(Ptr, &Tok);
Ptr += Size;
return C;
}
@@ -649,9 +685,7 @@ private:
// Otherwise, re-lex the character with a current token, allowing
// diagnostics to be emitted and flags to be set.
- Size = 0;
- getCharAndSizeSlow(Ptr, Size, &Tok);
- return Ptr+Size;
+ return Ptr + getCharAndSizeSlow(Ptr, &Tok).Size;
}
/// getCharAndSize - Peek a single 'character' from the specified buffer,
@@ -666,14 +700,14 @@ private:
return *Ptr;
}
- Size = 0;
- return getCharAndSizeSlow(Ptr, Size);
+ auto CharAndSize = getCharAndSizeSlow(Ptr);
+ Size = CharAndSize.Size;
+ return CharAndSize.Char;
}
/// getCharAndSizeSlow - Handle the slow/uncommon case of the getCharAndSize
/// method.
- char getCharAndSizeSlow(const char *Ptr, unsigned &Size,
- Token *Tok = nullptr);
+ SizedChar getCharAndSizeSlow(const char *Ptr, Token *Tok = nullptr);
/// getEscapedNewLineSize - Return the size of the specified escaped newline,
/// or 0 if it is not an escaped newline. P[-1] is known to be a "\" on entry
@@ -687,8 +721,8 @@ private:
/// getCharAndSizeSlowNoWarn - Same as getCharAndSizeSlow, but never emits a
/// diagnostic.
- static char getCharAndSizeSlowNoWarn(const char *Ptr, unsigned &Size,
- const LangOptions &LangOpts);
+ static SizedChar getCharAndSizeSlowNoWarn(const char *Ptr,
+ const LangOptions &LangOpts);
//===--------------------------------------------------------------------===//
// Other lexer functions.
@@ -701,7 +735,11 @@ private:
bool IsStringLiteral);
// Helper functions to lex the remainder of a token of the specific type.
- bool LexIdentifier (Token &Result, const char *CurPtr);
+
+ // This function handles both ASCII and Unicode identifiers after
+ // the first codepoint of the identifyier has been parsed.
+ bool LexIdentifierContinue(Token &Result, const char *CurPtr);
+
bool LexNumericConstant (Token &Result, const char *CurPtr);
bool LexStringLiteral (Token &Result, const char *CurPtr,
tok::TokenKind Kind);
@@ -732,10 +770,15 @@ private:
void codeCompleteIncludedFile(const char *PathStart,
const char *CompletionPoint, bool IsAngled);
+ std::optional<uint32_t>
+ tryReadNumericUCN(const char *&StartPtr, const char *SlashLoc, Token *Result);
+ std::optional<uint32_t> tryReadNamedUCN(const char *&StartPtr,
+ const char *SlashLoc, Token *Result);
+
/// Read a universal character name.
///
/// \param StartPtr The position in the source buffer after the initial '\'.
- /// If the UCN is syntactically well-formed (but not
+ /// If the UCN is syntactically well-formed (but not
/// necessarily valid), this parameter will be updated to
/// point to the character after the UCN.
/// \param SlashLoc The position in the source buffer of the '\'.
@@ -763,9 +806,10 @@ private:
/// Try to consume an identifier character encoded in UTF-8.
/// \param CurPtr Points to the start of the (potential) UTF-8 code unit
/// sequence. On success, updated to point past the end of it.
+ /// \param Result The token being formed.
/// \return \c true if a UTF-8 sequence mapping to an acceptable identifier
/// character was lexed, \c false otherwise.
- bool tryConsumeIdentifierUTF8Char(const char *&CurPtr);
+ bool tryConsumeIdentifierUTF8Char(const char *&CurPtr, Token &Result);
};
} // namespace clang
diff --git a/contrib/llvm-project/clang/include/clang/Lex/LiteralSupport.h b/contrib/llvm-project/clang/include/clang/Lex/LiteralSupport.h
index f131f045a73e..643ddbdad8c8 100644
--- a/contrib/llvm-project/clang/include/clang/Lex/LiteralSupport.h
+++ b/contrib/llvm-project/clang/include/clang/Lex/LiteralSupport.h
@@ -36,6 +36,15 @@ class LangOptions;
/// Copy characters from Input to Buf, expanding any UCNs.
void expandUCNs(SmallVectorImpl<char> &Buf, StringRef Input);
+/// Return true if the token corresponds to a function local predefined macro,
+/// which expands to a string literal, that can be concatenated with other
+/// string literals (only in Microsoft mode).
+bool isFunctionLocalStringLiteralMacro(tok::TokenKind K, const LangOptions &LO);
+
+/// Return true if the token is a string literal, or a function local
+/// predefined macro, which expands to a string literal.
+bool tokenIsLikeStringLiteral(const Token &Tok, const LangOptions &LO);
+
/// NumericLiteralParser - This performs strict semantic analysis of the content
/// of a ppnumber, classifying it as either integer, floating, or erroneous,
/// determines the radix of the value and can convert it to a useful value.
@@ -63,16 +72,17 @@ public:
bool isUnsigned : 1;
bool isLong : 1; // This is *not* set for long long.
bool isLongLong : 1;
- bool isSizeT : 1; // 1z, 1uz (C++2b)
+ bool isSizeT : 1; // 1z, 1uz (C++23)
bool isHalf : 1; // 1.0h
bool isFloat : 1; // 1.0f
bool isImaginary : 1; // 1.0i
bool isFloat16 : 1; // 1.0f16
bool isFloat128 : 1; // 1.0q
- uint8_t MicrosoftInteger; // Microsoft suffix extension i8, i16, i32, or i64.
-
bool isFract : 1; // 1.0hr/r/lr/uhr/ur/ulr
bool isAccum : 1; // 1.0hk/k/lk/uhk/uk/ulk
+ bool isBitInt : 1; // 1wb, 1uwb (C23)
+ uint8_t MicrosoftInteger; // Microsoft suffix extension i8, i16, i32, or i64.
+
bool isFixedPointLiteral() const {
return (saw_period || saw_exponent) && saw_fixed_point_suffix;
@@ -120,6 +130,13 @@ public:
/// calculating the digit sequence of the exponent.
bool GetFixedPointValue(llvm::APInt &StoreVal, unsigned Scale);
+ /// Get the digits that comprise the literal. This excludes any prefix or
+ /// suffix associated with the literal.
+ StringRef getLiteralDigits() const {
+ assert(!hadError && "cannot reliably get the literal digits with an error");
+ return StringRef(DigitsBegin, SuffixBegin - DigitsBegin);
+ }
+
private:
void ParseNumberStartingWithZero(SourceLocation TokLoc);
@@ -190,7 +207,7 @@ public:
tok::TokenKind kind);
bool hadError() const { return HadError; }
- bool isAscii() const { return Kind == tok::char_constant; }
+ bool isOrdinary() const { return Kind == tok::char_constant; }
bool isWide() const { return Kind == tok::wide_char_constant; }
bool isUTF8() const { return Kind == tok::utf8_char_constant; }
bool isUTF16() const { return Kind == tok::utf16_char_constant; }
@@ -204,6 +221,11 @@ public:
}
};
+enum class StringLiteralEvalMethod {
+ Evaluated,
+ Unevaluated,
+};
+
/// StringLiteralParser - This decodes string escape characters and performs
/// wide string analysis and Translation Phase #6 (concatenation of string
/// literals) (C99 5.1.1.2p1).
@@ -222,20 +244,23 @@ class StringLiteralParser {
SmallString<32> UDSuffixBuf;
unsigned UDSuffixToken;
unsigned UDSuffixOffset;
+ StringLiteralEvalMethod EvalMethod;
+
public:
- StringLiteralParser(ArrayRef<Token> StringToks,
- Preprocessor &PP, bool Complain = true);
- StringLiteralParser(ArrayRef<Token> StringToks,
- const SourceManager &sm, const LangOptions &features,
- const TargetInfo &target,
+ StringLiteralParser(ArrayRef<Token> StringToks, Preprocessor &PP,
+ StringLiteralEvalMethod StringMethod =
+ StringLiteralEvalMethod::Evaluated);
+ StringLiteralParser(ArrayRef<Token> StringToks, const SourceManager &sm,
+ const LangOptions &features, const TargetInfo &target,
DiagnosticsEngine *diags = nullptr)
- : SM(sm), Features(features), Target(target), Diags(diags),
- MaxTokenLength(0), SizeBound(0), CharByteWidth(0), Kind(tok::unknown),
- ResultPtr(ResultBuf.data()), hadError(false), Pascal(false) {
+ : SM(sm), Features(features), Target(target), Diags(diags),
+ MaxTokenLength(0), SizeBound(0), CharByteWidth(0), Kind(tok::unknown),
+ ResultPtr(ResultBuf.data()),
+ EvalMethod(StringLiteralEvalMethod::Evaluated), hadError(false),
+ Pascal(false) {
init(StringToks);
}
-
bool hadError;
bool Pascal;
@@ -255,12 +280,15 @@ public:
/// checking of the string literal and emit errors and warnings.
unsigned getOffsetOfStringByte(const Token &TheTok, unsigned ByteNo) const;
- bool isAscii() const { return Kind == tok::string_literal; }
+ bool isOrdinary() const { return Kind == tok::string_literal; }
bool isWide() const { return Kind == tok::wide_string_literal; }
bool isUTF8() const { return Kind == tok::utf8_string_literal; }
bool isUTF16() const { return Kind == tok::utf16_string_literal; }
bool isUTF32() const { return Kind == tok::utf32_string_literal; }
bool isPascal() const { return Pascal; }
+ bool isUnevaluated() const {
+ return EvalMethod == StringLiteralEvalMethod::Unevaluated;
+ }
StringRef getUDSuffix() const { return UDSuffixBuf; }
diff --git a/contrib/llvm-project/clang/include/clang/Lex/MacroInfo.h b/contrib/llvm-project/clang/include/clang/Lex/MacroInfo.h
index 0347a7a37186..1237fc62eb6c 100644
--- a/contrib/llvm-project/clang/include/clang/Lex/MacroInfo.h
+++ b/contrib/llvm-project/clang/include/clang/Lex/MacroInfo.h
@@ -54,11 +54,14 @@ class MacroInfo {
/// macro, this includes the \c __VA_ARGS__ identifier on the list.
IdentifierInfo **ParameterList = nullptr;
+ /// This is the list of tokens that the macro is defined to.
+ const Token *ReplacementTokens = nullptr;
+
/// \see ParameterList
unsigned NumParameters = 0;
- /// This is the list of tokens that the macro is defined to.
- SmallVector<Token, 8> ReplacementTokens;
+ /// \see ReplacementTokens
+ unsigned NumReplacementTokens = 0;
/// Length in characters of the macro definition.
mutable unsigned DefinitionLength;
@@ -114,9 +117,8 @@ class MacroInfo {
/// Whether this macro was used as header guard.
bool UsedForHeaderGuard : 1;
- // Only the Preprocessor gets to create and destroy these.
+ // Only the Preprocessor gets to create these.
MacroInfo(SourceLocation DefLoc);
- ~MacroInfo() = default;
public:
/// Return the location that the macro was defined at.
@@ -204,7 +206,7 @@ public:
void setIsGNUVarargs() { IsGNUVarargs = true; }
bool isC99Varargs() const { return IsC99Varargs; }
bool isGNUVarargs() const { return IsGNUVarargs; }
- bool isVariadic() const { return IsC99Varargs | IsGNUVarargs; }
+ bool isVariadic() const { return IsC99Varargs || IsGNUVarargs; }
/// Return true if this macro requires processing before expansion.
///
@@ -230,26 +232,47 @@ public:
bool isWarnIfUnused() const { return IsWarnIfUnused; }
/// Return the number of tokens that this macro expands to.
- unsigned getNumTokens() const { return ReplacementTokens.size(); }
+ unsigned getNumTokens() const { return NumReplacementTokens; }
const Token &getReplacementToken(unsigned Tok) const {
- assert(Tok < ReplacementTokens.size() && "Invalid token #");
+ assert(Tok < NumReplacementTokens && "Invalid token #");
return ReplacementTokens[Tok];
}
- using tokens_iterator = SmallVectorImpl<Token>::const_iterator;
+ using const_tokens_iterator = const Token *;
- tokens_iterator tokens_begin() const { return ReplacementTokens.begin(); }
- tokens_iterator tokens_end() const { return ReplacementTokens.end(); }
- bool tokens_empty() const { return ReplacementTokens.empty(); }
- ArrayRef<Token> tokens() const { return ReplacementTokens; }
+ const_tokens_iterator tokens_begin() const { return ReplacementTokens; }
+ const_tokens_iterator tokens_end() const {
+ return ReplacementTokens + NumReplacementTokens;
+ }
+ bool tokens_empty() const { return NumReplacementTokens == 0; }
+ ArrayRef<Token> tokens() const {
+ return llvm::ArrayRef(ReplacementTokens, NumReplacementTokens);
+ }
- /// Add the specified token to the replacement text for the macro.
- void AddTokenToBody(const Token &Tok) {
+ llvm::MutableArrayRef<Token>
+ allocateTokens(unsigned NumTokens, llvm::BumpPtrAllocator &PPAllocator) {
+ assert(ReplacementTokens == nullptr && NumReplacementTokens == 0 &&
+ "Token list already allocated!");
+ NumReplacementTokens = NumTokens;
+ Token *NewReplacementTokens = PPAllocator.Allocate<Token>(NumTokens);
+ ReplacementTokens = NewReplacementTokens;
+ return llvm::MutableArrayRef(NewReplacementTokens, NumTokens);
+ }
+
+ void setTokens(ArrayRef<Token> Tokens, llvm::BumpPtrAllocator &PPAllocator) {
assert(
!IsDefinitionLengthCached &&
"Changing replacement tokens after definition length got calculated");
- ReplacementTokens.push_back(Tok);
+ assert(ReplacementTokens == nullptr && NumReplacementTokens == 0 &&
+ "Token list already set!");
+ if (Tokens.empty())
+ return;
+
+ NumReplacementTokens = Tokens.size();
+ Token *NewReplacementTokens = PPAllocator.Allocate<Token>(Tokens.size());
+ std::copy(Tokens.begin(), Tokens.end(), NewReplacementTokens);
+ ReplacementTokens = NewReplacementTokens;
}
/// Return true if this macro is enabled.
@@ -302,15 +325,18 @@ protected:
SourceLocation Loc;
/// MacroDirective kind.
+ LLVM_PREFERRED_TYPE(Kind)
unsigned MDKind : 2;
/// True if the macro directive was loaded from a PCH file.
+ LLVM_PREFERRED_TYPE(bool)
unsigned IsFromPCH : 1;
// Used by VisibilityMacroDirective ----------------------------------------//
/// Whether the macro has public visibility (when described in a
/// module).
+ LLVM_PREFERRED_TYPE(bool)
unsigned IsPublic : 1;
MacroDirective(Kind K, SourceLocation Loc)
@@ -549,7 +575,7 @@ public:
}
ArrayRef<ModuleMacro *> overrides() const {
- return llvm::makeArrayRef(overrides_begin(), overrides_end());
+ return llvm::ArrayRef(overrides_begin(), overrides_end());
}
/// \}
diff --git a/contrib/llvm-project/clang/include/clang/Lex/ModuleLoader.h b/contrib/llvm-project/clang/include/clang/Lex/ModuleLoader.h
index bf044e0e5f50..f880a9091a2e 100644
--- a/contrib/llvm-project/clang/include/clang/Lex/ModuleLoader.h
+++ b/contrib/llvm-project/clang/include/clang/Lex/ModuleLoader.h
@@ -51,6 +51,11 @@ public:
ModuleLoadResult() = default;
ModuleLoadResult(Module *M) : Storage(M, Normal) {}
ModuleLoadResult(LoadResultKind Kind) : Storage(nullptr, Kind) {}
+ ModuleLoadResult(Module *M, LoadResultKind Kind) : Storage(M, Kind) {}
+
+ operator bool() const {
+ return Storage.getInt() == Normal && Storage.getPointer();
+ }
operator Module *() const { return Storage.getPointer(); }
diff --git a/contrib/llvm-project/clang/include/clang/Lex/ModuleMap.h b/contrib/llvm-project/clang/include/clang/Lex/ModuleMap.h
index 41f85a1f572d..867cb6eab42f 100644
--- a/contrib/llvm-project/clang/include/clang/Lex/ModuleMap.h
+++ b/contrib/llvm-project/clang/include/clang/Lex/ModuleMap.h
@@ -20,8 +20,8 @@
#include "clang/Basic/SourceLocation.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/PointerIntPair.h"
-#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
@@ -30,6 +30,7 @@
#include "llvm/ADT/Twine.h"
#include <ctime>
#include <memory>
+#include <optional>
#include <string>
#include <utility>
@@ -56,8 +57,8 @@ public:
/// contents.
/// \param File The file itself.
/// \param IsSystem Whether this is a module map from a system include path.
- virtual void moduleMapFileRead(SourceLocation FileStart,
- const FileEntry &File, bool IsSystem) {}
+ virtual void moduleMapFileRead(SourceLocation FileStart, FileEntryRef File,
+ bool IsSystem) {}
/// Called when a header is added during module map parsing.
///
@@ -66,10 +67,8 @@ public:
/// Called when an umbrella header is added during module map parsing.
///
- /// \param FileMgr FileManager instance
/// \param Header The umbrella header to collect.
- virtual void moduleMapAddUmbrellaHeader(FileManager *FileMgr,
- const FileEntry *Header) {}
+ virtual void moduleMapAddUmbrellaHeader(FileEntryRef Header) {}
};
class ModuleMap {
@@ -83,7 +82,7 @@ class ModuleMap {
/// The directory used for Clang-supplied, builtin include headers,
/// such as "stdint.h".
- const DirectoryEntry *BuiltinIncludeDir = nullptr;
+ OptionalDirectoryEntryRef BuiltinIncludeDir;
/// Language options used to parse the module map itself.
///
@@ -136,9 +135,11 @@ public:
/// should be textually included.
TextualHeader = 0x2,
+ /// This header is explicitly excluded from the module.
+ ExcludedHeader = 0x4,
+
// Caution: Adding an enumerator needs other changes.
// Adjust the number of bits for KnownHeader::Storage.
- // Adjust the bitfield HeaderFileInfo::HeaderRole size.
// Adjust the HeaderFileInfoTrait::ReadData streaming.
// Adjust the HeaderFileInfoTrait::EmitData streaming.
// Adjust ModuleMap::addHeader.
@@ -150,10 +151,13 @@ public:
/// Convert a header role to a kind.
static Module::HeaderKind headerRoleToKind(ModuleHeaderRole Role);
+ /// Check if the header with the given role is a modular one.
+ static bool isModular(ModuleHeaderRole Role);
+
/// A header that is known to reside within a given module,
/// whether it was included or excluded.
class KnownHeader {
- llvm::PointerIntPair<Module *, 2, ModuleHeaderRole> Storage;
+ llvm::PointerIntPair<Module *, 3, ModuleHeaderRole> Storage;
public:
KnownHeader() : Storage(nullptr, NormalHeader) {}
@@ -174,7 +178,7 @@ public:
/// Whether this header is available in the module.
bool isAvailable() const {
- return getModule()->isAvailable();
+ return getRole() != ExcludedHeader && getModule()->isAvailable();
}
/// Whether this header is accessible from the specified module.
@@ -190,13 +194,12 @@ public:
}
};
- using AdditionalModMapsSet = llvm::SmallPtrSet<const FileEntry *, 1>;
+ using AdditionalModMapsSet = llvm::DenseSet<FileEntryRef>;
private:
friend class ModuleMapParser;
- using HeadersMap =
- llvm::DenseMap<const FileEntry *, SmallVector<KnownHeader, 1>>;
+ using HeadersMap = llvm::DenseMap<FileEntryRef, SmallVector<KnownHeader, 1>>;
/// Mapping from each header to the module that owns the contents of
/// that header.
@@ -229,16 +232,20 @@ private:
/// The set of attributes that can be attached to a module.
struct Attributes {
/// Whether this is a system module.
+ LLVM_PREFERRED_TYPE(bool)
unsigned IsSystem : 1;
/// Whether this is an extern "C" module.
+ LLVM_PREFERRED_TYPE(bool)
unsigned IsExternC : 1;
/// Whether this is an exhaustive set of configuration macros.
+ LLVM_PREFERRED_TYPE(bool)
unsigned IsExhaustive : 1;
/// Whether files in this module can only include non-modular headers
/// and headers from used modules.
+ LLVM_PREFERRED_TYPE(bool)
unsigned NoUndeclaredIncludes : 1;
Attributes()
@@ -249,14 +256,15 @@ private:
/// A directory for which framework modules can be inferred.
struct InferredDirectory {
/// Whether to infer modules from this directory.
+ LLVM_PREFERRED_TYPE(bool)
unsigned InferModules : 1;
/// The attributes to use for inferred modules.
Attributes Attrs;
/// If \c InferModules is non-zero, the module map file that allowed
- /// inferred modules. Otherwise, nullptr.
- const FileEntry *ModuleMapFile;
+ /// inferred modules. Otherwise, nullopt.
+ OptionalFileEntryRef ModuleMapFile;
/// The names of modules that cannot be inferred within this
/// directory.
@@ -271,7 +279,8 @@ private:
/// A mapping from an inferred module to the module map that allowed the
/// inference.
- llvm::DenseMap<const Module *, const FileEntry *> InferredModuleAllowedBy;
+ // FIXME: Consider making the values non-optional.
+ llvm::DenseMap<const Module *, OptionalFileEntryRef> InferredModuleAllowedBy;
llvm::DenseMap<const Module *, AdditionalModMapsSet> AdditionalModMaps;
@@ -328,7 +337,7 @@ private:
/// \param NeedsFramework If M is not a framework but a missing header would
/// be found in case M was, set it to true. False otherwise.
/// \return The resolved file, if any.
- Optional<FileEntryRef>
+ OptionalFileEntryRef
findHeader(Module *M, const Module::UnresolvedHeaderDirective &Header,
SmallVectorImpl<char> &RelativePathName, bool &NeedsFramework);
@@ -352,7 +361,7 @@ private:
/// If \p File represents a builtin header within Clang's builtin include
/// directory, this also loads all of the module maps to see if it will get
/// associated with a specific module (e.g. in /usr/include).
- HeadersMap::iterator findKnownHeader(const FileEntry *File);
+ HeadersMap::iterator findKnownHeader(FileEntryRef File);
/// Searches for a module whose umbrella directory contains \p File.
///
@@ -360,22 +369,22 @@ private:
///
/// \param IntermediateDirs On success, contains the set of directories
/// searched before finding \p File.
- KnownHeader findHeaderInUmbrellaDirs(const FileEntry *File,
- SmallVectorImpl<const DirectoryEntry *> &IntermediateDirs);
+ KnownHeader findHeaderInUmbrellaDirs(
+ FileEntryRef File, SmallVectorImpl<DirectoryEntryRef> &IntermediateDirs);
/// Given that \p File is not in the Headers map, look it up within
/// umbrella directories and find or create a module for it.
- KnownHeader findOrCreateModuleForHeaderInUmbrellaDir(const FileEntry *File);
+ KnownHeader findOrCreateModuleForHeaderInUmbrellaDir(FileEntryRef File);
/// A convenience method to determine if \p File is (possibly nested)
/// in an umbrella directory.
- bool isHeaderInUmbrellaDirs(const FileEntry *File) {
- SmallVector<const DirectoryEntry *, 2> IntermediateDirs;
+ bool isHeaderInUmbrellaDirs(FileEntryRef File) {
+ SmallVector<DirectoryEntryRef, 2> IntermediateDirs;
return static_cast<bool>(findHeaderInUmbrellaDirs(File, IntermediateDirs));
}
- Module *inferFrameworkModule(const DirectoryEntry *FrameworkDir,
- Attributes Attrs, Module *Parent);
+ Module *inferFrameworkModule(DirectoryEntryRef FrameworkDir, Attributes Attrs,
+ Module *Parent);
public:
/// Construct a new module map.
@@ -399,20 +408,18 @@ public:
/// Set the target information.
void setTarget(const TargetInfo &Target);
- /// Set the directory that contains Clang-supplied include
- /// files, such as our stdarg.h or tgmath.h.
- void setBuiltinIncludeDir(const DirectoryEntry *Dir) {
- BuiltinIncludeDir = Dir;
- }
+ /// Set the directory that contains Clang-supplied include files, such as our
+ /// stdarg.h or tgmath.h.
+ void setBuiltinIncludeDir(DirectoryEntryRef Dir) { BuiltinIncludeDir = Dir; }
/// Get the directory that contains Clang-supplied include files.
- const DirectoryEntry *getBuiltinDir() const {
- return BuiltinIncludeDir;
- }
+ OptionalDirectoryEntryRef getBuiltinDir() const { return BuiltinIncludeDir; }
/// Is this a compiler builtin header?
- static bool isBuiltinHeader(StringRef FileName);
- bool isBuiltinHeader(const FileEntry *File);
+ bool isBuiltinHeader(FileEntryRef File);
+
+ bool shouldImportRelativeToBuiltinIncludeDir(StringRef FileName,
+ Module *Module) const;
/// Add a module map callback.
void addModuleMapCallbacks(std::unique_ptr<ModuleMapCallbacks> Callback) {
@@ -433,8 +440,8 @@ public:
/// \returns The module KnownHeader, which provides the module that owns the
/// given header file. The KnownHeader is default constructed to indicate
/// that no module owns this header file.
- KnownHeader findModuleForHeader(const FileEntry *File,
- bool AllowTextual = false);
+ KnownHeader findModuleForHeader(FileEntryRef File, bool AllowTextual = false,
+ bool AllowExcluded = false);
/// Retrieve all the modules that contain the given header file. Note that
/// this does not implicitly load module maps, except for builtin headers,
@@ -443,12 +450,11 @@ public:
///
/// Typically, \ref findModuleForHeader should be used instead, as it picks
/// the preferred module for the header.
- ArrayRef<KnownHeader> findAllModulesForHeader(const FileEntry *File);
+ ArrayRef<KnownHeader> findAllModulesForHeader(FileEntryRef File);
/// Like \ref findAllModulesForHeader, but do not attempt to infer module
/// ownership from umbrella headers if we've not already done so.
- ArrayRef<KnownHeader>
- findResolvedModulesForHeader(const FileEntry *File) const;
+ ArrayRef<KnownHeader> findResolvedModulesForHeader(FileEntryRef File) const;
/// Resolve all lazy header directives for the specified file.
///
@@ -456,8 +462,11 @@ public:
/// is effectively internal, but is exposed so HeaderSearch can call it.
void resolveHeaderDirectives(const FileEntry *File) const;
- /// Resolve all lazy header directives for the specified module.
- void resolveHeaderDirectives(Module *Mod) const;
+ /// Resolve lazy header directives for the specified module. If File is
+ /// provided, only headers with same size and modtime are resolved. If File
+ /// is not set, all headers are resolved.
+ void resolveHeaderDirectives(Module *Mod,
+ std::optional<const FileEntry *> File) const;
/// Reports errors if a module must not include a specific file.
///
@@ -476,15 +485,15 @@ public:
void diagnoseHeaderInclusion(Module *RequestingModule,
bool RequestingModuleIsModuleInterface,
SourceLocation FilenameLoc, StringRef Filename,
- const FileEntry *File);
+ FileEntryRef File);
/// Determine whether the given header is part of a module
/// marked 'unavailable'.
- bool isHeaderInUnavailableModule(const FileEntry *Header) const;
+ bool isHeaderInUnavailableModule(FileEntryRef Header) const;
/// Determine whether the given header is unavailable as part
/// of the specified module.
- bool isHeaderUnavailableInModule(const FileEntry *Header,
+ bool isHeaderUnavailableInModule(FileEntryRef Header,
const Module *RequestingModule) const;
/// Retrieve a module with the given name.
@@ -538,13 +547,23 @@ public:
///
/// We model the global module fragment as a submodule of the module
/// interface unit. Unfortunately, we can't create the module interface
- /// unit's Module until later, because we don't know what it will be called.
- Module *createGlobalModuleFragmentForModuleUnit(SourceLocation Loc);
+ /// unit's Module until later, because we don't know what it will be called
+ /// usually. See C++20 [module.unit]/7.2 for the case we could know its
+ /// parent.
+ Module *createGlobalModuleFragmentForModuleUnit(SourceLocation Loc,
+ Module *Parent = nullptr);
+ Module *createImplicitGlobalModuleFragmentForModuleUnit(SourceLocation Loc,
+ Module *Parent);
/// Create a global module fragment for a C++ module interface unit.
Module *createPrivateModuleFragmentForInterfaceUnit(Module *Parent,
SourceLocation Loc);
+ /// Create a new C++ module with the specified kind, and reparent any pending
+ /// global module fragment(s) to it.
+ Module *createModuleUnitWithKind(SourceLocation Loc, StringRef Name,
+ Module::ModuleKind Kind);
+
/// Create a new module for a C++ module interface unit.
/// The module must not already exist, and will be configured for the current
/// compilation.
@@ -552,16 +571,23 @@ public:
/// Note that this also sets the current module to the newly-created module.
///
/// \returns The newly-created module.
- Module *createModuleForInterfaceUnit(SourceLocation Loc, StringRef Name,
- Module *GlobalModule);
+ Module *createModuleForInterfaceUnit(SourceLocation Loc, StringRef Name);
- /// Create a header module from the specified list of headers.
- Module *createHeaderModule(StringRef Name, ArrayRef<Module::Header> Headers);
+ /// Create a new module for a C++ module implementation unit.
+ /// The interface module for this implementation (implicitly imported) must
+ /// exist and be loaded and present in the modules map.
+ ///
+ /// \returns The newly-created module.
+ Module *createModuleForImplementationUnit(SourceLocation Loc, StringRef Name);
+
+ /// Create a C++20 header unit.
+ Module *createHeaderUnit(SourceLocation Loc, StringRef Name,
+ Module::Header H);
/// Infer the contents of a framework module map from the given
/// framework directory.
- Module *inferFrameworkModule(const DirectoryEntry *FrameworkDir,
- bool IsSystem, Module *Parent);
+ Module *inferFrameworkModule(DirectoryEntryRef FrameworkDir, bool IsSystem,
+ Module *Parent);
/// Create a new top-level module that is shadowed by
/// \p ShadowingModule.
@@ -581,6 +607,12 @@ public:
return ModuleScopeIDs[ExistingModule] < CurrentModuleScopeID;
}
+ /// Check whether a framework module can be inferred in the given directory.
+ bool canInferFrameworkModule(const DirectoryEntry *Dir) const {
+ auto It = InferredDirectories.find(Dir);
+ return It != InferredDirectories.end() && It->getSecond().InferModules;
+ }
+
/// Retrieve the module map file containing the definition of the given
/// module.
///
@@ -588,7 +620,7 @@ public:
///
/// \returns The file entry for the module map file containing the given
/// module, or nullptr if the module definition was inferred.
- const FileEntry *getContainingModuleMapFile(const Module *Module) const;
+ OptionalFileEntryRef getContainingModuleMapFile(const Module *Module) const;
/// Get the module map file that (along with the module name) uniquely
/// identifies this module.
@@ -599,9 +631,18 @@ public:
/// of inferred modules, returns the module map that allowed the inference
/// (e.g. contained 'module *'). Otherwise, returns
/// getContainingModuleMapFile().
- const FileEntry *getModuleMapFileForUniquing(const Module *M) const;
+ OptionalFileEntryRef getModuleMapFileForUniquing(const Module *M) const;
- void setInferredModuleAllowedBy(Module *M, const FileEntry *ModMap);
+ void setInferredModuleAllowedBy(Module *M, OptionalFileEntryRef ModMap);
+
+ /// Canonicalize \p Path in a manner suitable for a module map file. In
+ /// particular, this canonicalizes the parent directory separately from the
+ /// filename so that it does not affect header resolution relative to the
+ /// modulemap.
+ ///
+ /// \returns an error code if any filesystem operations failed. In this case
+ /// \p Path is not modified.
+ std::error_code canonicalizeModuleMapPath(SmallVectorImpl<char> &Path);
/// Get any module map files other than getModuleMapFileForUniquing(M)
/// that define submodules of a top-level module \p M. This is cheaper than
@@ -614,7 +655,7 @@ public:
return &I->second;
}
- void addAdditionalModuleMapFile(const Module *M, const FileEntry *ModuleMap);
+ void addAdditionalModuleMapFile(const Module *M, FileEntryRef ModuleMap);
/// Resolve all of the unresolved exports in the given module.
///
@@ -646,26 +687,22 @@ public:
/// false otherwise.
bool resolveConflicts(Module *Mod, bool Complain);
- /// Sets the umbrella header of the given module to the given
- /// header.
- void setUmbrellaHeader(Module *Mod, const FileEntry *UmbrellaHeader,
- const Twine &NameAsWritten,
- const Twine &PathRelativeToRootModuleDirectory);
+ /// Sets the umbrella header of the given module to the given header.
+ void
+ setUmbrellaHeaderAsWritten(Module *Mod, FileEntryRef UmbrellaHeader,
+ const Twine &NameAsWritten,
+ const Twine &PathRelativeToRootModuleDirectory);
- /// Sets the umbrella directory of the given module to the given
- /// directory.
- void setUmbrellaDir(Module *Mod, const DirectoryEntry *UmbrellaDir,
- const Twine &NameAsWritten,
- const Twine &PathRelativeToRootModuleDirectory);
+ /// Sets the umbrella directory of the given module to the given directory.
+ void setUmbrellaDirAsWritten(Module *Mod, DirectoryEntryRef UmbrellaDir,
+ const Twine &NameAsWritten,
+ const Twine &PathRelativeToRootModuleDirectory);
/// Adds this header to the given module.
/// \param Role The role of the header wrt the module.
void addHeader(Module *Mod, Module::Header Header,
ModuleHeaderRole Role, bool Imported = false);
- /// Marks this header as being excluded from the given module.
- void excludeHeader(Module *Mod, Module::Header Header);
-
/// Parse the given module map file, and record any modules we
/// encounter.
///
@@ -686,9 +723,9 @@ public:
/// that caused us to load this module map file, if any.
///
/// \returns true if an error occurred, false otherwise.
- bool parseModuleMapFile(const FileEntry *File, bool IsSystem,
- const DirectoryEntry *HomeDir,
- FileID ID = FileID(), unsigned *Offset = nullptr,
+ bool parseModuleMapFile(FileEntryRef File, bool IsSystem,
+ DirectoryEntryRef HomeDir, FileID ID = FileID(),
+ unsigned *Offset = nullptr,
SourceLocation ExternModuleLoc = SourceLocation());
/// Dump the contents of the module map, for debugging purposes.
@@ -708,10 +745,10 @@ public:
}
/// Return a cached module load.
- llvm::Optional<Module *> getCachedModuleLoad(const IdentifierInfo &II) {
+ std::optional<Module *> getCachedModuleLoad(const IdentifierInfo &II) {
auto I = CachedModuleLoads.find(&II);
if (I == CachedModuleLoads.end())
- return None;
+ return std::nullopt;
return I->second;
}
};
diff --git a/contrib/llvm-project/clang/include/clang/Lex/MultipleIncludeOpt.h b/contrib/llvm-project/clang/include/clang/Lex/MultipleIncludeOpt.h
index 7ceb7e53c75d..8e570226c4b2 100644
--- a/contrib/llvm-project/clang/include/clang/Lex/MultipleIncludeOpt.h
+++ b/contrib/llvm-project/clang/include/clang/Lex/MultipleIncludeOpt.h
@@ -108,6 +108,12 @@ public:
ImmediatelyAfterTopLevelIfndef = false;
}
+ /// SetReadToken - Set whether the value of 'ReadAnyTokens'. Called to
+ /// override when encountering tokens outside of the include guard that have
+ /// no effect if the file in question is is included multiple times (e.g. the
+ /// null directive).
+ void SetReadToken(bool Value) { ReadAnyTokens = Value; }
+
/// ExpandedMacro - When a macro is expanded with this lexer as the current
/// buffer, this method is called to disable the MIOpt if needed.
void ExpandedMacro() { DidMacroExpansion = true; }
diff --git a/contrib/llvm-project/clang/include/clang/Lex/PPCallbacks.h b/contrib/llvm-project/clang/include/clang/Lex/PPCallbacks.h
index bcf49c577735..e3942af7be28 100644
--- a/contrib/llvm-project/clang/include/clang/Lex/PPCallbacks.h
+++ b/contrib/llvm-project/clang/include/clang/Lex/PPCallbacks.h
@@ -22,11 +22,11 @@
#include "llvm/ADT/StringRef.h"
namespace clang {
- class Token;
- class IdentifierInfo;
- class MacroDefinition;
- class MacroDirective;
- class MacroArgs;
+class Token;
+class IdentifierInfo;
+class MacroDefinition;
+class MacroDirective;
+class MacroArgs;
/// This interface provides a way to observe the actions of the
/// preprocessor as it does its thing.
@@ -43,12 +43,34 @@ public:
/// Callback invoked whenever a source file is entered or exited.
///
/// \param Loc Indicates the new location.
- /// \param PrevFID the file that was exited if \p Reason is ExitFile.
+ /// \param PrevFID the file that was exited if \p Reason is ExitFile or the
+ /// the file before the new one entered for \p Reason EnterFile.
virtual void FileChanged(SourceLocation Loc, FileChangeReason Reason,
SrcMgr::CharacteristicKind FileType,
FileID PrevFID = FileID()) {
}
+ enum class LexedFileChangeReason { EnterFile, ExitFile };
+
+ /// Callback invoked whenever the \p Lexer moves to a different file for
+ /// lexing. Unlike \p FileChanged line number directives and other related
+ /// pragmas do not trigger callbacks to \p LexedFileChanged.
+ ///
+ /// \param FID The \p FileID that the \p Lexer moved to.
+ ///
+ /// \param Reason Whether the \p Lexer entered a new file or exited one.
+ ///
+ /// \param FileType The \p CharacteristicKind of the file the \p Lexer moved
+ /// to.
+ ///
+ /// \param PrevFID The \p FileID the \p Lexer was using before the change.
+ ///
+ /// \param Loc The location where the \p Lexer entered a new file from or the
+ /// location that the \p Lexer moved into after exiting a file.
+ virtual void LexedFileChanged(FileID FID, LexedFileChangeReason Reason,
+ SrcMgr::CharacteristicKind FileType,
+ FileID PrevFID, SourceLocation Loc) {}
+
/// Callback invoked whenever a source file is skipped as the result
/// of header guard optimization.
///
@@ -61,22 +83,15 @@ public:
const Token &FilenameTok,
SrcMgr::CharacteristicKind FileType) {}
- /// Callback invoked whenever an inclusion directive results in a
- /// file-not-found error.
+ /// Callback invoked whenever the preprocessor cannot find a file for an
+ /// inclusion directive.
///
/// \param FileName The name of the file being included, as written in the
/// source code.
///
- /// \param RecoveryPath If this client indicates that it can recover from
- /// this missing file, the client should set this as an additional header
- /// search patch.
- ///
- /// \returns true to indicate that the preprocessor should attempt to recover
- /// by adding \p RecoveryPath as a header search path.
- virtual bool FileNotFound(StringRef FileName,
- SmallVectorImpl<char> &RecoveryPath) {
- return false;
- }
+ /// \returns true to indicate that the preprocessor should skip this file
+ /// and not issue any diagnostic.
+ virtual bool FileNotFound(StringRef FileName) { return false; }
/// Callback invoked whenever an inclusion directive of
/// any kind (\c \#include, \c \#import, etc.) has been processed, regardless
@@ -120,16 +135,12 @@ public:
/// implicitly 'extern "C"' in C++ mode.
///
virtual void InclusionDirective(SourceLocation HashLoc,
- const Token &IncludeTok,
- StringRef FileName,
- bool IsAngled,
- CharSourceRange FilenameRange,
- const FileEntry *File,
- StringRef SearchPath,
- StringRef RelativePath,
+ const Token &IncludeTok, StringRef FileName,
+ bool IsAngled, CharSourceRange FilenameRange,
+ OptionalFileEntryRef File,
+ StringRef SearchPath, StringRef RelativePath,
const Module *Imported,
- SrcMgr::CharacteristicKind FileType) {
- }
+ SrcMgr::CharacteristicKind FileType) {}
/// Callback invoked whenever a submodule was entered.
///
@@ -252,9 +263,20 @@ public:
}
/// Callback invoked when a \#pragma warning directive is read.
- virtual void PragmaWarning(SourceLocation Loc, StringRef WarningSpec,
- ArrayRef<int> Ids) {
- }
+ enum PragmaWarningSpecifier {
+ PWS_Default,
+ PWS_Disable,
+ PWS_Error,
+ PWS_Once,
+ PWS_Suppress,
+ PWS_Level1,
+ PWS_Level2,
+ PWS_Level3,
+ PWS_Level4,
+ };
+ virtual void PragmaWarning(SourceLocation Loc,
+ PragmaWarningSpecifier WarningSpec,
+ ArrayRef<int> Ids) {}
/// Callback invoked when a \#pragma warning(push) directive is read.
virtual void PragmaWarningPush(SourceLocation Loc, int Level) {
@@ -311,7 +333,7 @@ public:
/// Hook called when a '__has_include' or '__has_include_next' directive is
/// read.
virtual void HasInclude(SourceLocation Loc, StringRef FileName, bool IsAngled,
- Optional<FileEntryRef> File,
+ OptionalFileEntryRef File,
SrcMgr::CharacteristicKind FileType);
/// Hook called when a source range is skipped.
@@ -426,23 +448,32 @@ public:
Second->FileChanged(Loc, Reason, FileType, PrevFID);
}
+ void LexedFileChanged(FileID FID, LexedFileChangeReason Reason,
+ SrcMgr::CharacteristicKind FileType, FileID PrevFID,
+ SourceLocation Loc) override {
+ First->LexedFileChanged(FID, Reason, FileType, PrevFID, Loc);
+ Second->LexedFileChanged(FID, Reason, FileType, PrevFID, Loc);
+ }
+
void FileSkipped(const FileEntryRef &SkippedFile, const Token &FilenameTok,
SrcMgr::CharacteristicKind FileType) override {
First->FileSkipped(SkippedFile, FilenameTok, FileType);
Second->FileSkipped(SkippedFile, FilenameTok, FileType);
}
- bool FileNotFound(StringRef FileName,
- SmallVectorImpl<char> &RecoveryPath) override {
- return First->FileNotFound(FileName, RecoveryPath) ||
- Second->FileNotFound(FileName, RecoveryPath);
+ bool FileNotFound(StringRef FileName) override {
+ bool Skip = First->FileNotFound(FileName);
+ // Make sure to invoke the second callback, no matter if the first already
+ // returned true to skip the file.
+ Skip |= Second->FileNotFound(FileName);
+ return Skip;
}
void InclusionDirective(SourceLocation HashLoc, const Token &IncludeTok,
StringRef FileName, bool IsAngled,
- CharSourceRange FilenameRange, const FileEntry *File,
- StringRef SearchPath, StringRef RelativePath,
- const Module *Imported,
+ CharSourceRange FilenameRange,
+ OptionalFileEntryRef File, StringRef SearchPath,
+ StringRef RelativePath, const Module *Imported,
SrcMgr::CharacteristicKind FileType) override {
First->InclusionDirective(HashLoc, IncludeTok, FileName, IsAngled,
FilenameRange, File, SearchPath, RelativePath,
@@ -492,6 +523,11 @@ public:
Second->PragmaComment(Loc, Kind, Str);
}
+ void PragmaMark(SourceLocation Loc, StringRef Trivia) override {
+ First->PragmaMark(Loc, Trivia);
+ Second->PragmaMark(Loc, Trivia);
+ }
+
void PragmaDetectMismatch(SourceLocation Loc, StringRef Name,
StringRef Value) override {
First->PragmaDetectMismatch(Loc, Name, Value);
@@ -526,7 +562,7 @@ public:
}
void HasInclude(SourceLocation Loc, StringRef FileName, bool IsAngled,
- Optional<FileEntryRef> File,
+ OptionalFileEntryRef File,
SrcMgr::CharacteristicKind FileType) override;
void PragmaOpenCLExtension(SourceLocation NameLoc, const IdentifierInfo *Name,
@@ -535,7 +571,7 @@ public:
Second->PragmaOpenCLExtension(NameLoc, Name, StateLoc, State);
}
- void PragmaWarning(SourceLocation Loc, StringRef WarningSpec,
+ void PragmaWarning(SourceLocation Loc, PragmaWarningSpecifier WarningSpec,
ArrayRef<int> Ids) override {
First->PragmaWarning(Loc, WarningSpec, Ids);
Second->PragmaWarning(Loc, WarningSpec, Ids);
diff --git a/contrib/llvm-project/clang/include/clang/Lex/Pragma.h b/contrib/llvm-project/clang/include/clang/Lex/Pragma.h
index cf8cca5414ea..67eca618f6c4 100644
--- a/contrib/llvm-project/clang/include/clang/Lex/Pragma.h
+++ b/contrib/llvm-project/clang/include/clang/Lex/Pragma.h
@@ -123,6 +123,13 @@ public:
PragmaNamespace *getIfNamespace() override { return this; }
};
+/// Destringize a \c _Pragma("") string according to C11 6.10.9.1:
+/// "The string literal is destringized by deleting any encoding prefix,
+/// deleting the leading and trailing double-quotes, replacing each escape
+/// sequence \" by a double-quote, and replacing each escape sequence \\ by a
+/// single backslash."
+void prepare_PragmaString(SmallVectorImpl<char> &StrVal);
+
} // namespace clang
#endif // LLVM_CLANG_LEX_PRAGMA_H
diff --git a/contrib/llvm-project/clang/include/clang/Lex/PreprocessingRecord.h b/contrib/llvm-project/clang/include/clang/Lex/PreprocessingRecord.h
index 0137d871e916..5ddf024186f8 100644
--- a/contrib/llvm-project/clang/include/clang/Lex/PreprocessingRecord.h
+++ b/contrib/llvm-project/clang/include/clang/Lex/PreprocessingRecord.h
@@ -19,8 +19,6 @@
#include "clang/Basic/SourceLocation.h"
#include "clang/Lex/PPCallbacks.h"
#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/None.h"
-#include "llvm/ADT/Optional.h"
#include "llvm/ADT/PointerUnion.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/iterator.h"
@@ -30,6 +28,7 @@
#include <cassert>
#include <cstddef>
#include <iterator>
+#include <optional>
#include <utility>
#include <vector>
@@ -49,7 +48,6 @@ void operator delete(void *ptr, clang::PreprocessingRecord &PR,
namespace clang {
-class FileEntry;
class IdentifierInfo;
class MacroInfo;
class SourceManager;
@@ -230,25 +228,27 @@ class Token;
/// Whether the file name was in quotation marks; otherwise, it was
/// in angle brackets.
+ LLVM_PREFERRED_TYPE(bool)
unsigned InQuotes : 1;
/// The kind of inclusion directive we have.
///
/// This is a value of type InclusionKind.
+ LLVM_PREFERRED_TYPE(InclusionKind)
unsigned Kind : 2;
/// Whether the inclusion directive was automatically turned into
/// a module import.
+ LLVM_PREFERRED_TYPE(bool)
unsigned ImportedModule : 1;
/// The file that was included.
- const FileEntry *File;
+ OptionalFileEntryRef File;
public:
- InclusionDirective(PreprocessingRecord &PPRec,
- InclusionKind Kind, StringRef FileName,
- bool InQuotes, bool ImportedModule,
- const FileEntry *File, SourceRange Range);
+ InclusionDirective(PreprocessingRecord &PPRec, InclusionKind Kind,
+ StringRef FileName, bool InQuotes, bool ImportedModule,
+ OptionalFileEntryRef File, SourceRange Range);
/// Determine what kind of inclusion directive this is.
InclusionKind getKind() const { return static_cast<InclusionKind>(Kind); }
@@ -266,7 +266,7 @@ class Token;
/// Retrieve the file entry for the actual file that was included
/// by this directive.
- const FileEntry *getFile() const { return File; }
+ OptionalFileEntryRef getFile() const { return File; }
// Implement isa/cast/dyncast/etc.
static bool classof(const PreprocessedEntity *PE) {
@@ -293,9 +293,9 @@ class Token;
/// Optionally returns true or false if the preallocated preprocessed
/// entity with index \p Index came from file \p FID.
- virtual Optional<bool> isPreprocessedEntityInFileID(unsigned Index,
- FileID FID) {
- return None;
+ virtual std::optional<bool> isPreprocessedEntityInFileID(unsigned Index,
+ FileID FID) {
+ return std::nullopt;
}
/// Read a preallocated skipped range from the external source.
@@ -531,7 +531,7 @@ class Token;
void InclusionDirective(SourceLocation HashLoc, const Token &IncludeTok,
StringRef FileName, bool IsAngled,
CharSourceRange FilenameRange,
- const FileEntry *File, StringRef SearchPath,
+ OptionalFileEntryRef File, StringRef SearchPath,
StringRef RelativePath, const Module *Imported,
SrcMgr::CharacteristicKind FileType) override;
void Ifdef(SourceLocation Loc, const Token &MacroNameTok,
diff --git a/contrib/llvm-project/clang/include/clang/Lex/Preprocessor.h b/contrib/llvm-project/clang/include/clang/Lex/Preprocessor.h
index fe2327f0a480..b0a8ec0fec5e 100644
--- a/contrib/llvm-project/clang/include/clang/Lex/Preprocessor.h
+++ b/contrib/llvm-project/clang/include/clang/Lex/Preprocessor.h
@@ -15,6 +15,7 @@
#define LLVM_CLANG_LEX_PREPROCESSOR_H
#include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/DiagnosticIDs.h"
#include "clang/Basic/IdentifierTable.h"
#include "clang/Basic/LLVM.h"
#include "clang/Basic/LangOptions.h"
@@ -22,20 +23,18 @@
#include "clang/Basic/SourceLocation.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Basic/TokenKinds.h"
+#include "clang/Lex/HeaderSearch.h"
#include "clang/Lex/Lexer.h"
#include "clang/Lex/MacroInfo.h"
#include "clang/Lex/ModuleLoader.h"
#include "clang/Lex/ModuleMap.h"
#include "clang/Lex/PPCallbacks.h"
-#include "clang/Lex/PreprocessorExcludedConditionalDirectiveSkipMapping.h"
#include "clang/Lex/Token.h"
#include "clang/Lex/TokenLexer.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/FoldingSet.h"
#include "llvm/ADT/FunctionExtras.h"
-#include "llvm/ADT/None.h"
-#include "llvm/ADT/Optional.h"
#include "llvm/ADT/PointerUnion.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallPtrSet.h"
@@ -51,6 +50,7 @@
#include <cstdint>
#include <map>
#include <memory>
+#include <optional>
#include <string>
#include <utility>
#include <vector>
@@ -66,7 +66,6 @@ namespace clang {
class CodeCompletionHandler;
class CommentHandler;
class DirectoryEntry;
-class DirectoryLookup;
class EmptylineHandler;
class ExternalPreprocessorSource;
class FileEntry;
@@ -133,7 +132,7 @@ class Preprocessor {
llvm::unique_function<void(const clang::Token &)> OnToken;
std::shared_ptr<PreprocessorOptions> PPOpts;
DiagnosticsEngine *Diags;
- LangOptions &LangOpts;
+ const LangOptions &LangOpts;
const TargetInfo *Target = nullptr;
const TargetInfo *AuxTarget = nullptr;
FileManager &FileMgr;
@@ -164,6 +163,7 @@ class Preprocessor {
IdentifierInfo *Ident__has_feature; // __has_feature
IdentifierInfo *Ident__has_extension; // __has_extension
IdentifierInfo *Ident__has_builtin; // __has_builtin
+ IdentifierInfo *Ident__has_constexpr_builtin; // __has_constexpr_builtin
IdentifierInfo *Ident__has_attribute; // __has_attribute
IdentifierInfo *Ident__has_include; // __has_include
IdentifierInfo *Ident__has_include_next; // __has_include_next
@@ -178,12 +178,29 @@ class Preprocessor {
IdentifierInfo *Ident__is_target_vendor; // __is_target_vendor
IdentifierInfo *Ident__is_target_os; // __is_target_os
IdentifierInfo *Ident__is_target_environment; // __is_target_environment
+ IdentifierInfo *Ident__is_target_variant_os;
+ IdentifierInfo *Ident__is_target_variant_environment;
+ IdentifierInfo *Ident__FLT_EVAL_METHOD__; // __FLT_EVAL_METHOD
// Weak, only valid (and set) while InMacroArgs is true.
Token* ArgMacro;
SourceLocation DATELoc, TIMELoc;
+ // FEM_UnsetOnCommandLine means that an explicit evaluation method was
+ // not specified on the command line. The target is queried to set the
+ // default evaluation method.
+ LangOptions::FPEvalMethodKind CurrentFPEvalMethod =
+ LangOptions::FPEvalMethodKind::FEM_UnsetOnCommandLine;
+
+ // The most recent pragma location where the floating point evaluation
+ // method was modified. This is used to determine whether the
+ // 'pragma clang fp eval_method' was used whithin the current scope.
+ SourceLocation LastFPEvalPragmaLocation;
+
+ LangOptions::FPEvalMethodKind TUFPEvalMethod =
+ LangOptions::FPEvalMethodKind::FEM_UnsetOnCommandLine;
+
// Next __COUNTER__ value, starts at 0.
unsigned CounterValue = 0;
@@ -260,8 +277,7 @@ class Preprocessor {
/// Empty line handler.
EmptylineHandler *Emptyline = nullptr;
- /// True if we want to ignore EOF token and continue later on (thus
- /// avoid tearing the Lexer and etc. down).
+ /// True to avoid tearing down the lexer etc on EOF
bool IncrementalProcessing = false;
public:
@@ -292,14 +308,17 @@ private:
/// lexed, if any.
SourceLocation ModuleImportLoc;
- /// The module import path that we're currently processing.
- SmallVector<std::pair<IdentifierInfo *, SourceLocation>, 2> ModuleImportPath;
+ /// The import path for named module that we're currently processing.
+ SmallVector<std::pair<IdentifierInfo *, SourceLocation>, 2> NamedModuleImportPath;
+
+ /// Whether the import is an `@import` or a standard c++ modules import.
+ bool IsAtImport = false;
/// Whether the last token we lexed was an '@'.
bool LastTokenWasAt = false;
/// A position within a C++20 import-seq.
- class ImportSeq {
+ class StdCXXImportSeq {
public:
enum State : int {
// Positive values represent a number of unclosed brackets.
@@ -309,7 +328,7 @@ private:
AfterImportSeq = -3,
};
- ImportSeq(State S) : S(S) {}
+ StdCXXImportSeq(State S) : S(S) {}
/// Saw any kind of open bracket.
void handleOpenBracket() {
@@ -364,6 +383,7 @@ private:
bool atTopLevel() { return S <= 0; }
bool afterImportSeq() { return S == AfterImportSeq; }
+ bool afterTopLevelSeq() { return S == AfterTopLevelTokenSeq; }
private:
State S;
@@ -374,7 +394,206 @@ private:
};
/// Our current position within a C++20 import-seq.
- ImportSeq ImportSeqState = ImportSeq::AfterTopLevelTokenSeq;
+ StdCXXImportSeq StdCXXImportSeqState = StdCXXImportSeq::AfterTopLevelTokenSeq;
+
+ /// Track whether we are in a Global Module Fragment
+ class TrackGMF {
+ public:
+ enum GMFState : int {
+ GMFActive = 1,
+ MaybeGMF = 0,
+ BeforeGMFIntroducer = -1,
+ GMFAbsentOrEnded = -2,
+ };
+
+ TrackGMF(GMFState S) : S(S) {}
+
+ /// Saw a semicolon.
+ void handleSemi() {
+ // If it is immediately after the first instance of the module keyword,
+ // then that introduces the GMF.
+ if (S == MaybeGMF)
+ S = GMFActive;
+ }
+
+ /// Saw an 'export' identifier.
+ void handleExport() {
+ // The presence of an 'export' keyword always ends or excludes a GMF.
+ S = GMFAbsentOrEnded;
+ }
+
+ /// Saw an 'import' identifier.
+ void handleImport(bool AfterTopLevelTokenSeq) {
+ // If we see this before any 'module' kw, then we have no GMF.
+ if (AfterTopLevelTokenSeq && S == BeforeGMFIntroducer)
+ S = GMFAbsentOrEnded;
+ }
+
+ /// Saw a 'module' identifier.
+ void handleModule(bool AfterTopLevelTokenSeq) {
+ // This was the first module identifier and not preceded by any token
+ // that would exclude a GMF. It could begin a GMF, but only if directly
+ // followed by a semicolon.
+ if (AfterTopLevelTokenSeq && S == BeforeGMFIntroducer)
+ S = MaybeGMF;
+ else
+ S = GMFAbsentOrEnded;
+ }
+
+ /// Saw any other token.
+ void handleMisc() {
+ // We saw something other than ; after the 'module' kw, so not a GMF.
+ if (S == MaybeGMF)
+ S = GMFAbsentOrEnded;
+ }
+
+ bool inGMF() { return S == GMFActive; }
+
+ private:
+ /// Track the transitions into and out of a Global Module Fragment,
+ /// if one is present.
+ GMFState S;
+ };
+
+ TrackGMF TrackGMFState = TrackGMF::BeforeGMFIntroducer;
+
+ /// Track the status of the c++20 module decl.
+ ///
+ /// module-declaration:
+ /// 'export'[opt] 'module' module-name module-partition[opt]
+ /// attribute-specifier-seq[opt] ';'
+ ///
+ /// module-name:
+ /// module-name-qualifier[opt] identifier
+ ///
+ /// module-partition:
+ /// ':' module-name-qualifier[opt] identifier
+ ///
+ /// module-name-qualifier:
+ /// identifier '.'
+ /// module-name-qualifier identifier '.'
+ ///
+ /// Transition state:
+ ///
+ /// NotAModuleDecl --- export ---> FoundExport
+ /// NotAModuleDecl --- module ---> ImplementationCandidate
+ /// FoundExport --- module ---> InterfaceCandidate
+ /// ImplementationCandidate --- Identifier ---> ImplementationCandidate
+ /// ImplementationCandidate --- period ---> ImplementationCandidate
+ /// ImplementationCandidate --- colon ---> ImplementationCandidate
+ /// InterfaceCandidate --- Identifier ---> InterfaceCandidate
+ /// InterfaceCandidate --- period ---> InterfaceCandidate
+ /// InterfaceCandidate --- colon ---> InterfaceCandidate
+ /// ImplementationCandidate --- Semi ---> NamedModuleImplementation
+ /// NamedModuleInterface --- Semi ---> NamedModuleInterface
+ /// NamedModuleImplementation --- Anything ---> NamedModuleImplementation
+ /// NamedModuleInterface --- Anything ---> NamedModuleInterface
+ ///
+ /// FIXME: We haven't handle attribute-specifier-seq here. It may not be bad
+ /// soon since we don't support any module attributes yet.
+ class ModuleDeclSeq {
+ enum ModuleDeclState : int {
+ NotAModuleDecl,
+ FoundExport,
+ InterfaceCandidate,
+ ImplementationCandidate,
+ NamedModuleInterface,
+ NamedModuleImplementation,
+ };
+
+ public:
+ ModuleDeclSeq() = default;
+
+ void handleExport() {
+ if (State == NotAModuleDecl)
+ State = FoundExport;
+ else if (!isNamedModule())
+ reset();
+ }
+
+ void handleModule() {
+ if (State == FoundExport)
+ State = InterfaceCandidate;
+ else if (State == NotAModuleDecl)
+ State = ImplementationCandidate;
+ else if (!isNamedModule())
+ reset();
+ }
+
+ void handleIdentifier(IdentifierInfo *Identifier) {
+ if (isModuleCandidate() && Identifier)
+ Name += Identifier->getName().str();
+ else if (!isNamedModule())
+ reset();
+ }
+
+ void handleColon() {
+ if (isModuleCandidate())
+ Name += ":";
+ else if (!isNamedModule())
+ reset();
+ }
+
+ void handlePeriod() {
+ if (isModuleCandidate())
+ Name += ".";
+ else if (!isNamedModule())
+ reset();
+ }
+
+ void handleSemi() {
+ if (!Name.empty() && isModuleCandidate()) {
+ if (State == InterfaceCandidate)
+ State = NamedModuleInterface;
+ else if (State == ImplementationCandidate)
+ State = NamedModuleImplementation;
+ else
+ llvm_unreachable("Unimaged ModuleDeclState.");
+ } else if (!isNamedModule())
+ reset();
+ }
+
+ void handleMisc() {
+ if (!isNamedModule())
+ reset();
+ }
+
+ bool isModuleCandidate() const {
+ return State == InterfaceCandidate || State == ImplementationCandidate;
+ }
+
+ bool isNamedModule() const {
+ return State == NamedModuleInterface ||
+ State == NamedModuleImplementation;
+ }
+
+ bool isNamedInterface() const { return State == NamedModuleInterface; }
+
+ bool isImplementationUnit() const {
+ return State == NamedModuleImplementation && !getName().contains(':');
+ }
+
+ StringRef getName() const {
+ assert(isNamedModule() && "Can't get name from a non named module");
+ return Name;
+ }
+
+ StringRef getPrimaryName() const {
+ assert(isNamedModule() && "Can't get name from a non named module");
+ return getName().split(':').first;
+ }
+
+ void reset() {
+ Name.clear();
+ State = NotAModuleDecl;
+ }
+
+ private:
+ ModuleDeclState State = NotAModuleDecl;
+ std::string Name;
+ };
+
+ ModuleDeclSeq ModuleDeclState;
/// Whether the module import expects an identifier next. Otherwise,
/// it expects a '.' or ';'.
@@ -388,6 +607,14 @@ private:
/// \#pragma clang assume_nonnull begin.
SourceLocation PragmaAssumeNonNullLoc;
+ /// Set only for preambles which end with an active
+ /// \#pragma clang assume_nonnull begin.
+ ///
+ /// When the preamble is loaded into the main file,
+ /// `PragmaAssumeNonNullLoc` will be set to this to
+ /// replay the unterminated assume_nonnull.
+ SourceLocation PreambleRecordedPragmaAssumeNonNullLoc;
+
/// True if we hit the code-completion point.
bool CodeCompletionReached = false;
@@ -401,7 +628,7 @@ private:
/// The directory that the main file should be considered to occupy,
/// if it does not correspond to a real file (as happens when building a
/// module).
- const DirectoryEntry *MainFileDir = nullptr;
+ OptionalDirectoryEntryRef MainFileDir;
/// The number of bytes that we will initially skip when entering the
/// main file, along with a flag that indicates whether skipping this number
@@ -449,6 +676,8 @@ public:
ElseLoc(ElseLoc) {}
};
+ using IncludedFilesSet = llvm::DenseSet<const FileEntry *>;
+
private:
friend class ASTReader;
friend class MacroArgs;
@@ -486,11 +715,11 @@ private:
bool hasRecordedPreamble() const { return !ConditionalStack.empty(); }
- bool reachedEOFWhileSkipping() const { return SkipInfo.hasValue(); }
+ bool reachedEOFWhileSkipping() const { return SkipInfo.has_value(); }
void clearSkipInfo() { SkipInfo.reset(); }
- llvm::Optional<PreambleSkipInfo> SkipInfo;
+ std::optional<PreambleSkipInfo> SkipInfo;
private:
SmallVector<PPConditionalInfo, 4> ConditionalStack;
@@ -503,7 +732,7 @@ private:
/// Only one of CurLexer, or CurTokenLexer will be non-null.
std::unique_ptr<Lexer> CurLexer;
- /// The current top of the stack what we're lexing from
+ /// The current top of the stack that we're lexing from
/// if not expanding a macro.
///
/// This is an alias for CurLexer.
@@ -514,7 +743,7 @@ private:
///
/// This allows us to implement \#include_next and find directory-specific
/// properties.
- const DirectoryLookup *CurDirLookup = nullptr;
+ ConstSearchDirIterator CurDirLookup = nullptr;
/// The current macro we are expanding, if we are expanding a macro.
///
@@ -522,12 +751,8 @@ private:
std::unique_ptr<TokenLexer> CurTokenLexer;
/// The kind of lexer we're currently working with.
- enum CurLexerKind {
- CLK_Lexer,
- CLK_TokenLexer,
- CLK_CachingLexer,
- CLK_LexAfterModuleImport
- } CurLexerKind = CLK_Lexer;
+ typedef bool (*LexerCallback)(Preprocessor &, Token &);
+ LexerCallback CurLexerCallback = &CLK_Lexer;
/// If the current lexer is for a submodule that is being built, this
/// is that submodule.
@@ -537,21 +762,21 @@ private:
/// \#included, and macros currently being expanded from, not counting
/// CurLexer/CurTokenLexer.
struct IncludeStackInfo {
- enum CurLexerKind CurLexerKind;
+ LexerCallback CurLexerCallback;
Module *TheSubmodule;
std::unique_ptr<Lexer> TheLexer;
PreprocessorLexer *ThePPLexer;
std::unique_ptr<TokenLexer> TheTokenLexer;
- const DirectoryLookup *TheDirLookup;
+ ConstSearchDirIterator TheDirLookup;
// The following constructors are completely useless copies of the default
// versions, only needed to pacify MSVC.
- IncludeStackInfo(enum CurLexerKind CurLexerKind, Module *TheSubmodule,
+ IncludeStackInfo(LexerCallback CurLexerCallback, Module *TheSubmodule,
std::unique_ptr<Lexer> &&TheLexer,
PreprocessorLexer *ThePPLexer,
std::unique_ptr<TokenLexer> &&TheTokenLexer,
- const DirectoryLookup *TheDirLookup)
- : CurLexerKind(std::move(CurLexerKind)),
+ ConstSearchDirIterator TheDirLookup)
+ : CurLexerCallback(std::move(CurLexerCallback)),
TheSubmodule(std::move(TheSubmodule)), TheLexer(std::move(TheLexer)),
ThePPLexer(std::move(ThePPLexer)),
TheTokenLexer(std::move(TheTokenLexer)),
@@ -665,7 +890,7 @@ private:
getActiveModuleMacros(Preprocessor &PP, const IdentifierInfo *II) const {
if (auto *Info = getModuleInfo(PP, II))
return Info->ActiveModuleMacros;
- return None;
+ return std::nullopt;
}
MacroDirective::DefInfo findDirectiveAtLoc(SourceLocation Loc,
@@ -689,7 +914,7 @@ private:
ArrayRef<ModuleMacro*> getOverriddenMacros() const {
if (auto *Info = State.dyn_cast<ModuleMacroInfo*>())
return Info->OverriddenMacros;
- return None;
+ return std::nullopt;
}
void setOverriddenMacros(Preprocessor &PP,
@@ -764,6 +989,13 @@ private:
/// in a submodule.
SubmoduleState *CurSubmoduleState;
+ /// The files that have been included.
+ IncludedFilesSet IncludedFiles;
+
+ /// The set of top-level modules that affected preprocessing, but were not
+ /// imported.
+ llvm::SmallSetVector<Module *, 2> AffectingClangModules;
+
/// The set of known macros exported from modules.
llvm::FoldingSet<ModuleMacro> ModuleMacros;
@@ -786,6 +1018,42 @@ private:
using WarnUnusedMacroLocsTy = llvm::SmallDenseSet<SourceLocation, 32>;
WarnUnusedMacroLocsTy WarnUnusedMacroLocs;
+ /// This is a pair of an optional message and source location used for pragmas
+ /// that annotate macros like pragma clang restrict_expansion and pragma clang
+ /// deprecated. This pair stores the optional message and the location of the
+ /// annotation pragma for use producing diagnostics and notes.
+ using MsgLocationPair = std::pair<std::string, SourceLocation>;
+
+ struct MacroAnnotationInfo {
+ SourceLocation Location;
+ std::string Message;
+ };
+
+ struct MacroAnnotations {
+ std::optional<MacroAnnotationInfo> DeprecationInfo;
+ std::optional<MacroAnnotationInfo> RestrictExpansionInfo;
+ std::optional<SourceLocation> FinalAnnotationLoc;
+
+ static MacroAnnotations makeDeprecation(SourceLocation Loc,
+ std::string Msg) {
+ return MacroAnnotations{MacroAnnotationInfo{Loc, std::move(Msg)},
+ std::nullopt, std::nullopt};
+ }
+
+ static MacroAnnotations makeRestrictExpansion(SourceLocation Loc,
+ std::string Msg) {
+ return MacroAnnotations{
+ std::nullopt, MacroAnnotationInfo{Loc, std::move(Msg)}, std::nullopt};
+ }
+
+ static MacroAnnotations makeFinal(SourceLocation Loc) {
+ return MacroAnnotations{std::nullopt, std::nullopt, Loc};
+ }
+ };
+
+ /// Warning information for macro annotations.
+ llvm::DenseMap<const IdentifierInfo *, MacroAnnotations> AnnotationInfos;
+
/// A "freelist" of MacroArg objects that can be
/// reused for quick allocation.
MacroArgs *MacroArgCache = nullptr;
@@ -872,21 +1140,25 @@ private:
/// invoked (at which point the last position is popped).
std::vector<CachedTokensTy::size_type> BacktrackPositions;
- struct MacroInfoChain {
- MacroInfo MI;
- MacroInfoChain *Next;
- };
+ /// True if \p Preprocessor::SkipExcludedConditionalBlock() is running.
+ /// This is used to guard against calling this function recursively.
+ ///
+ /// See comments at the use-site for more context about why it is needed.
+ bool SkippingExcludedConditionalBlock = false;
- /// MacroInfos are managed as a chain for easy disposal. This is the head
- /// of that list.
- MacroInfoChain *MIChainHead = nullptr;
+ /// Keeps track of skipped range mappings that were recorded while skipping
+ /// excluded conditional directives. It maps the source buffer pointer at
+ /// the beginning of a skipped block, to the number of bytes that should be
+ /// skipped.
+ llvm::DenseMap<const char *, unsigned> RecordedSkippedRanges;
void updateOutOfDateIdentifier(IdentifierInfo &II) const;
public:
Preprocessor(std::shared_ptr<PreprocessorOptions> PPOpts,
- DiagnosticsEngine &diags, LangOptions &opts, SourceManager &SM,
- HeaderSearch &Headers, ModuleLoader &TheModuleLoader,
+ DiagnosticsEngine &diags, const LangOptions &LangOpts,
+ SourceManager &SM, HeaderSearch &Headers,
+ ModuleLoader &TheModuleLoader,
IdentifierInfoLookup *IILookup = nullptr,
bool OwnsHeaderSearch = false,
TranslationUnitKind TUKind = TU_Complete);
@@ -1161,7 +1433,7 @@ public:
auto I = LeafModuleMacros.find(II);
if (I != LeafModuleMacros.end())
return I->second;
- return None;
+ return std::nullopt;
}
/// Get the list of submodules that we're currently building.
@@ -1187,19 +1459,55 @@ public:
/// \}
+ /// Mark the given clang module as affecting the current clang module or translation unit.
+ void markClangModuleAsAffecting(Module *M) {
+ assert(M->isModuleMapModule());
+ if (!BuildingSubmoduleStack.empty()) {
+ if (M != BuildingSubmoduleStack.back().M)
+ BuildingSubmoduleStack.back().M->AffectingClangModules.insert(M);
+ } else {
+ AffectingClangModules.insert(M);
+ }
+ }
+
+ /// Get the set of top-level clang modules that affected preprocessing, but were not
+ /// imported.
+ const llvm::SmallSetVector<Module *, 2> &getAffectingClangModules() const {
+ return AffectingClangModules;
+ }
+
+ /// Mark the file as included.
+ /// Returns true if this is the first time the file was included.
+ bool markIncluded(FileEntryRef File) {
+ HeaderInfo.getFileInfo(File);
+ return IncludedFiles.insert(File).second;
+ }
+
+ /// Return true if this header has already been included.
+ bool alreadyIncluded(FileEntryRef File) const {
+ HeaderInfo.getFileInfo(File);
+ 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.
StringRef getLastMacroWithSpelling(SourceLocation Loc,
ArrayRef<TokenValue> Tokens) const;
+ /// Get the predefines for this processor.
+ /// Used by some third-party tools to inspect and add predefines (see
+ /// https://github.com/llvm/llvm-project/issues/57483).
const std::string &getPredefines() const { return Predefines; }
/// Set the predefines for this Preprocessor.
///
/// These predefines are automatically injected when parsing the main file.
- void setPredefines(const char *P) { Predefines = P; }
- void setPredefines(StringRef P) { Predefines = std::string(P); }
+ void setPredefines(std::string P) { Predefines = std::move(P); }
/// Return information about the specified preprocessor
/// identifier token.
@@ -1330,8 +1638,8 @@ public:
/// start lexing tokens from it instead of the current buffer.
///
/// Emits a diagnostic, doesn't enter the file, and returns true on error.
- bool EnterSourceFile(FileID FID, const DirectoryLookup *Dir,
- SourceLocation Loc);
+ bool EnterSourceFile(FileID FID, ConstSearchDirIterator Dir,
+ SourceLocation Loc, bool IsFirstIncludeOfFile = true);
/// Add a Macro to the top of the include stack and start lexing
/// tokens from it instead of the current buffer.
@@ -1409,6 +1717,9 @@ public:
/// Lex the next token for this preprocessor.
void Lex(Token &Result);
+ /// Lex all tokens for this preprocessor until (and excluding) end of file.
+ void LexTokensUntilEOF(std::vector<Token> *Tokens = nullptr);
+
/// Lex a token, forming a header-name token if possible.
bool LexHeaderName(Token &Result, bool AllowMacroExpansion = true);
@@ -1585,7 +1896,7 @@ public:
/// Determine whether it's possible for a future call to Lex to produce an
/// annotation token created by a previous call to EnterAnnotationToken.
bool mightHavePendingAnnotationTokens() {
- return CurLexerKind != CLK_Lexer;
+ return CurLexerCallback != CLK_Lexer;
}
/// Update the current token to represent the provided
@@ -1622,8 +1933,8 @@ public:
/// (1-based).
///
/// \returns true if an error occurred, false otherwise.
- bool SetCodeCompletionPoint(const FileEntry *File,
- unsigned Line, unsigned Column);
+ bool SetCodeCompletionPoint(FileEntryRef File, unsigned Line,
+ unsigned Column);
/// Determine if we are performing code completion.
bool isCodeCompletionEnabled() const { return CodeCompletionFile != nullptr; }
@@ -1684,11 +1995,24 @@ public:
PragmaAssumeNonNullLoc = Loc;
}
+ /// Get the location of the recorded unterminated \#pragma clang
+ /// assume_nonnull begin in the preamble, if one exists.
+ ///
+ /// Returns an invalid location if the premable did not end with
+ /// such a pragma active or if there is no recorded preamble.
+ SourceLocation getPreambleRecordedPragmaAssumeNonNullLoc() const {
+ return PreambleRecordedPragmaAssumeNonNullLoc;
+ }
+
+ /// Record the location of the unterminated \#pragma clang
+ /// assume_nonnull begin in the preamble.
+ void setPreambleRecordedPragmaAssumeNonNullLoc(SourceLocation Loc) {
+ PreambleRecordedPragmaAssumeNonNullLoc = Loc;
+ }
+
/// Set the directory in which the main file should be considered
/// to have been found, if it is not a real file.
- void setMainFileDir(const DirectoryEntry *Dir) {
- MainFileDir = Dir;
- }
+ void setMainFileDir(DirectoryEntryRef Dir) { MainFileDir = Dir; }
/// Instruct the preprocessor to skip part of the main source file.
///
@@ -1953,8 +2277,7 @@ public:
/// This either returns the EOF token and returns true, or
/// pops a level off the include stack and returns false, at which point the
/// client should call lex again.
- bool HandleEndOfFile(Token &Result, SourceLocation Loc,
- bool isEndOfMacro = false);
+ bool HandleEndOfFile(Token &Result, bool isEndOfMacro = false);
/// Callback invoked when the current TokenLexer hits the end of its
/// token stream.
@@ -1990,9 +2313,74 @@ public:
unsigned getCounterValue() const { return CounterValue; }
void setCounterValue(unsigned V) { CounterValue = V; }
+ LangOptions::FPEvalMethodKind getCurrentFPEvalMethod() const {
+ assert(CurrentFPEvalMethod != LangOptions::FEM_UnsetOnCommandLine &&
+ "FPEvalMethod should be set either from command line or from the "
+ "target info");
+ return CurrentFPEvalMethod;
+ }
+
+ LangOptions::FPEvalMethodKind getTUFPEvalMethod() const {
+ return TUFPEvalMethod;
+ }
+
+ SourceLocation getLastFPEvalPragmaLocation() const {
+ return LastFPEvalPragmaLocation;
+ }
+
+ void setCurrentFPEvalMethod(SourceLocation PragmaLoc,
+ LangOptions::FPEvalMethodKind Val) {
+ assert(Val != LangOptions::FEM_UnsetOnCommandLine &&
+ "FPEvalMethod should never be set to FEM_UnsetOnCommandLine");
+ // This is the location of the '#pragma float_control" where the
+ // execution state is modifed.
+ LastFPEvalPragmaLocation = PragmaLoc;
+ CurrentFPEvalMethod = Val;
+ TUFPEvalMethod = Val;
+ }
+
+ void setTUFPEvalMethod(LangOptions::FPEvalMethodKind Val) {
+ assert(Val != LangOptions::FEM_UnsetOnCommandLine &&
+ "TUPEvalMethod should never be set to FEM_UnsetOnCommandLine");
+ TUFPEvalMethod = Val;
+ }
+
/// Retrieves the module that we're currently building, if any.
Module *getCurrentModule();
+ /// Retrieves the module whose implementation we're current compiling, if any.
+ Module *getCurrentModuleImplementation();
+
+ /// If we are preprocessing a named module.
+ bool isInNamedModule() const { return ModuleDeclState.isNamedModule(); }
+
+ /// If we are proprocessing a named interface unit.
+ /// Note that a module implementation partition is not considered as an
+ /// named interface unit here although it is importable
+ /// to ease the parsing.
+ bool isInNamedInterfaceUnit() const {
+ return ModuleDeclState.isNamedInterface();
+ }
+
+ /// Get the named module name we're preprocessing.
+ /// Requires we're preprocessing a named module.
+ StringRef getNamedModuleName() const { return ModuleDeclState.getName(); }
+
+ /// If we are implementing an implementation module unit.
+ /// Note that the module implementation partition is not considered as an
+ /// implementation unit.
+ bool isInImplementationUnit() const {
+ return ModuleDeclState.isImplementationUnit();
+ }
+
+ /// If we're importing a standard C++20 Named Modules.
+ bool isInImportingCXXNamedModules() const {
+ // NamedModuleImportPath will be non-empty only if we're importing
+ // Standard C++ named modules.
+ return !NamedModuleImportPath.empty() && getLangOpts().CPlusPlusModules &&
+ !IsAtImport;
+ }
+
/// Allocate a new MacroInfo object with the provided SourceLocation.
MacroInfo *AllocateMacroInfo(SourceLocation L);
@@ -2009,22 +2397,16 @@ public:
/// Given a "foo" or \<foo> reference, look up the indicated file.
///
- /// Returns None on failure. \p isAngled indicates whether the file
+ /// Returns std::nullopt on failure. \p isAngled indicates whether the file
/// reference is for system \#include's or not (i.e. using <> instead of "").
- Optional<FileEntryRef>
+ OptionalFileEntryRef
LookupFile(SourceLocation FilenameLoc, StringRef Filename, bool isAngled,
- const DirectoryLookup *FromDir, const FileEntry *FromFile,
- const DirectoryLookup *&CurDir, SmallVectorImpl<char> *SearchPath,
+ ConstSearchDirIterator FromDir, const FileEntry *FromFile,
+ ConstSearchDirIterator *CurDir, SmallVectorImpl<char> *SearchPath,
SmallVectorImpl<char> *RelativePath,
ModuleMap::KnownHeader *SuggestedModule, bool *IsMapped,
- bool *IsFrameworkFound, bool SkipCache = false);
-
- /// Get the DirectoryLookup structure used to find the current
- /// FileEntry, if CurLexer is non-null and if applicable.
- ///
- /// This allows us to implement \#include_next and find directory-specific
- /// properties.
- const DirectoryLookup *GetCurDirLookup() { return CurDirLookup; }
+ bool *IsFrameworkFound, bool SkipCache = false,
+ bool OpenFile = true, bool CacheFailures = true);
/// Return true if we're in the top-level file, not in a \#include.
bool isInPrimaryFile() const;
@@ -2043,8 +2425,9 @@ private:
friend void TokenLexer::ExpandFunctionArguments();
void PushIncludeMacroStack() {
- assert(CurLexerKind != CLK_CachingLexer && "cannot push a caching lexer");
- IncludeMacroStack.emplace_back(CurLexerKind, CurLexerSubmodule,
+ assert(CurLexerCallback != CLK_CachingLexer &&
+ "cannot push a caching lexer");
+ IncludeMacroStack.emplace_back(CurLexerCallback, CurLexerSubmodule,
std::move(CurLexer), CurPPLexer,
std::move(CurTokenLexer), CurDirLookup);
CurPPLexer = nullptr;
@@ -2056,7 +2439,7 @@ private:
CurTokenLexer = std::move(IncludeMacroStack.back().TheTokenLexer);
CurDirLookup = IncludeMacroStack.back().TheDirLookup;
CurLexerSubmodule = IncludeMacroStack.back().TheSubmodule;
- CurLexerKind = IncludeMacroStack.back().CurLexerKind;
+ CurLexerCallback = IncludeMacroStack.back().CurLexerCallback;
IncludeMacroStack.pop_back();
}
@@ -2107,6 +2490,13 @@ private:
/// Return true if an error occurs parsing the arg list.
bool ReadMacroParameterList(MacroInfo *MI, Token& LastTok);
+ /// Provide a suggestion for a typoed directive. If there is no typo, then
+ /// just skip suggesting.
+ ///
+ /// \param Tok - Token that represents the directive
+ /// \param Directive - String reference for the directive name
+ void SuggestTypoedDirective(const Token &Tok, StringRef Directive) const;
+
/// We just read a \#if or related directive and decided that the
/// subsequent tokens are in the \#if'd out portion of the
/// file. Lex the rest of the file, until we see an \#endif. If \p
@@ -2139,6 +2529,20 @@ private:
/// If the expression is equivalent to "!defined(X)" return X in IfNDefMacro.
DirectiveEvalResult EvaluateDirectiveExpression(IdentifierInfo *&IfNDefMacro);
+ /// Process a '__has_include("path")' expression.
+ ///
+ /// Returns true if successful.
+ bool EvaluateHasInclude(Token &Tok, IdentifierInfo *II);
+
+ /// Process '__has_include_next("path")' expression.
+ ///
+ /// Returns true if successful.
+ bool EvaluateHasIncludeNext(Token &Tok, IdentifierInfo *II);
+
+ /// Get the directory and file from which to start \#include_next lookup.
+ std::pair<ConstSearchDirIterator, const FileEntry *>
+ getIncludeNextStart(const Token &IncludeNextTok) const;
+
/// Install the standard preprocessor pragmas:
/// \#pragma GCC poison/system_header/dependency and \#pragma once.
void RegisterBuiltinPragmas();
@@ -2186,7 +2590,7 @@ private:
/// Add a lexer to the top of the include stack and
/// start lexing tokens from it instead of the current buffer.
- void EnterSourceFileWithLexer(Lexer *TheLexer, const DirectoryLookup *Dir);
+ void EnterSourceFileWithLexer(Lexer *TheLexer, ConstSearchDirIterator Dir);
/// Set the FileID for the preprocessor predefines.
void setPredefinesFileID(FileID FID) {
@@ -2250,6 +2654,7 @@ private:
None,
ModuleBegin,
ModuleImport,
+ HeaderUnitImport,
SkippedModuleImport,
Failure,
} Kind;
@@ -2262,23 +2667,23 @@ private:
}
};
- Optional<FileEntryRef> LookupHeaderIncludeOrImport(
- const DirectoryLookup *&CurDir, StringRef &Filename,
+ OptionalFileEntryRef LookupHeaderIncludeOrImport(
+ ConstSearchDirIterator *CurDir, StringRef &Filename,
SourceLocation FilenameLoc, CharSourceRange FilenameRange,
const Token &FilenameTok, bool &IsFrameworkFound, bool IsImportDecl,
- bool &IsMapped, const DirectoryLookup *LookupFrom,
+ bool &IsMapped, ConstSearchDirIterator LookupFrom,
const FileEntry *LookupFromFile, StringRef &LookupFilename,
SmallVectorImpl<char> &RelativePath, SmallVectorImpl<char> &SearchPath,
ModuleMap::KnownHeader &SuggestedModule, bool isAngled);
// File inclusion.
void HandleIncludeDirective(SourceLocation HashLoc, Token &Tok,
- const DirectoryLookup *LookupFrom = nullptr,
+ ConstSearchDirIterator LookupFrom = nullptr,
const FileEntry *LookupFromFile = nullptr);
ImportAction
HandleHeaderIncludeOrImport(SourceLocation HashLoc, Token &IncludeTok,
Token &FilenameTok, SourceLocation EndLoc,
- const DirectoryLookup *LookupFrom = nullptr,
+ ConstSearchDirIterator LookupFrom = nullptr,
const FileEntry *LookupFromFile = nullptr);
void HandleIncludeNextDirective(SourceLocation HashLoc, Token &Tok);
void HandleIncludeMacrosDirective(SourceLocation HashLoc, Token &Tok);
@@ -2291,13 +2696,13 @@ public:
/// \c false if the module appears to be usable.
static bool checkModuleIsAvailable(const LangOptions &LangOpts,
const TargetInfo &TargetInfo,
- DiagnosticsEngine &Diags, Module *M);
+ const Module &M, DiagnosticsEngine &Diags);
// Module inclusion testing.
/// Find the module that owns the source or header file that
/// \p Loc points to. If the location is in a file that was included
/// into a module, or is outside any module, returns nullptr.
- Module *getModuleForLocation(SourceLocation Loc);
+ Module *getModuleForLocation(SourceLocation Loc, bool AllowTextual);
/// We want to produce a diagnostic at location IncLoc concerning an
/// unreachable effect at location MLoc (eg, where a desired entity was
@@ -2313,8 +2718,8 @@ public:
/// \return A file that can be #included to provide the desired effect. Null
/// if no such file could be determined or if a #include is not
/// appropriate (eg, if a module should be imported instead).
- const FileEntry *getHeaderToIncludeForDiagnostics(SourceLocation IncLoc,
- SourceLocation MLoc);
+ OptionalFileEntryRef getHeaderToIncludeForDiagnostics(SourceLocation IncLoc,
+ SourceLocation MLoc);
bool isRecordingPreamble() const {
return PreambleConditionalStack.isRecording();
@@ -2332,14 +2737,14 @@ public:
PreambleConditionalStack.setStack(s);
}
- void setReplayablePreambleConditionalStack(ArrayRef<PPConditionalInfo> s,
- llvm::Optional<PreambleSkipInfo> SkipInfo) {
+ void setReplayablePreambleConditionalStack(
+ ArrayRef<PPConditionalInfo> s, std::optional<PreambleSkipInfo> SkipInfo) {
PreambleConditionalStack.startReplaying();
PreambleConditionalStack.setStack(s);
PreambleConditionalStack.SkipInfo = SkipInfo;
}
- llvm::Optional<PreambleSkipInfo> getPreambleSkipInfo() const {
+ std::optional<PreambleSkipInfo> getPreambleSkipInfo() const {
return PreambleConditionalStack.SkipInfo;
}
@@ -2364,14 +2769,12 @@ private:
// Pragmas.
void HandlePragmaDirective(PragmaIntroducer Introducer);
- void ResolvePragmaIncludeInstead(SourceLocation Location) const;
public:
void HandlePragmaOnce(Token &OnceTok);
void HandlePragmaMark(Token &MarkTok);
void HandlePragmaPoison();
void HandlePragmaSystemHeader(Token &SysHeaderTok);
- void HandlePragmaIncludeInstead(Token &Tok);
void HandlePragmaDependency(Token &DependencyTok);
void HandlePragmaPushMacro(Token &Tok);
void HandlePragmaPopMacro(Token &Tok);
@@ -2388,14 +2791,141 @@ public:
/// warnings.
void markMacroAsUsed(MacroInfo *MI);
+ void addMacroDeprecationMsg(const IdentifierInfo *II, std::string Msg,
+ SourceLocation AnnotationLoc) {
+ auto Annotations = AnnotationInfos.find(II);
+ if (Annotations == AnnotationInfos.end())
+ AnnotationInfos.insert(std::make_pair(
+ II,
+ MacroAnnotations::makeDeprecation(AnnotationLoc, std::move(Msg))));
+ else
+ Annotations->second.DeprecationInfo =
+ MacroAnnotationInfo{AnnotationLoc, std::move(Msg)};
+ }
+
+ void addRestrictExpansionMsg(const IdentifierInfo *II, std::string Msg,
+ SourceLocation AnnotationLoc) {
+ auto Annotations = AnnotationInfos.find(II);
+ if (Annotations == AnnotationInfos.end())
+ AnnotationInfos.insert(
+ std::make_pair(II, MacroAnnotations::makeRestrictExpansion(
+ AnnotationLoc, std::move(Msg))));
+ else
+ Annotations->second.RestrictExpansionInfo =
+ MacroAnnotationInfo{AnnotationLoc, std::move(Msg)};
+ }
+
+ void addFinalLoc(const IdentifierInfo *II, SourceLocation AnnotationLoc) {
+ auto Annotations = AnnotationInfos.find(II);
+ if (Annotations == AnnotationInfos.end())
+ AnnotationInfos.insert(
+ std::make_pair(II, MacroAnnotations::makeFinal(AnnotationLoc)));
+ else
+ Annotations->second.FinalAnnotationLoc = AnnotationLoc;
+ }
+
+ const MacroAnnotations &getMacroAnnotations(const IdentifierInfo *II) const {
+ return AnnotationInfos.find(II)->second;
+ }
+
+ void emitMacroExpansionWarnings(const Token &Identifier,
+ bool IsIfnDef = false) const {
+ IdentifierInfo *Info = Identifier.getIdentifierInfo();
+ if (Info->isDeprecatedMacro())
+ emitMacroDeprecationWarning(Identifier);
+
+ if (Info->isRestrictExpansion() &&
+ !SourceMgr.isInMainFile(Identifier.getLocation()))
+ emitRestrictExpansionWarning(Identifier);
+
+ if (!IsIfnDef) {
+ if (Info->getName() == "INFINITY" && getLangOpts().NoHonorInfs)
+ emitRestrictInfNaNWarning(Identifier, 0);
+ if (Info->getName() == "NAN" && getLangOpts().NoHonorNaNs)
+ emitRestrictInfNaNWarning(Identifier, 1);
+ }
+ }
+
+ static void processPathForFileMacro(SmallVectorImpl<char> &Path,
+ const LangOptions &LangOpts,
+ const TargetInfo &TI);
+
+ static void processPathToFileName(SmallVectorImpl<char> &FileName,
+ const PresumedLoc &PLoc,
+ const LangOptions &LangOpts,
+ const TargetInfo &TI);
+
private:
- Optional<unsigned>
- getSkippedRangeForExcludedConditionalBlock(SourceLocation HashLoc);
+ void emitMacroDeprecationWarning(const Token &Identifier) const;
+ void emitRestrictExpansionWarning(const Token &Identifier) const;
+ void emitFinalMacroWarning(const Token &Identifier, bool IsUndef) const;
+ void emitRestrictInfNaNWarning(const Token &Identifier,
+ unsigned DiagSelection) const;
+
+ /// This boolean state keeps track if the current scanned token (by this PP)
+ /// is in an "-Wunsafe-buffer-usage" opt-out region. Assuming PP scans a
+ /// translation unit in a linear order.
+ bool InSafeBufferOptOutRegion = false;
+
+ /// Hold the start location of the current "-Wunsafe-buffer-usage" opt-out
+ /// region if PP is currently in such a region. Hold undefined value
+ /// otherwise.
+ SourceLocation CurrentSafeBufferOptOutStart; // It is used to report the start location of an never-closed region.
+
+ // An ordered sequence of "-Wunsafe-buffer-usage" opt-out regions in one
+ // translation unit. Each region is represented by a pair of start and end
+ // locations. A region is "open" if its' start and end locations are
+ // identical.
+ SmallVector<std::pair<SourceLocation, SourceLocation>, 8> SafeBufferOptOutMap;
- /// Contains the currently active skipped range mappings for skipping excluded
- /// conditional directives.
- ExcludedPreprocessorDirectiveSkipMapping
- *ExcludedConditionalDirectiveSkipMappings;
+public:
+ /// \return true iff the given `Loc` is in a "-Wunsafe-buffer-usage" opt-out
+ /// region. This `Loc` must be a source location that has been pre-processed.
+ bool isSafeBufferOptOut(const SourceManager&SourceMgr, const SourceLocation &Loc) const;
+
+ /// Alter the state of whether this PP currently is in a
+ /// "-Wunsafe-buffer-usage" opt-out region.
+ ///
+ /// \param isEnter true if this PP is entering a region; otherwise, this PP
+ /// is exiting a region
+ /// \param Loc the location of the entry or exit of a
+ /// region
+ /// \return true iff it is INVALID to enter or exit a region, i.e.,
+ /// attempt to enter a region before exiting a previous region, or exiting a
+ /// region that PP is not currently in.
+ bool enterOrExitSafeBufferOptOutRegion(bool isEnter,
+ const SourceLocation &Loc);
+
+ /// \return true iff this PP is currently in a "-Wunsafe-buffer-usage"
+ /// opt-out region
+ bool isPPInSafeBufferOptOutRegion();
+
+ /// \param StartLoc output argument. It will be set to the start location of
+ /// the current "-Wunsafe-buffer-usage" opt-out region iff this function
+ /// returns true.
+ /// \return true iff this PP is currently in a "-Wunsafe-buffer-usage"
+ /// opt-out region
+ bool isPPInSafeBufferOptOutRegion(SourceLocation &StartLoc);
+
+private:
+ /// Helper functions to forward lexing to the actual lexer. They all share the
+ /// same signature.
+ static bool CLK_Lexer(Preprocessor &P, Token &Result) {
+ return P.CurLexer->Lex(Result);
+ }
+ static bool CLK_TokenLexer(Preprocessor &P, Token &Result) {
+ return P.CurTokenLexer->Lex(Result);
+ }
+ static bool CLK_CachingLexer(Preprocessor &P, Token &Result) {
+ P.CachingLex(Result);
+ return true;
+ }
+ static bool CLK_DependencyDirectivesLexer(Preprocessor &P, Token &Result) {
+ return P.CurLexer->LexDependencyDirectiveToken(Result);
+ }
+ static bool CLK_LexAfterModuleImport(Preprocessor &P, Token &Result) {
+ return P.LexAfterModuleImport(Result);
+ }
};
/// Abstract base class that describes a handler that will receive
diff --git a/contrib/llvm-project/clang/include/clang/Lex/PreprocessorExcludedConditionalDirectiveSkipMapping.h b/contrib/llvm-project/clang/include/clang/Lex/PreprocessorExcludedConditionalDirectiveSkipMapping.h
deleted file mode 100644
index 1a0d5ed57b28..000000000000
--- a/contrib/llvm-project/clang/include/clang/Lex/PreprocessorExcludedConditionalDirectiveSkipMapping.h
+++ /dev/null
@@ -1,30 +0,0 @@
-//===- PreprocessorExcludedConditionalDirectiveSkipMapping.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
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_LEX_PREPROCESSOR_EXCLUDED_COND_DIRECTIVE_SKIP_MAPPING_H
-#define LLVM_CLANG_LEX_PREPROCESSOR_EXCLUDED_COND_DIRECTIVE_SKIP_MAPPING_H
-
-#include "clang/Basic/LLVM.h"
-#include "llvm/ADT/DenseMap.h"
-#include "llvm/Support/MemoryBuffer.h"
-
-namespace clang {
-
-/// A mapping from an offset into a buffer to the number of bytes that can be
-/// skipped by the preprocessor when skipping over excluded conditional
-/// directive ranges.
-using PreprocessorSkippedRangeMapping = llvm::DenseMap<unsigned, unsigned>;
-
-/// The datastructure that holds the mapping between the active memory buffers
-/// and the individual skip mappings.
-using ExcludedPreprocessorDirectiveSkipMapping =
- llvm::DenseMap<const char *, const PreprocessorSkippedRangeMapping *>;
-
-} // end namespace clang
-
-#endif // LLVM_CLANG_LEX_PREPROCESSOR_EXCLUDED_COND_DIRECTIVE_SKIP_MAPPING_H
diff --git a/contrib/llvm-project/clang/include/clang/Lex/PreprocessorLexer.h b/contrib/llvm-project/clang/include/clang/Lex/PreprocessorLexer.h
index b43197a6031c..d71fe708ab20 100644
--- a/contrib/llvm-project/clang/include/clang/Lex/PreprocessorLexer.h
+++ b/contrib/llvm-project/clang/include/clang/Lex/PreprocessorLexer.h
@@ -14,13 +14,12 @@
#ifndef LLVM_CLANG_LEX_PREPROCESSORLEXER_H
#define LLVM_CLANG_LEX_PREPROCESSORLEXER_H
+#include "clang/Basic/FileEntry.h"
#include "clang/Basic/SourceLocation.h"
-#include "clang/Lex/HeaderSearch.h"
#include "clang/Lex/MultipleIncludeOpt.h"
#include "clang/Lex/Token.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/StringMap.h"
#include <cassert>
namespace clang {
@@ -76,13 +75,6 @@ protected:
/// we are currently in.
SmallVector<PPConditionalInfo, 4> ConditionalStack;
- struct IncludeInfo {
- const FileEntry *File;
- SourceLocation Location;
- };
- // A complete history of all the files included by the current file.
- llvm::StringMap<IncludeInfo> IncludeHistory;
-
PreprocessorLexer() : FID() {}
PreprocessorLexer(Preprocessor *pp, FileID fid);
virtual ~PreprocessorLexer() = default;
@@ -165,7 +157,7 @@ public:
/// getFileEntry - Return the FileEntry corresponding to this FileID. Like
/// getFileID(), this only works for lexers with attached preprocessors.
- const FileEntry *getFileEntry() const;
+ OptionalFileEntryRef getFileEntry() const;
/// Iterator that traverses the current stack of preprocessor
/// conditional directives (\#if/\#ifdef/\#ifndef).
@@ -184,15 +176,6 @@ public:
ConditionalStack.clear();
ConditionalStack.append(CL.begin(), CL.end());
}
-
- void addInclude(StringRef Filename, const FileEntry &File,
- SourceLocation Location) {
- IncludeHistory.insert({Filename, {&File, Location}});
- }
-
- const llvm::StringMap<IncludeInfo> &getIncludeHistory() const {
- return IncludeHistory;
- }
};
} // namespace clang
diff --git a/contrib/llvm-project/clang/include/clang/Lex/PreprocessorOptions.h b/contrib/llvm-project/clang/include/clang/Lex/PreprocessorOptions.h
index a7aabc3e1df2..f841e4a028df 100644
--- a/contrib/llvm-project/clang/include/clang/Lex/PreprocessorOptions.h
+++ b/contrib/llvm-project/clang/include/clang/Lex/PreprocessorOptions.h
@@ -10,13 +10,15 @@
#define LLVM_CLANG_LEX_PREPROCESSOROPTIONS_H_
#include "clang/Basic/BitmaskEnum.h"
+#include "clang/Basic/FileEntry.h"
#include "clang/Basic/LLVM.h"
-#include "clang/Lex/PreprocessorExcludedConditionalDirectiveSkipMapping.h"
+#include "clang/Lex/DependencyDirectivesScanner.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/StringSet.h"
#include <functional>
#include <map>
#include <memory>
+#include <optional>
#include <set>
#include <string>
#include <utility>
@@ -67,10 +69,16 @@ public:
std::vector<std::string> Includes;
std::vector<std::string> MacroIncludes;
+ /// Perform extra checks when loading PCM files for mutable file systems.
+ bool ModulesCheckRelocated = true;
+
/// Initialize the preprocessor with the compiler and target specific
/// predefines.
bool UsePredefines = true;
+ /// Indicates whether to predefine target OS macros.
+ bool DefineTargetOSMacros = false;
+
/// Whether we should maintain a detailed record of all macro
/// definitions and expansions.
bool DetailedRecord = false;
@@ -128,7 +136,8 @@ public:
///
/// When the lexer is done, one of the things that need to be preserved is the
/// conditional #if stack, so the ASTWriter/ASTReader can save/restore it when
- /// processing the rest of the file.
+ /// processing the rest of the file. Similarly, we track an unterminated
+ /// #pragma assume_nonnull.
bool GeneratePreamble = false;
/// Whether to write comment locations into the PCH when building it.
@@ -199,13 +208,18 @@ public:
/// build it again.
std::shared_ptr<FailedModulesSet> FailedModules;
- /// Contains the currently active skipped range mappings for skipping excluded
- /// conditional directives.
+ /// Function for getting the dependency preprocessor directives of a file.
///
- /// The pointer is passed to the Preprocessor when it's constructed. The
- /// pointer is unowned, the client is responsible for its lifetime.
- ExcludedPreprocessorDirectiveSkipMapping
- *ExcludedConditionalDirectiveSkipMappings = nullptr;
+ /// These are directives derived from a special form of lexing where the
+ /// source input is scanned for the preprocessor directives that might have an
+ /// effect on the dependencies for a compilation unit.
+ ///
+ /// Enables a client to cache the directives for a file and provide them
+ /// across multiple compiler invocations.
+ /// FIXME: Allow returning an error.
+ std::function<std::optional<ArrayRef<dependency_directives_scan::Directive>>(
+ FileEntryRef)>
+ DependencyDirectivesForFile;
/// Set up preprocessor for RunAnalysis action.
bool SetUpStaticAnalyzer = false;
@@ -213,6 +227,9 @@ public:
/// Prevents intended crashes when using #pragma clang __debug. For testing.
bool DisablePragmaDebugCrash = false;
+ /// If set, the UNIX timestamp specified by SOURCE_DATE_EPOCH.
+ std::optional<uint64_t> SourceDateEpoch;
+
public:
PreprocessorOptions() : PrecompiledPreambleBytes(0, false) {}
diff --git a/contrib/llvm-project/clang/include/clang/Lex/Token.h b/contrib/llvm-project/clang/include/clang/Lex/Token.h
index 00fbe6d18f72..1409e2c58b55 100644
--- a/contrib/llvm-project/clang/include/clang/Lex/Token.h
+++ b/contrib/llvm-project/clang/include/clang/Lex/Token.h
@@ -15,6 +15,7 @@
#include "clang/Basic/SourceLocation.h"
#include "clang/Basic/TokenKinds.h"
+#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/StringRef.h"
#include <cassert>
@@ -99,9 +100,8 @@ public:
bool isOneOf(tok::TokenKind K1, tok::TokenKind K2) const {
return is(K1) || is(K2);
}
- template <typename... Ts>
- bool isOneOf(tok::TokenKind K1, tok::TokenKind K2, Ts... Ks) const {
- return is(K1) || isOneOf(K2, Ks...);
+ template <typename... Ts> bool isOneOf(tok::TokenKind K1, Ts... Ks) const {
+ return is(K1) || isOneOf(Ks...);
}
/// Return true if this is a raw identifier (when lexing
@@ -117,8 +117,13 @@ public:
}
/// Return true if this is any of tok::annot_* kind tokens.
- bool isAnnotation() const {
- return tok::isAnnotation(getKind());
+ bool isAnnotation() const { return tok::isAnnotation(getKind()); }
+
+ /// Return true if the token is a keyword that is parsed in the same
+ /// position as a standard attribute, but that has semantic meaning
+ /// and so cannot be a true attribute.
+ bool isRegularKeywordAttribute() const {
+ return tok::isRegularKeywordAttribute(getKind());
}
/// Return a source location identifier for the specified
@@ -176,6 +181,8 @@ public:
Loc = SourceLocation().getRawEncoding();
}
+ bool hasPtrData() const { return PtrData != nullptr; }
+
IdentifierInfo *getIdentifierInfo() const {
assert(isNot(tok::raw_identifier) &&
"getIdentifierInfo() on a tok::raw_identifier token!");
@@ -329,6 +336,12 @@ struct PPConditionalInfo {
bool FoundElse;
};
+// Extra information needed for annonation tokens.
+struct PragmaLoopHintInfo {
+ Token PragmaName;
+ Token Option;
+ ArrayRef<Token> Toks;
+};
} // end namespace clang
#endif // LLVM_CLANG_LEX_TOKEN_H
diff --git a/contrib/llvm-project/clang/include/clang/Lex/VariadicMacroSupport.h b/contrib/llvm-project/clang/include/clang/Lex/VariadicMacroSupport.h
index 119f02201fc6..cf86a00c6d66 100644
--- a/contrib/llvm-project/clang/include/clang/Lex/VariadicMacroSupport.h
+++ b/contrib/llvm-project/clang/include/clang/Lex/VariadicMacroSupport.h
@@ -129,11 +129,16 @@ namespace clang {
// the function-like macro's new replacement list.
int NumOfTokensPriorToVAOpt = -1;
+ LLVM_PREFERRED_TYPE(bool)
unsigned LeadingSpaceForStringifiedToken : 1;
+ LLVM_PREFERRED_TYPE(bool)
unsigned StringifyBefore : 1;
+ LLVM_PREFERRED_TYPE(bool)
unsigned CharifyBefore : 1;
+ LLVM_PREFERRED_TYPE(bool)
unsigned BeginsWithPlaceholder : 1;
+ LLVM_PREFERRED_TYPE(bool)
unsigned EndsWithPlaceholder : 1;
bool hasStringifyBefore() const {
diff --git a/contrib/llvm-project/clang/include/clang/Parse/LoopHint.h b/contrib/llvm-project/clang/include/clang/Parse/LoopHint.h
index 6e363f72b658..cec5605ea361 100644
--- a/contrib/llvm-project/clang/include/clang/Parse/LoopHint.h
+++ b/contrib/llvm-project/clang/include/clang/Parse/LoopHint.h
@@ -9,13 +9,13 @@
#ifndef LLVM_CLANG_PARSE_LOOPHINT_H
#define LLVM_CLANG_PARSE_LOOPHINT_H
-#include "clang/Basic/IdentifierTable.h"
#include "clang/Basic/SourceLocation.h"
-#include "clang/Sema/Ownership.h"
-#include "clang/Sema/ParsedAttr.h"
namespace clang {
+class Expr;
+struct IdentifierLoc;
+
/// Loop optimization hint for loop and unroll pragmas.
struct LoopHint {
// Source range of the directive.
@@ -23,20 +23,18 @@ struct LoopHint {
// Identifier corresponding to the name of the pragma. "loop" for
// "#pragma clang loop" directives and "unroll" for "#pragma unroll"
// hints.
- IdentifierLoc *PragmaNameLoc;
+ IdentifierLoc *PragmaNameLoc = nullptr;
// Name of the loop hint. Examples: "unroll", "vectorize". In the
// "#pragma unroll" and "#pragma nounroll" cases, this is identical to
// PragmaNameLoc.
- IdentifierLoc *OptionLoc;
+ IdentifierLoc *OptionLoc = nullptr;
// Identifier for the hint state argument. If null, then the state is
// default value such as for "#pragma unroll".
- IdentifierLoc *StateLoc;
+ IdentifierLoc *StateLoc = nullptr;
// Expression for the hint argument if it exists, null otherwise.
- Expr *ValueExpr;
+ Expr *ValueExpr = nullptr;
- LoopHint()
- : PragmaNameLoc(nullptr), OptionLoc(nullptr), StateLoc(nullptr),
- ValueExpr(nullptr) {}
+ LoopHint() = default;
};
} // end namespace clang
diff --git a/contrib/llvm-project/clang/include/clang/Parse/Parser.h b/contrib/llvm-project/clang/include/clang/Parse/Parser.h
index 8eb3f9029d9d..ffbde370e8f9 100644
--- a/contrib/llvm-project/clang/include/clang/Parse/Parser.h
+++ b/contrib/llvm-project/clang/include/clang/Parse/Parser.h
@@ -13,21 +13,15 @@
#ifndef LLVM_CLANG_PARSE_PARSER_H
#define LLVM_CLANG_PARSE_PARSER_H
-#include "clang/AST/Availability.h"
-#include "clang/Basic/BitmaskEnum.h"
-#include "clang/Basic/OpenMPKinds.h"
+#include "clang/Basic/OpenACCKinds.h"
#include "clang/Basic/OperatorPrecedence.h"
-#include "clang/Basic/Specifiers.h"
#include "clang/Lex/CodeCompletionHandler.h"
#include "clang/Lex/Preprocessor.h"
-#include "clang/Sema/DeclSpec.h"
#include "clang/Sema/Sema.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Frontend/OpenMP/OMPContext.h"
-#include "llvm/Support/Compiler.h"
-#include "llvm/Support/PrettyStackTrace.h"
#include "llvm/Support/SaveAndRestore.h"
-#include <memory>
+#include <optional>
#include <stack>
namespace clang {
@@ -60,7 +54,9 @@ namespace clang {
class Parser : public CodeCompletionHandler {
friend class ColonProtectionRAIIObject;
friend class ParsingOpenMPDirectiveRAII;
+ friend class ParsingOpenACCDirectiveRAII;
friend class InMessageExpressionRAIIObject;
+ friend class OffsetOfStateRAIIObject;
friend class PoisonSEHIdentifiersRAIIObject;
friend class ObjCDeclContextSwitch;
friend class ParenBraceBracketBalancer;
@@ -155,7 +151,7 @@ class Parser : public CodeCompletionHandler {
/// Identifiers used by the 'external_source_symbol' attribute.
IdentifierInfo *Ident_language, *Ident_defined_in,
- *Ident_generated_declaration;
+ *Ident_generated_declaration, *Ident_USR;
/// C++11 contextual keywords.
mutable IdentifierInfo *Ident_final;
@@ -181,9 +177,11 @@ class Parser : public CodeCompletionHandler {
std::unique_ptr<PragmaHandler> FPContractHandler;
std::unique_ptr<PragmaHandler> OpenCLExtensionHandler;
std::unique_ptr<PragmaHandler> OpenMPHandler;
+ std::unique_ptr<PragmaHandler> OpenACCHandler;
std::unique_ptr<PragmaHandler> PCSectionHandler;
std::unique_ptr<PragmaHandler> MSCommentHandler;
std::unique_ptr<PragmaHandler> MSDetectMismatchHandler;
+ std::unique_ptr<PragmaHandler> FPEvalMethodHandler;
std::unique_ptr<PragmaHandler> FloatControlHandler;
std::unique_ptr<PragmaHandler> MSPointersToMembers;
std::unique_ptr<PragmaHandler> MSVtorDisp;
@@ -193,9 +191,13 @@ class Parser : public CodeCompletionHandler {
std::unique_ptr<PragmaHandler> MSConstSeg;
std::unique_ptr<PragmaHandler> MSCodeSeg;
std::unique_ptr<PragmaHandler> MSSection;
+ std::unique_ptr<PragmaHandler> MSStrictGuardStackCheck;
std::unique_ptr<PragmaHandler> MSRuntimeChecks;
std::unique_ptr<PragmaHandler> MSIntrinsic;
+ std::unique_ptr<PragmaHandler> MSFunction;
std::unique_ptr<PragmaHandler> MSOptimize;
+ std::unique_ptr<PragmaHandler> MSFenvAccess;
+ std::unique_ptr<PragmaHandler> MSAllocText;
std::unique_ptr<PragmaHandler> CUDAForceHostDeviceHandler;
std::unique_ptr<PragmaHandler> OptimizeHandler;
std::unique_ptr<PragmaHandler> LoopHintHandler;
@@ -211,6 +213,7 @@ class Parser : public CodeCompletionHandler {
std::unique_ptr<PragmaHandler> AttributePragmaHandler;
std::unique_ptr<PragmaHandler> MaxTokensHerePragmaHandler;
std::unique_ptr<PragmaHandler> MaxTokensTotalPragmaHandler;
+ std::unique_ptr<PragmaHandler> RISCVPragmaHandler;
std::unique_ptr<CommentHandler> CommentSemaHandler;
@@ -229,6 +232,29 @@ class Parser : public CodeCompletionHandler {
/// Parsing OpenMP directive mode.
bool OpenMPDirectiveParsing = false;
+ /// Parsing OpenACC directive mode.
+ bool OpenACCDirectiveParsing = false;
+
+ /// Currently parsing a situation where an OpenACC array section could be
+ /// legal, such as a 'var-list'.
+ bool AllowOpenACCArraySections = false;
+
+ /// RAII object to set reset OpenACC parsing a context where Array Sections
+ /// are allowed.
+ class OpenACCArraySectionRAII {
+ Parser &P;
+
+ public:
+ OpenACCArraySectionRAII(Parser &P) : P(P) {
+ assert(!P.AllowOpenACCArraySections);
+ P.AllowOpenACCArraySections = true;
+ }
+ ~OpenACCArraySectionRAII() {
+ assert(P.AllowOpenACCArraySections);
+ P.AllowOpenACCArraySections = false;
+ }
+ };
+
/// When true, we are directly inside an Objective-C message
/// send expression.
///
@@ -241,6 +267,8 @@ class Parser : public CodeCompletionHandler {
/// function call.
bool CalledSignatureHelp = false;
+ Sema::OffsetOfKind OffsetOfState = Sema::OffsetOfKind::OOK_Outside;
+
/// The "depth" of the template parameters currently being parsed.
unsigned TemplateParameterDepth;
@@ -408,18 +436,15 @@ class Parser : public CodeCompletionHandler {
/// Flags describing a context in which we're parsing a statement.
enum class ParsedStmtContext {
- /// This context permits declarations in language modes where declarations
- /// are not statements.
- AllowDeclarationsInC = 0x1,
/// This context permits standalone OpenMP directives.
- AllowStandaloneOpenMPDirectives = 0x2,
+ AllowStandaloneOpenMPDirectives = 0x1,
/// This context is at the top level of a GNU statement expression.
- InStmtExpr = 0x4,
+ InStmtExpr = 0x2,
/// The context of a regular substatement.
SubStmt = 0,
/// The context of a compound-statement.
- Compound = AllowDeclarationsInC | AllowStandaloneOpenMPDirectives,
+ Compound = AllowStandaloneOpenMPDirectives,
LLVM_MARK_AS_BITMASK_ENUM(InStmtExpr)
};
@@ -445,7 +470,9 @@ public:
return Actions.incrementMSManglingNumber();
}
- Decl *getObjCDeclContext() const { return Actions.getObjCDeclContext(); }
+ ObjCContainerDecl *getObjCDeclContext() const {
+ return Actions.getObjCDeclContext();
+ }
// Type forwarding. All of these are statically 'void*', but they may all be
// different actual classes based on the actions in place.
@@ -456,6 +483,9 @@ public:
typedef Sema::FullExprArg FullExprArg;
+ /// A SmallVector of statements.
+ typedef SmallVector<Stmt *, 32> StmtVector;
+
// Parsing methods.
/// Initialize - Warm up the parser.
@@ -463,14 +493,17 @@ public:
void Initialize();
/// Parse the first top-level declaration in a translation unit.
- bool ParseFirstTopLevelDecl(DeclGroupPtrTy &Result);
+ bool ParseFirstTopLevelDecl(DeclGroupPtrTy &Result,
+ Sema::ModuleImportState &ImportState);
/// ParseTopLevelDecl - Parse one top-level declaration. Returns true if
/// the EOF was encountered.
- bool ParseTopLevelDecl(DeclGroupPtrTy &Result, bool IsFirstDecl = false);
+ bool ParseTopLevelDecl(DeclGroupPtrTy &Result,
+ Sema::ModuleImportState &ImportState);
bool ParseTopLevelDecl() {
DeclGroupPtrTy Result;
- return ParseTopLevelDecl(Result);
+ Sema::ModuleImportState IS = Sema::ModuleImportState::NotACXX20Module;
+ return ParseTopLevelDecl(Result, IS);
}
/// ConsumeToken - Consume the current 'peek token' and lex the next one.
@@ -653,9 +686,9 @@ private:
return PrevTokLocation;
}
- ///\ brief When we are consuming a code-completion token without having
- /// matched specific position in the grammar, provide code-completion results
- /// based on context.
+ /// When we are consuming a code-completion token without having matched
+ /// specific position in the grammar, provide code-completion results based
+ /// on context.
///
/// \returns the source location of the code-completion token.
SourceLocation handleUnexpectedCodeCompletionToken();
@@ -674,7 +707,8 @@ private:
bool isEofOrEom() {
tok::TokenKind Kind = Tok.getKind();
return Kind == tok::eof || Kind == tok::annot_module_begin ||
- Kind == tok::annot_module_end || Kind == tok::annot_module_include;
+ Kind == tok::annot_module_end || Kind == tok::annot_module_include ||
+ Kind == tok::annot_repl_input_end;
}
/// Checks if the \p Level is valid for use in a fold expression.
@@ -715,6 +749,14 @@ private:
SourceLocation PragmaLocation);
bool HandlePragmaMSInitSeg(StringRef PragmaName,
SourceLocation PragmaLocation);
+ bool HandlePragmaMSStrictGuardStackCheck(StringRef PragmaName,
+ SourceLocation PragmaLocation);
+ bool HandlePragmaMSFunction(StringRef PragmaName,
+ SourceLocation PragmaLocation);
+ bool HandlePragmaMSAllocText(StringRef PragmaName,
+ SourceLocation PragmaLocation);
+ bool HandlePragmaMSOptimize(StringRef PragmaName,
+ SourceLocation PragmaLocation);
/// Handle the annotation token produced for
/// #pragma align...
@@ -749,6 +791,10 @@ private:
void HandlePragmaFEnvRound();
/// Handle the annotation token produced for
+ /// #pragma STDC CX_LIMITED_RANGE...
+ void HandlePragmaCXLimitedRange();
+
+ /// Handle the annotation token produced for
/// #pragma float_control
void HandlePragmaFloatControl();
@@ -838,16 +884,20 @@ private:
public:
// If NeedType is true, then TryAnnotateTypeOrScopeToken will try harder to
// find a type name by attempting typo correction.
- bool TryAnnotateTypeOrScopeToken();
- bool TryAnnotateTypeOrScopeTokenAfterScopeSpec(CXXScopeSpec &SS,
- bool IsNewScope);
+ bool
+ TryAnnotateTypeOrScopeToken(ImplicitTypenameContext AllowImplicitTypename =
+ ImplicitTypenameContext::No);
+ bool TryAnnotateTypeOrScopeTokenAfterScopeSpec(
+ CXXScopeSpec &SS, bool IsNewScope,
+ ImplicitTypenameContext AllowImplicitTypename);
bool TryAnnotateCXXScopeToken(bool EnteringContext = false);
bool MightBeCXXScopeToken() {
- return Tok.is(tok::identifier) || Tok.is(tok::coloncolon) ||
- (Tok.is(tok::annot_template_id) &&
- NextToken().is(tok::coloncolon)) ||
- Tok.is(tok::kw_decltype) || Tok.is(tok::kw___super);
+ return getLangOpts().CPlusPlus &&
+ (Tok.is(tok::identifier) || Tok.is(tok::coloncolon) ||
+ (Tok.is(tok::annot_template_id) &&
+ NextToken().is(tok::coloncolon)) ||
+ Tok.is(tok::kw_decltype) || Tok.is(tok::kw___super));
}
bool TryAnnotateOptionalCXXScopeToken(bool EnteringContext = false) {
return MightBeCXXScopeToken() && TryAnnotateCXXScopeToken(EnteringContext);
@@ -866,7 +916,11 @@ private:
/// Annotation was successful.
ANK_Success
};
- AnnotatedNameKind TryAnnotateName(CorrectionCandidateCallback *CCC = nullptr);
+
+ AnnotatedNameKind
+ TryAnnotateName(CorrectionCandidateCallback *CCC = nullptr,
+ ImplicitTypenameContext AllowImplicitTypename =
+ ImplicitTypenameContext::No);
/// Push a tok::annot_cxxscope token onto the token stream.
void AnnotateScopeToken(CXXScopeSpec &SS, bool IsNewAnnotation);
@@ -996,18 +1050,18 @@ private:
/// back.
class ObjCDeclContextSwitch {
Parser &P;
- Decl *DC;
+ ObjCContainerDecl *DC;
SaveAndRestore<bool> WithinObjCContainer;
public:
explicit ObjCDeclContextSwitch(Parser &p)
: P(p), DC(p.getObjCDeclContext()),
WithinObjCContainer(P.ParsingInObjCContainer, DC != nullptr) {
if (DC)
- P.Actions.ActOnObjCTemporaryExitContainerContext(cast<DeclContext>(DC));
+ P.Actions.ActOnObjCTemporaryExitContainerContext(DC);
}
~ObjCDeclContextSwitch() {
if (DC)
- P.Actions.ActOnObjCReenterContainerContext(cast<DeclContext>(DC));
+ P.Actions.ActOnObjCReenterContainerContext(DC);
}
};
@@ -1028,7 +1082,7 @@ private:
/// If the next token is not a semicolon, this emits the specified diagnostic,
/// or, if there's just some closing-delimiter noise (e.g., ')' or ']') prior
/// to the semicolon, consumes that extra token.
- bool ExpectAndConsumeSemi(unsigned DiagID);
+ bool ExpectAndConsumeSemi(unsigned DiagID , StringRef TokenUsed = "");
/// The kind of extra semi diagnostic to emit.
enum ExtraSemiKind {
@@ -1055,9 +1109,9 @@ private:
StmtExprBegin,
/// A '}' ')' ending a statement-expression.
StmtExprEnd,
- /// A '[' '[' beginning a C++11 or C2x attribute.
+ /// A '[' '[' beginning a C++11 or C23 attribute.
AttrBegin,
- /// A ']' ']' ending a C++11 or C2x attribute.
+ /// A ']' ']' ending a C++11 or C23 attribute.
AttrEnd,
/// A '::' '*' forming a C++ pointer-to-member declaration.
MemberPtr,
@@ -1152,7 +1206,7 @@ private:
/// RAII object used to modify the scope flags for the current scope.
class ParseScopeFlags {
Scope *CurScope;
- unsigned OldFlags;
+ unsigned OldFlags = 0;
ParseScopeFlags(const ParseScopeFlags &) = delete;
void operator=(const ParseScopeFlags &) = delete;
@@ -1203,7 +1257,7 @@ public:
/// returns false.
bool SkipUntil(tok::TokenKind T,
SkipUntilFlags Flags = static_cast<SkipUntilFlags>(0)) {
- return SkipUntil(llvm::makeArrayRef(T), Flags);
+ return SkipUntil(llvm::ArrayRef(T), Flags);
}
bool SkipUntil(tok::TokenKind T1, tok::TokenKind T2,
SkipUntilFlags Flags = static_cast<SkipUntilFlags>(0)) {
@@ -1474,8 +1528,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,
@@ -1540,7 +1593,7 @@ private:
};
NamedDecl *ParseCXXInlineMethodDef(AccessSpecifier AS,
- ParsedAttributes &AccessAttrs,
+ const ParsedAttributesView &AccessAttrs,
ParsingDeclarator &D,
const ParsedTemplateInfo &TemplateInfo,
const VirtSpecifiers &VS,
@@ -1576,15 +1629,16 @@ private:
//===--------------------------------------------------------------------===//
// C99 6.9: External Definitions.
- DeclGroupPtrTy ParseExternalDeclaration(ParsedAttributesWithRange &attrs,
+ DeclGroupPtrTy ParseExternalDeclaration(ParsedAttributes &DeclAttrs,
+ ParsedAttributes &DeclSpecAttrs,
ParsingDeclSpec *DS = nullptr);
bool isDeclarationAfterDeclarator();
bool isStartOfFunctionDefinition(const ParsingDeclarator &Declarator);
DeclGroupPtrTy ParseDeclarationOrFunctionDefinition(
- ParsedAttributesWithRange &attrs,
- ParsingDeclSpec *DS = nullptr,
- AccessSpecifier AS = AS_none);
- DeclGroupPtrTy ParseDeclOrFunctionDefInternal(ParsedAttributesWithRange &attrs,
+ ParsedAttributes &DeclAttrs, ParsedAttributes &DeclSpecAttrs,
+ ParsingDeclSpec *DS = nullptr, AccessSpecifier AS = AS_none);
+ DeclGroupPtrTy ParseDeclOrFunctionDefInternal(ParsedAttributes &Attrs,
+ ParsedAttributes &DeclSpecAttrs,
ParsingDeclSpec &DS,
AccessSpecifier AS);
@@ -1599,7 +1653,8 @@ private:
// Objective-C External Declarations
void MaybeSkipAttributes(tok::ObjCKeywordKind Kind);
- DeclGroupPtrTy ParseObjCAtDirectives(ParsedAttributesWithRange &Attrs);
+ DeclGroupPtrTy ParseObjCAtDirectives(ParsedAttributes &DeclAttrs,
+ ParsedAttributes &DeclSpecAttrs);
DeclGroupPtrTy ParseObjCAtClassDeclaration(SourceLocation atLoc);
Decl *ParseObjCAtInterfaceDeclaration(SourceLocation AtLoc,
ParsedAttributes &prefixAttrs);
@@ -1610,11 +1665,12 @@ private:
SmallVectorImpl<IdentifierLocPair> &protocolIdents,
SourceLocation &rAngleLoc, bool mayBeProtocolList = true);
- void HelperActionsForIvarDeclarations(Decl *interfaceDecl, SourceLocation atLoc,
+ void HelperActionsForIvarDeclarations(ObjCContainerDecl *interfaceDecl,
+ SourceLocation atLoc,
BalancedDelimiterTracker &T,
SmallVectorImpl<Decl *> &AllIvarDecls,
bool RBraceMissing);
- void ParseObjCClassInstanceVariables(Decl *interfaceDecl,
+ void ParseObjCClassInstanceVariables(ObjCContainerDecl *interfaceDecl,
tok::ObjCKeywordKind visibility,
SourceLocation atLoc);
bool ParseObjCProtocolReferences(SmallVectorImpl<Decl *> &P,
@@ -1736,7 +1792,8 @@ public:
ExprResult ParseExpression(TypeCastState isTypeCast = NotTypeCast);
ExprResult ParseConstantExpressionInExprEvalContext(
TypeCastState isTypeCast = NotTypeCast);
- ExprResult ParseConstantExpression(TypeCastState isTypeCast = NotTypeCast);
+ ExprResult ParseConstantExpression();
+ ExprResult ParseArrayBoundExpression();
ExprResult ParseCaseExpression(SourceLocation CaseLoc);
ExprResult ParseConstraintExpression();
ExprResult
@@ -1750,8 +1807,12 @@ public:
bool IsUnevaluated);
ExprResult ParseStringLiteralExpression(bool AllowUserDefinedLiteral = false);
+ ExprResult ParseUnevaluatedStringLiteralExpression();
private:
+ ExprResult ParseStringLiteralExpression(bool AllowUserDefinedLiteral,
+ bool Unevaluated);
+
ExprResult ParseExpressionWithLeadingAt(SourceLocation AtLoc);
ExprResult ParseExpressionWithLeadingExtension(SourceLocation ExtLoc);
@@ -1808,19 +1869,16 @@ private:
ParsedType &CastTy,
SourceRange &CastRange);
- typedef SmallVector<SourceLocation, 20> CommaLocsTy;
-
/// ParseExpressionList - Used for C/C++ (argument-)expression-list.
bool ParseExpressionList(SmallVectorImpl<Expr *> &Exprs,
- SmallVectorImpl<SourceLocation> &CommaLocs,
llvm::function_ref<void()> ExpressionStarts =
- llvm::function_ref<void()>());
+ llvm::function_ref<void()>(),
+ bool FailImmediatelyOnInvalidExpr = false,
+ bool EarlyTypoCorrection = false);
/// ParseSimpleExpressionList - A simple comma-separated list of expressions,
/// used for misc language extensions.
- bool ParseSimpleExpressionList(SmallVectorImpl<Expr*> &Exprs,
- SmallVectorImpl<SourceLocation> &CommaLocs);
-
+ bool ParseSimpleExpressionList(SmallVectorImpl<Expr *> &Exprs);
/// ParenParseOption - Control what ParseParenExpression will parse.
enum ParenParseOption {
@@ -1958,7 +2016,8 @@ private:
/// simple-type-specifier.
void ParseCXXSimpleTypeSpecifier(DeclSpec &DS);
- bool ParseCXXTypeSpecifierSeq(DeclSpec &DS);
+ bool ParseCXXTypeSpecifierSeq(
+ DeclSpec &DS, DeclaratorContext Context = DeclaratorContext::TypeName);
//===--------------------------------------------------------------------===//
// C++ 5.3.4 and 5.3.5: C++ new and delete
@@ -1975,8 +2034,11 @@ private:
Sema::ConditionResult ParseCXXCondition(StmtResult *InitStmt,
SourceLocation Loc,
Sema::ConditionKind CK,
+ bool MissingOK,
ForRangeInfo *FRI = nullptr,
bool EnterForConditionScope = false);
+ DeclGroupPtrTy ParseAliasDeclarationInInitStatement(DeclaratorContext Context,
+ ParsedAttributes &Attrs);
//===--------------------------------------------------------------------===//
// C++ Coroutines
@@ -2041,13 +2103,8 @@ private:
//===--------------------------------------------------------------------===//
// C99 6.8: Statements and Blocks.
- /// A SmallVector of statements, with stack size 32 (as that is the only one
- /// used.)
- typedef SmallVector<Stmt*, 32> StmtVector;
- /// A SmallVector of expressions, with stack size 12 (the maximum used.)
+ /// A SmallVector of expressions.
typedef SmallVector<Expr*, 12> ExprVector;
- /// A SmallVector of types.
- typedef SmallVector<ParsedType, 12> TypeVector;
StmtResult
ParseStatement(SourceLocation *TrailingElseLoc = nullptr,
@@ -2056,12 +2113,11 @@ private:
StmtVector &Stmts, ParsedStmtContext StmtCtx,
SourceLocation *TrailingElseLoc = nullptr);
StmtResult ParseStatementOrDeclarationAfterAttributes(
- StmtVector &Stmts,
- ParsedStmtContext StmtCtx,
- SourceLocation *TrailingElseLoc,
- ParsedAttributesWithRange &Attrs);
+ StmtVector &Stmts, ParsedStmtContext StmtCtx,
+ SourceLocation *TrailingElseLoc, ParsedAttributes &DeclAttrs,
+ ParsedAttributes &DeclSpecAttrs);
StmtResult ParseExprStatement(ParsedStmtContext StmtCtx);
- StmtResult ParseLabeledStatement(ParsedAttributesWithRange &attrs,
+ StmtResult ParseLabeledStatement(ParsedAttributes &Attrs,
ParsedStmtContext StmtCtx);
StmtResult ParseCaseStatement(ParsedStmtContext StmtCtx,
bool MissingCase = false,
@@ -2071,13 +2127,14 @@ private:
StmtResult ParseCompoundStatement(bool isStmtExpr,
unsigned ScopeFlags);
void ParseCompoundStatementLeadingPragmas();
+ void DiagnoseLabelAtEndOfCompoundStatement();
bool ConsumeNullStmt(StmtVector &Stmts);
StmtResult ParseCompoundStatementBody(bool isStmtExpr = false);
bool ParseParenExprOrCondition(StmtResult *InitStmt,
Sema::ConditionResult &CondResult,
SourceLocation Loc, Sema::ConditionKind CK,
- SourceLocation *LParenLoc = nullptr,
- SourceLocation *RParenLoc = nullptr);
+ SourceLocation &LParenLoc,
+ SourceLocation &RParenLoc);
StmtResult ParseIfStatement(SourceLocation *TrailingElseLoc);
StmtResult ParseSwitchStatement(SourceLocation *TrailingElseLoc);
StmtResult ParseWhileStatement(SourceLocation *TrailingElseLoc);
@@ -2089,10 +2146,9 @@ private:
StmtResult ParseReturnStatement();
StmtResult ParseAsmStatement(bool &msAsm);
StmtResult ParseMicrosoftAsmStatement(SourceLocation AsmLoc);
- StmtResult ParsePragmaLoopHint(StmtVector &Stmts,
- ParsedStmtContext StmtCtx,
+ StmtResult ParsePragmaLoopHint(StmtVector &Stmts, ParsedStmtContext StmtCtx,
SourceLocation *TrailingElseLoc,
- ParsedAttributesWithRange &Attrs);
+ ParsedAttributes &Attrs);
/// Describes the behavior that should be taken for an __if_exists
/// block.
@@ -2171,16 +2227,21 @@ private:
/// out, there are other significant restrictions on specifiers than
/// would be best implemented in the parser.
enum class DeclSpecContext {
- DSC_normal, // normal context
- DSC_class, // class context, enables 'friend'
+ DSC_normal, // normal context
+ DSC_class, // class context, enables 'friend'
DSC_type_specifier, // C++ type-specifier-seq or C specifier-qualifier-list
DSC_trailing, // C++11 trailing-type-specifier in a trailing return type
- DSC_alias_declaration, // C++11 type-specifier-seq in an alias-declaration
- DSC_top_level, // top-level/namespace declaration context
- DSC_template_param, // template parameter context
- DSC_template_type_arg, // template type argument context
- DSC_objc_method_result, // ObjC method result context, enables 'instancetype'
- DSC_condition // condition declaration context
+ DSC_alias_declaration, // C++11 type-specifier-seq in an alias-declaration
+ DSC_conv_operator, // C++ type-specifier-seq in an conversion operator
+ DSC_top_level, // top-level/namespace declaration context
+ DSC_template_param, // template parameter context
+ DSC_template_arg, // template argument context
+ DSC_template_type_arg, // template type argument context
+ DSC_objc_method_result, // ObjC method result context, enables
+ // 'instancetype'
+ DSC_condition, // condition declaration context
+ DSC_association, // A _Generic selection expression's type association
+ DSC_new, // C++ new expression
};
/// Is this a context in which we are parsing just a type-specifier (or
@@ -2189,6 +2250,7 @@ private:
switch (DSC) {
case DeclSpecContext::DSC_normal:
case DeclSpecContext::DSC_template_param:
+ case DeclSpecContext::DSC_template_arg:
case DeclSpecContext::DSC_class:
case DeclSpecContext::DSC_top_level:
case DeclSpecContext::DSC_objc_method_result:
@@ -2197,8 +2259,11 @@ private:
case DeclSpecContext::DSC_template_type_arg:
case DeclSpecContext::DSC_type_specifier:
+ case DeclSpecContext::DSC_conv_operator:
case DeclSpecContext::DSC_trailing:
case DeclSpecContext::DSC_alias_declaration:
+ case DeclSpecContext::DSC_association:
+ case DeclSpecContext::DSC_new:
return true;
}
llvm_unreachable("Missing DeclSpecContext case");
@@ -2223,7 +2288,7 @@ private:
/// so permit class and enum definitions in addition to non-defining class and
/// enum elaborated-type-specifiers)?
static AllowDefiningTypeSpec
- isDefiningTypeSpecifierContext(DeclSpecContext DSC) {
+ isDefiningTypeSpecifierContext(DeclSpecContext DSC, bool IsCPlusPlus) {
switch (DSC) {
case DeclSpecContext::DSC_normal:
case DeclSpecContext::DSC_class:
@@ -2240,7 +2305,14 @@ private:
case DeclSpecContext::DSC_type_specifier:
return AllowDefiningTypeSpec::NoButErrorRecovery;
+ case DeclSpecContext::DSC_association:
+ return IsCPlusPlus ? AllowDefiningTypeSpec::NoButErrorRecovery
+ : AllowDefiningTypeSpec::Yes;
+
case DeclSpecContext::DSC_trailing:
+ case DeclSpecContext::DSC_conv_operator:
+ case DeclSpecContext::DSC_template_arg:
+ case DeclSpecContext::DSC_new:
return AllowDefiningTypeSpec::No;
}
llvm_unreachable("Missing DeclSpecContext case");
@@ -2261,6 +2333,11 @@ private:
case DeclSpecContext::DSC_template_type_arg:
case DeclSpecContext::DSC_type_specifier:
case DeclSpecContext::DSC_trailing:
+ case DeclSpecContext::DSC_association:
+ case DeclSpecContext::DSC_conv_operator:
+ case DeclSpecContext::DSC_template_arg:
+ case DeclSpecContext::DSC_new:
+
return false;
}
llvm_unreachable("Missing DeclSpecContext case");
@@ -2272,10 +2349,14 @@ private:
switch (DSC) {
case DeclSpecContext::DSC_normal:
case DeclSpecContext::DSC_template_param:
+ case DeclSpecContext::DSC_template_arg:
case DeclSpecContext::DSC_class:
case DeclSpecContext::DSC_top_level:
case DeclSpecContext::DSC_condition:
case DeclSpecContext::DSC_type_specifier:
+ case DeclSpecContext::DSC_association:
+ case DeclSpecContext::DSC_conv_operator:
+ case DeclSpecContext::DSC_new:
return true;
case DeclSpecContext::DSC_objc_method_result:
@@ -2287,6 +2368,31 @@ private:
llvm_unreachable("Missing DeclSpecContext case");
}
+ // Is this a context in which an implicit 'typename' is allowed?
+ static ImplicitTypenameContext
+ getImplicitTypenameContext(DeclSpecContext DSC) {
+ switch (DSC) {
+ case DeclSpecContext::DSC_class:
+ case DeclSpecContext::DSC_top_level:
+ case DeclSpecContext::DSC_type_specifier:
+ case DeclSpecContext::DSC_template_type_arg:
+ case DeclSpecContext::DSC_trailing:
+ case DeclSpecContext::DSC_alias_declaration:
+ case DeclSpecContext::DSC_template_param:
+ case DeclSpecContext::DSC_new:
+ return ImplicitTypenameContext::Yes;
+
+ case DeclSpecContext::DSC_normal:
+ case DeclSpecContext::DSC_objc_method_result:
+ case DeclSpecContext::DSC_condition:
+ case DeclSpecContext::DSC_template_arg:
+ case DeclSpecContext::DSC_conv_operator:
+ case DeclSpecContext::DSC_association:
+ return ImplicitTypenameContext::No;
+ }
+ llvm_unreachable("Missing DeclSpecContext case");
+ }
+
/// Information on a C++0x for-range-initializer found while parsing a
/// declaration which turns out to be a for-range-declaration.
struct ForRangeInit {
@@ -2301,15 +2407,18 @@ private:
DeclGroupPtrTy ParseDeclaration(DeclaratorContext Context,
SourceLocation &DeclEnd,
- ParsedAttributesWithRange &attrs,
+ ParsedAttributes &DeclAttrs,
+ ParsedAttributes &DeclSpecAttrs,
SourceLocation *DeclSpecStart = nullptr);
DeclGroupPtrTy
ParseSimpleDeclaration(DeclaratorContext Context, SourceLocation &DeclEnd,
- ParsedAttributesWithRange &attrs, bool RequireSemi,
+ ParsedAttributes &DeclAttrs,
+ ParsedAttributes &DeclSpecAttrs, bool RequireSemi,
ForRangeInit *FRI = nullptr,
SourceLocation *DeclSpecStart = nullptr);
bool MightBeDeclarator(DeclaratorContext Context);
DeclGroupPtrTy ParseDeclGroup(ParsingDeclSpec &DS, DeclaratorContext Context,
+ ParsedAttributes &Attrs,
SourceLocation *DeclEnd = nullptr,
ForRangeInit *FRI = nullptr);
Decl *ParseDeclarationAfterDeclarator(Declarator &D,
@@ -2331,7 +2440,7 @@ private:
bool ParseImplicitInt(DeclSpec &DS, CXXScopeSpec *SS,
const ParsedTemplateInfo &TemplateInfo,
AccessSpecifier AS, DeclSpecContext DSC,
- ParsedAttributesWithRange &Attrs);
+ ParsedAttributes &Attrs);
DeclSpecContext
getDeclSpecContextFromDeclaratorContext(DeclaratorContext Context);
void ParseDeclarationSpecifiers(
@@ -2339,13 +2448,28 @@ private:
const ParsedTemplateInfo &TemplateInfo = ParsedTemplateInfo(),
AccessSpecifier AS = AS_none,
DeclSpecContext DSC = DeclSpecContext::DSC_normal,
- LateParsedAttrList *LateAttrs = nullptr);
+ LateParsedAttrList *LateAttrs = nullptr) {
+ return ParseDeclarationSpecifiers(DS, TemplateInfo, AS, DSC, LateAttrs,
+ getImplicitTypenameContext(DSC));
+ }
+ void ParseDeclarationSpecifiers(
+ DeclSpec &DS, const ParsedTemplateInfo &TemplateInfo, AccessSpecifier AS,
+ DeclSpecContext DSC, LateParsedAttrList *LateAttrs,
+ ImplicitTypenameContext AllowImplicitTypename);
+
bool DiagnoseMissingSemiAfterTagDefinition(
DeclSpec &DS, AccessSpecifier AS, DeclSpecContext DSContext,
LateParsedAttrList *LateAttrs = nullptr);
void ParseSpecifierQualifierList(
DeclSpec &DS, AccessSpecifier AS = AS_none,
+ DeclSpecContext DSC = DeclSpecContext::DSC_normal) {
+ ParseSpecifierQualifierList(DS, getImplicitTypenameContext(DSC), AS, DSC);
+ }
+
+ void ParseSpecifierQualifierList(
+ DeclSpec &DS, ImplicitTypenameContext AllowImplicitTypename,
+ AccessSpecifier AS = AS_none,
DeclSpecContext DSC = DeclSpecContext::DSC_normal);
void ParseObjCTypeQualifierList(ObjCDeclSpec &DS,
@@ -2362,7 +2486,10 @@ private:
ParsingDeclSpec &DS,
llvm::function_ref<void(ParsingFieldDeclarator &)> FieldsCallback);
- bool isDeclarationSpecifier(bool DisambiguatingWithExpression = false);
+ DeclGroupPtrTy ParseTopLevelStmtDecl();
+
+ bool isDeclarationSpecifier(ImplicitTypenameContext AllowImplicitTypename,
+ bool DisambiguatingWithExpression = false);
bool isTypeSpecifierQualifier();
/// isKnownToBeTypeSpecifier - Return true if we know that the specified token
@@ -2375,17 +2502,21 @@ private:
/// cast. Return false if it's no a decl-specifier, or we're not sure.
bool isKnownToBeDeclarationSpecifier() {
if (getLangOpts().CPlusPlus)
- return isCXXDeclarationSpecifier() == TPResult::True;
- return isDeclarationSpecifier(true);
+ return isCXXDeclarationSpecifier(ImplicitTypenameContext::No) ==
+ TPResult::True;
+ return isDeclarationSpecifier(ImplicitTypenameContext::No, true);
}
/// isDeclarationStatement - Disambiguates between a declaration or an
/// expression statement, when parsing function bodies.
+ ///
+ /// \param DisambiguatingWithExpression - True to indicate that the purpose of
+ /// this check is to disambiguate between an expression and a declaration.
/// Returns true for declaration, false for expression.
- bool isDeclarationStatement() {
+ bool isDeclarationStatement(bool DisambiguatingWithExpression = false) {
if (getLangOpts().CPlusPlus)
- return isCXXDeclarationStatement();
- return isDeclarationSpecifier(true);
+ return isCXXDeclarationStatement(DisambiguatingWithExpression);
+ return isDeclarationSpecifier(ImplicitTypenameContext::No, true);
}
/// isForInitDeclaration - Disambiguates between a declaration or an
@@ -2396,8 +2527,9 @@ private:
if (getLangOpts().OpenMP)
Actions.startOpenMPLoop();
if (getLangOpts().CPlusPlus)
- return isCXXSimpleDeclaration(/*AllowForRangeDecl=*/true);
- return isDeclarationSpecifier(true);
+ return Tok.is(tok::kw_using) ||
+ isCXXSimpleDeclaration(/*AllowForRangeDecl=*/true);
+ return isDeclarationSpecifier(ImplicitTypenameContext::No, true);
}
/// Determine whether this is a C++1z for-range-identifier.
@@ -2410,17 +2542,21 @@ private:
/// Starting with a scope specifier, identifier, or
/// template-id that refers to the current class, determine whether
/// this is a constructor declarator.
- bool isConstructorDeclarator(bool Unqualified, bool DeductionGuide = false);
+ bool isConstructorDeclarator(
+ bool Unqualified, bool DeductionGuide = false,
+ DeclSpec::FriendSpecified IsFriend = DeclSpec::FriendSpecified::No,
+ const ParsedTemplateInfo *TemplateInfo = nullptr);
/// Specifies the context in which type-id/expression
/// disambiguation will occur.
enum TentativeCXXTypeIdContext {
TypeIdInParens,
TypeIdUnambiguous,
- TypeIdAsTemplateArgument
+ TypeIdAsTemplateArgument,
+ TypeIdInTrailingReturnType,
+ TypeIdAsGenericSelectionArgument,
};
-
/// isTypeIdInParens - Assumes that a '(' was parsed and now we want to know
/// whether the parens contain an expression or a type-id.
/// Returns true for a type-id and false for an expression.
@@ -2435,20 +2571,36 @@ private:
return isTypeIdInParens(isAmbiguous);
}
+ /// Checks whether the current tokens form a type-id or an expression for the
+ /// purposes of use as the initial operand to a generic selection expression.
+ /// This requires special handling in C++ because it accepts either a type or
+ /// an expression, and we need to disambiguate which is which. However, we
+ /// cannot use the same logic as we've used for sizeof expressions, because
+ /// that logic relies on the operator only accepting a single argument,
+ /// whereas _Generic accepts a list of arguments.
+ bool isTypeIdForGenericSelection() {
+ if (getLangOpts().CPlusPlus) {
+ bool isAmbiguous;
+ return isCXXTypeId(TypeIdAsGenericSelectionArgument, isAmbiguous);
+ }
+ return isTypeSpecifierQualifier();
+ }
+
/// Checks if the current tokens form type-id or expression.
/// It is similar to isTypeIdInParens but does not suppose that type-id
/// is in parenthesis.
bool isTypeIdUnambiguously() {
- bool IsAmbiguous;
- if (getLangOpts().CPlusPlus)
- return isCXXTypeId(TypeIdUnambiguous, IsAmbiguous);
+ if (getLangOpts().CPlusPlus) {
+ bool isAmbiguous;
+ return isCXXTypeId(TypeIdUnambiguous, isAmbiguous);
+ }
return isTypeSpecifierQualifier();
}
/// isCXXDeclarationStatement - C++-specialized function that disambiguates
/// between a declaration or an expression statement, when parsing function
/// bodies. Returns true for declaration, false for expression.
- bool isCXXDeclarationStatement();
+ bool isCXXDeclarationStatement(bool DisambiguatingWithExpression = false);
/// isCXXSimpleDeclaration - C++-specialized function that disambiguates
/// between a simple-declaration or an expression-statement.
@@ -2464,7 +2616,9 @@ private:
/// might be a constructor-style initializer.
/// If during the disambiguation process a parsing error is encountered,
/// the function returns true to let the declaration parsing code handle it.
- bool isCXXFunctionDeclarator(bool *IsAmbiguous = nullptr);
+ bool isCXXFunctionDeclarator(bool *IsAmbiguous = nullptr,
+ ImplicitTypenameContext AllowImplicitTypename =
+ ImplicitTypenameContext::No);
struct ConditionDeclarationOrInitStatementState;
enum class ConditionOrInitStatement {
@@ -2510,7 +2664,8 @@ private:
/// BracedCastResult.
/// Doesn't consume tokens.
TPResult
- isCXXDeclarationSpecifier(TPResult BracedCastResult = TPResult::False,
+ isCXXDeclarationSpecifier(ImplicitTypenameContext AllowImplicitTypename,
+ TPResult BracedCastResult = TPResult::False,
bool *InvalidAsDeclSpec = nullptr);
/// Given that isCXXDeclarationSpecifier returns \c TPResult::True or
@@ -2545,13 +2700,16 @@ private:
TPResult TryParseProtocolQualifiers();
TPResult TryParsePtrOperatorSeq();
TPResult TryParseOperatorId();
- TPResult TryParseInitDeclaratorList();
+ TPResult TryParseInitDeclaratorList(bool MayHaveTrailingReturnType = false);
TPResult TryParseDeclarator(bool mayBeAbstract, bool mayHaveIdentifier = true,
- bool mayHaveDirectInit = false);
- TPResult
- TryParseParameterDeclarationClause(bool *InvalidAsDeclaration = nullptr,
- bool VersusTemplateArg = false);
- TPResult TryParseFunctionDeclarator();
+ bool mayHaveDirectInit = false,
+ bool mayHaveTrailingReturnType = false);
+ TPResult TryParseParameterDeclarationClause(
+ bool *InvalidAsDeclaration = nullptr, bool VersusTemplateArg = false,
+ ImplicitTypenameContext AllowImplicitTypename =
+ ImplicitTypenameContext::No);
+ TPResult TryParseFunctionDeclarator(bool MayHaveTrailingReturnType = false);
+ bool NameAfterArrowIsNonType();
TPResult TryParseBracketDeclarator();
TPResult TryConsumeDeclarationSpecifier();
@@ -2559,6 +2717,10 @@ private:
/// full validation of the syntactic structure of attributes.
bool TrySkipAttributes();
+ /// Diagnoses use of _ExtInt as being deprecated, and diagnoses use of
+ /// _BitInt as an extension when appropriate.
+ void DiagnoseBitIntUse(const Token &Tok);
+
public:
TypeResult
ParseTypeName(SourceRange *Range = nullptr,
@@ -2569,75 +2731,90 @@ public:
private:
void ParseBlockId(SourceLocation CaretLoc);
- /// Are [[]] attributes enabled?
- bool standardAttributesAllowed() const {
- const LangOptions &LO = getLangOpts();
- return LO.DoubleSquareBracketAttributes;
+ /// Return true if the next token should be treated as a [[]] attribute,
+ /// or as a keyword that behaves like one. The former is only true if
+ /// [[]] attributes are enabled, whereas the latter is true whenever
+ /// such a keyword appears. The arguments are as for
+ /// isCXX11AttributeSpecifier.
+ bool isAllowedCXX11AttributeSpecifier(bool Disambiguate = false,
+ bool OuterMightBeMessageSend = false) {
+ return (Tok.isRegularKeywordAttribute() ||
+ isCXX11AttributeSpecifier(Disambiguate, OuterMightBeMessageSend));
}
// Check for the start of an attribute-specifier-seq in a context where an
// attribute is not allowed.
bool CheckProhibitedCXX11Attribute() {
assert(Tok.is(tok::l_square));
- if (!standardAttributesAllowed() || NextToken().isNot(tok::l_square))
+ if (NextToken().isNot(tok::l_square))
return false;
return DiagnoseProhibitedCXX11Attribute();
}
bool DiagnoseProhibitedCXX11Attribute();
- void CheckMisplacedCXX11Attribute(ParsedAttributesWithRange &Attrs,
+ void CheckMisplacedCXX11Attribute(ParsedAttributes &Attrs,
SourceLocation CorrectLocation) {
- if (!standardAttributesAllowed())
- return;
- if ((Tok.isNot(tok::l_square) || NextToken().isNot(tok::l_square)) &&
+ if (!Tok.isRegularKeywordAttribute() &&
+ (Tok.isNot(tok::l_square) || NextToken().isNot(tok::l_square)) &&
Tok.isNot(tok::kw_alignas))
return;
DiagnoseMisplacedCXX11Attribute(Attrs, CorrectLocation);
}
- void DiagnoseMisplacedCXX11Attribute(ParsedAttributesWithRange &Attrs,
+ void DiagnoseMisplacedCXX11Attribute(ParsedAttributes &Attrs,
SourceLocation CorrectLocation);
- void stripTypeAttributesOffDeclSpec(ParsedAttributesWithRange &Attrs,
- DeclSpec &DS, Sema::TagUseKind TUK);
+ void stripTypeAttributesOffDeclSpec(ParsedAttributes &Attrs, DeclSpec &DS,
+ Sema::TagUseKind TUK);
// FixItLoc = possible correct location for the attributes
- void ProhibitAttributes(ParsedAttributesWithRange &Attrs,
+ void ProhibitAttributes(ParsedAttributes &Attrs,
SourceLocation FixItLoc = SourceLocation()) {
if (Attrs.Range.isInvalid())
return;
- DiagnoseProhibitedAttributes(Attrs.Range, FixItLoc);
+ DiagnoseProhibitedAttributes(Attrs, FixItLoc);
Attrs.clear();
}
- void ProhibitAttributes(ParsedAttributesViewWithRange &Attrs,
+ void ProhibitAttributes(ParsedAttributesView &Attrs,
SourceLocation FixItLoc = SourceLocation()) {
if (Attrs.Range.isInvalid())
return;
- DiagnoseProhibitedAttributes(Attrs.Range, FixItLoc);
+ DiagnoseProhibitedAttributes(Attrs, FixItLoc);
Attrs.clearListOnly();
}
- void DiagnoseProhibitedAttributes(const SourceRange &Range,
+ void DiagnoseProhibitedAttributes(const ParsedAttributesView &Attrs,
SourceLocation FixItLoc);
- // Forbid C++11 and C2x attributes that appear on certain syntactic locations
+ // Forbid C++11 and C23 attributes that appear on certain syntactic locations
// which standard permits but we don't supported yet, for example, attributes
// appertain to decl specifiers.
- void ProhibitCXX11Attributes(ParsedAttributesWithRange &Attrs,
- unsigned DiagID,
- bool DiagnoseEmptyAttrs = false);
-
- /// Skip C++11 and C2x attributes and return the end location of the
+ // For the most cases we don't want to warn on unknown type attributes, but
+ // left them to later diagnoses. However, for a few cases like module
+ // declarations and module import declarations, we should do it.
+ void ProhibitCXX11Attributes(ParsedAttributes &Attrs, unsigned AttrDiagID,
+ unsigned KeywordDiagId,
+ bool DiagnoseEmptyAttrs = false,
+ bool WarnOnUnknownAttrs = false);
+
+ /// Skip C++11 and C23 attributes and return the end location of the
/// last one.
/// \returns SourceLocation() if there are no attributes.
SourceLocation SkipCXX11Attributes();
- /// Diagnose and skip C++11 and C2x attributes that appear in syntactic
+ /// Diagnose and skip C++11 and C23 attributes that appear in syntactic
/// locations where attributes are not allowed.
void DiagnoseAndSkipCXX11Attributes();
- /// Emit warnings for C++11 and C2x attributes that are in a position that
+ /// Emit warnings for C++11 and C23 attributes that are in a position that
/// clang accepts as an extension.
- void DiagnoseCXX11AttributeExtension(ParsedAttributesWithRange &Attrs);
+ void DiagnoseCXX11AttributeExtension(ParsedAttributes &Attrs);
+
+ ExprResult ParseUnevaluatedStringInAttribute(const IdentifierInfo &AttrName);
+
+ bool
+ ParseAttributeArgumentList(const clang::IdentifierInfo &AttrName,
+ SmallVectorImpl<Expr *> &Exprs,
+ ParsedAttributeArgumentsProperties ArgsProperties);
/// Parses syntax-generic attribute arguments for attributes which are
/// known to the implementation, and adds them to the given ParsedAttributes
@@ -2647,7 +2824,7 @@ private:
ParseAttributeArgsCommon(IdentifierInfo *AttrName, SourceLocation AttrNameLoc,
ParsedAttributes &Attrs, SourceLocation *EndLoc,
IdentifierInfo *ScopeName, SourceLocation ScopeLoc,
- ParsedAttr::Syntax Syntax);
+ ParsedAttr::Form Form);
enum ParseAttrKindMask {
PAKM_GNU = 1 << 0,
@@ -2669,36 +2846,15 @@ private:
/// __attribute__(()) [[]] int i; // Not OK
///
/// Such situations should use the specific attribute parsing functionality.
- void ParseAttributes(unsigned WhichAttrKinds,
- ParsedAttributesWithRange &Attrs,
- SourceLocation *End = nullptr,
- LateParsedAttrList *LateAttrs = nullptr);
void ParseAttributes(unsigned WhichAttrKinds, ParsedAttributes &Attrs,
- SourceLocation *End = nullptr,
- LateParsedAttrList *LateAttrs = nullptr) {
- ParsedAttributesWithRange AttrsWithRange(AttrFactory);
- ParseAttributes(WhichAttrKinds, AttrsWithRange, End, LateAttrs);
- Attrs.takeAllFrom(AttrsWithRange);
- }
+ LateParsedAttrList *LateAttrs = nullptr);
/// \brief Possibly parse attributes based on what syntaxes are desired,
/// allowing for the order to vary.
- bool MaybeParseAttributes(unsigned WhichAttrKinds,
- ParsedAttributesWithRange &Attrs,
- SourceLocation *End = nullptr,
- LateParsedAttrList *LateAttrs = nullptr) {
- if (Tok.isOneOf(tok::kw___attribute, tok::kw___declspec) ||
- (standardAttributesAllowed() && isCXX11AttributeSpecifier())) {
- ParseAttributes(WhichAttrKinds, Attrs, End, LateAttrs);
- return true;
- }
- return false;
- }
bool MaybeParseAttributes(unsigned WhichAttrKinds, ParsedAttributes &Attrs,
- SourceLocation *End = nullptr,
LateParsedAttrList *LateAttrs = nullptr) {
if (Tok.isOneOf(tok::kw___attribute, tok::kw___declspec) ||
- (standardAttributesAllowed() && isCXX11AttributeSpecifier())) {
- ParseAttributes(WhichAttrKinds, Attrs, End, LateAttrs);
+ isAllowedCXX11AttributeSpecifier()) {
+ ParseAttributes(WhichAttrKinds, Attrs, LateAttrs);
return true;
}
return false;
@@ -2707,70 +2863,36 @@ private:
void MaybeParseGNUAttributes(Declarator &D,
LateParsedAttrList *LateAttrs = nullptr) {
if (Tok.is(tok::kw___attribute)) {
- ParsedAttributes attrs(AttrFactory);
- SourceLocation endLoc;
- ParseGNUAttributes(attrs, &endLoc, LateAttrs, &D);
- D.takeAttributes(attrs, endLoc);
+ ParsedAttributes Attrs(AttrFactory);
+ ParseGNUAttributes(Attrs, LateAttrs, &D);
+ D.takeAttributes(Attrs);
}
}
- /// Parses GNU-style attributes and returns them without source range
- /// information.
- ///
- /// This API is discouraged. Use the version that takes a
- /// ParsedAttributesWithRange instead.
bool MaybeParseGNUAttributes(ParsedAttributes &Attrs,
- SourceLocation *EndLoc = nullptr,
- LateParsedAttrList *LateAttrs = nullptr) {
- if (Tok.is(tok::kw___attribute)) {
- ParsedAttributesWithRange AttrsWithRange(AttrFactory);
- ParseGNUAttributes(Attrs, EndLoc, LateAttrs);
- Attrs.takeAllFrom(AttrsWithRange);
- return true;
- }
- return false;
- }
-
- bool MaybeParseGNUAttributes(ParsedAttributesWithRange &Attrs,
- SourceLocation *EndLoc = nullptr,
LateParsedAttrList *LateAttrs = nullptr) {
if (Tok.is(tok::kw___attribute)) {
- ParseGNUAttributes(Attrs, EndLoc, LateAttrs);
+ ParseGNUAttributes(Attrs, LateAttrs);
return true;
}
return false;
}
- /// Parses GNU-style attributes and returns them without source range
- /// information.
- ///
- /// This API is discouraged. Use the version that takes a
- /// ParsedAttributesWithRange instead.
void ParseGNUAttributes(ParsedAttributes &Attrs,
- SourceLocation *EndLoc = nullptr,
- LateParsedAttrList *LateAttrs = nullptr,
- Declarator *D = nullptr) {
- ParsedAttributesWithRange AttrsWithRange(AttrFactory);
- ParseGNUAttributes(AttrsWithRange, EndLoc, LateAttrs, D);
- Attrs.takeAllFrom(AttrsWithRange);
- }
-
- void ParseGNUAttributes(ParsedAttributesWithRange &Attrs,
- SourceLocation *EndLoc = nullptr,
LateParsedAttrList *LateAttrs = nullptr,
Declarator *D = nullptr);
void ParseGNUAttributeArgs(IdentifierInfo *AttrName,
SourceLocation AttrNameLoc,
ParsedAttributes &Attrs, SourceLocation *EndLoc,
IdentifierInfo *ScopeName, SourceLocation ScopeLoc,
- ParsedAttr::Syntax Syntax, Declarator *D);
+ ParsedAttr::Form Form, Declarator *D);
IdentifierLoc *ParseIdentifierLoc();
unsigned
ParseClangAttributeArgs(IdentifierInfo *AttrName, SourceLocation AttrNameLoc,
ParsedAttributes &Attrs, SourceLocation *EndLoc,
IdentifierInfo *ScopeName, SourceLocation ScopeLoc,
- ParsedAttr::Syntax Syntax);
+ ParsedAttr::Form Form);
void ReplayOpenMPAttributeTokens(CachedTokens &OpenMPTokens) {
// If parsing the attributes found an OpenMP directive, emit those tokens
@@ -2783,35 +2905,23 @@ private:
}
}
void MaybeParseCXX11Attributes(Declarator &D) {
- if (standardAttributesAllowed() && isCXX11AttributeSpecifier()) {
- ParsedAttributesWithRange attrs(AttrFactory);
- SourceLocation endLoc;
- ParseCXX11Attributes(attrs, &endLoc);
- D.takeAttributes(attrs, endLoc);
- }
- }
- bool MaybeParseCXX11Attributes(ParsedAttributes &attrs,
- SourceLocation *endLoc = nullptr) {
- if (standardAttributesAllowed() && isCXX11AttributeSpecifier()) {
- ParsedAttributesWithRange attrsWithRange(AttrFactory);
- ParseCXX11Attributes(attrsWithRange, endLoc);
- attrs.takeAllFrom(attrsWithRange);
- return true;
+ if (isAllowedCXX11AttributeSpecifier()) {
+ ParsedAttributes Attrs(AttrFactory);
+ ParseCXX11Attributes(Attrs);
+ D.takeAttributes(Attrs);
}
- return false;
}
- bool MaybeParseCXX11Attributes(ParsedAttributesWithRange &attrs,
- SourceLocation *endLoc = nullptr,
+
+ bool MaybeParseCXX11Attributes(ParsedAttributes &Attrs,
bool OuterMightBeMessageSend = false) {
- if (standardAttributesAllowed() &&
- isCXX11AttributeSpecifier(false, OuterMightBeMessageSend)) {
- ParseCXX11Attributes(attrs, endLoc);
+ if (isAllowedCXX11AttributeSpecifier(false, OuterMightBeMessageSend)) {
+ ParseCXX11Attributes(Attrs);
return true;
}
return false;
}
- void ParseOpenMPAttributeArgs(IdentifierInfo *AttrName,
+ void ParseOpenMPAttributeArgs(const IdentifierInfo *AttrName,
CachedTokens &OpenMPTokens);
void ParseCXX11AttributeSpecifierInternal(ParsedAttributes &Attrs,
@@ -2823,9 +2933,8 @@ private:
ParseCXX11AttributeSpecifierInternal(Attrs, OpenMPTokens, EndLoc);
ReplayOpenMPAttributeTokens(OpenMPTokens);
}
- void ParseCXX11Attributes(ParsedAttributesWithRange &attrs,
- SourceLocation *EndLoc = nullptr);
- /// Parses a C++11 (or C2x)-style attribute argument list. Returns true
+ void ParseCXX11Attributes(ParsedAttributes &attrs);
+ /// Parses a C++11 (or C23)-style attribute argument list. Returns true
/// if this results in adding an attribute to the ParsedAttributes list.
bool ParseCXX11AttributeArgs(IdentifierInfo *AttrName,
SourceLocation AttrNameLoc,
@@ -2834,31 +2943,55 @@ private:
SourceLocation ScopeLoc,
CachedTokens &OpenMPTokens);
- IdentifierInfo *TryParseCXX11AttributeIdentifier(SourceLocation &Loc);
+ IdentifierInfo *TryParseCXX11AttributeIdentifier(
+ SourceLocation &Loc,
+ Sema::AttributeCompletion Completion = Sema::AttributeCompletion::None,
+ const IdentifierInfo *EnclosingScope = nullptr);
+
+ void MaybeParseHLSLSemantics(Declarator &D,
+ SourceLocation *EndLoc = nullptr) {
+ assert(getLangOpts().HLSL && "MaybeParseHLSLSemantics is for HLSL only");
+ if (Tok.is(tok::colon)) {
+ ParsedAttributes Attrs(AttrFactory);
+ ParseHLSLSemantics(Attrs, EndLoc);
+ D.takeAttributes(Attrs);
+ }
+ }
- void MaybeParseMicrosoftAttributes(ParsedAttributes &attrs,
- SourceLocation *endLoc = nullptr) {
- if (getLangOpts().MicrosoftExt && Tok.is(tok::l_square))
- ParseMicrosoftAttributes(attrs, endLoc);
+ void MaybeParseHLSLSemantics(ParsedAttributes &Attrs,
+ SourceLocation *EndLoc = nullptr) {
+ assert(getLangOpts().HLSL && "MaybeParseHLSLSemantics is for HLSL only");
+ if (getLangOpts().HLSL && Tok.is(tok::colon))
+ ParseHLSLSemantics(Attrs, EndLoc);
+ }
+
+ void ParseHLSLSemantics(ParsedAttributes &Attrs,
+ SourceLocation *EndLoc = nullptr);
+ Decl *ParseHLSLBuffer(SourceLocation &DeclEnd);
+
+ void MaybeParseMicrosoftAttributes(ParsedAttributes &Attrs) {
+ if ((getLangOpts().MicrosoftExt || getLangOpts().HLSL) &&
+ Tok.is(tok::l_square)) {
+ ParsedAttributes AttrsWithRange(AttrFactory);
+ ParseMicrosoftAttributes(AttrsWithRange);
+ Attrs.takeAllFrom(AttrsWithRange);
+ }
}
void ParseMicrosoftUuidAttributeArgs(ParsedAttributes &Attrs);
- void ParseMicrosoftAttributes(ParsedAttributes &attrs,
- SourceLocation *endLoc = nullptr);
- bool MaybeParseMicrosoftDeclSpecs(ParsedAttributes &Attrs,
- SourceLocation *End = nullptr) {
- const auto &LO = getLangOpts();
- if (LO.DeclSpecKeyword && Tok.is(tok::kw___declspec)) {
- ParseMicrosoftDeclSpecs(Attrs, End);
+ void ParseMicrosoftAttributes(ParsedAttributes &Attrs);
+ bool MaybeParseMicrosoftDeclSpecs(ParsedAttributes &Attrs) {
+ if (getLangOpts().DeclSpecKeyword && Tok.is(tok::kw___declspec)) {
+ ParseMicrosoftDeclSpecs(Attrs);
return true;
}
return false;
}
- void ParseMicrosoftDeclSpecs(ParsedAttributes &Attrs,
- SourceLocation *End = nullptr);
+ void ParseMicrosoftDeclSpecs(ParsedAttributes &Attrs);
bool ParseMicrosoftDeclSpecArgs(IdentifierInfo *AttrName,
SourceLocation AttrNameLoc,
ParsedAttributes &Attrs);
void ParseMicrosoftTypeAttributes(ParsedAttributes &attrs);
+ void ParseWebAssemblyFuncrefTypeAttribute(ParsedAttributes &Attrs);
void DiagnoseAndSkipExtendedMicrosoftTypeAttributes();
SourceLocation SkipExtendedMicrosoftTypeAttributes();
void ParseMicrosoftInheritanceClassAttributes(ParsedAttributes &attrs);
@@ -2866,6 +2999,9 @@ private:
void ParseOpenCLKernelAttributes(ParsedAttributes &attrs);
void ParseOpenCLQualifiers(ParsedAttributes &Attrs);
void ParseNullabilityTypeSpecifiers(ParsedAttributes &attrs);
+ void ParseCUDAFunctionAttributes(ParsedAttributes &attrs);
+ bool isHLSLQualifier(const Token &Tok) const;
+ void ParseHLSLQualifiers(ParsedAttributes &Attrs);
VersionTuple ParseVersionTuple(SourceRange &Range);
void ParseAvailabilityAttribute(IdentifierInfo &Availability,
@@ -2874,9 +3010,9 @@ private:
SourceLocation *endLoc,
IdentifierInfo *ScopeName,
SourceLocation ScopeLoc,
- ParsedAttr::Syntax Syntax);
+ ParsedAttr::Form Form);
- Optional<AvailabilitySpec> ParseAvailabilitySpec();
+ std::optional<AvailabilitySpec> ParseAvailabilitySpec();
ExprResult ParseAvailabilityCheckExpr(SourceLocation StartLoc);
void ParseExternalSourceSymbolAttribute(IdentifierInfo &ExternalSourceSymbol,
@@ -2885,15 +3021,15 @@ private:
SourceLocation *EndLoc,
IdentifierInfo *ScopeName,
SourceLocation ScopeLoc,
- ParsedAttr::Syntax Syntax);
+ ParsedAttr::Form Form);
void ParseObjCBridgeRelatedAttribute(IdentifierInfo &ObjCBridgeRelated,
SourceLocation ObjCBridgeRelatedLoc,
- ParsedAttributes &attrs,
- SourceLocation *endLoc,
+ ParsedAttributes &Attrs,
+ SourceLocation *EndLoc,
IdentifierInfo *ScopeName,
SourceLocation ScopeLoc,
- ParsedAttr::Syntax Syntax);
+ ParsedAttr::Form Form);
void ParseSwiftNewTypeAttribute(IdentifierInfo &AttrName,
SourceLocation AttrNameLoc,
@@ -2901,7 +3037,7 @@ private:
SourceLocation *EndLoc,
IdentifierInfo *ScopeName,
SourceLocation ScopeLoc,
- ParsedAttr::Syntax Syntax);
+ ParsedAttr::Form Form);
void ParseTypeTagForDatatypeAttribute(IdentifierInfo &AttrName,
SourceLocation AttrNameLoc,
@@ -2909,24 +3045,25 @@ private:
SourceLocation *EndLoc,
IdentifierInfo *ScopeName,
SourceLocation ScopeLoc,
- ParsedAttr::Syntax Syntax);
+ ParsedAttr::Form Form);
- void
- ParseAttributeWithTypeArg(IdentifierInfo &AttrName,
- SourceLocation AttrNameLoc, ParsedAttributes &Attrs,
- SourceLocation *EndLoc, IdentifierInfo *ScopeName,
- SourceLocation ScopeLoc, ParsedAttr::Syntax Syntax);
+ void ParseAttributeWithTypeArg(IdentifierInfo &AttrName,
+ SourceLocation AttrNameLoc,
+ ParsedAttributes &Attrs,
+ IdentifierInfo *ScopeName,
+ SourceLocation ScopeLoc,
+ ParsedAttr::Form Form);
void ParseTypeofSpecifier(DeclSpec &DS);
SourceLocation ParseDecltypeSpecifier(DeclSpec &DS);
void AnnotateExistingDecltypeSpecifier(const DeclSpec &DS,
SourceLocation StartLoc,
SourceLocation EndLoc);
- void ParseUnderlyingTypeSpecifier(DeclSpec &DS);
void ParseAtomicSpecifier(DeclSpec &DS);
- ExprResult ParseAlignArgument(SourceLocation Start,
- SourceLocation &EllipsisLoc);
+ ExprResult ParseAlignArgument(StringRef KWName, SourceLocation Start,
+ SourceLocation &EllipsisLoc, bool &IsType,
+ ParsedType &Ty);
void ParseAlignmentSpecifier(ParsedAttributes &Attrs,
SourceLocation *endLoc = nullptr);
ExprResult ParseExtIntegerArgument();
@@ -2997,18 +3134,17 @@ private:
void ParseTypeQualifierListOpt(
DeclSpec &DS, unsigned AttrReqs = AR_AllAttributesParsed,
bool AtomicAllowed = true, bool IdentifierRequired = false,
- Optional<llvm::function_ref<void()>> CodeCompletionHandler = None);
+ std::optional<llvm::function_ref<void()>> CodeCompletionHandler =
+ std::nullopt);
void ParseDirectDeclarator(Declarator &D);
void ParseDecompositionDeclarator(Declarator &D);
void ParseParenDeclarator(Declarator &D);
- void ParseFunctionDeclarator(Declarator &D,
- ParsedAttributes &attrs,
+ void ParseFunctionDeclarator(Declarator &D, ParsedAttributes &FirstArgAttrs,
BalancedDelimiterTracker &Tracker,
- bool IsAmbiguous,
- bool RequiresArg = false);
+ bool IsAmbiguous, bool RequiresArg = false);
void InitCXXThisScopeForDeclaratorIfRelevant(
const Declarator &D, const DeclSpec &DS,
- llvm::Optional<Sema::CXXThisScopeRAII> &ThisScope);
+ std::optional<Sema::CXXThisScopeRAII> &ThisScope);
bool ParseRefQualifier(bool &RefQualifierIsLValueRef,
SourceLocation &RefQualifierLoc);
bool isFunctionDeclaratorIdentifierList();
@@ -3016,12 +3152,23 @@ private:
Declarator &D,
SmallVectorImpl<DeclaratorChunk::ParamInfo> &ParamInfo);
void ParseParameterDeclarationClause(
- DeclaratorContext DeclaratorContext,
- ParsedAttributes &attrs,
- SmallVectorImpl<DeclaratorChunk::ParamInfo> &ParamInfo,
- SourceLocation &EllipsisLoc);
+ Declarator &D, ParsedAttributes &attrs,
+ SmallVectorImpl<DeclaratorChunk::ParamInfo> &ParamInfo,
+ SourceLocation &EllipsisLoc) {
+ return ParseParameterDeclarationClause(
+ D.getContext(), attrs, ParamInfo, EllipsisLoc,
+ D.getCXXScopeSpec().isSet() &&
+ D.isFunctionDeclaratorAFunctionDeclaration());
+ }
+ void ParseParameterDeclarationClause(
+ DeclaratorContext DeclaratorContext, ParsedAttributes &attrs,
+ SmallVectorImpl<DeclaratorChunk::ParamInfo> &ParamInfo,
+ SourceLocation &EllipsisLoc, bool IsACXXFunctionDeclaration = false);
+
void ParseBracketDeclarator(Declarator &D);
void ParseMisplacedBracketDeclarator(Declarator &D);
+ bool MaybeParseTypeTransformTypeSpecifier(DeclSpec &DS);
+ DeclSpec::TST TypeTransformTokToDeclSpec();
//===--------------------------------------------------------------------===//
// C++ 7: Declarations [dcl.dcl]
@@ -3062,7 +3209,7 @@ private:
Decl *ParseExportDeclaration();
DeclGroupPtrTy ParseUsingDirectiveOrDeclaration(
DeclaratorContext Context, const ParsedTemplateInfo &TemplateInfo,
- SourceLocation &DeclEnd, ParsedAttributesWithRange &attrs);
+ SourceLocation &DeclEnd, ParsedAttributes &Attrs);
Decl *ParseUsingDirective(DeclaratorContext Context,
SourceLocation UsingLoc,
SourceLocation &DeclEnd,
@@ -3086,7 +3233,7 @@ private:
const ParsedTemplateInfo &TemplateInfo,
SourceLocation UsingLoc,
SourceLocation &DeclEnd,
- ParsedAttributesWithRange &Attrs,
+ ParsedAttributes &Attrs,
AccessSpecifier AS = AS_none);
Decl *ParseAliasDeclarationAfterDeclarator(
const ParsedTemplateInfo &TemplateInfo, SourceLocation UsingLoc,
@@ -3104,16 +3251,14 @@ private:
void ParseClassSpecifier(tok::TokenKind TagTokKind, SourceLocation TagLoc,
DeclSpec &DS, const ParsedTemplateInfo &TemplateInfo,
AccessSpecifier AS, bool EnteringContext,
- DeclSpecContext DSC,
- ParsedAttributesWithRange &Attributes);
+ DeclSpecContext DSC, ParsedAttributes &Attributes);
void SkipCXXMemberSpecification(SourceLocation StartLoc,
SourceLocation AttrFixitLoc,
unsigned TagType,
Decl *TagDecl);
void ParseCXXMemberSpecification(SourceLocation StartLoc,
SourceLocation AttrFixitLoc,
- ParsedAttributesWithRange &Attrs,
- unsigned TagType,
+ ParsedAttributes &Attrs, unsigned TagType,
Decl *TagDecl);
ExprResult ParseCXXMemberInitializer(Decl *D, bool IsFunction,
SourceLocation &EqualLoc);
@@ -3128,9 +3273,10 @@ private:
AccessSpecifier AS, ParsedAttributes &Attr,
const ParsedTemplateInfo &TemplateInfo = ParsedTemplateInfo(),
ParsingDeclRAIIObject *DiagsFromTParams = nullptr);
- DeclGroupPtrTy ParseCXXClassMemberDeclarationWithPragmas(
- AccessSpecifier &AS, ParsedAttributesWithRange &AccessAttrs,
- DeclSpec::TST TagType, Decl *Tag);
+ DeclGroupPtrTy
+ ParseCXXClassMemberDeclarationWithPragmas(AccessSpecifier &AS,
+ ParsedAttributes &AccessAttrs,
+ DeclSpec::TST TagType, Decl *Tag);
void ParseConstructorInitializer(Decl *ConstructorDecl);
MemInitResult ParseMemInitializer(Decl *ConstructorDecl);
void HandleMemberFunctionDeclDelays(Declarator& DeclaratorInfo,
@@ -3197,6 +3343,9 @@ private:
/// Parses OpenMP context selectors.
bool parseOMPContextSelectors(SourceLocation Loc, OMPTraitInfo &TI);
+ /// Parse an 'append_args' clause for '#pragma omp declare variant'.
+ bool parseOpenMPAppendArgs(SmallVectorImpl<OMPInteropInfo> &InteropInfos);
+
/// Parse a `match` clause for an '#pragma omp declare variant'. Return true
/// if there was an error.
bool parseOMPDeclareVariantMatchClause(SourceLocation Loc, OMPTraitInfo &TI,
@@ -3213,6 +3362,15 @@ private:
/// Parse 'omp end assumes' directive.
void ParseOpenMPEndAssumesDirective(SourceLocation Loc);
+ /// Parses clauses for directive.
+ ///
+ /// \param DKind Kind of current directive.
+ /// \param clauses for current directive.
+ /// \param start location for clauses of current directive
+ void ParseOpenMPClauses(OpenMPDirectiveKind DKind,
+ SmallVectorImpl<clang::OMPClause *> &Clauses,
+ SourceLocation Loc);
+
/// Parse clauses for '#pragma omp [begin] declare target'.
void ParseOMPDeclareTargetClauses(Sema::DeclareTargetContextInfo &DTCI);
@@ -3238,8 +3396,8 @@ private:
/// Parses declarative OpenMP directives.
DeclGroupPtrTy ParseOpenMPDeclarativeDirectiveWithExtDecl(
- AccessSpecifier &AS, ParsedAttributesWithRange &Attrs,
- bool Delayed = false, DeclSpec::TST TagType = DeclSpec::TST_unspecified,
+ AccessSpecifier &AS, ParsedAttributes &Attrs, bool Delayed = false,
+ DeclSpec::TST TagType = DeclSpec::TST_unspecified,
Decl *TagDecl = nullptr);
/// Parse 'omp declare reduction' construct.
DeclGroupPtrTy ParseOpenMPDeclareReductionDirective(AccessSpecifier AS);
@@ -3273,8 +3431,10 @@ private:
/// Parses declarative or executable directive.
///
/// \param StmtCtx The context in which we're parsing the directive.
- StmtResult
- ParseOpenMPDeclarativeOrExecutableDirective(ParsedStmtContext StmtCtx);
+ /// \param ReadDirectiveWithinMetadirective true if directive is within a
+ /// metadirective and therefore ends on the closing paren.
+ StmtResult ParseOpenMPDeclarativeOrExecutableDirective(
+ ParsedStmtContext StmtCtx, bool ReadDirectiveWithinMetadirective = false);
/// Parses clause of kind \a CKind for directive of a kind \a Kind.
///
/// \param DKind Kind of current directive.
@@ -3299,6 +3459,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.
///
@@ -3340,6 +3505,9 @@ private:
/// '(' { <allocator> [ '(' <allocator_traits> ')' ] }+ ')'
OMPClause *ParseOpenMPUsesAllocatorClause(OpenMPDirectiveKind DKind);
+ /// Parses the 'interop' parts of the 'append_args' and 'init' clauses.
+ bool ParseOMPInteropInfo(OMPInteropInfo &InteropInfo, OpenMPClauseKind Kind);
+
/// Parses clause with an interop variable of kind \a Kind.
///
/// \param Kind Kind of current clause.
@@ -3348,6 +3516,13 @@ private:
//
OMPClause *ParseOpenMPInteropClause(OpenMPClauseKind Kind, bool ParseOnly);
+ /// Parses a ompx_attribute clause
+ ///
+ /// \param ParseOnly true to skip the clause's semantic actions and return
+ /// nullptr.
+ //
+ OMPClause *ParseOpenMPOMPXAttributesClause(bool ParseOnly);
+
public:
/// Parses simple expression in parens for single-expression clauses of OpenMP
/// constructs.
@@ -3355,30 +3530,14 @@ public:
ExprResult ParseOpenMPParensExpr(StringRef ClauseName, SourceLocation &RLoc,
bool IsAddressOfOperand = false);
- /// Data used for parsing list of variables in OpenMP clauses.
- struct OpenMPVarListDataTy {
- Expr *DepModOrTailExpr = nullptr;
- SourceLocation ColonLoc;
- SourceLocation RLoc;
- CXXScopeSpec ReductionOrMapperIdScopeSpec;
- DeclarationNameInfo ReductionOrMapperId;
- int ExtraModifier = -1; ///< Additional modifier for linear, map, depend or
- ///< lastprivate clause.
- SmallVector<OpenMPMapModifierKind, NumberOfOMPMapClauseModifiers>
- MapTypeModifiers;
- SmallVector<SourceLocation, NumberOfOMPMapClauseModifiers>
- MapTypeModifiersLoc;
- SmallVector<OpenMPMotionModifierKind, NumberOfOMPMotionModifiers>
- MotionModifiers;
- SmallVector<SourceLocation, NumberOfOMPMotionModifiers> MotionModifiersLoc;
- bool IsMapTypeImplicit = false;
- SourceLocation ExtraModifierLoc;
- };
-
+ /// Parses a reserved locator like 'omp_all_memory'.
+ bool ParseOpenMPReservedLocator(OpenMPClauseKind Kind,
+ Sema::OpenMPVarListDataTy &Data,
+ const LangOptions &LangOpts);
/// Parses clauses with list.
bool ParseOpenMPVarList(OpenMPDirectiveKind DKind, OpenMPClauseKind Kind,
SmallVectorImpl<Expr *> &Vars,
- OpenMPVarListDataTy &Data);
+ Sema::OpenMPVarListDataTy &Data);
bool ParseUnqualifiedId(CXXScopeSpec &SS, ParsedType ObjectType,
bool ObjectHadErrors, bool EnteringContext,
bool AllowDestructorName, bool AllowConstructorName,
@@ -3386,11 +3545,50 @@ public:
SourceLocation *TemplateKWLoc, UnqualifiedId &Result);
/// Parses the mapper modifier in map, to, and from clauses.
- bool parseMapperModifier(OpenMPVarListDataTy &Data);
+ bool parseMapperModifier(Sema::OpenMPVarListDataTy &Data);
/// Parses map-type-modifiers in map clause.
/// map([ [map-type-modifier[,] [map-type-modifier[,] ...] map-type : ] list)
/// where, map-type-modifier ::= always | close | mapper(mapper-identifier)
- bool parseMapTypeModifiers(OpenMPVarListDataTy &Data);
+ bool parseMapTypeModifiers(Sema::OpenMPVarListDataTy &Data);
+
+ //===--------------------------------------------------------------------===//
+ // OpenACC Parsing.
+
+ /// Placeholder for now, should just ignore the directives after emitting a
+ /// diagnostic. Eventually will be split into a few functions to parse
+ /// different situations.
+public:
+ DeclGroupPtrTy ParseOpenACCDirectiveDecl();
+ StmtResult ParseOpenACCDirectiveStmt();
+
+private:
+ void ParseOpenACCDirective();
+ /// Helper that parses an ID Expression based on the language options.
+ ExprResult ParseOpenACCIDExpression();
+ /// Parses the variable list for the `cache` construct.
+ void ParseOpenACCCacheVarList();
+ /// Parses a single variable in a variable list for OpenACC.
+ bool ParseOpenACCVar();
+ /// Parses the variable list for the variety of clauses that take a var-list,
+ /// including the optional Special Token listed for some,based on clause type.
+ bool ParseOpenACCClauseVarList(OpenACCClauseKind Kind);
+ /// Parses any parameters for an OpenACC Clause, including required/optional
+ /// parens.
+ bool ParseOpenACCClauseParams(OpenACCDirectiveKind DirKind,
+ OpenACCClauseKind Kind);
+ /// Parses a single clause in a clause-list for OpenACC.
+ bool ParseOpenACCClause(OpenACCDirectiveKind DirKind);
+ /// Parses the clause-list for an OpenACC directive.
+ void ParseOpenACCClauseList(OpenACCDirectiveKind DirKind);
+ bool ParseOpenACCWaitArgument();
+ /// Parses the clause of the 'bind' argument, which can be a string literal or
+ /// an ID expression.
+ ExprResult ParseOpenACCBindClauseArgument();
+ /// Parses the clause kind of 'int-expr', which can be any integral
+ /// expression.
+ ExprResult ParseOpenACCIntExpr();
+ /// Parses the 'device-type-list', which is a list of identifiers.
+ bool ParseOpenACCDeviceTypeList();
private:
//===--------------------------------------------------------------------===//
@@ -3438,7 +3636,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,
@@ -3446,9 +3645,12 @@ private:
UnqualifiedId &TemplateName,
bool AllowTypeAnnotation = true,
bool TypeConstraint = false);
- void AnnotateTemplateIdTokenAsType(CXXScopeSpec &SS,
- bool IsClassName = false);
- bool ParseTemplateArgumentList(TemplateArgList &TemplateArgs);
+ void
+ AnnotateTemplateIdTokenAsType(CXXScopeSpec &SS,
+ ImplicitTypenameContext AllowImplicitTypename,
+ bool IsClassName = false);
+ bool ParseTemplateArgumentList(TemplateArgList &TemplateArgs,
+ TemplateTy Template, SourceLocation OpenLoc);
ParsedTemplateArgument ParseTemplateTemplateArgument();
ParsedTemplateArgument ParseTemplateArgument();
Decl *ParseExplicitInstantiation(DeclaratorContext Context,
@@ -3462,10 +3664,23 @@ private:
ParseConceptDefinition(const ParsedTemplateInfo &TemplateInfo,
SourceLocation &DeclEnd);
+ /// Parse the given string as a type.
+ ///
+ /// This is a dangerous utility function currently employed only by API notes.
+ /// It is not a general entry-point for safely parsing types from strings.
+ ///
+ /// \param TypeStr The string to be parsed as a type.
+ /// \param Context The name of the context in which this string is being
+ /// parsed, which will be used in diagnostics.
+ /// \param IncludeLoc The location at which this parse was triggered.
+ TypeResult ParseTypeFromString(StringRef TypeStr, StringRef Context,
+ SourceLocation IncludeLoc);
+
//===--------------------------------------------------------------------===//
// Modules
- DeclGroupPtrTy ParseModuleDecl(bool IsFirstDecl);
- Decl *ParseModuleImport(SourceLocation AtLoc);
+ DeclGroupPtrTy ParseModuleDecl(Sema::ModuleImportState &ImportState);
+ Decl *ParseModuleImport(SourceLocation AtLoc,
+ Sema::ModuleImportState &ImportState);
bool parseMisplacedModuleImport();
bool tryParseMisplacedModuleImport() {
tok::TokenKind Kind = Tok.getKind();
diff --git a/contrib/llvm-project/clang/include/clang/Parse/RAIIObjectsForParser.h b/contrib/llvm-project/clang/include/clang/Parse/RAIIObjectsForParser.h
index bc1754614ad9..e1626a7870bb 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"
@@ -201,9 +201,11 @@ namespace clang {
ParsingDeclRAIIObject ParsingRAII;
public:
- ParsingDeclarator(Parser &P, const ParsingDeclSpec &DS, DeclaratorContext C)
- : Declarator(DS, C), ParsingRAII(P, &DS.getDelayedDiagnosticPool()) {
- }
+ ParsingDeclarator(Parser &P, const ParsingDeclSpec &DS,
+ const ParsedAttributes &DeclarationAttrs,
+ DeclaratorContext C)
+ : Declarator(DS, DeclarationAttrs, C),
+ ParsingRAII(P, &DS.getDelayedDiagnosticPool()) {}
const ParsingDeclSpec &getDeclSpec() const {
return static_cast<const ParsingDeclSpec&>(Declarator::getDeclSpec());
@@ -228,9 +230,10 @@ namespace clang {
ParsingDeclRAIIObject ParsingRAII;
public:
- ParsingFieldDeclarator(Parser &P, const ParsingDeclSpec &DS)
- : FieldDeclarator(DS), ParsingRAII(P, &DS.getDelayedDiagnosticPool()) {
- }
+ ParsingFieldDeclarator(Parser &P, const ParsingDeclSpec &DS,
+ const ParsedAttributes &DeclarationAttrs)
+ : FieldDeclarator(DS, DeclarationAttrs),
+ ParsingRAII(P, &DS.getDelayedDiagnosticPool()) {}
const ParsingDeclSpec &getDeclSpec() const {
return static_cast<const ParsingDeclSpec&>(D.getDeclSpec());
@@ -306,6 +309,25 @@ namespace clang {
~ParsingOpenMPDirectiveRAII() { restore(); }
};
+ /// Activates OpenACC parsing mode to preseve OpenACC specific annotation
+ /// tokens.
+ class ParsingOpenACCDirectiveRAII {
+ Parser &P;
+ bool OldVal;
+
+ public:
+ ParsingOpenACCDirectiveRAII(Parser &P, bool Value = true)
+ : P(P), OldVal(P.OpenACCDirectiveParsing) {
+ P.OpenACCDirectiveParsing = Value;
+ }
+
+ /// This can be used to restore the state early, before the dtor
+ /// is run.
+ void restore() { P.OpenMPDirectiveParsing = OldVal; }
+
+ ~ParsingOpenACCDirectiveRAII() { restore(); }
+ };
+
/// RAII object that makes '>' behave either as an operator
/// or as the closing angle bracket for a template argument list.
class GreaterThanIsOperatorScope {
@@ -338,6 +360,19 @@ namespace clang {
}
};
+ class OffsetOfStateRAIIObject {
+ Sema::OffsetOfKind &OffsetOfState;
+ Sema::OffsetOfKind OldValue;
+
+ public:
+ OffsetOfStateRAIIObject(Parser &P, Sema::OffsetOfKind Value)
+ : OffsetOfState(P.OffsetOfState), OldValue(P.OffsetOfState) {
+ OffsetOfState = Value;
+ }
+
+ ~OffsetOfStateRAIIObject() { OffsetOfState = OldValue; }
+ };
+
/// RAII object that makes sure paren/bracket/brace count is correct
/// after declaration/statement parsing, even when there's a parsing error.
class ParenBraceBracketBalancer {
diff --git a/contrib/llvm-project/clang/include/clang/Rewrite/Core/RewriteRope.h b/contrib/llvm-project/clang/include/clang/Rewrite/Core/RewriteRope.h
index 8fa7af245eb8..73e66e111f57 100644
--- a/contrib/llvm-project/clang/include/clang/Rewrite/Core/RewriteRope.h
+++ b/contrib/llvm-project/clang/include/clang/Rewrite/Core/RewriteRope.h
@@ -181,6 +181,10 @@ public:
RewriteRope() = default;
RewriteRope(const RewriteRope &RHS) : Chunks(RHS.Chunks) {}
+ // The copy assignment operator is defined as deleted pending further
+ // motivation.
+ RewriteRope &operator=(const RewriteRope &) = delete;
+
using iterator = RopePieceBTree::iterator;
using const_iterator = RopePieceBTree::iterator;
diff --git a/contrib/llvm-project/clang/include/clang/Sema/AnalysisBasedWarnings.h b/contrib/llvm-project/clang/include/clang/Sema/AnalysisBasedWarnings.h
index 49b69c585ff7..020ddd36cf73 100644
--- a/contrib/llvm-project/clang/include/clang/Sema/AnalysisBasedWarnings.h
+++ b/contrib/llvm-project/clang/include/clang/Sema/AnalysisBasedWarnings.h
@@ -13,15 +13,14 @@
#ifndef LLVM_CLANG_SEMA_ANALYSISBASEDWARNINGS_H
#define LLVM_CLANG_SEMA_ANALYSISBASEDWARNINGS_H
+#include "clang/AST/Decl.h"
#include "llvm/ADT/DenseMap.h"
#include <memory>
namespace clang {
-class BlockExpr;
class Decl;
class FunctionDecl;
-class ObjCMethodDecl;
class QualType;
class Sema;
namespace sema {
@@ -97,6 +96,9 @@ public:
void IssueWarnings(Policy P, FunctionScopeInfo *fscope,
const Decl *D, QualType BlockType);
+ // Issue warnings that require whole-translation-unit analysis.
+ void IssueWarnings(TranslationUnitDecl *D);
+
Policy getDefaultPolicy() { return DefaultPolicy; }
void PrintStats() const;
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 87646ab95025..274eaac819af 100644
--- a/contrib/llvm-project/clang/include/clang/Sema/CodeCompleteConsumer.h
+++ b/contrib/llvm-project/clang/include/clang/Sema/CodeCompleteConsumer.h
@@ -21,8 +21,6 @@
#include "clang/Sema/DeclSpec.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/None.h"
-#include "llvm/ADT/Optional.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
@@ -30,6 +28,7 @@
#include "llvm/Support/type_traits.h"
#include <cassert>
#include <memory>
+#include <optional>
#include <string>
#include <utility>
@@ -329,9 +328,20 @@ public:
/// Code completion inside the filename part of a #include directive.
CCC_IncludedFile,
+ /// Code completion of an attribute name.
+ CCC_Attribute,
+
/// An unknown context, in which we are recovering from a parsing
/// error and don't know which completions we should give.
- CCC_Recovery
+ CCC_Recovery,
+
+ /// Code completion in a @class forward declaration.
+ CCC_ObjCClassForwardDecl,
+
+ /// Code completion at a top level, i.e. in a namespace or global scope,
+ /// but also in expression statements. This is because REPL inputs can be
+ /// declarations or expression statements.
+ CCC_TopLevelOrExpression,
};
using VisitedContextSet = llvm::SmallPtrSet<DeclContext *, 8>;
@@ -356,7 +366,7 @@ private:
/// The scope specifier that comes before the completion token e.g.
/// "a::b::"
- llvm::Optional<CXXScopeSpec> ScopeSpecifier;
+ std::optional<CXXScopeSpec> ScopeSpecifier;
/// A set of declaration contexts visited by Sema when doing lookup for
/// code completion.
@@ -365,11 +375,11 @@ private:
public:
/// Construct a new code-completion context of the given kind.
CodeCompletionContext(Kind CCKind)
- : CCKind(CCKind), IsUsingDeclaration(false), SelIdents(None) {}
+ : CCKind(CCKind), IsUsingDeclaration(false), SelIdents(std::nullopt) {}
/// Construct a new code-completion context of the given kind.
CodeCompletionContext(Kind CCKind, QualType T,
- ArrayRef<IdentifierInfo *> SelIdents = None)
+ ArrayRef<IdentifierInfo *> SelIdents = std::nullopt)
: CCKind(CCKind), IsUsingDeclaration(false), SelIdents(SelIdents) {
if (CCKind == CCC_DotMemberAccess || CCKind == CCC_ArrowMemberAccess ||
CCKind == CCC_ObjCPropertyAccess || CCKind == CCC_ObjCClassMessage ||
@@ -419,14 +429,14 @@ public:
return VisitedContexts;
}
- llvm::Optional<const CXXScopeSpec *> getCXXScopeSpecifier() {
+ std::optional<const CXXScopeSpec *> getCXXScopeSpecifier() {
if (ScopeSpecifier)
- return ScopeSpecifier.getPointer();
- return llvm::None;
+ return &*ScopeSpecifier;
+ return std::nullopt;
}
};
-/// Get string representation of \p Kind, useful for for debugging.
+/// Get string representation of \p Kind, useful for debugging.
llvm::StringRef getCompletionKindString(CodeCompletionContext::Kind Kind);
/// A "string" used to describe how code completion can
@@ -603,9 +613,12 @@ public:
return begin()[I];
}
- /// Returns the text in the TypedText chunk.
+ /// Returns the text in the first TypedText chunk.
const char *getTypedText() const;
+ /// Returns the combined text from all TypedText chunks.
+ std::string getAllTypedText() const;
+
/// Retrieve the priority of this code completion result.
unsigned getPriority() const { return Priority; }
@@ -844,6 +857,12 @@ public:
/// rather than a use of that entity.
bool DeclaringEntity : 1;
+ /// When completing a function, whether it can be a call. This will usually be
+ /// true, but we have some heuristics, e.g. when a pointer to a non-static
+ /// member function is completed outside of that class' scope, it can never
+ /// be a call.
+ bool FunctionCanBeCall : 1;
+
/// If the result should have a nested-name-specifier, this is it.
/// When \c QualifierIsInformative, the nested-name-specifier is
/// informative rather than required.
@@ -870,7 +889,7 @@ public:
FixIts(std::move(FixIts)), Hidden(false), InBaseClass(false),
QualifierIsInformative(QualifierIsInformative),
StartsNestedNameSpecifier(false), AllParametersAreInformative(false),
- DeclaringEntity(false), Qualifier(Qualifier) {
+ DeclaringEntity(false), FunctionCanBeCall(true), Qualifier(Qualifier) {
// FIXME: Add assert to check FixIts range requirements.
computeCursorKindAndAvailability(Accessible);
}
@@ -880,7 +899,8 @@ public:
: Keyword(Keyword), Priority(Priority), Kind(RK_Keyword),
CursorKind(CXCursor_NotImplemented), Hidden(false), InBaseClass(false),
QualifierIsInformative(false), StartsNestedNameSpecifier(false),
- AllParametersAreInformative(false), DeclaringEntity(false) {}
+ AllParametersAreInformative(false), DeclaringEntity(false),
+ FunctionCanBeCall(true) {}
/// Build a result that refers to a macro.
CodeCompletionResult(const IdentifierInfo *Macro,
@@ -890,7 +910,7 @@ public:
CursorKind(CXCursor_MacroDefinition), Hidden(false), InBaseClass(false),
QualifierIsInformative(false), StartsNestedNameSpecifier(false),
AllParametersAreInformative(false), DeclaringEntity(false),
- MacroDefInfo(MI) {}
+ FunctionCanBeCall(true), MacroDefInfo(MI) {}
/// Build a result that refers to a pattern.
CodeCompletionResult(
@@ -902,7 +922,7 @@ public:
CursorKind(CursorKind), Availability(Availability), Hidden(false),
InBaseClass(false), QualifierIsInformative(false),
StartsNestedNameSpecifier(false), AllParametersAreInformative(false),
- DeclaringEntity(false) {}
+ DeclaringEntity(false), FunctionCanBeCall(true) {}
/// Build a result that refers to a pattern with an associated
/// declaration.
@@ -911,7 +931,7 @@ public:
: Declaration(D), Pattern(Pattern), Priority(Priority), Kind(RK_Pattern),
Hidden(false), InBaseClass(false), QualifierIsInformative(false),
StartsNestedNameSpecifier(false), AllParametersAreInformative(false),
- DeclaringEntity(false) {
+ DeclaringEntity(false), FunctionCanBeCall(true) {
computeCursorKindAndAvailability();
}
@@ -1006,12 +1026,22 @@ 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 variable or expression of function type
+ /// for which we have the location of the prototype declaration.
+ CK_FunctionProtoTypeLoc,
+
+ /// The candidate is a template, template arguments are being completed.
+ CK_Template,
+
+ /// The candidate is aggregate initialization of a record type.
+ CK_Aggregate,
};
private:
@@ -1030,17 +1060,48 @@ public:
/// The function type that describes the entity being called,
/// when Kind == CK_FunctionType.
const FunctionType *Type;
+
+ /// The location of the function prototype that describes the entity being
+ /// called, when Kind == CK_FunctionProtoTypeLoc.
+ FunctionProtoTypeLoc ProtoTypeLoc;
+
+ /// 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(FunctionProtoTypeLoc Prototype)
+ : Kind(CK_FunctionProtoTypeLoc), ProtoTypeLoc(Prototype) {
+ assert(!Prototype.isNull());
+ }
+
+ 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; }
@@ -1059,13 +1120,40 @@ public:
/// function is stored.
const FunctionType *getFunctionType() const;
+ /// Retrieve the function ProtoTypeLoc candidate.
+ /// This can be called for any Kind, but returns null for kinds
+ /// other than CK_FunctionProtoTypeLoc.
+ const FunctionProtoTypeLoc getFunctionProtoTypeLoc() 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)
@@ -1139,7 +1227,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
@@ -1190,7 +1279,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 423f4f4ee7b7..4561cca929c0 100644
--- a/contrib/llvm-project/clang/include/clang/Sema/DeclSpec.h
+++ b/contrib/llvm-project/clang/include/clang/Sema/DeclSpec.h
@@ -32,6 +32,7 @@
#include "clang/Lex/Token.h"
#include "clang/Sema/Ownership.h"
#include "clang/Sema/ParsedAttr.h"
+#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/ErrorHandling.h"
@@ -61,9 +62,18 @@ namespace clang {
/// often used as if it meant "present".
///
/// The actual scope is described by getScopeRep().
+///
+/// If the kind of getScopeRep() is TypeSpec then TemplateParamLists may be empty
+/// or contain the template parameter lists attached to the current declaration.
+/// Consider the following example:
+/// template <class T> void SomeType<T>::some_method() {}
+/// If CXXScopeSpec refers to SomeType<T> then TemplateParamLists will contain
+/// a single element referring to template <class T>.
+
class CXXScopeSpec {
SourceRange Range;
NestedNameSpecifierLocBuilder Builder;
+ ArrayRef<TemplateParameterList *> TemplateParamLists;
public:
SourceRange getRange() const { return Range; }
@@ -73,6 +83,13 @@ public:
SourceLocation getBeginLoc() const { return Range.getBegin(); }
SourceLocation getEndLoc() const { return Range.getEnd(); }
+ void setTemplateParamLists(ArrayRef<TemplateParameterList *> L) {
+ TemplateParamLists = L;
+ }
+ ArrayRef<TemplateParameterList *> getTemplateParamLists() const {
+ return TemplateParamLists;
+ }
+
/// Retrieve the representation of the nested-name-specifier.
NestedNameSpecifier *getScopeRep() const {
return Builder.getRepresentation();
@@ -266,7 +283,7 @@ public:
static const TST TST_char32 = clang::TST_char32;
static const TST TST_int = clang::TST_int;
static const TST TST_int128 = clang::TST_int128;
- static const TST TST_extint = clang::TST_extint;
+ static const TST TST_bitint = clang::TST_bitint;
static const TST TST_half = clang::TST_half;
static const TST TST_BFloat16 = clang::TST_BFloat16;
static const TST TST_float = clang::TST_float;
@@ -275,6 +292,7 @@ public:
static const TST TST_accum = clang::TST_Accum;
static const TST TST_fract = clang::TST_Fract;
static const TST TST_float128 = clang::TST_float128;
+ static const TST TST_ibm128 = clang::TST_ibm128;
static const TST TST_bool = clang::TST_bool;
static const TST TST_decimal32 = clang::TST_decimal32;
static const TST TST_decimal64 = clang::TST_decimal64;
@@ -287,9 +305,13 @@ public:
static const TST TST_typename = clang::TST_typename;
static const TST TST_typeofType = clang::TST_typeofType;
static const TST TST_typeofExpr = clang::TST_typeofExpr;
+ static const TST TST_typeof_unqualType = clang::TST_typeof_unqualType;
+ static const TST TST_typeof_unqualExpr = clang::TST_typeof_unqualExpr;
static const TST TST_decltype = clang::TST_decltype;
static const TST TST_decltype_auto = clang::TST_decltype_auto;
- static const TST TST_underlyingType = clang::TST_underlyingType;
+#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) \
+ static const TST TST_##Trait = clang::TST_##Trait;
+#include "clang/Basic/TransformTypeTraits.def"
static const TST TST_auto = clang::TST_auto;
static const TST TST_auto_type = clang::TST_auto_type;
static const TST TST_unknown_anytype = clang::TST_unknown_anytype;
@@ -322,6 +344,11 @@ public:
// FIXME: Attributes should be included here.
};
+ enum FriendSpecified : bool {
+ No,
+ Yes,
+ };
+
private:
// storage-class-specifier
/*SCS*/unsigned StorageClassSpec : 3;
@@ -332,7 +359,7 @@ private:
/*TypeSpecifierWidth*/ unsigned TypeSpecWidth : 2;
/*TSC*/unsigned TypeSpecComplex : 2;
/*TSS*/unsigned TypeSpecSign : 2;
- /*TST*/unsigned TypeSpecType : 6;
+ /*TST*/unsigned TypeSpecType : 7;
unsigned TypeAltiVecVector : 1;
unsigned TypeAltiVecPixel : 1;
unsigned TypeAltiVecBool : 1;
@@ -399,11 +426,12 @@ private:
ObjCDeclSpec *ObjCQualifiers;
static bool isTypeRep(TST T) {
- return (T == TST_typename || T == TST_typeofType ||
- T == TST_underlyingType || T == TST_atomic);
+ return T == TST_atomic || T == TST_typename || T == TST_typeofType ||
+ T == TST_typeof_unqualType || isTransformTypeTrait(T);
}
static bool isExprRep(TST T) {
- return (T == TST_typeofExpr || T == TST_decltype || T == TST_extint);
+ return T == TST_typeofExpr || T == TST_typeof_unqualExpr ||
+ T == TST_decltype || T == TST_bitint;
}
static bool isTemplateIdRep(TST T) {
return (T == TST_auto || T == TST_decltype_auto);
@@ -417,6 +445,14 @@ public:
T == TST_interface || T == TST_union ||
T == TST_class);
}
+ static bool isTransformTypeTrait(TST T) {
+ constexpr std::array<TST, 16> Traits = {
+#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) TST_##Trait,
+#include "clang/Basic/TransformTypeTraits.def"
+ };
+
+ return T >= Traits.front() && T <= Traits.back();
+ }
DeclSpec(AttributeFactory &attrFactory)
: StorageClassSpec(SCS_unspecified),
@@ -433,8 +469,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; }
@@ -516,12 +551,13 @@ public:
SourceLocation getTypeSpecSatLoc() const { return TSSatLoc; }
SourceLocation getTypeSpecTypeNameLoc() const {
- assert(isDeclRep((TST) TypeSpecType) || TypeSpecType == TST_typename);
+ assert(isDeclRep((TST)TypeSpecType) || isTypeRep((TST)TypeSpecType) ||
+ isExprRep((TST)TypeSpecType));
return TSTNameLoc;
}
SourceRange getTypeofParensRange() const { return TypeofParensRange; }
- void setTypeofParensRange(SourceRange range) { TypeofParensRange = range; }
+ void setTypeArgumentRange(SourceRange range) { TypeofParensRange = range; }
bool hasAutoTypeSpec() const {
return (TypeSpecType == TST_auto || TypeSpecType == TST_auto_type ||
@@ -702,7 +738,7 @@ public:
bool SetTypePipe(bool isPipe, SourceLocation Loc,
const char *&PrevSpec, unsigned &DiagID,
const PrintingPolicy &Policy);
- bool SetExtIntType(SourceLocation KWLoc, Expr *BitWidth,
+ bool SetBitIntType(SourceLocation KWLoc, Expr *BitWidth,
const char *&PrevSpec, unsigned &DiagID,
const PrintingPolicy &Policy);
bool SetTypeSpecSat(SourceLocation Loc, const char *&PrevSpec,
@@ -745,7 +781,10 @@ public:
bool SetConstexprSpec(ConstexprSpecKind ConstexprKind, SourceLocation Loc,
const char *&PrevSpec, unsigned &DiagID);
- bool isFriendSpecified() const { return Friend_specified; }
+ FriendSpecified isFriendSpecified() const {
+ return static_cast<FriendSpecified>(Friend_specified);
+ }
+
SourceLocation getFriendSpecLoc() const { return FriendLoc; }
bool isModulePrivateSpecified() const { return ModulePrivateLoc.isValid(); }
@@ -786,7 +825,7 @@ public:
/// int __attribute__((may_alias)) __attribute__((aligned(16))) var;
/// \endcode
///
- void addAttributes(ParsedAttributesView &AL) {
+ void addAttributes(const ParsedAttributesView &AL) {
Attrs.addAll(AL.begin(), AL.end());
}
@@ -952,10 +991,10 @@ private:
UnqualifiedId(const UnqualifiedId &Other) = delete;
const UnqualifiedId &operator=(const UnqualifiedId &) = delete;
-public:
/// Describes the kind of unqualified-id parsed.
UnqualifiedIdKind Kind;
+public:
struct OFI {
/// The kind of overloaded operator.
OverloadedOperatorKind Operator;
@@ -1342,7 +1381,7 @@ struct DeclaratorChunk {
/// DeclSpec for the function with the qualifier related info.
DeclSpec *MethodQualifiers;
- /// AtttibuteFactory for the MethodQualifiers.
+ /// AttributeFactory for the MethodQualifiers.
AttributeFactory *QualAttrFactory;
union {
@@ -1490,7 +1529,7 @@ struct DeclaratorChunk {
/// prototype. Typically these are tag declarations.
ArrayRef<NamedDecl *> getDeclsInPrototype() const {
assert(ExceptionSpecType == EST_None);
- return llvm::makeArrayRef(DeclsInPrototype, NumExceptionsOrDecls);
+ return llvm::ArrayRef(DeclsInPrototype, NumExceptionsOrDecls);
}
/// Determine whether this function declarator had a
@@ -1737,7 +1776,7 @@ public:
}
ArrayRef<Binding> bindings() const {
- return llvm::makeArrayRef(Bindings, NumBindings);
+ return llvm::ArrayRef(Bindings, NumBindings);
}
bool isSet() const { return LSquareLoc.isValid(); }
@@ -1785,7 +1824,15 @@ enum class DeclaratorContext {
TemplateTypeArg, // Template type argument (in default argument).
AliasDecl, // C++11 alias-declaration.
AliasTemplate, // C++11 alias-declaration template.
- RequiresExpr // C++2a requires-expression.
+ RequiresExpr, // C++2a requires-expression.
+ Association // C11 _Generic selection expression association.
+};
+
+// Describes whether the current context is a context where an implicit
+// typename is allowed (C++2a [temp.res]p5]).
+enum class ImplicitTypenameContext {
+ No,
+ Yes,
};
/// Information about one declarator, including the parsed type
@@ -1850,9 +1897,13 @@ private:
/// Indicates whether this declarator has an initializer.
unsigned HasInitializer : 1;
- /// Attrs - Attributes.
+ /// Attributes attached to the declarator.
ParsedAttributes Attrs;
+ /// Attributes attached to the declaration. See also documentation for the
+ /// corresponding constructor parameter.
+ const ParsedAttributesView &DeclarationAttrs;
+
/// The asm label, if specified.
Expr *AsmLabel;
@@ -1891,16 +1942,41 @@ private:
friend struct DeclaratorChunk;
public:
- Declarator(const DeclSpec &ds, DeclaratorContext C)
- : DS(ds), Range(ds.getSourceRange()), Context(C),
+ /// `DS` and `DeclarationAttrs` must outlive the `Declarator`. In particular,
+ /// take care not to pass temporary objects for these parameters.
+ ///
+ /// `DeclarationAttrs` contains [[]] attributes from the
+ /// attribute-specifier-seq at the beginning of a declaration, which appertain
+ /// to the declared entity itself. Attributes with other syntax (e.g. GNU)
+ /// should not be placed in this attribute list; if they occur at the
+ /// beginning of a declaration, they apply to the `DeclSpec` and should be
+ /// attached to that instead.
+ ///
+ /// Here is an example of an attribute associated with a declaration:
+ ///
+ /// [[deprecated]] int x, y;
+ ///
+ /// This attribute appertains to all of the entities declared in the
+ /// declaration, i.e. `x` and `y` in this case.
+ Declarator(const DeclSpec &DS, const ParsedAttributesView &DeclarationAttrs,
+ DeclaratorContext C)
+ : DS(DS), Range(DS.getSourceRange()), Context(C),
InvalidType(DS.getTypeSpecType() == DeclSpec::TST_error),
GroupingParens(false), FunctionDefinition(static_cast<unsigned>(
FunctionDefinitionKind::Declaration)),
Redeclaration(false), Extension(false), ObjCIvar(false),
ObjCWeakProperty(false), InlineStorageUsed(false),
- HasInitializer(false), Attrs(ds.getAttributePool().getFactory()),
- AsmLabel(nullptr), TrailingRequiresClause(nullptr),
- InventedTemplateParameterList(nullptr) {}
+ HasInitializer(false), Attrs(DS.getAttributePool().getFactory()),
+ DeclarationAttrs(DeclarationAttrs), AsmLabel(nullptr),
+ TrailingRequiresClause(nullptr),
+ InventedTemplateParameterList(nullptr) {
+ assert(llvm::all_of(DeclarationAttrs,
+ [](const ParsedAttr &AL) {
+ return (AL.isStandardAttributeSyntax() ||
+ AL.isRegularKeywordAttribute());
+ }) &&
+ "DeclarationAttrs may only contain [[]] and keyword attributes");
+ }
~Declarator() {
clear();
@@ -2023,6 +2099,7 @@ public:
case DeclaratorContext::TrailingReturn:
case DeclaratorContext::TrailingReturnVar:
case DeclaratorContext::RequiresExpr:
+ case DeclaratorContext::Association:
return true;
}
llvm_unreachable("unknown context kind!");
@@ -2062,6 +2139,7 @@ public:
case DeclaratorContext::TemplateTypeArg:
case DeclaratorContext::TrailingReturn:
case DeclaratorContext::TrailingReturnVar:
+ case DeclaratorContext::Association:
return false;
}
llvm_unreachable("unknown context kind!");
@@ -2105,6 +2183,7 @@ public:
case DeclaratorContext::TemplateTypeArg:
case DeclaratorContext::TrailingReturn:
case DeclaratorContext::TrailingReturnVar:
+ case DeclaratorContext::Association:
return false;
}
llvm_unreachable("unknown context kind!");
@@ -2161,6 +2240,7 @@ public:
case DeclaratorContext::TemplateTypeArg:
case DeclaratorContext::TrailingReturn:
case DeclaratorContext::RequiresExpr:
+ case DeclaratorContext::Association:
return false;
}
llvm_unreachable("unknown context kind!");
@@ -2383,6 +2463,7 @@ public:
case DeclaratorContext::TrailingReturn:
case DeclaratorContext::TrailingReturnVar:
case DeclaratorContext::RequiresExpr:
+ case DeclaratorContext::Association:
return false;
}
llvm_unreachable("unknown context kind!");
@@ -2417,6 +2498,7 @@ public:
case DeclaratorContext::TrailingReturnVar:
case DeclaratorContext::TemplateTypeArg:
case DeclaratorContext::RequiresExpr:
+ case DeclaratorContext::Association:
return false;
case DeclaratorContext::Block:
@@ -2513,19 +2595,24 @@ public:
/// __attribute__((common,deprecated));
///
/// Also extends the range of the declarator.
- void takeAttributes(ParsedAttributes &attrs, SourceLocation lastLoc) {
+ void takeAttributes(ParsedAttributes &attrs) {
Attrs.takeAllFrom(attrs);
- if (!lastLoc.isInvalid())
- SetRangeEnd(lastLoc);
+ if (attrs.Range.getEnd().isValid())
+ SetRangeEnd(attrs.Range.getEnd());
}
const ParsedAttributes &getAttributes() const { return Attrs; }
ParsedAttributes &getAttributes() { return Attrs; }
+ const ParsedAttributesView &getDeclarationAttributes() const {
+ return DeclarationAttrs;
+ }
+
/// hasAttributes - do we contain any attributes?
bool hasAttributes() const {
- if (!getAttributes().empty() || getDeclSpec().hasAttributes())
+ if (!getAttributes().empty() || !getDeclarationAttributes().empty() ||
+ getDeclSpec().hasAttributes())
return true;
for (unsigned i = 0, e = getNumTypeObjects(); i != e; ++i)
if (!getTypeObject(i).getAttrs().empty())
@@ -2533,14 +2620,6 @@ public:
return false;
}
- /// Return a source range list of C++11 attributes associated
- /// with the declarator.
- void getCXX11AttributeRanges(SmallVectorImpl<SourceRange> &Ranges) {
- for (const ParsedAttr &AL : Attrs)
- if (AL.isCXX11Attribute())
- Ranges.push_back(AL.getRange());
- }
-
void setAsmLabel(Expr *E) { AsmLabel = E; }
Expr *getAsmLabel() const { return AsmLabel; }
@@ -2595,6 +2674,8 @@ public:
/// redeclaration time if the decl is static.
bool isStaticMember();
+ bool isExplicitObjectMemberFunction();
+
/// Returns true if this declares a constructor or a destructor.
bool isCtorOrDtor();
@@ -2607,8 +2688,10 @@ public:
struct FieldDeclarator {
Declarator D;
Expr *BitfieldSize;
- explicit FieldDeclarator(const DeclSpec &DS)
- : D(DS, DeclaratorContext::Member), BitfieldSize(nullptr) {}
+ explicit FieldDeclarator(const DeclSpec &DS,
+ const ParsedAttributes &DeclarationAttrs)
+ : D(DS, DeclarationAttrs, DeclaratorContext::Member),
+ BitfieldSize(nullptr) {}
};
/// Represents a C++11 virt-specifier-seq.
@@ -2624,7 +2707,7 @@ public:
VS_Abstract = 16
};
- VirtSpecifiers() : Specifiers(0), LastSpecifier(VS_None) { }
+ VirtSpecifiers() = default;
bool SetSpecifier(Specifier VS, SourceLocation Loc,
const char *&PrevSpec);
@@ -2648,8 +2731,8 @@ public:
Specifier getLastSpecifier() const { return LastSpecifier; }
private:
- unsigned Specifiers;
- Specifier LastSpecifier;
+ unsigned Specifiers = 0;
+ Specifier LastSpecifier = VS_None;
SourceLocation VS_overrideLoc, VS_finalLoc, VS_abstractLoc;
SourceLocation FirstLocation;
@@ -2688,11 +2771,14 @@ struct LambdaIntroducer {
SourceRange Range;
SourceLocation DefaultLoc;
- LambdaCaptureDefault Default;
+ LambdaCaptureDefault Default = LCD_None;
SmallVector<LambdaCapture, 4> Captures;
- LambdaIntroducer()
- : Default(LCD_None) {}
+ LambdaIntroducer() = default;
+
+ bool hasLambdaCapture() const {
+ return Captures.size() > 0 || Default != LCD_None;
+ }
/// Append a capture in a lambda introducer.
void addCapture(LambdaCaptureKind Kind,
diff --git a/contrib/llvm-project/clang/include/clang/Sema/DelayedDiagnostic.h b/contrib/llvm-project/clang/include/clang/Sema/DelayedDiagnostic.h
index 50abcc421d45..9de7131f74c7 100644
--- a/contrib/llvm-project/clang/include/clang/Sema/DelayedDiagnostic.h
+++ b/contrib/llvm-project/clang/include/clang/Sema/DelayedDiagnostic.h
@@ -190,8 +190,8 @@ public:
ArrayRef<SourceLocation> getAvailabilitySelectorLocs() const {
assert(Kind == Availability && "Not an availability diagnostic.");
- return llvm::makeArrayRef(AvailabilityData.SelectorLocs,
- AvailabilityData.NumSelectorLocs);
+ return llvm::ArrayRef(AvailabilityData.SelectorLocs,
+ AvailabilityData.NumSelectorLocs);
}
AvailabilityResult getAvailabilityResult() const {
diff --git a/contrib/llvm-project/clang/include/clang/Sema/Designator.h b/contrib/llvm-project/clang/include/clang/Sema/Designator.h
index 84837bfeba5b..244535978d4b 100644
--- a/contrib/llvm-project/clang/include/clang/Sema/Designator.h
+++ b/contrib/llvm-project/clang/include/clang/Sema/Designator.h
@@ -21,60 +21,108 @@ namespace clang {
class Expr;
class IdentifierInfo;
-class Sema;
/// Designator - A designator in a C99 designated initializer.
///
/// This class is a discriminated union which holds the various
-/// different sorts of designators possible. A Designation is an array of
+/// different sorts of designators possible. A Designation is an array of
/// these. An example of a designator are things like this:
-/// [8] .field [47] // C99 designation: 3 designators
-/// [8 ... 47] field: // GNU extensions: 2 designators
+///
+/// [8] .field [47] // C99 designation: 3 designators
+/// [8 ... 47] field: // GNU extensions: 2 designators
+///
/// These occur in initializers, e.g.:
-/// int a[10] = {2, 4, [8]=9, 10};
+///
+/// int a[10] = {2, 4, [8]=9, 10};
///
class Designator {
-public:
- enum DesignatorKind {
- FieldDesignator, ArrayDesignator, ArrayRangeDesignator
- };
-private:
- Designator() {};
-
- DesignatorKind Kind;
-
+ /// A field designator, e.g., ".x = 42".
struct FieldDesignatorInfo {
- const IdentifierInfo *II;
+ /// Refers to the field being initialized.
+ const IdentifierInfo *FieldName;
+
+ /// The location of the '.' in the designated initializer.
SourceLocation DotLoc;
- SourceLocation NameLoc;
+
+ /// The location of the field name in the designated initializer.
+ SourceLocation FieldLoc;
+
+ FieldDesignatorInfo(const IdentifierInfo *FieldName, SourceLocation DotLoc,
+ SourceLocation FieldLoc)
+ : FieldName(FieldName), DotLoc(DotLoc), FieldLoc(FieldLoc) {}
};
+
+ /// An array designator, e.g., "[42] = 0".
struct ArrayDesignatorInfo {
Expr *Index;
+
+ // The location of the '[' in the designated initializer.
SourceLocation LBracketLoc;
+
+ // The location of the ']' in the designated initializer.
mutable SourceLocation RBracketLoc;
+
+ ArrayDesignatorInfo(Expr *Index, SourceLocation LBracketLoc)
+ : Index(Index), LBracketLoc(LBracketLoc) {}
};
+
+ /// An array range designator, e.g. "[42 ... 50] = 1".
struct ArrayRangeDesignatorInfo {
- Expr *Start, *End;
- SourceLocation LBracketLoc, EllipsisLoc;
+ Expr *Start;
+ Expr *End;
+
+ // The location of the '[' in the designated initializer.
+ SourceLocation LBracketLoc;
+
+ // The location of the '...' in the designated initializer.
+ SourceLocation EllipsisLoc;
+
+ // The location of the ']' in the designated initializer.
mutable SourceLocation RBracketLoc;
+
+ ArrayRangeDesignatorInfo(Expr *Start, Expr *End, SourceLocation LBracketLoc,
+ SourceLocation EllipsisLoc)
+ : Start(Start), End(End), LBracketLoc(LBracketLoc),
+ EllipsisLoc(EllipsisLoc) {}
};
+ /// The kind of designator this describes.
+ enum DesignatorKind {
+ FieldDesignator,
+ ArrayDesignator,
+ ArrayRangeDesignator
+ };
+
+ DesignatorKind Kind;
+
union {
FieldDesignatorInfo FieldInfo;
ArrayDesignatorInfo ArrayInfo;
ArrayRangeDesignatorInfo ArrayRangeInfo;
};
-public:
+ Designator(DesignatorKind Kind) : Kind(Kind) {}
- DesignatorKind getKind() const { return Kind; }
+public:
bool isFieldDesignator() const { return Kind == FieldDesignator; }
bool isArrayDesignator() const { return Kind == ArrayDesignator; }
bool isArrayRangeDesignator() const { return Kind == ArrayRangeDesignator; }
- const IdentifierInfo *getField() const {
+ //===--------------------------------------------------------------------===//
+ // FieldDesignatorInfo
+
+ /// Creates a field designator.
+ static Designator CreateFieldDesignator(const IdentifierInfo *FieldName,
+ SourceLocation DotLoc,
+ SourceLocation FieldLoc) {
+ Designator D(FieldDesignator);
+ new (&D.FieldInfo) FieldDesignatorInfo(FieldName, DotLoc, FieldLoc);
+ return D;
+ }
+
+ const IdentifierInfo *getFieldDecl() const {
assert(isFieldDesignator() && "Invalid accessor");
- return FieldInfo.II;
+ return FieldInfo.FieldName;
}
SourceLocation getDotLoc() const {
@@ -84,7 +132,18 @@ public:
SourceLocation getFieldLoc() const {
assert(isFieldDesignator() && "Invalid accessor");
- return FieldInfo.NameLoc;
+ return FieldInfo.FieldLoc;
+ }
+
+ //===--------------------------------------------------------------------===//
+ // ArrayDesignatorInfo:
+
+ /// Creates an array designator.
+ static Designator CreateArrayDesignator(Expr *Index,
+ SourceLocation LBracketLoc) {
+ Designator D(ArrayDesignator);
+ new (&D.ArrayInfo) ArrayDesignatorInfo(Index, LBracketLoc);
+ return D;
}
Expr *getArrayIndex() const {
@@ -92,73 +151,46 @@ public:
return ArrayInfo.Index;
}
- Expr *getArrayRangeStart() const {
- assert(isArrayRangeDesignator() && "Invalid accessor");
- return ArrayRangeInfo.Start;
- }
- Expr *getArrayRangeEnd() const {
- assert(isArrayRangeDesignator() && "Invalid accessor");
- return ArrayRangeInfo.End;
- }
-
SourceLocation getLBracketLoc() const {
assert((isArrayDesignator() || isArrayRangeDesignator()) &&
"Invalid accessor");
- if (isArrayDesignator())
- return ArrayInfo.LBracketLoc;
- else
- return ArrayRangeInfo.LBracketLoc;
+ return isArrayDesignator() ? ArrayInfo.LBracketLoc
+ : ArrayRangeInfo.LBracketLoc;
}
SourceLocation getRBracketLoc() const {
assert((isArrayDesignator() || isArrayRangeDesignator()) &&
"Invalid accessor");
- if (isArrayDesignator())
- return ArrayInfo.RBracketLoc;
- else
- return ArrayRangeInfo.RBracketLoc;
+ return isArrayDesignator() ? ArrayInfo.RBracketLoc
+ : ArrayRangeInfo.RBracketLoc;
}
- SourceLocation getEllipsisLoc() const {
- assert(isArrayRangeDesignator() && "Invalid accessor");
- return ArrayRangeInfo.EllipsisLoc;
- }
+ //===--------------------------------------------------------------------===//
+ // ArrayRangeDesignatorInfo:
- static Designator getField(const IdentifierInfo *II, SourceLocation DotLoc,
- SourceLocation NameLoc) {
- Designator D;
- D.Kind = FieldDesignator;
- new (&D.FieldInfo) FieldDesignatorInfo;
- D.FieldInfo.II = II;
- D.FieldInfo.DotLoc = DotLoc;
- D.FieldInfo.NameLoc = NameLoc;
+ /// Creates a GNU array-range designator.
+ static Designator CreateArrayRangeDesignator(Expr *Start, Expr *End,
+ SourceLocation LBracketLoc,
+ SourceLocation EllipsisLoc) {
+ Designator D(ArrayRangeDesignator);
+ new (&D.ArrayRangeInfo)
+ ArrayRangeDesignatorInfo(Start, End, LBracketLoc, EllipsisLoc);
return D;
}
- static Designator getArray(Expr *Index,
- SourceLocation LBracketLoc) {
- Designator D;
- D.Kind = ArrayDesignator;
- new (&D.ArrayInfo) ArrayDesignatorInfo;
- D.ArrayInfo.Index = Index;
- D.ArrayInfo.LBracketLoc = LBracketLoc;
- D.ArrayInfo.RBracketLoc = SourceLocation();
- return D;
+ Expr *getArrayRangeStart() const {
+ assert(isArrayRangeDesignator() && "Invalid accessor");
+ return ArrayRangeInfo.Start;
}
- static Designator getArrayRange(Expr *Start,
- Expr *End,
- SourceLocation LBracketLoc,
- SourceLocation EllipsisLoc) {
- Designator D;
- D.Kind = ArrayRangeDesignator;
- new (&D.ArrayRangeInfo) ArrayRangeDesignatorInfo;
- D.ArrayRangeInfo.Start = Start;
- D.ArrayRangeInfo.End = End;
- D.ArrayRangeInfo.LBracketLoc = LBracketLoc;
- D.ArrayRangeInfo.EllipsisLoc = EllipsisLoc;
- D.ArrayRangeInfo.RBracketLoc = SourceLocation();
- return D;
+ Expr *getArrayRangeEnd() const {
+ assert(isArrayRangeDesignator() && "Invalid accessor");
+ return ArrayRangeInfo.End;
+ }
+
+ SourceLocation getEllipsisLoc() const {
+ assert(isArrayRangeDesignator() && "Invalid accessor");
+ return ArrayRangeInfo.EllipsisLoc;
}
void setRBracketLoc(SourceLocation RBracketLoc) const {
@@ -169,17 +201,8 @@ public:
else
ArrayRangeInfo.RBracketLoc = RBracketLoc;
}
-
- /// ClearExprs - Null out any expression references, which prevents
- /// them from being 'delete'd later.
- void ClearExprs(Sema &Actions) {}
-
- /// FreeExprs - Release any unclaimed memory for the expressions in
- /// this designator.
- void FreeExprs(Sema &Actions) {}
};
-
/// Designation - Represent a full designation, which is a sequence of
/// designators. This class is mostly a helper for InitListDesignations.
class Designation {
@@ -188,9 +211,7 @@ class Designation {
public:
/// AddDesignator - Add a designator to the end of this list.
- void AddDesignator(Designator D) {
- Designators.push_back(D);
- }
+ void AddDesignator(Designator D) { Designators.push_back(D); }
bool empty() const { return Designators.empty(); }
@@ -199,14 +220,6 @@ public:
assert(Idx < Designators.size());
return Designators[Idx];
}
-
- /// ClearExprs - Null out any expression references, which prevents them from
- /// being 'delete'd later.
- void ClearExprs(Sema &Actions) {}
-
- /// FreeExprs - Release any unclaimed memory for the expressions in this
- /// designation.
- void FreeExprs(Sema &Actions) {}
};
} // end namespace clang
diff --git a/contrib/llvm-project/clang/include/clang/Sema/EnterExpressionEvaluationContext.h b/contrib/llvm-project/clang/include/clang/Sema/EnterExpressionEvaluationContext.h
new file mode 100644
index 000000000000..5eca797b8842
--- /dev/null
+++ b/contrib/llvm-project/clang/include/clang/Sema/EnterExpressionEvaluationContext.h
@@ -0,0 +1,69 @@
+//===--- EnterExpressionEvaluationContext.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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_SEMA_ENTEREXPRESSIONEVALUATIONCONTEXT_H
+#define LLVM_CLANG_SEMA_ENTEREXPRESSIONEVALUATIONCONTEXT_H
+
+#include "clang/Sema/Sema.h"
+
+namespace clang {
+
+class Decl;
+
+/// RAII object that enters a new expression evaluation context.
+class EnterExpressionEvaluationContext {
+ Sema &Actions;
+ bool Entered = true;
+
+public:
+ EnterExpressionEvaluationContext(
+ Sema &Actions, Sema::ExpressionEvaluationContext NewContext,
+ Decl *LambdaContextDecl = nullptr,
+ Sema::ExpressionEvaluationContextRecord::ExpressionKind ExprContext =
+ Sema::ExpressionEvaluationContextRecord::EK_Other,
+ bool ShouldEnter = true)
+ : Actions(Actions), Entered(ShouldEnter) {
+ if (Entered)
+ Actions.PushExpressionEvaluationContext(NewContext, LambdaContextDecl,
+ ExprContext);
+ }
+ EnterExpressionEvaluationContext(
+ Sema &Actions, Sema::ExpressionEvaluationContext NewContext,
+ Sema::ReuseLambdaContextDecl_t,
+ Sema::ExpressionEvaluationContextRecord::ExpressionKind ExprContext =
+ Sema::ExpressionEvaluationContextRecord::EK_Other)
+ : Actions(Actions) {
+ Actions.PushExpressionEvaluationContext(
+ NewContext, Sema::ReuseLambdaContextDecl, ExprContext);
+ }
+
+ enum InitListTag { InitList };
+ EnterExpressionEvaluationContext(Sema &Actions, InitListTag,
+ bool ShouldEnter = true)
+ : Actions(Actions), Entered(false) {
+ // In C++11 onwards, narrowing checks are performed on the contents of
+ // braced-init-lists, even when they occur within unevaluated operands.
+ // Therefore we still need to instantiate constexpr functions used in such
+ // a context.
+ if (ShouldEnter && Actions.isUnevaluatedContext() &&
+ Actions.getLangOpts().CPlusPlus11) {
+ Actions.PushExpressionEvaluationContext(
+ Sema::ExpressionEvaluationContext::UnevaluatedList);
+ Entered = true;
+ }
+ }
+
+ ~EnterExpressionEvaluationContext() {
+ if (Entered)
+ Actions.PopExpressionEvaluationContext();
+ }
+};
+
+} // namespace clang
+
+#endif
diff --git a/contrib/llvm-project/clang/include/clang/Sema/ExternalSemaSource.h b/contrib/llvm-project/clang/include/clang/Sema/ExternalSemaSource.h
index 9c18aa1398d3..22d1ee2df115 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;
@@ -232,6 +230,11 @@ public:
return false;
}
+ /// Notify the external source that a lambda was assigned a mangling number.
+ /// This enables the external source to track the correspondence between
+ /// lambdas and mangling numbers if necessary.
+ virtual void AssignedLambdaNumbering(const CXXRecordDecl *Lambda) {}
+
/// LLVM-style RTTI.
/// \{
bool isA(const void *ClassID) const override {
diff --git a/contrib/llvm-project/clang/include/clang/Sema/HLSLExternalSemaSource.h b/contrib/llvm-project/clang/include/clang/Sema/HLSLExternalSemaSource.h
new file mode 100644
index 000000000000..c0bfff327139
--- /dev/null
+++ b/contrib/llvm-project/clang/include/clang/Sema/HLSLExternalSemaSource.h
@@ -0,0 +1,55 @@
+//===--- HLSLExternalSemaSource.h - HLSL Sema Source ------------*- 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 the HLSLExternalSemaSource interface.
+//
+//===----------------------------------------------------------------------===//
+#ifndef CLANG_SEMA_HLSLEXTERNALSEMASOURCE_H
+#define CLANG_SEMA_HLSLEXTERNALSEMASOURCE_H
+
+#include "llvm/ADT/DenseMap.h"
+
+#include "clang/Sema/ExternalSemaSource.h"
+
+namespace clang {
+class NamespaceDecl;
+class Sema;
+
+class HLSLExternalSemaSource : public ExternalSemaSource {
+ Sema *SemaPtr = nullptr;
+ NamespaceDecl *HLSLNamespace = nullptr;
+ CXXRecordDecl *ResourceDecl = nullptr;
+
+ using CompletionFunction = std::function<void(CXXRecordDecl *)>;
+ llvm::DenseMap<CXXRecordDecl *, CompletionFunction> Completions;
+
+ void defineHLSLVectorAlias();
+ void defineTrivialHLSLTypes();
+ void defineHLSLTypesWithForwardDeclarations();
+
+ void onCompletion(CXXRecordDecl *Record, CompletionFunction Fn);
+
+public:
+ ~HLSLExternalSemaSource() override;
+
+ /// Initialize the semantic source with the Sema instance
+ /// being used to perform semantic analysis on the abstract syntax
+ /// tree.
+ void InitializeSema(Sema &S) override;
+
+ /// Inform the semantic consumer that Sema is no longer available.
+ void ForgetSema() override { SemaPtr = nullptr; }
+
+ using ExternalASTSource::CompleteType;
+ /// Complete an incomplete HLSL builtin type
+ void CompleteType(TagDecl *Tag) override;
+};
+
+} // namespace clang
+
+#endif // CLANG_SEMA_HLSLEXTERNALSEMASOURCE_H
diff --git a/contrib/llvm-project/clang/include/clang/Sema/IdentifierResolver.h b/contrib/llvm-project/clang/include/clang/Sema/IdentifierResolver.h
index 7c8dc46307d4..557f51314640 100644
--- a/contrib/llvm-project/clang/include/clang/Sema/IdentifierResolver.h
+++ b/contrib/llvm-project/clang/include/clang/Sema/IdentifierResolver.h
@@ -134,13 +134,17 @@ public:
explicit IdentifierResolver(Preprocessor &PP);
~IdentifierResolver();
- /// begin - Returns an iterator for decls with the name 'Name'.
+ IdentifierResolver(const IdentifierResolver &) = delete;
+ IdentifierResolver &operator=(const IdentifierResolver &) = delete;
+
+ /// Returns a range of decls with the name 'Name'.
+ llvm::iterator_range<iterator> decls(DeclarationName Name);
+
+ /// Returns an iterator over decls with the name 'Name'.
iterator begin(DeclarationName Name);
- /// end - Returns an iterator that has 'finished'.
- iterator end() {
- return iterator();
- }
+ /// Returns the end iterator.
+ iterator end() { return iterator(); }
/// isDeclInScope - If 'Ctx' is a function/method, isDeclInScope returns true
/// if 'D' is in Scope 'S', otherwise 'S' is ignored and isDeclInScope returns
diff --git a/contrib/llvm-project/clang/include/clang/Sema/Initialization.h b/contrib/llvm-project/clang/include/clang/Sema/Initialization.h
index 420803f8e33c..2072cd8d1c3e 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;
@@ -124,6 +123,10 @@ public:
/// decomposition declaration.
EK_Binding,
+ /// The entity being initialized is a non-static data member subobject of an
+ /// object initialized via parenthesized aggregate initialization.
+ EK_ParenAggInitMember,
+
// Note: err_init_conversion_failed in DiagnosticSemaKinds.td uses this
// enum as an index for its first %select. When modifying this list,
// that diagnostic text needs to be updated as well.
@@ -228,8 +231,10 @@ private:
/// Create the initialization entity for a member subobject.
InitializedEntity(FieldDecl *Member, const InitializedEntity *Parent,
- bool Implicit, bool DefaultMemberInit)
- : Kind(EK_Member), Parent(Parent), Type(Member->getType()),
+ bool Implicit, bool DefaultMemberInit,
+ bool IsParenAggInit = false)
+ : Kind(IsParenAggInit ? EK_ParenAggInitMember : EK_Member),
+ Parent(Parent), Type(Member->getType()),
Variable{Member, Implicit, DefaultMemberInit} {}
/// Create the initialization entity for an array element.
@@ -335,8 +340,15 @@ public:
}
/// Create the initialization entity for a temporary.
- static InitializedEntity InitializeTemporary(TypeSourceInfo *TypeInfo) {
- return InitializeTemporary(TypeInfo, TypeInfo->getType());
+ static InitializedEntity InitializeTemporary(ASTContext &Context,
+ TypeSourceInfo *TypeInfo) {
+ QualType Type = TypeInfo->getType();
+ if (Context.getLangOpts().OpenCLCPlusPlus) {
+ assert(!Type.hasAddressSpace() && "Temporary already has address space!");
+ Type = Context.getAddrSpaceQualType(Type, LangAS::opencl_private);
+ }
+
+ return InitializeTemporary(TypeInfo, Type);
}
/// Create the initialization entity for a temporary.
@@ -382,6 +394,14 @@ public:
return InitializedEntity(Member->getAnonField(), Parent, Implicit, false);
}
+ /// Create the initialization entity for a member subobject initialized via
+ /// parenthesized aggregate init.
+ static InitializedEntity InitializeMemberFromParenAggInit(FieldDecl *Member) {
+ return InitializedEntity(Member, /*Parent=*/nullptr, /*Implicit=*/false,
+ /*DefaultMemberInit=*/false,
+ /*IsParenAggInit=*/true);
+ }
+
/// Create the initialization entity for a default member initializer.
static InitializedEntity
InitializeMemberFromDefaultMemberInitializer(FieldDecl *Member) {
@@ -481,7 +501,7 @@ public:
/// Determine whether this is an array new with an unknown bound.
bool isVariableLengthArrayNew() const {
- return getKind() == EK_New && dyn_cast_or_null<IncompleteArrayType>(
+ return getKind() == EK_New && isa_and_nonnull<IncompleteArrayType>(
getType()->getAsArrayTypeUnsafe());
}
@@ -917,7 +937,11 @@ public:
SK_OCLSamplerInit,
/// Initialize an opaque OpenCL type (event_t, queue_t, etc.) with zero
- SK_OCLZeroOpaqueType
+ SK_OCLZeroOpaqueType,
+
+ /// Initialize an aggreagate with parenthesized list of values.
+ /// This is a C++20 feature.
+ SK_ParenthesizedListInit
};
/// A single step in the initialization sequence.
@@ -1093,6 +1117,13 @@ public:
/// List-copy-initialization chose an explicit constructor.
FK_ExplicitConstructor,
+
+ /// Parenthesized list initialization failed at some point.
+ /// This is a C++20 feature.
+ FK_ParenthesizedListInitFailed,
+
+ // A designated initializer was provided for a non-aggregate type.
+ FK_DesignatedInitForNonAggregate,
};
private:
@@ -1351,6 +1382,8 @@ public:
/// from a zero constant.
void AddOCLZeroOpaqueTypeStep(QualType T);
+ void AddParenthesizedListInitStep(QualType T);
+
/// Add steps to unwrap a initializer list for a reference around a
/// single element and rewrap it at the end.
void RewrapReferenceInitList(QualType T, InitListExpr *Syntactic);
diff --git a/contrib/llvm-project/clang/include/clang/Sema/Lookup.h b/contrib/llvm-project/clang/include/clang/Sema/Lookup.h
index c6edc2df5b9f..2f2f2607a937 100644
--- a/contrib/llvm-project/clang/include/clang/Sema/Lookup.h
+++ b/contrib/llvm-project/clang/include/clang/Sema/Lookup.h
@@ -26,10 +26,10 @@
#include "clang/Basic/Specifiers.h"
#include "clang/Sema/Sema.h"
#include "llvm/ADT/MapVector.h"
-#include "llvm/ADT/Optional.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/Casting.h"
#include <cassert>
+#include <optional>
#include <utility>
namespace clang {
@@ -117,6 +117,17 @@ public:
/// @endcode
AmbiguousReference,
+ /// Name lookup results in an ambiguity because multiple placeholder
+ /// variables were found in the same scope.
+ /// @code
+ /// void f() {
+ /// int _ = 0;
+ /// int _ = 0;
+ /// return _; // ambiguous use of placeholder variable
+ /// }
+ /// @endcode
+ AmbiguousReferenceToPlaceholderVariable,
+
/// Name lookup results in an ambiguity because an entity with a
/// tag name was hidden by an entity with an ordinary name from
/// a different context.
@@ -148,20 +159,22 @@ public:
: SemaPtr(&SemaRef), NameInfo(NameInfo), LookupKind(LookupKind),
Redecl(Redecl != Sema::NotForRedeclaration),
ExternalRedecl(Redecl == Sema::ForExternalRedeclaration),
- Diagnose(Redecl == Sema::NotForRedeclaration) {
+ DiagnoseAccess(Redecl == Sema::NotForRedeclaration),
+ DiagnoseAmbiguous(Redecl == Sema::NotForRedeclaration) {
configure();
}
// TODO: consider whether this constructor should be restricted to take
// as input a const IdentifierInfo* (instead of Name),
// forcing other cases towards the constructor taking a DNInfo.
- LookupResult(Sema &SemaRef, DeclarationName Name,
- SourceLocation NameLoc, Sema::LookupNameKind LookupKind,
+ LookupResult(Sema &SemaRef, DeclarationName Name, SourceLocation NameLoc,
+ Sema::LookupNameKind LookupKind,
Sema::RedeclarationKind Redecl = Sema::NotForRedeclaration)
: SemaPtr(&SemaRef), NameInfo(Name, NameLoc), LookupKind(LookupKind),
Redecl(Redecl != Sema::NotForRedeclaration),
ExternalRedecl(Redecl == Sema::ForExternalRedeclaration),
- Diagnose(Redecl == Sema::NotForRedeclaration) {
+ DiagnoseAccess(Redecl == Sema::NotForRedeclaration),
+ DiagnoseAmbiguous(Redecl == Sema::NotForRedeclaration) {
configure();
}
@@ -192,12 +205,14 @@ public:
Redecl(std::move(Other.Redecl)),
ExternalRedecl(std::move(Other.ExternalRedecl)),
HideTags(std::move(Other.HideTags)),
- Diagnose(std::move(Other.Diagnose)),
+ DiagnoseAccess(std::move(Other.DiagnoseAccess)),
+ DiagnoseAmbiguous(std::move(Other.DiagnoseAmbiguous)),
AllowHidden(std::move(Other.AllowHidden)),
Shadowed(std::move(Other.Shadowed)),
TemplateNameLookup(std::move(Other.TemplateNameLookup)) {
Other.Paths = nullptr;
- Other.Diagnose = false;
+ Other.DiagnoseAccess = false;
+ Other.DiagnoseAmbiguous = false;
}
LookupResult &operator=(LookupResult &&Other) {
@@ -215,17 +230,22 @@ public:
Redecl = std::move(Other.Redecl);
ExternalRedecl = std::move(Other.ExternalRedecl);
HideTags = std::move(Other.HideTags);
- Diagnose = std::move(Other.Diagnose);
+ DiagnoseAccess = std::move(Other.DiagnoseAccess);
+ DiagnoseAmbiguous = std::move(Other.DiagnoseAmbiguous);
AllowHidden = std::move(Other.AllowHidden);
Shadowed = std::move(Other.Shadowed);
TemplateNameLookup = std::move(Other.TemplateNameLookup);
Other.Paths = nullptr;
- Other.Diagnose = false;
+ Other.DiagnoseAccess = false;
+ Other.DiagnoseAmbiguous = false;
return *this;
}
~LookupResult() {
- if (Diagnose) diagnose();
+ if (DiagnoseAccess)
+ diagnoseAccess();
+ if (DiagnoseAmbiguous)
+ diagnoseAmbiguous();
if (Paths) deletePaths(Paths);
}
@@ -319,7 +339,7 @@ public:
}
LookupResultKind getResultKind() const {
- assert(sanity());
+ assert(checkDebugAssumptions());
return ResultKind;
}
@@ -346,30 +366,56 @@ public:
/// Determine whether the given declaration is visible to the
/// program.
- static bool isVisible(Sema &SemaRef, NamedDecl *D) {
- // If this declaration is not hidden, it's visible.
- if (D->isUnconditionallyVisible())
- return true;
+ static bool isVisible(Sema &SemaRef, NamedDecl *D);
- // During template instantiation, we can refer to hidden declarations, if
- // they were visible in any module along the path of instantiation.
- return isVisibleSlow(SemaRef, D);
+ static bool isReachable(Sema &SemaRef, NamedDecl *D);
+
+ static bool isAcceptable(Sema &SemaRef, NamedDecl *D,
+ Sema::AcceptableKind Kind) {
+ return Kind == Sema::AcceptableKind::Visible ? isVisible(SemaRef, D)
+ : isReachable(SemaRef, D);
}
+ /// Determine whether this lookup is permitted to see the declaration.
+ /// Note that a reachable but not visible declaration inhabiting a namespace
+ /// is not allowed to be seen during name lookup.
+ ///
+ /// For example:
+ /// ```
+ /// // m.cppm
+ /// export module m;
+ /// struct reachable { int v; }
+ /// export auto func() { return reachable{43}; }
+ /// // Use.cpp
+ /// import m;
+ /// auto Use() {
+ /// // Not valid. We couldn't see reachable here.
+ /// // So isAvailableForLookup would return false when we look
+ /// up 'reachable' here.
+ /// // return reachable(43).v;
+ /// // Valid. The field name 'v' is allowed during name lookup.
+ /// // So isAvailableForLookup would return true when we look up 'v' here.
+ /// return func().v;
+ /// }
+ /// ```
+ static bool isAvailableForLookup(Sema &SemaRef, NamedDecl *ND);
+
/// Retrieve the accepted (re)declaration of the given declaration,
/// if there is one.
NamedDecl *getAcceptableDecl(NamedDecl *D) const {
if (!D->isInIdentifierNamespace(IDNS))
return nullptr;
- if (isVisible(getSema(), D) || isHiddenDeclarationVisible(D))
+ if (isAvailableForLookup(getSema(), D) || isHiddenDeclarationVisible(D))
return D;
return getAcceptableDeclSlow(D);
}
private:
- static bool isVisibleSlow(Sema &SemaRef, NamedDecl *D);
+ static bool isAcceptableSlow(Sema &SemaRef, NamedDecl *D,
+ Sema::AcceptableKind Kind);
+ static bool isReachableSlow(Sema &SemaRef, NamedDecl *D);
NamedDecl *getAcceptableDeclSlow(NamedDecl *D) const;
public:
@@ -481,7 +527,7 @@ public:
Paths = nullptr;
}
} else {
- llvm::Optional<AmbiguityKind> SavedAK;
+ std::optional<AmbiguityKind> SavedAK;
bool WasAmbiguous = false;
if (ResultKind == Ambiguous) {
SavedAK = Ambiguity;
@@ -495,7 +541,7 @@ public:
if (ResultKind == Ambiguous) {
(void)WasAmbiguous;
assert(WasAmbiguous);
- Ambiguity = SavedAK.getValue();
+ Ambiguity = *SavedAK;
} else if (Paths) {
deletePaths(Paths);
Paths = nullptr;
@@ -581,13 +627,20 @@ public:
/// Suppress the diagnostics that would normally fire because of this
/// lookup. This happens during (e.g.) redeclaration lookups.
void suppressDiagnostics() {
- Diagnose = false;
+ DiagnoseAccess = false;
+ DiagnoseAmbiguous = false;
}
- /// Determines whether this lookup is suppressing diagnostics.
- bool isSuppressingDiagnostics() const {
- return !Diagnose;
- }
+ /// Suppress the diagnostics that would normally fire because of this
+ /// lookup due to access control violations.
+ void suppressAccessDiagnostics() { DiagnoseAccess = false; }
+
+ /// Determines whether this lookup is suppressing access control diagnostics.
+ bool isSuppressingAccessDiagnostics() const { return !DiagnoseAccess; }
+
+ /// Determines whether this lookup is suppressing ambiguous lookup
+ /// diagnostics.
+ bool isSuppressingAmbiguousDiagnostics() const { return !DiagnoseAmbiguous; }
/// Sets a 'context' source range.
void setContextRange(SourceRange SR) {
@@ -631,6 +684,15 @@ public:
F.CalledDone = true;
}
+ // The move assignment operator is defined as deleted pending
+ // further motivation.
+ Filter &operator=(Filter &&) = delete;
+
+ // The copy constrcutor and copy assignment operator is defined as deleted
+ // pending further motivation.
+ Filter(const Filter &) = delete;
+ Filter &operator=(const Filter &) = delete;
+
~Filter() {
assert(CalledDone &&
"LookupResult::Filter destroyed without done() call");
@@ -691,11 +753,15 @@ public:
}
private:
- void diagnose() {
+ void diagnoseAccess() {
+ if (!isAmbiguous() && isClassLookup() &&
+ getSema().getLangOpts().AccessControl)
+ getSema().CheckLookupAccess(*this);
+ }
+
+ void diagnoseAmbiguous() {
if (isAmbiguous())
getSema().DiagnoseAmbiguousLookup(*this);
- else if (isClassLookup() && getSema().getLangOpts().AccessControl)
- getSema().CheckLookupAccess(*this);
}
void setAmbiguous(AmbiguityKind AK) {
@@ -706,10 +772,9 @@ private:
void addDeclsFromBasePaths(const CXXBasePaths &P);
void configure();
- // Sanity checks.
- bool sanity() const;
+ bool checkDebugAssumptions() const;
- bool sanityCheckUnresolved() const {
+ bool checkUnresolved() const {
for (iterator I = begin(), E = end(); I != E; ++I)
if (isa<UnresolvedUsingValueDecl>((*I)->getUnderlyingDecl()))
return true;
@@ -742,7 +807,8 @@ private:
/// are present
bool HideTags = true;
- bool Diagnose = false;
+ bool DiagnoseAccess = false;
+ bool DiagnoseAmbiguous = false;
/// True if we should allow hidden declarations to be 'visible'.
bool AllowHidden = false;
diff --git a/contrib/llvm-project/clang/include/clang/Sema/MultiplexExternalSemaSource.h b/contrib/llvm-project/clang/include/clang/Sema/MultiplexExternalSemaSource.h
index 78658dcf990c..2bf91cb5212c 100644
--- a/contrib/llvm-project/clang/include/clang/Sema/MultiplexExternalSemaSource.h
+++ b/contrib/llvm-project/clang/include/clang/Sema/MultiplexExternalSemaSource.h
@@ -40,25 +40,24 @@ class MultiplexExternalSemaSource : public ExternalSemaSource {
static char ID;
private:
- SmallVector<ExternalSemaSource *, 2> Sources; // doesn't own them.
+ SmallVector<ExternalSemaSource *, 2> Sources;
public:
-
- ///Constructs a new multiplexing external sema source and appends the
+ /// Constructs a new multiplexing external sema source and appends the
/// given element to it.
///
- ///\param[in] s1 - A non-null (old) ExternalSemaSource.
- ///\param[in] s2 - A non-null (new) ExternalSemaSource.
+ ///\param[in] S1 - A non-null (old) ExternalSemaSource.
+ ///\param[in] S2 - A non-null (new) ExternalSemaSource.
///
- MultiplexExternalSemaSource(ExternalSemaSource& s1, ExternalSemaSource& s2);
+ MultiplexExternalSemaSource(ExternalSemaSource *S1, ExternalSemaSource *S2);
~MultiplexExternalSemaSource() override;
- ///Appends new source to the source list.
+ /// Appends new source to the source list.
///
- ///\param[in] source - An ExternalSemaSource.
+ ///\param[in] Source - An ExternalSemaSource.
///
- void addSource(ExternalSemaSource &source);
+ void AddSource(ExternalSemaSource *Source);
//===--------------------------------------------------------------------===//
// ExternalASTSource.
@@ -361,6 +360,9 @@ public:
bool MaybeDiagnoseMissingCompleteType(SourceLocation Loc,
QualType T) override;
+ // Inform all attached sources that a mangling number was assigned.
+ void AssignedLambdaNumbering(const CXXRecordDecl *Lambda) override;
+
/// LLVM-style RTTI.
/// \{
bool isA(const void *ClassID) const override {
diff --git a/contrib/llvm-project/clang/include/clang/Sema/Overload.h b/contrib/llvm-project/clang/include/clang/Sema/Overload.h
index 82661cb3d12a..6ccabad3af54 100644
--- a/contrib/llvm-project/clang/include/clang/Sema/Overload.h
+++ b/contrib/llvm-project/clang/include/clang/Sema/Overload.h
@@ -26,7 +26,6 @@
#include "clang/Sema/SemaFixItUtils.h"
#include "clang/Sema/TemplateDeduction.h"
#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/None.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
@@ -163,6 +162,9 @@ class Sema;
/// Arm SVE Vector conversions
ICK_SVE_Vector_Conversion,
+ /// RISC-V RVV Vector conversions
+ ICK_RVV_Vector_Conversion,
+
/// A vector splat from an arithmetic type
ICK_Vector_Splat,
@@ -190,6 +192,9 @@ class Sema;
/// C-only conversion between pointers with incompatible types
ICK_Incompatible_Pointer_Conversion,
+ /// Fixed point type conversions according to N1169.
+ ICK_Fixed_Point_Conversion,
+
/// The number of conversion kinds
ICK_Num_Conversion_Kinds,
};
@@ -252,10 +257,7 @@ class Sema;
/// sequence (C++ 13.3.3.1.1). A standard conversion sequence
/// contains between zero and three conversions. If a particular
/// conversion is not needed, it will be set to the identity conversion
- /// (ICK_Identity). Note that the three conversions are
- /// specified as separate members (rather than in an array) so that
- /// we can keep the size of a standard conversion sequence to a
- /// single word.
+ /// (ICK_Identity).
class StandardConversionSequence {
public:
/// First -- The first conversion can be an lvalue-to-rvalue
@@ -469,7 +471,9 @@ class Sema;
unrelated_class,
bad_qualifiers,
lvalue_ref_to_rvalue,
- rvalue_ref_to_lvalue
+ rvalue_ref_to_lvalue,
+ too_few_initializers,
+ too_many_initializers,
};
// This can be null, e.g. for implicit object arguments.
@@ -519,8 +523,12 @@ class Sema;
/// specifies that there is no conversion from the source type to
/// the target type. AmbiguousConversion represents the unique
/// ambiguous conversion (C++0x [over.best.ics]p10).
+ /// StaticObjectArgumentConversion represents the conversion rules for
+ /// the synthesized first argument of calls to static member functions
+ /// ([over.best.ics.general]p8).
enum Kind {
StandardConversion = 0,
+ StaticObjectArgumentConversion,
UserDefinedConversion,
AmbiguousConversion,
EllipsisConversion,
@@ -533,11 +541,17 @@ class Sema;
};
/// ConversionKind - The kind of implicit conversion sequence.
- unsigned ConversionKind : 30;
+ unsigned ConversionKind : 31;
+
+ // Whether the initializer list was of an incomplete array.
+ unsigned InitializerListOfIncompleteArray : 1;
- /// Whether the target is really a std::initializer_list, and the
- /// sequence only represents the worst element conversion.
- unsigned StdInitializerListElement : 1;
+ /// When initializing an array or std::initializer_list from an
+ /// initializer-list, this is the array or std::initializer_list type being
+ /// initialized. The remainder of the conversion sequence, including ToType,
+ /// describe the worst conversion of an initializer to an element of the
+ /// array or std::initializer_list. (Note, 'worst' is not well defined.)
+ QualType InitializerListContainerType;
void setKind(Kind K) {
destruct();
@@ -568,16 +582,21 @@ class Sema;
};
ImplicitConversionSequence()
- : ConversionKind(Uninitialized), StdInitializerListElement(false) {
+ : ConversionKind(Uninitialized),
+ InitializerListOfIncompleteArray(false) {
Standard.setAsIdentityConversion();
}
ImplicitConversionSequence(const ImplicitConversionSequence &Other)
: ConversionKind(Other.ConversionKind),
- StdInitializerListElement(Other.StdInitializerListElement) {
+ InitializerListOfIncompleteArray(
+ Other.InitializerListOfIncompleteArray),
+ InitializerListContainerType(Other.InitializerListContainerType) {
switch (ConversionKind) {
case Uninitialized: break;
case StandardConversion: Standard = Other.Standard; break;
+ case StaticObjectArgumentConversion:
+ break;
case UserDefinedConversion: UserDefined = Other.UserDefined; break;
case AmbiguousConversion: Ambiguous.copyFrom(Other.Ambiguous); break;
case EllipsisConversion: break;
@@ -611,6 +630,7 @@ class Sema;
unsigned getKindRank() const {
switch (getKind()) {
case StandardConversion:
+ case StaticObjectArgumentConversion:
return 0;
case UserDefinedConversion:
@@ -629,6 +649,9 @@ class Sema;
bool isBad() const { return getKind() == BadConversion; }
bool isStandard() const { return getKind() == StandardConversion; }
+ bool isStaticObjectArgument() const {
+ return getKind() == StaticObjectArgumentConversion;
+ }
bool isEllipsis() const { return getKind() == EllipsisConversion; }
bool isAmbiguous() const { return getKind() == AmbiguousConversion; }
bool isUserDefined() const { return getKind() == UserDefinedConversion; }
@@ -654,6 +677,7 @@ class Sema;
}
void setStandard() { setKind(StandardConversion); }
+ void setStaticObjectArgument() { setKind(StaticObjectArgumentConversion); }
void setEllipsis() { setKind(EllipsisConversion); }
void setUserDefined() { setKind(UserDefinedConversion); }
@@ -670,14 +694,22 @@ class Sema;
Standard.setAllToTypes(T);
}
- /// Whether the target is really a std::initializer_list, and the
- /// sequence only represents the worst element conversion.
- bool isStdInitializerListElement() const {
- return StdInitializerListElement;
+ // True iff this is a conversion sequence from an initializer list to an
+ // array or std::initializer.
+ bool hasInitializerListContainerType() const {
+ return !InitializerListContainerType.isNull();
}
-
- void setStdInitializerListElement(bool V = true) {
- StdInitializerListElement = V;
+ void setInitializerListContainerType(QualType T, bool IA) {
+ InitializerListContainerType = T;
+ InitializerListOfIncompleteArray = IA;
+ }
+ bool isInitializerListOfIncompleteArray() const {
+ return InitializerListOfIncompleteArray;
+ }
+ QualType getInitializerListContainerType() const {
+ assert(hasInitializerListContainerType() &&
+ "not initializer list container");
+ return InitializerListContainerType;
}
/// Form an "implicit" conversion sequence from nullptr_t to bool, for a
@@ -776,6 +808,10 @@ class Sema;
/// This candidate was not viable because its associated constraints were
/// not satisfied.
ovl_fail_constraints_not_satisfied,
+
+ /// This candidate was not viable because it has internal linkage and is
+ /// from a different module unit than the use.
+ ovl_fail_module_mismatched,
};
/// A list of implicit conversion sequences for the arguments of an
@@ -905,6 +941,8 @@ class Sema;
return ExplicitCallArguments;
}
+ bool NotValidBecauseConstraintExprHasError() const;
+
private:
friend class OverloadCandidateSet;
OverloadCandidate()
@@ -941,12 +979,16 @@ class Sema;
/// functions to a candidate set.
struct OperatorRewriteInfo {
OperatorRewriteInfo()
- : OriginalOperator(OO_None), AllowRewrittenCandidates(false) {}
- OperatorRewriteInfo(OverloadedOperatorKind Op, bool AllowRewritten)
- : OriginalOperator(Op), AllowRewrittenCandidates(AllowRewritten) {}
+ : OriginalOperator(OO_None), OpLoc(), AllowRewrittenCandidates(false) {}
+ OperatorRewriteInfo(OverloadedOperatorKind Op, SourceLocation OpLoc,
+ bool AllowRewritten)
+ : OriginalOperator(Op), OpLoc(OpLoc),
+ AllowRewrittenCandidates(AllowRewritten) {}
/// The original operator as written in the source.
OverloadedOperatorKind OriginalOperator;
+ /// The source location of the operator.
+ SourceLocation OpLoc;
/// Whether we should include rewritten candidates in the overload set.
bool AllowRewrittenCandidates;
@@ -982,22 +1024,23 @@ class Sema;
CRK = OverloadCandidateRewriteKind(CRK | CRK_Reversed);
return CRK;
}
-
/// Determines whether this operator could be implemented by a function
/// with reversed parameter order.
bool isReversible() {
return AllowRewrittenCandidates && OriginalOperator &&
(getRewrittenOverloadedOperator(OriginalOperator) != OO_None ||
- shouldAddReversed(OriginalOperator));
+ allowsReversed(OriginalOperator));
}
- /// Determine whether we should consider looking for and adding reversed
- /// candidates for operator Op.
- bool shouldAddReversed(OverloadedOperatorKind Op);
+ /// Determine whether reversing parameter order is allowed for operator
+ /// Op.
+ bool allowsReversed(OverloadedOperatorKind Op);
/// Determine whether we should add a rewritten candidate for \p FD with
/// reversed parameter order.
- bool shouldAddReversed(ASTContext &Ctx, const FunctionDecl *FD);
+ /// \param OriginalArgs are the original non reversed arguments.
+ bool shouldAddReversed(Sema &S, ArrayRef<Expr *> OriginalArgs,
+ FunctionDecl *FD);
};
private:
@@ -1105,8 +1148,9 @@ class Sema;
/// Add a new candidate with NumConversions conversion sequence slots
/// to the overload set.
- OverloadCandidate &addCandidate(unsigned NumConversions = 0,
- ConversionSequenceList Conversions = None) {
+ OverloadCandidate &
+ addCandidate(unsigned NumConversions = 0,
+ ConversionSequenceList Conversions = std::nullopt) {
assert((Conversions.empty() || Conversions.size() == NumConversions) &&
"preallocated conversion sequence has wrong length");
@@ -1184,6 +1228,20 @@ class Sema;
return Info;
}
+ // Returns false if signature help is relevant despite number of arguments
+ // exceeding parameters. Specifically, it returns false when
+ // PartialOverloading is true and one of the following:
+ // * Function is variadic
+ // * Function is template variadic
+ // * Function is an instantiation of template variadic function
+ // The last case may seem strange. The idea is that if we added one more
+ // argument, we'd end up with a function similar to Function. Since, in the
+ // context of signature help and/or code completion, we do not know what the
+ // type of the next argument (that the user is typing) will be, this is as
+ // good candidate as we can get, despite the fact that it takes one less
+ // parameter.
+ bool shouldEnforceArgLimit(bool PartialOverloading, FunctionDecl *Function);
+
} // namespace clang
#endif // LLVM_CLANG_SEMA_OVERLOAD_H
diff --git a/contrib/llvm-project/clang/include/clang/Sema/Ownership.h b/contrib/llvm-project/clang/include/clang/Sema/Ownership.h
index 5c7b010ed736..0752f5de7e33 100644
--- a/contrib/llvm-project/clang/include/clang/Sema/Ownership.h
+++ b/contrib/llvm-project/clang/include/clang/Sema/Ownership.h
@@ -132,7 +132,6 @@ namespace llvm {
namespace clang {
- // Basic
class StreamingDiagnostic;
// Determines whether the low bit of the result pointer for the
@@ -140,164 +139,147 @@ class StreamingDiagnostic;
// for it's "invalid" flag.
template <class Ptr> struct IsResultPtrLowBitFree {
static const bool value = false;
- };
-
- /// ActionResult - This structure is used while parsing/acting on
- /// expressions, stmts, etc. It encapsulates both the object returned by
- /// the action, plus a sense of whether or not it is valid.
- /// When CompressInvalid is true, the "invalid" flag will be
- /// stored in the low bit of the Val pointer.
- template<class PtrTy,
- bool CompressInvalid = IsResultPtrLowBitFree<PtrTy>::value>
- class ActionResult {
- PtrTy Val;
- bool Invalid;
-
- public:
- ActionResult(bool Invalid = false) : Val(PtrTy()), Invalid(Invalid) {}
- ActionResult(PtrTy val) : Val(val), Invalid(false) {}
- ActionResult(const DiagnosticBuilder &) : Val(PtrTy()), Invalid(true) {}
-
- // These two overloads prevent void* -> bool conversions.
- ActionResult(const void *) = delete;
- ActionResult(volatile void *) = delete;
-
- bool isInvalid() const { return Invalid; }
- bool isUsable() const { return !Invalid && Val; }
- bool isUnset() const { return !Invalid && !Val; }
-
- PtrTy get() const { return Val; }
- template <typename T> T *getAs() { return static_cast<T*>(get()); }
-
- void set(PtrTy V) { Val = V; }
-
- const ActionResult &operator=(PtrTy RHS) {
- Val = RHS;
- Invalid = false;
- return *this;
- }
- };
-
- // This ActionResult partial specialization places the "invalid"
- // flag into the low bit of the pointer.
- template<typename PtrTy>
- class ActionResult<PtrTy, true> {
- // A pointer whose low bit is 1 if this result is invalid, 0
- // otherwise.
- uintptr_t PtrWithInvalid;
-
- using PtrTraits = llvm::PointerLikeTypeTraits<PtrTy>;
-
- public:
- ActionResult(bool Invalid = false)
- : PtrWithInvalid(static_cast<uintptr_t>(Invalid)) {}
-
- ActionResult(PtrTy V) {
- void *VP = PtrTraits::getAsVoidPointer(V);
- PtrWithInvalid = reinterpret_cast<uintptr_t>(VP);
- assert((PtrWithInvalid & 0x01) == 0 && "Badly aligned pointer");
- }
-
- ActionResult(const DiagnosticBuilder &) : PtrWithInvalid(0x01) {}
-
- // These two overloads prevent void* -> bool conversions.
- ActionResult(const void *) = delete;
- ActionResult(volatile void *) = delete;
-
- bool isInvalid() const { return PtrWithInvalid & 0x01; }
- bool isUsable() const { return PtrWithInvalid > 0x01; }
- bool isUnset() const { return PtrWithInvalid == 0; }
-
- PtrTy get() const {
- void *VP = reinterpret_cast<void *>(PtrWithInvalid & ~0x01);
- return PtrTraits::getFromVoidPointer(VP);
- }
-
- template <typename T> T *getAs() { return static_cast<T*>(get()); }
-
- void set(PtrTy V) {
- void *VP = PtrTraits::getAsVoidPointer(V);
- PtrWithInvalid = reinterpret_cast<uintptr_t>(VP);
- assert((PtrWithInvalid & 0x01) == 0 && "Badly aligned pointer");
- }
-
- const ActionResult &operator=(PtrTy RHS) {
- void *VP = PtrTraits::getAsVoidPointer(RHS);
- PtrWithInvalid = reinterpret_cast<uintptr_t>(VP);
- assert((PtrWithInvalid & 0x01) == 0 && "Badly aligned pointer");
- return *this;
- }
-
- // For types where we can fit a flag in with the pointer, provide
- // conversions to/from pointer type.
- static ActionResult getFromOpaquePointer(void *P) {
- ActionResult Result;
- Result.PtrWithInvalid = (uintptr_t)P;
- return Result;
- }
- void *getAsOpaquePointer() const { return (void*)PtrWithInvalid; }
- };
+};
+
+/// The result of parsing/analyzing an expression, statement etc.
+///
+/// It may be:
+/// - usable: a valid pointer to the result object
+/// - unset (null but valid): for constructs that may legitimately be absent
+/// (for example, the condition of a for loop)
+/// - invalid: indicating an error
+/// (no detail is provided, usually the error has already been diagnosed)
+template <class PtrTy, bool Compress = IsResultPtrLowBitFree<PtrTy>::value>
+class ActionResult {
+ PtrTy Val = {};
+ bool Invalid = false;
+
+public:
+ ActionResult(bool Invalid = false) : Val(PtrTy()), Invalid(Invalid) {}
+ ActionResult(PtrTy Val) { *this = Val; }
+ ActionResult(const DiagnosticBuilder &) : ActionResult(/*Invalid=*/true) {}
+
+ // These two overloads prevent void* -> bool conversions.
+ ActionResult(const void *) = delete;
+ ActionResult(volatile void *) = delete;
+
+ bool isInvalid() const { return Invalid; }
+ bool isUnset() const { return !Invalid && !Val; }
+ bool isUsable() const { return !isInvalid() && !isUnset(); }
+
+ PtrTy get() const { return Val; }
+ template <typename T> T *getAs() { return static_cast<T *>(get()); }
+
+ ActionResult &operator=(PtrTy RHS) {
+ Val = RHS;
+ Invalid = false;
+ return *this;
+ }
+};
- /// An opaque type for threading parsed type information through the
- /// parser.
- using ParsedType = OpaquePtr<QualType>;
- using UnionParsedType = UnionOpaquePtr<QualType>;
+// If we PtrTy has a free bit, we can represent "invalid" as nullptr|1.
+template <typename PtrTy> class ActionResult<PtrTy, true> {
+ static constexpr uintptr_t UnsetValue = 0x0;
+ static constexpr uintptr_t InvalidValue = 0x1;
- // We can re-use the low bit of expression, statement, base, and
- // member-initializer pointers for the "invalid" flag of
- // ActionResult.
- template<> struct IsResultPtrLowBitFree<Expr*> {
- static const bool value = true;
- };
- template<> struct IsResultPtrLowBitFree<Stmt*> {
- static const bool value = true;
- };
- template<> struct IsResultPtrLowBitFree<CXXBaseSpecifier*> {
- static const bool value = true;
- };
- template<> struct IsResultPtrLowBitFree<CXXCtorInitializer*> {
- static const bool value = true;
- };
+ uintptr_t Value = UnsetValue;
- using ExprResult = ActionResult<Expr *>;
- using StmtResult = ActionResult<Stmt *>;
- using TypeResult = ActionResult<ParsedType>;
- using BaseResult = ActionResult<CXXBaseSpecifier *>;
- using MemInitResult = ActionResult<CXXCtorInitializer *>;
+ using PtrTraits = llvm::PointerLikeTypeTraits<PtrTy>;
- using DeclResult = ActionResult<Decl *>;
- using ParsedTemplateTy = OpaquePtr<TemplateName>;
- using UnionParsedTemplateTy = UnionOpaquePtr<TemplateName>;
+public:
+ ActionResult(bool Invalid = false)
+ : Value(Invalid ? InvalidValue : UnsetValue) {}
+ ActionResult(PtrTy V) { *this = V; }
+ ActionResult(const DiagnosticBuilder &) : ActionResult(/*Invalid=*/true) {}
- using MultiExprArg = MutableArrayRef<Expr *>;
- using MultiStmtArg = MutableArrayRef<Stmt *>;
- using ASTTemplateArgsPtr = MutableArrayRef<ParsedTemplateArgument>;
- using MultiTypeArg = MutableArrayRef<ParsedType>;
- using MultiTemplateParamsArg = MutableArrayRef<TemplateParameterList *>;
+ // These two overloads prevent void* -> bool conversions.
+ ActionResult(const void *) = delete;
+ ActionResult(volatile void *) = delete;
- inline ExprResult ExprError() { return ExprResult(true); }
- inline StmtResult StmtError() { return StmtResult(true); }
- inline TypeResult TypeError() { return TypeResult(true); }
+ bool isInvalid() const { return Value == InvalidValue; }
+ bool isUnset() const { return Value == UnsetValue; }
+ bool isUsable() const { return !isInvalid() && !isUnset(); }
- inline ExprResult ExprError(const StreamingDiagnostic &) {
- return ExprError();
+ PtrTy get() const {
+ void *VP = reinterpret_cast<void *>(Value & ~0x01);
+ return PtrTraits::getFromVoidPointer(VP);
}
- inline StmtResult StmtError(const StreamingDiagnostic &) {
- return StmtError();
- }
-
- inline ExprResult ExprEmpty() { return ExprResult(false); }
- inline StmtResult StmtEmpty() { return StmtResult(false); }
+ template <typename T> T *getAs() { return static_cast<T *>(get()); }
- inline Expr *AssertSuccess(ExprResult R) {
- assert(!R.isInvalid() && "operation was asserted to never fail!");
- return R.get();
+ ActionResult &operator=(PtrTy RHS) {
+ void *VP = PtrTraits::getAsVoidPointer(RHS);
+ Value = reinterpret_cast<uintptr_t>(VP);
+ assert((Value & 0x01) == 0 && "Badly aligned pointer");
+ return *this;
}
- inline Stmt *AssertSuccess(StmtResult R) {
- assert(!R.isInvalid() && "operation was asserted to never fail!");
- return R.get();
+ // For types where we can fit a flag in with the pointer, provide
+ // conversions to/from pointer type.
+ static ActionResult getFromOpaquePointer(void *P) {
+ ActionResult Result;
+ Result.Value = (uintptr_t)P;
+ assert(Result.isInvalid() ||
+ PtrTraits::getAsVoidPointer(Result.get()) == P);
+ return Result;
}
+ void *getAsOpaquePointer() const { return (void *)Value; }
+};
+
+/// An opaque type for threading parsed type information through the parser.
+using ParsedType = OpaquePtr<QualType>;
+using UnionParsedType = UnionOpaquePtr<QualType>;
+
+// We can re-use the low bit of expression, statement, base, and
+// member-initializer pointers for the "invalid" flag of
+// ActionResult.
+template <> struct IsResultPtrLowBitFree<Expr *> {
+ static const bool value = true;
+};
+template <> struct IsResultPtrLowBitFree<Stmt *> {
+ static const bool value = true;
+};
+template <> struct IsResultPtrLowBitFree<CXXBaseSpecifier *> {
+ static const bool value = true;
+};
+template <> struct IsResultPtrLowBitFree<CXXCtorInitializer *> {
+ static const bool value = true;
+};
+
+using ExprResult = ActionResult<Expr *>;
+using StmtResult = ActionResult<Stmt *>;
+using TypeResult = ActionResult<ParsedType>;
+using BaseResult = ActionResult<CXXBaseSpecifier *>;
+using MemInitResult = ActionResult<CXXCtorInitializer *>;
+
+using DeclResult = ActionResult<Decl *>;
+using ParsedTemplateTy = OpaquePtr<TemplateName>;
+using UnionParsedTemplateTy = UnionOpaquePtr<TemplateName>;
+
+using MultiExprArg = MutableArrayRef<Expr *>;
+using MultiStmtArg = MutableArrayRef<Stmt *>;
+using ASTTemplateArgsPtr = MutableArrayRef<ParsedTemplateArgument>;
+using MultiTypeArg = MutableArrayRef<ParsedType>;
+using MultiTemplateParamsArg = MutableArrayRef<TemplateParameterList *>;
+
+inline ExprResult ExprError() { return ExprResult(true); }
+inline StmtResult StmtError() { return StmtResult(true); }
+inline TypeResult TypeError() { return TypeResult(true); }
+
+inline ExprResult ExprError(const StreamingDiagnostic &) { return ExprError(); }
+inline StmtResult StmtError(const StreamingDiagnostic &) { return StmtError(); }
+
+inline ExprResult ExprEmpty() { return ExprResult(false); }
+inline StmtResult StmtEmpty() { return StmtResult(false); }
+
+inline Expr *AssertSuccess(ExprResult R) {
+ assert(!R.isInvalid() && "operation was asserted to never fail!");
+ return R.get();
+}
+
+inline Stmt *AssertSuccess(StmtResult R) {
+ assert(!R.isInvalid() && "operation was asserted to never fail!");
+ return R.get();
+}
} // namespace clang
diff --git a/contrib/llvm-project/clang/include/clang/Sema/ParsedAttr.h b/contrib/llvm-project/clang/include/clang/Sema/ParsedAttr.h
index f47f557adeb1..8c0edca1ebc5 100644
--- a/contrib/llvm-project/clang/include/clang/Sema/ParsedAttr.h
+++ b/contrib/llvm-project/clang/include/clang/Sema/ParsedAttr.h
@@ -11,20 +11,20 @@
//
//===----------------------------------------------------------------------===//
-#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"
#include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/ParsedAttrInfo.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Sema/Ownership.h"
#include "llvm/ADT/PointerUnion.h"
#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/TinyPtrVector.h"
#include "llvm/Support/Allocator.h"
-#include "llvm/Support/Registry.h"
#include "llvm/Support/VersionTuple.h"
+#include <bitset>
#include <cassert>
#include <cstddef>
#include <cstring>
@@ -37,98 +37,10 @@ class Decl;
class Expr;
class IdentifierInfo;
class LangOptions;
-class ParsedAttr;
class Sema;
class Stmt;
class TargetInfo;
-struct ParsedAttrInfo {
- /// Corresponds to the Kind enum.
- unsigned AttrKind : 16;
- /// The number of required arguments of this attribute.
- unsigned NumArgs : 4;
- /// The number of optional arguments of this attributes.
- unsigned OptArgs : 4;
- /// True if the parsing does not match the semantic content.
- unsigned HasCustomParsing : 1;
- /// True if this attribute is only available for certain targets.
- unsigned IsTargetSpecific : 1;
- /// True if this attribute applies to types.
- unsigned IsType : 1;
- /// True if this attribute applies to statements.
- unsigned IsStmt : 1;
- /// True if this attribute has any spellings that are known to gcc.
- unsigned IsKnownToGCC : 1;
- /// True if this attribute is supported by #pragma clang attribute.
- unsigned IsSupportedByPragmaAttribute : 1;
- /// The syntaxes supported by this attribute and how they're spelled.
- struct Spelling {
- AttributeCommonInfo::Syntax Syntax;
- const char *NormalizedFullName;
- };
- ArrayRef<Spelling> Spellings;
-
- ParsedAttrInfo(AttributeCommonInfo::Kind AttrKind =
- AttributeCommonInfo::NoSemaHandlerAttribute)
- : AttrKind(AttrKind), NumArgs(0), OptArgs(0), HasCustomParsing(0),
- IsTargetSpecific(0), IsType(0), IsStmt(0), IsKnownToGCC(0),
- IsSupportedByPragmaAttribute(0) {}
-
- virtual ~ParsedAttrInfo() = default;
-
- /// Check if this attribute appertains to D, and issue a diagnostic if not.
- virtual bool diagAppertainsToDecl(Sema &S, const ParsedAttr &Attr,
- const Decl *D) const {
- return true;
- }
- /// Check if this attribute appertains to St, and issue a diagnostic if not.
- virtual bool diagAppertainsToStmt(Sema &S, const ParsedAttr &Attr,
- const Stmt *St) const {
- return true;
- }
- /// Check if the given attribute is mutually exclusive with other attributes
- /// already applied to the given declaration.
- virtual bool diagMutualExclusion(Sema &S, const ParsedAttr &A,
- const Decl *D) const {
- return true;
- }
- /// Check if this attribute is allowed by the language we are compiling, and
- /// issue a diagnostic if not.
- virtual bool diagLangOpts(Sema &S, const ParsedAttr &Attr) const {
- return true;
- }
- /// Check if this attribute is allowed when compiling for the given target.
- virtual bool existsInTarget(const TargetInfo &Target) const {
- return true;
- }
- /// Convert the spelling index of Attr to a semantic spelling enum value.
- virtual unsigned
- spellingIndexToSemanticSpelling(const ParsedAttr &Attr) const {
- return UINT_MAX;
- }
- /// Populate Rules with the match rules of this attribute.
- virtual void getPragmaAttributeMatchRules(
- llvm::SmallVectorImpl<std::pair<attr::SubjectMatchRule, bool>> &Rules,
- const LangOptions &LangOpts) const {
- }
- enum AttrHandling {
- NotHandled,
- AttributeApplied,
- AttributeNotApplied
- };
- /// If this ParsedAttrInfo knows how to handle this ParsedAttr applied to this
- /// Decl then do so and return either AttributeApplied if it was applied or
- /// AttributeNotApplied if it wasn't. Otherwise return NotHandled.
- virtual AttrHandling handleDeclAttribute(Sema &S, Decl *D,
- const ParsedAttr &Attr) const {
- return NotHandled;
- }
-
- static const ParsedAttrInfo &get(const AttributeCommonInfo &A);
-};
-
-typedef llvm::Registry<ParsedAttrInfo> ParsedAttrInfoRegistry;
-
/// Represents information about a change in availability for
/// an entity, which is part of the encoding of the 'availability'
/// attribute.
@@ -293,10 +205,9 @@ private:
/// Constructor for attributes with expression arguments.
ParsedAttr(IdentifierInfo *attrName, SourceRange attrRange,
IdentifierInfo *scopeName, SourceLocation scopeLoc,
- ArgsUnion *args, unsigned numArgs, Syntax syntaxUsed,
+ ArgsUnion *args, unsigned numArgs, Form formUsed,
SourceLocation ellipsisLoc)
- : AttributeCommonInfo(attrName, scopeName, attrRange, scopeLoc,
- syntaxUsed),
+ : AttributeCommonInfo(attrName, scopeName, attrRange, scopeLoc, formUsed),
EllipsisLoc(ellipsisLoc), NumArgs(numArgs), Invalid(false),
UsedAsTypeAttr(false), IsAvailability(false),
IsTypeTagForDatatype(false), IsProperty(false), HasParsedType(false),
@@ -312,10 +223,9 @@ private:
IdentifierLoc *Parm, const AvailabilityChange &introduced,
const AvailabilityChange &deprecated,
const AvailabilityChange &obsoleted, SourceLocation unavailable,
- const Expr *messageExpr, Syntax syntaxUsed, SourceLocation strict,
+ const Expr *messageExpr, Form formUsed, SourceLocation strict,
const Expr *replacementExpr)
- : AttributeCommonInfo(attrName, scopeName, attrRange, scopeLoc,
- syntaxUsed),
+ : AttributeCommonInfo(attrName, scopeName, attrRange, scopeLoc, formUsed),
NumArgs(1), Invalid(false), UsedAsTypeAttr(false), IsAvailability(true),
IsTypeTagForDatatype(false), IsProperty(false), HasParsedType(false),
HasProcessingCache(false), IsPragmaClangAttribute(false),
@@ -331,9 +241,8 @@ private:
ParsedAttr(IdentifierInfo *attrName, SourceRange attrRange,
IdentifierInfo *scopeName, SourceLocation scopeLoc,
IdentifierLoc *Parm1, IdentifierLoc *Parm2, IdentifierLoc *Parm3,
- Syntax syntaxUsed)
- : AttributeCommonInfo(attrName, scopeName, attrRange, scopeLoc,
- syntaxUsed),
+ Form formUsed)
+ : AttributeCommonInfo(attrName, scopeName, attrRange, scopeLoc, formUsed),
NumArgs(3), Invalid(false), UsedAsTypeAttr(false),
IsAvailability(false), IsTypeTagForDatatype(false), IsProperty(false),
HasParsedType(false), HasProcessingCache(false),
@@ -348,9 +257,8 @@ private:
ParsedAttr(IdentifierInfo *attrName, SourceRange attrRange,
IdentifierInfo *scopeName, SourceLocation scopeLoc,
IdentifierLoc *ArgKind, ParsedType matchingCType,
- bool layoutCompatible, bool mustBeNull, Syntax syntaxUsed)
- : AttributeCommonInfo(attrName, scopeName, attrRange, scopeLoc,
- syntaxUsed),
+ bool layoutCompatible, bool mustBeNull, Form formUsed)
+ : AttributeCommonInfo(attrName, scopeName, attrRange, scopeLoc, formUsed),
NumArgs(1), Invalid(false), UsedAsTypeAttr(false),
IsAvailability(false), IsTypeTagForDatatype(true), IsProperty(false),
HasParsedType(false), HasProcessingCache(false),
@@ -366,23 +274,21 @@ private:
/// Constructor for attributes with a single type argument.
ParsedAttr(IdentifierInfo *attrName, SourceRange attrRange,
IdentifierInfo *scopeName, SourceLocation scopeLoc,
- ParsedType typeArg, Syntax syntaxUsed)
- : AttributeCommonInfo(attrName, scopeName, attrRange, scopeLoc,
- syntaxUsed),
- NumArgs(0), Invalid(false), UsedAsTypeAttr(false),
- IsAvailability(false), IsTypeTagForDatatype(false), IsProperty(false),
- HasParsedType(true), HasProcessingCache(false),
- IsPragmaClangAttribute(false), Info(ParsedAttrInfo::get(*this)) {
+ ParsedType typeArg, Form formUsed, SourceLocation ellipsisLoc)
+ : AttributeCommonInfo(attrName, scopeName, attrRange, scopeLoc, formUsed),
+ EllipsisLoc(ellipsisLoc), NumArgs(0), Invalid(false),
+ UsedAsTypeAttr(false), IsAvailability(false),
+ IsTypeTagForDatatype(false), IsProperty(false), HasParsedType(true),
+ HasProcessingCache(false), IsPragmaClangAttribute(false),
+ Info(ParsedAttrInfo::get(*this)) {
new (&getTypeBuffer()) ParsedType(typeArg);
}
/// Constructor for microsoft __declspec(property) attribute.
ParsedAttr(IdentifierInfo *attrName, SourceRange attrRange,
IdentifierInfo *scopeName, SourceLocation scopeLoc,
- IdentifierInfo *getterId, IdentifierInfo *setterId,
- Syntax syntaxUsed)
- : AttributeCommonInfo(attrName, scopeName, attrRange, scopeLoc,
- syntaxUsed),
+ IdentifierInfo *getterId, IdentifierInfo *setterId, Form formUsed)
+ : AttributeCommonInfo(attrName, scopeName, attrRange, scopeLoc, formUsed),
NumArgs(0), Invalid(false), UsedAsTypeAttr(false),
IsAvailability(false), IsTypeTagForDatatype(false), IsProperty(true),
HasParsedType(false), HasProcessingCache(false),
@@ -407,7 +313,7 @@ private:
return *getTrailingObjects<ParsedType>();
}
- /// The property data immediately follows the object is is mutually exclusive
+ /// The property data immediately follows the object is mutually exclusive
/// with arguments.
detail::PropertyData &getPropertyDataBuffer() {
assert(IsProperty);
@@ -600,9 +506,13 @@ public:
bool isStmtAttr() const;
bool hasCustomParsing() const;
+ bool acceptsExprPack() const;
+ bool isParamExpr(size_t N) const;
unsigned getMinArgs() const;
unsigned getMaxArgs() const;
+ unsigned getNumArgMembers() const;
bool hasVariadicArg() const;
+ void handleAttrWithDelayedArgs(Sema &S, Decl *D) const;
bool diagnoseAppertainsTo(class Sema &S, const Decl *D) const;
bool diagnoseAppertainsTo(class Sema &S, const Stmt *St) const;
bool diagnoseMutualExclusion(class Sema &S, const Decl *D) const;
@@ -621,6 +531,18 @@ public:
bool isKnownToGCC() const;
bool isSupportedByPragmaAttribute() const;
+ /// Returns whether a [[]] attribute, if specified ahead of a declaration,
+ /// should be applied to the decl-specifier-seq instead (i.e. whether it
+ /// "slides" to the decl-specifier-seq).
+ ///
+ /// By the standard, attributes specified before the declaration always
+ /// appertain to the declaration, but historically we have allowed some of
+ /// these attributes to slide to the decl-specifier-seq, so we need to keep
+ /// supporting this behavior.
+ ///
+ /// This may only be called if isStandardAttributeSyntax() returns true.
+ bool slidesFromDeclToDeclSpecLegacyBehavior() const;
+
/// If the parsed attribute has a semantic equivalent, and it would
/// have a semantic Spelling enumeration (due to having semantically-distinct
/// spelling variations), return the value of that semantic spelling. If the
@@ -628,7 +550,7 @@ public:
/// a Spelling enumeration, the value UINT_MAX is returned.
unsigned getSemanticSpelling() const;
- /// If this is an OpenCL address space attribute returns its representation
+ /// If this is an OpenCL address space attribute, returns its representation
/// in LangAS, otherwise returns default address space.
LangAS asOpenCLLangAS() const {
switch (getParsedKind()) {
@@ -651,7 +573,7 @@ public:
}
}
- /// If this is an OpenCL address space attribute returns its SYCL
+ /// If this is an OpenCL address space attribute, returns its SYCL
/// representation in LangAS, otherwise returns default address space.
LangAS asSYCLLangAS() const {
switch (getKind()) {
@@ -671,6 +593,17 @@ public:
}
}
+ /// If this is an HLSL address space attribute, returns its representation
+ /// in LangAS, otherwise returns default address space.
+ LangAS asHLSLLangAS() const {
+ switch (getParsedKind()) {
+ case ParsedAttr::AT_HLSLGroupSharedAddressSpace:
+ return LangAS::hlsl_groupshared;
+ default:
+ return LangAS::Default;
+ }
+ }
+
AttributeCommonInfo::Kind getKind() const {
return AttributeCommonInfo::Kind(Info.AttrKind);
}
@@ -741,7 +674,7 @@ class AttributePool {
friend class AttributeFactory;
friend class ParsedAttributes;
AttributeFactory &Factory;
- llvm::TinyPtrVector<ParsedAttr *> Attrs;
+ llvm::SmallVector<ParsedAttr *> Attrs;
void *allocate(size_t size) {
return Factory.allocate(size);
@@ -765,12 +698,19 @@ public:
AttributePool(AttributeFactory &factory) : Factory(factory) {}
AttributePool(const AttributePool &) = delete;
+ // The copy assignment operator is defined as deleted pending further
+ // motivation.
+ AttributePool &operator=(const AttributePool &) = delete;
~AttributePool() { Factory.reclaimPool(*this); }
/// Move the given pool's allocations to this pool.
AttributePool(AttributePool &&pool) = default;
+ // The move assignment operator is defined as deleted pending further
+ // motivation.
+ AttributePool &operator=(AttributePool &&pool) = delete;
+
AttributeFactory &getFactory() const { return Factory; }
void clear() {
@@ -786,8 +726,7 @@ public:
ParsedAttr *create(IdentifierInfo *attrName, SourceRange attrRange,
IdentifierInfo *scopeName, SourceLocation scopeLoc,
- ArgsUnion *args, unsigned numArgs,
- ParsedAttr::Syntax syntax,
+ ArgsUnion *args, unsigned numArgs, ParsedAttr::Form form,
SourceLocation ellipsisLoc = SourceLocation()) {
size_t temp =
ParsedAttr::totalSizeToAlloc<ArgsUnion, detail::AvailabilityData,
@@ -800,7 +739,7 @@ public:
detail::PropertyData>(numArgs, 0, 0, 0,
0));
return add(new (memory) ParsedAttr(attrName, attrRange, scopeName, scopeLoc,
- args, numArgs, syntax, ellipsisLoc));
+ args, numArgs, form, ellipsisLoc));
}
ParsedAttr *create(IdentifierInfo *attrName, SourceRange attrRange,
@@ -809,24 +748,24 @@ public:
const AvailabilityChange &deprecated,
const AvailabilityChange &obsoleted,
SourceLocation unavailable, const Expr *MessageExpr,
- ParsedAttr::Syntax syntax, SourceLocation strict,
+ ParsedAttr::Form form, SourceLocation strict,
const Expr *ReplacementExpr) {
void *memory = allocate(AttributeFactory::AvailabilityAllocSize);
return add(new (memory) ParsedAttr(
attrName, attrRange, scopeName, scopeLoc, Param, introduced, deprecated,
- obsoleted, unavailable, MessageExpr, syntax, strict, ReplacementExpr));
+ obsoleted, unavailable, MessageExpr, form, strict, ReplacementExpr));
}
ParsedAttr *create(IdentifierInfo *attrName, SourceRange attrRange,
IdentifierInfo *scopeName, SourceLocation scopeLoc,
IdentifierLoc *Param1, IdentifierLoc *Param2,
- IdentifierLoc *Param3, ParsedAttr::Syntax syntax) {
+ IdentifierLoc *Param3, ParsedAttr::Form form) {
void *memory = allocate(
ParsedAttr::totalSizeToAlloc<ArgsUnion, detail::AvailabilityData,
detail::TypeTagForDatatypeData, ParsedType,
detail::PropertyData>(3, 0, 0, 0, 0));
return add(new (memory) ParsedAttr(attrName, attrRange, scopeName, scopeLoc,
- Param1, Param2, Param3, syntax));
+ Param1, Param2, Param3, form));
}
ParsedAttr *
@@ -834,42 +773,50 @@ public:
IdentifierInfo *scopeName, SourceLocation scopeLoc,
IdentifierLoc *argumentKind,
ParsedType matchingCType, bool layoutCompatible,
- bool mustBeNull, ParsedAttr::Syntax syntax) {
+ bool mustBeNull, ParsedAttr::Form form) {
void *memory = allocate(AttributeFactory::TypeTagForDatatypeAllocSize);
return add(new (memory) ParsedAttr(attrName, attrRange, scopeName, scopeLoc,
argumentKind, matchingCType,
- layoutCompatible, mustBeNull, syntax));
+ layoutCompatible, mustBeNull, form));
}
ParsedAttr *createTypeAttribute(IdentifierInfo *attrName,
SourceRange attrRange,
IdentifierInfo *scopeName,
SourceLocation scopeLoc, ParsedType typeArg,
- ParsedAttr::Syntax syntaxUsed) {
+ ParsedAttr::Form formUsed,
+ SourceLocation ellipsisLoc) {
void *memory = allocate(
ParsedAttr::totalSizeToAlloc<ArgsUnion, detail::AvailabilityData,
detail::TypeTagForDatatypeData, ParsedType,
detail::PropertyData>(0, 0, 0, 1, 0));
return add(new (memory) ParsedAttr(attrName, attrRange, scopeName, scopeLoc,
- typeArg, syntaxUsed));
+ typeArg, formUsed, ellipsisLoc));
}
ParsedAttr *
createPropertyAttribute(IdentifierInfo *attrName, SourceRange attrRange,
IdentifierInfo *scopeName, SourceLocation scopeLoc,
IdentifierInfo *getterId, IdentifierInfo *setterId,
- ParsedAttr::Syntax syntaxUsed) {
+ ParsedAttr::Form formUsed) {
void *memory = allocate(AttributeFactory::PropertyAllocSize);
return add(new (memory) ParsedAttr(attrName, attrRange, scopeName, scopeLoc,
- getterId, setterId, syntaxUsed));
+ getterId, setterId, formUsed));
}
};
class ParsedAttributesView {
- using VecTy = llvm::TinyPtrVector<ParsedAttr *>;
+ using VecTy = llvm::SmallVector<ParsedAttr *>;
using SizeType = decltype(std::declval<VecTy>().size());
public:
+ SourceRange Range;
+
+ static const ParsedAttributesView &none() {
+ static const ParsedAttributesView Attrs;
+ return Attrs;
+ }
+
bool empty() const { return AttrList.empty(); }
SizeType size() const { return AttrList.size(); }
ParsedAttr &operator[](SizeType pos) { return *AttrList[pos]; }
@@ -893,7 +840,7 @@ public:
ParsedAttr> {
iterator() : iterator_adaptor_base(nullptr) {}
iterator(VecTy::iterator I) : iterator_adaptor_base(I) {}
- reference operator*() { return **I; }
+ reference operator*() const { return **I; }
friend class ParsedAttributesView;
};
struct const_iterator
@@ -951,10 +898,34 @@ public:
});
}
+ const ParsedAttr *getMSPropertyAttr() const {
+ auto It = llvm::find_if(AttrList, [](const ParsedAttr *AL) {
+ return AL->isDeclspecPropertyAttribute();
+ });
+ if (It != AttrList.end())
+ return *It;
+ return nullptr;
+ }
+ bool hasMSPropertyAttr() const { return getMSPropertyAttr(); }
+
private:
VecTy AttrList;
};
+struct ParsedAttributeArgumentsProperties {
+ ParsedAttributeArgumentsProperties(uint32_t StringLiteralBits)
+ : StringLiterals(StringLiteralBits) {}
+ bool isStringLiteralArg(unsigned I) const {
+ // If the last bit is set, assume we have a variadic parameter
+ if (I >= StringLiterals.size())
+ return StringLiterals.test(StringLiterals.size() - 1);
+ return StringLiterals.test(I);
+ }
+
+private:
+ std::bitset<32> StringLiterals;
+};
+
/// ParsedAttributes - A collection of parsed attributes. Currently
/// we don't differentiate between the various attribute syntaxes,
/// which is basically silly.
@@ -965,18 +936,23 @@ class ParsedAttributes : public ParsedAttributesView {
public:
ParsedAttributes(AttributeFactory &factory) : pool(factory) {}
ParsedAttributes(const ParsedAttributes &) = delete;
+ ParsedAttributes &operator=(const ParsedAttributes &) = delete;
AttributePool &getPool() const { return pool; }
- void takeAllFrom(ParsedAttributes &attrs) {
- addAll(attrs.begin(), attrs.end());
- attrs.clearListOnly();
- pool.takeAllFrom(attrs.pool);
+ void takeAllFrom(ParsedAttributes &Other) {
+ assert(&Other != this &&
+ "ParsedAttributes can't take attributes from itself");
+ addAll(Other.begin(), Other.end());
+ Other.clearListOnly();
+ pool.takeAllFrom(Other.pool);
}
- void takeOneFrom(ParsedAttributes &Attrs, ParsedAttr *PA) {
- Attrs.getPool().remove(PA);
- Attrs.remove(PA);
+ void takeOneFrom(ParsedAttributes &Other, ParsedAttr *PA) {
+ assert(&Other != this &&
+ "ParsedAttributes can't take attribute from itself");
+ Other.getPool().remove(PA);
+ Other.remove(PA);
getPool().add(PA);
addAtEnd(PA);
}
@@ -984,16 +960,16 @@ public:
void clear() {
clearListOnly();
pool.clear();
+ Range = SourceRange();
}
/// Add attribute with expression arguments.
ParsedAttr *addNew(IdentifierInfo *attrName, SourceRange attrRange,
IdentifierInfo *scopeName, SourceLocation scopeLoc,
- ArgsUnion *args, unsigned numArgs,
- ParsedAttr::Syntax syntax,
+ ArgsUnion *args, unsigned numArgs, ParsedAttr::Form form,
SourceLocation ellipsisLoc = SourceLocation()) {
ParsedAttr *attr = pool.create(attrName, attrRange, scopeName, scopeLoc,
- args, numArgs, syntax, ellipsisLoc);
+ args, numArgs, form, ellipsisLoc);
addAtEnd(attr);
return attr;
}
@@ -1005,11 +981,11 @@ public:
const AvailabilityChange &deprecated,
const AvailabilityChange &obsoleted,
SourceLocation unavailable, const Expr *MessageExpr,
- ParsedAttr::Syntax syntax, SourceLocation strict,
+ ParsedAttr::Form form, SourceLocation strict,
const Expr *ReplacementExpr) {
ParsedAttr *attr = pool.create(
attrName, attrRange, scopeName, scopeLoc, Param, introduced, deprecated,
- obsoleted, unavailable, MessageExpr, syntax, strict, ReplacementExpr);
+ obsoleted, unavailable, MessageExpr, form, strict, ReplacementExpr);
addAtEnd(attr);
return attr;
}
@@ -1018,9 +994,9 @@ public:
ParsedAttr *addNew(IdentifierInfo *attrName, SourceRange attrRange,
IdentifierInfo *scopeName, SourceLocation scopeLoc,
IdentifierLoc *Param1, IdentifierLoc *Param2,
- IdentifierLoc *Param3, ParsedAttr::Syntax syntax) {
+ IdentifierLoc *Param3, ParsedAttr::Form form) {
ParsedAttr *attr = pool.create(attrName, attrRange, scopeName, scopeLoc,
- Param1, Param2, Param3, syntax);
+ Param1, Param2, Param3, form);
addAtEnd(attr);
return attr;
}
@@ -1031,10 +1007,10 @@ public:
IdentifierInfo *scopeName, SourceLocation scopeLoc,
IdentifierLoc *argumentKind,
ParsedType matchingCType, bool layoutCompatible,
- bool mustBeNull, ParsedAttr::Syntax syntax) {
+ bool mustBeNull, ParsedAttr::Form form) {
ParsedAttr *attr = pool.createTypeTagForDatatype(
attrName, attrRange, scopeName, scopeLoc, argumentKind, matchingCType,
- layoutCompatible, mustBeNull, syntax);
+ layoutCompatible, mustBeNull, form);
addAtEnd(attr);
return attr;
}
@@ -1042,10 +1018,11 @@ public:
/// Add an attribute with a single type argument.
ParsedAttr *addNewTypeAttr(IdentifierInfo *attrName, SourceRange attrRange,
IdentifierInfo *scopeName, SourceLocation scopeLoc,
- ParsedType typeArg,
- ParsedAttr::Syntax syntaxUsed) {
- ParsedAttr *attr = pool.createTypeAttribute(attrName, attrRange, scopeName,
- scopeLoc, typeArg, syntaxUsed);
+ ParsedType typeArg, ParsedAttr::Form formUsed,
+ SourceLocation ellipsisLoc = SourceLocation()) {
+ ParsedAttr *attr =
+ pool.createTypeAttribute(attrName, attrRange, scopeName, scopeLoc,
+ typeArg, formUsed, ellipsisLoc);
addAtEnd(attr);
return attr;
}
@@ -1055,10 +1032,9 @@ public:
addNewPropertyAttr(IdentifierInfo *attrName, SourceRange attrRange,
IdentifierInfo *scopeName, SourceLocation scopeLoc,
IdentifierInfo *getterId, IdentifierInfo *setterId,
- ParsedAttr::Syntax syntaxUsed) {
- ParsedAttr *attr =
- pool.createPropertyAttribute(attrName, attrRange, scopeName, scopeLoc,
- getterId, setterId, syntaxUsed);
+ ParsedAttr::Form formUsed) {
+ ParsedAttr *attr = pool.createPropertyAttribute(
+ attrName, attrRange, scopeName, scopeLoc, getterId, setterId, formUsed);
addAtEnd(attr);
return attr;
}
@@ -1067,26 +1043,10 @@ private:
mutable AttributePool pool;
};
-struct ParsedAttributesWithRange : ParsedAttributes {
- ParsedAttributesWithRange(AttributeFactory &factory)
- : ParsedAttributes(factory) {}
-
- void clear() {
- ParsedAttributes::clear();
- Range = SourceRange();
- }
-
- SourceRange Range;
-};
-struct ParsedAttributesViewWithRange : ParsedAttributesView {
- ParsedAttributesViewWithRange() : ParsedAttributesView() {}
- void clearListOnly() {
- ParsedAttributesView::clearListOnly();
- Range = SourceRange();
- }
-
- SourceRange Range;
-};
+/// Consumes the attributes from `First` and `Second` and concatenates them into
+/// `Result`. Sets `Result.Range` to the combined range of `First` and `Second`.
+void takeAndConcatenateAttrs(ParsedAttributes &First, ParsedAttributes &Second,
+ ParsedAttributes &Result);
/// These constants match the enumerated choices of
/// err_attribute_argument_n_type and err_attribute_argument_type.
@@ -1096,6 +1056,7 @@ enum AttributeArgumentNType {
AANT_ArgumentString,
AANT_ArgumentIdentifier,
AANT_ArgumentConstantExpr,
+ AANT_ArgumentBuiltinFunction,
};
/// These constants match the enumerated choices of
@@ -1118,14 +1079,14 @@ enum AttributeDeclKind {
inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB,
const ParsedAttr &At) {
- DB.AddTaggedVal(reinterpret_cast<intptr_t>(At.getAttrName()),
+ DB.AddTaggedVal(reinterpret_cast<uint64_t>(At.getAttrName()),
DiagnosticsEngine::ak_identifierinfo);
return DB;
}
inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB,
const ParsedAttr *At) {
- DB.AddTaggedVal(reinterpret_cast<intptr_t>(At->getAttrName()),
+ DB.AddTaggedVal(reinterpret_cast<uint64_t>(At->getAttrName()),
DiagnosticsEngine::ak_identifierinfo);
return DB;
}
@@ -1135,26 +1096,26 @@ inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB,
/// it explicit is hard. This constructor causes ambiguity with
/// DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB, SourceRange R).
/// We use SFINAE to disable any conversion and remove any ambiguity.
-template <typename ACI,
- typename std::enable_if_t<
- std::is_same<ACI, AttributeCommonInfo>::value, int> = 0>
+template <
+ typename ACI,
+ std::enable_if_t<std::is_same<ACI, AttributeCommonInfo>::value, int> = 0>
inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB,
- const ACI &CI) {
- DB.AddTaggedVal(reinterpret_cast<intptr_t>(CI.getAttrName()),
+ const ACI &CI) {
+ DB.AddTaggedVal(reinterpret_cast<uint64_t>(CI.getAttrName()),
DiagnosticsEngine::ak_identifierinfo);
return DB;
}
-template <typename ACI,
- typename std::enable_if_t<
- std::is_same<ACI, AttributeCommonInfo>::value, int> = 0>
+template <
+ typename ACI,
+ std::enable_if_t<std::is_same<ACI, AttributeCommonInfo>::value, int> = 0>
inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB,
- const ACI* CI) {
- DB.AddTaggedVal(reinterpret_cast<intptr_t>(CI->getAttrName()),
+ const ACI *CI) {
+ DB.AddTaggedVal(reinterpret_cast<uint64_t>(CI->getAttrName()),
DiagnosticsEngine::ak_identifierinfo);
return 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..65182d57246a 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; }
@@ -213,9 +212,9 @@ namespace clang {
}
void Destroy() {
- std::for_each(
- getTemplateArgs(), getTemplateArgs() + NumArgs,
- [](ParsedTemplateArgument &A) { A.~ParsedTemplateArgument(); });
+ for (ParsedTemplateArgument &A :
+ llvm::make_range(getTemplateArgs(), getTemplateArgs() + NumArgs))
+ A.~ParsedTemplateArgument();
this->~TemplateIdAnnotation();
free(this);
}
diff --git a/contrib/llvm-project/clang/include/clang/Sema/RISCVIntrinsicManager.h b/contrib/llvm-project/clang/include/clang/Sema/RISCVIntrinsicManager.h
new file mode 100644
index 000000000000..2a3dd1e7c469
--- /dev/null
+++ b/contrib/llvm-project/clang/include/clang/Sema/RISCVIntrinsicManager.h
@@ -0,0 +1,41 @@
+//===- RISCVIntrinsicManager.h - RISC-V Intrinsic Handler -------*- 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 the RISCVIntrinsicManager, which handles RISC-V vector
+// intrinsic functions.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_SEMA_RISCVINTRINSICMANAGER_H
+#define LLVM_CLANG_SEMA_RISCVINTRINSICMANAGER_H
+
+#include <cstdint>
+
+namespace clang {
+class LookupResult;
+class IdentifierInfo;
+class Preprocessor;
+
+namespace sema {
+class RISCVIntrinsicManager {
+public:
+ enum class IntrinsicKind : uint8_t { RVV, SIFIVE_VECTOR };
+
+ virtual ~RISCVIntrinsicManager() = default;
+
+ virtual void InitIntrinsicList() = 0;
+
+ // Create RISC-V intrinsic and insert into symbol table and return true if
+ // found, otherwise return false.
+ virtual bool CreateIntrinsicIfFound(LookupResult &LR, IdentifierInfo *II,
+ Preprocessor &PP) = 0;
+};
+} // end namespace sema
+} // end namespace clang
+
+#endif
diff --git a/contrib/llvm-project/clang/include/clang/Sema/Scope.h b/contrib/llvm-project/clang/include/clang/Sema/Scope.h
index b499ba1e7c2a..9e81706cd2aa 100644
--- a/contrib/llvm-project/clang/include/clang/Sema/Scope.h
+++ b/contrib/llvm-project/clang/include/clang/Sema/Scope.h
@@ -20,6 +20,7 @@
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/iterator_range.h"
#include <cassert>
+#include <optional>
namespace llvm {
@@ -44,11 +45,11 @@ public:
enum ScopeFlags {
/// This indicates that the scope corresponds to a function, which
/// means that labels are set here.
- FnScope = 0x01,
+ FnScope = 0x01,
/// This is a while, do, switch, for, etc that can have break
/// statements embedded into it.
- BreakScope = 0x02,
+ BreakScope = 0x02,
/// This is a while, do, for, which can have continue statements
/// embedded into it.
@@ -140,6 +141,15 @@ public:
/// parsed. If such a scope is a ContinueScope, it's invalid to jump to the
/// continue block from here.
ConditionVarScope = 0x2000000,
+
+ /// This is a scope of some OpenMP directive with
+ /// order clause which specifies concurrent
+ OpenMPOrderClauseScope = 0x4000000,
+ /// This is the scope for a lambda, after the lambda introducer.
+ /// Lambdas need two FunctionPrototypeScope scopes (because there is a
+ /// template scope in between), the outer scope does not increase the
+ /// depth of recursion.
+ LambdaScope = 0x8000000,
};
private:
@@ -210,9 +220,19 @@ private:
/// Used to determine if errors occurred in this scope.
DiagnosticErrorTrap ErrorTrap;
- /// A lattice consisting of undefined, a single NRVO candidate variable in
- /// this scope, or over-defined. The bit is true when over-defined.
- llvm::PointerIntPair<VarDecl *, 1, bool> NRVO;
+ /// A single NRVO candidate variable in this scope.
+ /// There are three possible values:
+ /// 1) pointer to VarDecl that denotes NRVO candidate itself.
+ /// 2) nullptr value means that NRVO is not allowed in this scope
+ /// (e.g. return a function parameter).
+ /// 3) std::nullopt value means that there is no NRVO candidate in this scope
+ /// (i.e. there are no return statements in this scope).
+ std::optional<VarDecl *> NRVO;
+
+ /// Represents return slots for NRVO candidates in the current scope.
+ /// If a variable is present in this set, it means that a return slot is
+ /// available for this variable in the current scope.
+ llvm::SmallPtrSet<VarDecl *, 8> ReturnSlots;
void setFlags(Scope *Parent, unsigned F);
@@ -304,12 +324,14 @@ public:
bool decl_empty() const { return DeclsInScope.empty(); }
void AddDecl(Decl *D) {
+ if (auto *VD = dyn_cast<VarDecl>(D))
+ if (!isa<ParmVarDecl>(VD))
+ ReturnSlots.insert(VD);
+
DeclsInScope.insert(D);
}
- void RemoveDecl(Decl *D) {
- DeclsInScope.erase(D);
- }
+ void RemoveDecl(Decl *D) { DeclsInScope.erase(D); }
void incrementMSManglingNumber() {
if (Scope *MSLMP = getMSLastManglingParent()) {
@@ -337,7 +359,7 @@ public:
/// isDeclScope - Return true if this is the scope that the specified decl is
/// declared in.
- bool isDeclScope(const Decl *D) const { return DeclsInScope.count(D) != 0; }
+ bool isDeclScope(const Decl *D) const { return DeclsInScope.contains(D); }
/// Get the entity corresponding to this scope.
DeclContext *getEntity() const {
@@ -364,11 +386,15 @@ public:
}
/// isFunctionScope() - Return true if this scope is a function scope.
- bool isFunctionScope() const { return (getFlags() & Scope::FnScope); }
+ bool isFunctionScope() const { return getFlags() & Scope::FnScope; }
/// isClassScope - Return true if this scope is a class/struct/union scope.
- bool isClassScope() const {
- return (getFlags() & Scope::ClassScope);
+ bool isClassScope() const { return getFlags() & Scope::ClassScope; }
+
+ /// Determines whether this scope is between inheritance colon and the real
+ /// class/struct definition.
+ bool isClassInheritanceScope() const {
+ return getFlags() & Scope::ClassInheritanceScope;
}
/// isInCXXInlineMethodScope - Return true if this scope is a C++ inline
@@ -426,6 +452,9 @@ public:
return getFlags() & Scope::AtCatchScope;
}
+ /// isCatchScope - Return true if this scope is a C++ catch statement.
+ bool isCatchScope() const { return getFlags() & Scope::CatchScope; }
+
/// isSwitchScope - Return true if this scope is a switch scope.
bool isSwitchScope() const {
for (const Scope *S = this; S; S = S->getParent()) {
@@ -469,9 +498,26 @@ public:
return P && P->isOpenMPLoopDirectiveScope();
}
+ /// Determine whether this scope is some OpenMP directive with
+ /// order clause which specifies concurrent scope.
+ bool isOpenMPOrderClauseScope() const {
+ return getFlags() & Scope::OpenMPOrderClauseScope;
+ }
+
+ /// Determine whether this scope is a while/do/for statement, which can have
+ /// continue statements embedded into it.
+ bool isContinueScope() const {
+ return getFlags() & ScopeFlags::ContinueScope;
+ }
+
/// Determine whether this scope is a C++ 'try' block.
bool isTryScope() const { return getFlags() & Scope::TryScope; }
+ /// Determine whether this scope is a function-level C++ try or catch scope.
+ bool isFnTryCatchScope() const {
+ return getFlags() & ScopeFlags::FnTryCatchScope;
+ }
+
/// Determine whether this scope is a SEH '__try' block.
bool isSEHTryScope() const { return getFlags() & Scope::SEHTryScope; }
@@ -483,6 +529,10 @@ public:
return getFlags() & Scope::CompoundStmtScope;
}
+ /// Determine whether this scope is a controlling scope in a
+ /// if/switch/while/for statement.
+ bool isControlScope() const { return getFlags() & Scope::ControlScope; }
+
/// Returns if rhs has a higher scope depth than this.
///
/// The caller is responsible for calling this only if one of the two scopes
@@ -505,23 +555,9 @@ public:
UsingDirectives.end());
}
- void addNRVOCandidate(VarDecl *VD) {
- if (NRVO.getInt())
- return;
- if (NRVO.getPointer() == nullptr) {
- NRVO.setPointer(VD);
- return;
- }
- if (NRVO.getPointer() != VD)
- setNoNRVO();
- }
-
- void setNoNRVO() {
- NRVO.setInt(true);
- NRVO.setPointer(nullptr);
- }
+ void updateNRVOCandidate(VarDecl *VD);
- void mergeNRVOIntoParent();
+ void applyNRVO();
/// Init - This is used by the parser to implement scope caching.
void Init(Scope *parent, unsigned flags);
diff --git a/contrib/llvm-project/clang/include/clang/Sema/ScopeInfo.h b/contrib/llvm-project/clang/include/clang/Sema/ScopeInfo.h
index 98ed75acd9d2..06e47eed4e93 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 {
@@ -67,7 +66,7 @@ namespace sema {
/// parsed.
class CompoundScopeInfo {
public:
- /// Whether this compound stamement contains `for' or `while' loops
+ /// Whether this compound statement contains `for' or `while' loops
/// with empty bodies.
bool HasEmptyLoopBodies = false;
@@ -75,7 +74,12 @@ public:
/// expression.
bool IsStmtExpr;
- CompoundScopeInfo(bool IsStmtExpr) : IsStmtExpr(IsStmtExpr) {}
+ /// FP options at the beginning of the compound statement, prior to
+ /// any pragma.
+ FPOptions InitialFPFeatures;
+
+ CompoundScopeInfo(bool IsStmtExpr, FPOptions FPO)
+ : IsStmtExpr(IsStmtExpr), InitialFPFeatures(FPO) {}
void setHasEmptyLoopBodies() {
HasEmptyLoopBodies = true;
@@ -164,10 +168,13 @@ public:
/// to build, the initial and final coroutine suspend points
bool NeedsCoroutineSuspends : 1;
- /// An enumeration represeting the kind of the first coroutine statement
+ /// An enumeration representing the kind of the first coroutine statement
/// in the function. One of co_return, co_await, or co_yield.
unsigned char FirstCoroutineStmtKind : 2;
+ /// Whether we found an immediate-escalating expression.
+ bool FoundImmediateEscalatingExpression : 1;
+
/// First coroutine statement in the current function.
/// (ex co_return, co_await, co_yield)
SourceLocation FirstCoroutineStmtLoc;
@@ -175,12 +182,16 @@ public:
/// First 'return' statement in the current function.
SourceLocation FirstReturnLoc;
- /// First C++ 'try' statement in the current function.
- SourceLocation FirstCXXTryLoc;
+ /// First C++ 'try' or ObjC @try statement in the current function.
+ SourceLocation FirstCXXOrObjCTryLoc;
+ enum { TryLocIsCXX, TryLocIsObjC, Unknown } FirstTryType = Unknown;
/// First SEH '__try' statement in the current function.
SourceLocation FirstSEHTryLoc;
+ /// First use of a VLA within the current function.
+ SourceLocation FirstVLALoc;
+
private:
/// Used to determine if errors occurred in this function or block.
DiagnosticErrorTrap ErrorTrap;
@@ -209,7 +220,7 @@ public:
/// The initial and final coroutine suspend points.
std::pair<Stmt *, Stmt *> CoroutineSuspends;
- /// The stack of currently active compound stamement scopes in the
+ /// The stack of currently active compound statement scopes in the
/// function.
SmallVector<CompoundScopeInfo, 4> CompoundScopes;
@@ -228,6 +239,9 @@ public:
/// modified in the function.
llvm::SmallPtrSet<const ParmVarDecl *, 8> ModifiedNonNullParams;
+ /// The set of GNU address of label extension "&&label".
+ llvm::SmallVector<AddrLabelExpr *, 4> AddrLabels;
+
public:
/// Represents a simple identification of a weak object.
///
@@ -380,7 +394,8 @@ public:
HasPotentialAvailabilityViolations(false), ObjCShouldCallSuper(false),
ObjCIsDesignatedInit(false), ObjCWarnForNoDesignatedInitChain(false),
ObjCIsSecondaryInit(false), ObjCWarnForNoInitDelegation(false),
- NeedsCoroutineSuspends(true), ErrorTrap(Diag) {}
+ NeedsCoroutineSuspends(true), FoundImmediateEscalatingExpression(false),
+ ErrorTrap(Diag) {}
virtual ~FunctionScopeInfo();
@@ -446,7 +461,14 @@ public:
void setHasCXXTry(SourceLocation TryLoc) {
setHasBranchProtectedScope();
- FirstCXXTryLoc = TryLoc;
+ FirstCXXOrObjCTryLoc = TryLoc;
+ FirstTryType = TryLocIsCXX;
+ }
+
+ void setHasObjCTry(SourceLocation TryLoc) {
+ setHasBranchProtectedScope();
+ FirstCXXOrObjCTryLoc = TryLoc;
+ FirstTryType = TryLocIsObjC;
}
void setHasSEHTry(SourceLocation TryLoc) {
@@ -454,6 +476,11 @@ public:
FirstSEHTryLoc = TryLoc;
}
+ void setHasVLA(SourceLocation VLALoc) {
+ if (FirstVLALoc.isInvalid())
+ FirstVLALoc = VLALoc;
+ }
+
bool NeedsScopeChecking() const {
return !HasDroppedStmt && (HasIndirectGoto || HasMustTail ||
(HasBranchProtectedScope && HasBranchIntoScope));
@@ -541,7 +568,7 @@ class Capture {
const VariableArrayType *CapturedVLA;
/// Otherwise, the captured variable (if any).
- VarDecl *CapturedVar;
+ ValueDecl *CapturedVar;
};
/// The source location at which the first capture occurred.
@@ -577,12 +604,13 @@ class Capture {
unsigned Invalid : 1;
public:
- Capture(VarDecl *Var, bool Block, bool ByRef, bool IsNested,
+ Capture(ValueDecl *Var, bool Block, bool ByRef, bool IsNested,
SourceLocation Loc, SourceLocation EllipsisLoc, QualType CaptureType,
bool Invalid)
: CapturedVar(Var), Loc(Loc), EllipsisLoc(EllipsisLoc),
- CaptureType(CaptureType),
- Kind(Block ? Cap_Block : ByRef ? Cap_ByRef : Cap_ByCopy),
+ CaptureType(CaptureType), Kind(Block ? Cap_Block
+ : ByRef ? Cap_ByRef
+ : Cap_ByCopy),
Nested(IsNested), CapturesThis(false), ODRUsed(false),
NonODRUsed(false), Invalid(Invalid) {}
@@ -627,7 +655,7 @@ public:
NonODRUsed = true;
}
- VarDecl *getVariable() const {
+ ValueDecl *getVariable() const {
assert(isVariableCapture());
return CapturedVar;
}
@@ -666,7 +694,7 @@ public:
: FunctionScopeInfo(Diag), ImpCaptureStyle(Style) {}
/// CaptureMap - A map of captured variables to (index+1) into Captures.
- llvm::DenseMap<VarDecl*, unsigned> CaptureMap;
+ llvm::DenseMap<ValueDecl *, unsigned> CaptureMap;
/// CXXThisCaptureIndex - The (index+1) of the capture of 'this';
/// zero if 'this' is not captured.
@@ -683,7 +711,7 @@ public:
/// or null if unknown.
QualType ReturnType;
- void addCapture(VarDecl *Var, bool isBlock, bool isByref, bool isNested,
+ void addCapture(ValueDecl *Var, bool isBlock, bool isByref, bool isNested,
SourceLocation Loc, SourceLocation EllipsisLoc,
QualType CaptureType, bool Invalid) {
Captures.push_back(Capture(Var, isBlock, isByref, isNested, Loc,
@@ -710,23 +738,21 @@ public:
}
/// Determine whether the given variable has been captured.
- bool isCaptured(VarDecl *Var) const {
- return CaptureMap.count(Var);
- }
+ bool isCaptured(ValueDecl *Var) const { return CaptureMap.count(Var); }
/// Determine whether the given variable-array type has been captured.
bool isVLATypeCaptured(const VariableArrayType *VAT) const;
/// Retrieve the capture of the given variable, if it has been
/// captured already.
- Capture &getCapture(VarDecl *Var) {
+ Capture &getCapture(ValueDecl *Var) {
assert(isCaptured(Var) && "Variable has not been captured");
return Captures[CaptureMap[Var] - 1];
}
- const Capture &getCapture(VarDecl *Var) const {
- llvm::DenseMap<VarDecl*, unsigned>::const_iterator Known
- = CaptureMap.find(Var);
+ const Capture &getCapture(ValueDecl *Var) const {
+ llvm::DenseMap<ValueDecl *, unsigned>::const_iterator Known =
+ CaptureMap.find(Var);
assert(Known != CaptureMap.end() && "Variable has not been captured");
return Captures[Known->second - 1];
}
@@ -824,6 +850,13 @@ public:
/// The lambda's compiler-generated \c operator().
CXXMethodDecl *CallOperator = nullptr;
+ /// Indicate that we parsed the parameter list
+ /// at which point the mutability of the lambda
+ /// is known.
+ bool AfterParameterList = true;
+
+ ParmVarDecl *ExplicitObjectParameter = nullptr;
+
/// Source range covering the lambda introducer [...].
SourceRange IntroducerRange;
@@ -835,8 +868,9 @@ public:
/// explicit captures.
unsigned NumExplicitCaptures = 0;
- /// Whether this is a mutable lambda.
- bool Mutable = false;
+ /// Whether this is a mutable lambda. Until the mutable keyword is parsed,
+ /// we assume the lambda is mutable.
+ bool Mutable = true;
/// Whether the (empty) parameter list is explicit.
bool ExplicitParams = false;
@@ -872,7 +906,7 @@ public:
/// This is specifically useful for generic lambdas or
/// lambdas within a potentially evaluated-if-used context.
/// If an enclosing variable is named in an expression of a lambda nested
- /// within a generic lambda, we don't always know know whether the variable
+ /// within a generic lambda, we don't always know whether the variable
/// will truly be odr-used (i.e. need to be captured) by that nested lambda,
/// until its instantiation. But we still need to capture it in the
/// enclosing lambda if all intervening lambdas can capture the variable.
@@ -891,8 +925,8 @@ public:
/// that were defined in parent contexts. Used to avoid warnings when the
/// shadowed variables are uncaptured by this lambda.
struct ShadowedOuterDecl {
- const VarDecl *VD;
- const VarDecl *ShadowedDecl;
+ const NamedDecl *VD;
+ const NamedDecl *ShadowedDecl;
};
llvm::SmallVector<ShadowedOuterDecl, 4> ShadowingDecls;
@@ -1001,10 +1035,7 @@ public:
return NonODRUsedCapturingExprs.count(CapturingVarExpr);
}
void removePotentialCapture(Expr *E) {
- PotentiallyCapturingExprs.erase(
- std::remove(PotentiallyCapturingExprs.begin(),
- PotentiallyCapturingExprs.end(), E),
- PotentiallyCapturingExprs.end());
+ llvm::erase(PotentiallyCapturingExprs, E);
}
void clearPotentialCaptures() {
PotentiallyCapturingExprs.clear();
@@ -1020,7 +1051,9 @@ public:
}
void visitPotentialCaptures(
- llvm::function_ref<void(VarDecl *, Expr *)> Callback) const;
+ llvm::function_ref<void(ValueDecl *, Expr *)> Callback) const;
+
+ bool lambdaCaptureShouldBeConst() const;
};
FunctionScopeInfo::WeakObjectProfileTy::WeakObjectProfileTy()
diff --git a/contrib/llvm-project/clang/include/clang/Sema/Sema.h b/contrib/llvm-project/clang/include/clang/Sema/Sema.h
index d8b2546b81a3..6adb8fb7966b 100644
--- a/contrib/llvm-project/clang/include/clang/Sema/Sema.h
+++ b/contrib/llvm-project/clang/include/clang/Sema/Sema.h
@@ -14,6 +14,7 @@
#ifndef LLVM_CLANG_SEMA_SEMA_H
#define LLVM_CLANG_SEMA_SEMA_H
+#include "clang/APINotes/APINotesManager.h"
#include "clang/AST/ASTConcept.h"
#include "clang/AST/ASTFwd.h"
#include "clang/AST/Attr.h"
@@ -58,7 +59,6 @@
#include "clang/Sema/TypoCorrection.h"
#include "clang/Sema/Weak.h"
#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/Optional.h"
#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/SmallBitVector.h"
#include "llvm/ADT/SmallPtrSet.h"
@@ -68,13 +68,13 @@
#include "llvm/Frontend/OpenMP/OMPConstants.h"
#include <deque>
#include <memory>
+#include <optional>
#include <string>
#include <tuple>
#include <vector>
namespace llvm {
class APSInt;
- template <typename ValueT> struct DenseMapInfo;
template <typename ValueT, typename ValueInfoT> class DenseSet;
class SmallBitVector;
struct InlineAsmIdentifierInfo;
@@ -227,6 +227,7 @@ namespace sema {
class FunctionScopeInfo;
class LambdaScopeInfo;
class PossiblyUnreachableDiag;
+ class RISCVIntrinsicManager;
class SemaPPCallbacks;
class TemplateDeductionInfo;
}
@@ -238,8 +239,9 @@ namespace threadSafety {
// FIXME: No way to easily map from TemplateTypeParmTypes to
// TemplateTypeParmDecls, so we have this horrible PointerUnion.
-typedef std::pair<llvm::PointerUnion<const TemplateTypeParmType*, NamedDecl*>,
- SourceLocation> UnexpandedParameterPack;
+typedef std::pair<llvm::PointerUnion<const TemplateTypeParmType *, NamedDecl *>,
+ SourceLocation>
+ UnexpandedParameterPack;
/// Describes whether we've seen any nullability information for the given
/// file.
@@ -306,7 +308,7 @@ public:
/// Computing a type for the function argument may require running
/// overloading, so we postpone its computation until it is actually needed.
///
- /// Clients should be very careful when using this funciton, as it stores a
+ /// Clients should be very careful when using this function, as it stores a
/// function_ref, clients should make sure all calls to get() with the same
/// location happen while function_ref is alive.
///
@@ -357,15 +359,10 @@ class Sema final {
void operator=(const Sema &) = delete;
///Source of additional semantic information.
- ExternalSemaSource *ExternalSource;
-
- ///Whether Sema has generated a multiplexer and has to delete it.
- bool isMultiplexExternalSource;
+ IntrusiveRefCntPtr<ExternalSemaSource> ExternalSource;
static bool mightHaveNonExternalLinkage(const DeclaratorDecl *FD);
- bool isVisibleSlow(const NamedDecl *D);
-
/// Determine whether two declarations should be linked together, given that
/// the old declaration might not be visible and the new declaration might
/// not have external linkage.
@@ -396,8 +393,8 @@ public:
///
/// This is the greatest alignment value supported by load, store, and alloca
/// instructions, and global values.
- static const unsigned MaxAlignmentExponent = 29;
- static const unsigned MaximumAlignment = 1u << MaxAlignmentExponent;
+ static const unsigned MaxAlignmentExponent = 32;
+ static const uint64_t MaximumAlignment = 1ull << MaxAlignmentExponent;
typedef OpaquePtr<DeclGroupRef> DeclGroupPtrTy;
typedef OpaquePtr<TemplateName> TemplateTy;
@@ -412,6 +409,7 @@ public:
ASTConsumer &Consumer;
DiagnosticsEngine &Diags;
SourceManager &SourceMgr;
+ api_notes::APINotesManager APINotes;
/// Flag indicating whether or not to collect detailed statistics.
bool CollectStats;
@@ -485,6 +483,12 @@ public:
PSK_Pop_Set = PSK_Pop | PSK_Set, // #pragma (pop[, id], value)
};
+ struct PragmaPackInfo {
+ PragmaMsStackAction Action;
+ StringRef SlotLabel;
+ Token Alignment;
+ };
+
// #pragma pack and align.
class AlignPackInfo {
public:
@@ -693,6 +697,9 @@ public:
PragmaStack<StringLiteral *> ConstSegStack;
PragmaStack<StringLiteral *> CodeSegStack;
+ // #pragma strict_gs_check.
+ PragmaStack<bool> StrictGuardStackCheckStack;
+
// This stack tracks the current state of Sema.CurFPFeatures.
PragmaStack<FPOptionsOverride> FpPragmaStack;
FPOptionsOverride CurFPFeatureOverrides() {
@@ -705,6 +712,25 @@ public:
return result;
}
+ // Saves the current floating-point pragma stack and clear it in this Sema.
+ class FpPragmaStackSaveRAII {
+ public:
+ FpPragmaStackSaveRAII(Sema &S)
+ : S(S), SavedStack(std::move(S.FpPragmaStack)) {
+ S.FpPragmaStack.Stack.clear();
+ }
+ ~FpPragmaStackSaveRAII() { S.FpPragmaStack = std::move(SavedStack); }
+
+ private:
+ Sema &S;
+ PragmaStack<FPOptionsOverride> SavedStack;
+ };
+
+ void resetFPOptions(FPOptions FPO) {
+ CurFPFeatures = FPO;
+ FpPragmaStack.CurrentValue = FPO.getChangesFrom(FPOptions(LangOpts));
+ }
+
// RAII object to push / pop sentinel slots for all MS #pragma stacks.
// Actions should be performed only if we enter / exit a C++ method body.
class PragmaStackSentinelRAII {
@@ -725,6 +751,9 @@ public:
StringLiteral *CurInitSeg;
SourceLocation CurInitSegLoc;
+ /// Sections used with #pragma alloc_text.
+ llvm::StringMap<std::tuple<StringRef, SourceLocation>> FunctionToSectionMap;
+
/// VisContext - Manages the stack for \#pragma GCC visibility.
void *VisContext; // Really a "PragmaVisStack*"
@@ -756,6 +785,16 @@ public:
/// optimizations are currently "on", this is set to an invalid location.
SourceLocation OptimizeOffPragmaLocation;
+ /// The "on" or "off" argument passed by \#pragma optimize, that denotes
+ /// whether the optimizations in the list passed to the pragma should be
+ /// turned off or on. This boolean is true by default because command line
+ /// options are honored when `#pragma optimize("", on)`.
+ /// (i.e. `ModifyFnAttributeMSPragmaOptimze()` does nothing)
+ bool MSPragmaOptimizeIsOn = true;
+
+ /// Set of no-builtin functions listed by \#pragma function.
+ llvm::SmallSetVector<StringRef, 4> MSFunctionNoBuiltins;
+
/// Flag indicating if Sema is building a recovery call expression.
///
/// This flag is used to avoid building recovery call expressions
@@ -774,8 +813,7 @@ public:
/// we won't know until all lvalue-to-rvalue and discarded value conversions
/// have been applied to all subexpressions of the enclosing full expression.
/// This is cleared at the end of each full expression.
- using MaybeODRUseExprSet = llvm::SetVector<Expr *, SmallVector<Expr *, 4>,
- llvm::SmallPtrSet<Expr *, 4>>;
+ using MaybeODRUseExprSet = llvm::SmallSetVector<Expr *, 4>;
MaybeODRUseExprSet MaybeODRUseExprs;
std::unique_ptr<sema::FunctionScopeInfo> CachedFunctionScope;
@@ -788,9 +826,12 @@ public:
/// context.
unsigned FunctionScopesStart = 0;
+ /// Track the number of currently active capturing scopes.
+ unsigned CapturingFunctionScopes = 0;
+
ArrayRef<sema::FunctionScopeInfo*> getFunctionScopes() const {
- return llvm::makeArrayRef(FunctionScopes.begin() + FunctionScopesStart,
- FunctionScopes.end());
+ return llvm::ArrayRef(FunctionScopes.begin() + FunctionScopesStart,
+ FunctionScopes.end());
}
/// Stack containing information needed when in C++2a an 'auto' is encountered
@@ -805,9 +846,9 @@ public:
unsigned InventedParameterInfosStart = 0;
ArrayRef<InventedTemplateParameterInfo> getInventedParameterInfos() const {
- return llvm::makeArrayRef(InventedParameterInfos.begin() +
- InventedParameterInfosStart,
- InventedParameterInfos.end());
+ return llvm::ArrayRef(InventedParameterInfos.begin() +
+ InventedParameterInfosStart,
+ InventedParameterInfos.end());
}
typedef LazyVector<TypedefNameDecl *, ExternalSemaSource,
@@ -822,7 +863,7 @@ public:
/// FieldCollector - Collects CXXFieldDecls during parsing of C++ classes.
std::unique_ptr<CXXFieldCollector> FieldCollector;
- typedef llvm::SmallSetVector<NamedDecl *, 16> NamedDeclSetType;
+ typedef llvm::SmallSetVector<const NamedDecl *, 16> NamedDeclSetType;
/// Set containing all declared private fields that are not used.
NamedDeclSetType UnusedPrivateFields;
@@ -914,14 +955,14 @@ public:
OpaqueParser = P;
}
- // Does the work necessary to deal with a SYCL kernel lambda. At the moment,
- // this just marks the list of lambdas required to name the kernel.
- void AddSYCLKernelLambda(const FunctionDecl *FD);
+ /// Callback to the parser to parse a type expressed as a string.
+ std::function<TypeResult(StringRef, StringRef, SourceLocation)>
+ ParseTypeFromStringCallback;
class DelayedDiagnostics;
class DelayedDiagnosticsState {
- sema::DelayedDiagnosticPool *SavedPool;
+ sema::DelayedDiagnosticPool *SavedPool = nullptr;
friend class Sema::DelayedDiagnostics;
};
typedef DelayedDiagnosticsState ParsingDeclState;
@@ -932,10 +973,10 @@ public:
class DelayedDiagnostics {
/// The current pool of diagnostics into which delayed
/// diagnostics should go.
- sema::DelayedDiagnosticPool *CurPool;
+ sema::DelayedDiagnosticPool *CurPool = nullptr;
public:
- DelayedDiagnostics() : CurPool(nullptr) {}
+ DelayedDiagnostics() = default;
/// Adds a delayed diagnostic.
void add(const sema::DelayedDiagnostic &diag); // in DelayedDiagnostic.h
@@ -980,6 +1021,14 @@ public:
}
} DelayedDiagnostics;
+ enum CUDAFunctionTarget {
+ CFT_Device,
+ CFT_Global,
+ CFT_Host,
+ CFT_HostDevice,
+ CFT_InvalidTarget
+ };
+
/// A RAII object to temporarily push a declaration context.
class ContextRAII {
private:
@@ -1022,20 +1071,6 @@ public:
}
};
- /// Whether the AST is currently being rebuilt to correct immediate
- /// invocations. Immediate invocation candidates and references to consteval
- /// functions aren't tracked when this is set.
- bool RebuildingImmediateInvocation = false;
-
- /// Used to change context to isConstantEvaluated without pushing a heavy
- /// ExpressionEvaluationContextRecord object.
- bool isConstantEvaluatedOverride;
-
- bool isConstantEvaluated() {
- return ExprEvalContexts.back().isConstantEvaluated() ||
- isConstantEvaluatedOverride;
- }
-
/// RAII object to handle the state changes required to synthesize
/// a function body.
class SynthesizedFunctionScope {
@@ -1046,12 +1081,21 @@ public:
public:
SynthesizedFunctionScope(Sema &S, DeclContext *DC)
: S(S), SavedContext(S, DC) {
+ auto *FD = dyn_cast<FunctionDecl>(DC);
S.PushFunctionScope();
S.PushExpressionEvaluationContext(
- Sema::ExpressionEvaluationContext::PotentiallyEvaluated);
- if (auto *FD = dyn_cast<FunctionDecl>(DC))
+ (FD && FD->isConsteval())
+ ? ExpressionEvaluationContext::ImmediateFunctionContext
+ : ExpressionEvaluationContext::PotentiallyEvaluated);
+ if (FD) {
FD->setWillHaveBody(true);
- else
+ S.ExprEvalContexts.back().InImmediateFunctionContext =
+ FD->isImmediateFunction() ||
+ S.ExprEvalContexts[S.ExprEvalContexts.size() - 2]
+ .isConstantEvaluated();
+ S.ExprEvalContexts.back().InImmediateEscalatingFunctionContext =
+ S.getLangOpts().CPlusPlus20 && FD->isImmediateEscalating();
+ } else
assert(isa<ObjCMethodDecl>(DC));
}
@@ -1070,17 +1114,29 @@ public:
~SynthesizedFunctionScope() {
if (PushedCodeSynthesisContext)
S.popCodeSynthesisContext();
- if (auto *FD = dyn_cast<FunctionDecl>(S.CurContext))
+ if (auto *FD = dyn_cast<FunctionDecl>(S.CurContext)) {
FD->setWillHaveBody(false);
+ S.CheckImmediateEscalatingFunctionDefinition(FD, S.getCurFunction());
+ }
S.PopExpressionEvaluationContext();
S.PopFunctionScopeInfo();
}
};
- /// WeakUndeclaredIdentifiers - Identifiers contained in
- /// \#pragma weak before declared. rare. may alias another
- /// identifier, declared or undeclared
- llvm::MapVector<IdentifierInfo *, WeakInfo> WeakUndeclaredIdentifiers;
+ /// WeakUndeclaredIdentifiers - Identifiers contained in \#pragma weak before
+ /// declared. Rare. May alias another identifier, declared or undeclared.
+ ///
+ /// For aliases, the target identifier is used as a key for eventual
+ /// processing when the target is declared. For the single-identifier form,
+ /// the sole identifier is used as the key. Each entry is a `SetVector`
+ /// (ordered by parse order) of aliases (identified by the alias name) in case
+ /// of multiple aliases to the same undeclared identifier.
+ llvm::MapVector<
+ IdentifierInfo *,
+ llvm::SetVector<
+ WeakInfo, llvm::SmallVector<WeakInfo, 1u>,
+ llvm::SmallDenseSet<WeakInfo, 2u, WeakInfo::DenseMapInfoByAliasOnly>>>
+ WeakUndeclaredIdentifiers;
/// ExtnameUndeclaredIdentifiers - Identifiers contained in
/// \#pragma redefine_extname before declared. Used in Solaris system headers
@@ -1117,10 +1173,6 @@ public:
/// standard library.
LazyDeclPtr StdAlignValT;
- /// The C++ "std::experimental" namespace, where the experimental parts
- /// of the standard library resides.
- NamespaceDecl *StdExperimentalNamespaceCache;
-
/// The C++ "std::initializer_list" template, which is defined in
/// \<initializer_list>.
ClassTemplateDecl *StdInitializerList;
@@ -1132,8 +1184,9 @@ public:
/// The C++ "type_info" declaration, which is defined in \<typeinfo>.
RecordDecl *CXXTypeInfoDecl;
- /// The MSVC "_GUID" struct, which is defined in MSVC header files.
- RecordDecl *MSVCGuidDecl;
+ /// The C++ "std::source_location::__impl" struct, defined in
+ /// \<source_location>.
+ RecordDecl *StdSourceLocationImplDecl;
/// Caches identifiers/selectors for NSFoundation APIs.
std::unique_ptr<NSAPI> NSAPIObj;
@@ -1218,6 +1271,11 @@ public:
/// cases in a switch statement).
ConstantEvaluated,
+ /// In addition of being constant evaluated, the current expression
+ /// occurs in an immediate function context - either a consteval function
+ /// or a consteval if statement.
+ ImmediateFunctionContext,
+
/// The current expression is potentially evaluated at run time,
/// which means that code may be generated to evaluate the value of the
/// expression at run time.
@@ -1292,6 +1350,36 @@ public:
EK_Decltype, EK_TemplateArgument, EK_Other
} ExprContext;
+ // A context can be nested in both a discarded statement context and
+ // an immediate function context, so they need to be tracked independently.
+ bool InDiscardedStatement;
+ bool InImmediateFunctionContext;
+ bool InImmediateEscalatingFunctionContext;
+
+ bool IsCurrentlyCheckingDefaultArgumentOrInitializer = false;
+
+ // We are in a constant context, but we also allow
+ // non constant expressions, for example for array bounds (which may be
+ // VLAs).
+ bool InConditionallyConstantEvaluateContext = false;
+
+ // When evaluating immediate functions in the initializer of a default
+ // argument or default member initializer, this is the declaration whose
+ // default initializer is being evaluated and the location of the call
+ // or constructor definition.
+ struct InitializationContext {
+ InitializationContext(SourceLocation Loc, ValueDecl *Decl,
+ DeclContext *Context)
+ : Loc(Loc), Decl(Decl), Context(Context) {
+ assert(Decl && Context && "invalid initialization context");
+ }
+
+ SourceLocation Loc;
+ ValueDecl *Decl = nullptr;
+ DeclContext *Context = nullptr;
+ };
+ std::optional<InitializationContext> DelayedDefaultInitializationContext;
+
ExpressionEvaluationContextRecord(ExpressionEvaluationContext Context,
unsigned NumCleanupObjects,
CleanupInfo ParentCleanup,
@@ -1299,21 +1387,50 @@ public:
ExpressionKind ExprContext)
: Context(Context), ParentCleanup(ParentCleanup),
NumCleanupObjects(NumCleanupObjects), NumTypos(0),
- ManglingContextDecl(ManglingContextDecl), ExprContext(ExprContext) {}
+ ManglingContextDecl(ManglingContextDecl), ExprContext(ExprContext),
+ InDiscardedStatement(false), InImmediateFunctionContext(false),
+ InImmediateEscalatingFunctionContext(false) {}
bool isUnevaluated() const {
return Context == ExpressionEvaluationContext::Unevaluated ||
Context == ExpressionEvaluationContext::UnevaluatedAbstract ||
Context == ExpressionEvaluationContext::UnevaluatedList;
}
+
bool isConstantEvaluated() const {
- return Context == ExpressionEvaluationContext::ConstantEvaluated;
+ return Context == ExpressionEvaluationContext::ConstantEvaluated ||
+ Context == ExpressionEvaluationContext::ImmediateFunctionContext;
+ }
+
+ bool isImmediateFunctionContext() const {
+ return Context == ExpressionEvaluationContext::ImmediateFunctionContext ||
+ (Context == ExpressionEvaluationContext::DiscardedStatement &&
+ InImmediateFunctionContext) ||
+ // C++23 [expr.const]p14:
+ // An expression or conversion is in an immediate function
+ // context if it is potentially evaluated and either:
+ // * its innermost enclosing non-block scope is a function
+ // parameter scope of an immediate function, or
+ // * its enclosing statement is enclosed by the compound-
+ // statement of a consteval if statement.
+ (Context == ExpressionEvaluationContext::PotentiallyEvaluated &&
+ InImmediateFunctionContext);
+ }
+
+ bool isDiscardedStatementContext() const {
+ return Context == ExpressionEvaluationContext::DiscardedStatement ||
+ (Context ==
+ ExpressionEvaluationContext::ImmediateFunctionContext &&
+ InDiscardedStatement);
}
};
/// A stack of expression evaluation contexts.
SmallVector<ExpressionEvaluationContextRecord, 8> ExprEvalContexts;
+ // Set of failed immediate invocations to avoid double diagnosing.
+ llvm::SmallPtrSet<ConstantExpr *, 4> FailedImmediateInvocations;
+
/// Emit a warning for all pending noderef expressions that we recorded.
void WarnOnPendingNoDerefs(ExpressionEvaluationContextRecord &Rec);
@@ -1340,10 +1457,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) {}
@@ -1408,7 +1525,7 @@ public:
/// Determine if VD, which must be a variable or function, is an external
/// symbol that nonetheless can't be referenced from outside this translation
/// unit because its type has no linkage and it's not extern "C".
- bool isExternalWithNoLinkageType(ValueDecl *VD);
+ bool isExternalWithNoLinkageType(const ValueDecl *VD) const;
/// Obtain a sorted list of functions that are undefined but ODR-used.
void getUndefinedButUsed(
@@ -1419,8 +1536,22 @@ public:
const llvm::MapVector<FieldDecl *, DeleteLocs> &
getMismatchingDeleteExpressions() const;
- typedef std::pair<ObjCMethodList, ObjCMethodList> GlobalMethods;
- typedef llvm::DenseMap<Selector, GlobalMethods> GlobalMethodPool;
+ class GlobalMethodPool {
+ public:
+ using Lists = std::pair<ObjCMethodList, ObjCMethodList>;
+ using iterator = llvm::DenseMap<Selector, Lists>::iterator;
+ iterator begin() { return Methods.begin(); }
+ iterator end() { return Methods.end(); }
+ iterator find(Selector Sel) { return Methods.find(Sel); }
+ std::pair<iterator, bool> insert(std::pair<Selector, Lists> &&Val) {
+ return Methods.insert(Val);
+ }
+ int count(Selector Sel) const { return Methods.count(Sel); }
+ bool empty() const { return Methods.empty(); }
+
+ private:
+ llvm::DenseMap<Selector, Lists> Methods;
+ };
/// Method Pool - allows efficient lookup when typechecking messages to "id".
/// We need to maintain a list, since selectors can have differing signatures
@@ -1502,19 +1633,16 @@ public:
/// statements.
class FPFeaturesStateRAII {
public:
- FPFeaturesStateRAII(Sema &S) : S(S), OldFPFeaturesState(S.CurFPFeatures) {
- OldOverrides = S.FpPragmaStack.CurrentValue;
- }
- ~FPFeaturesStateRAII() {
- S.CurFPFeatures = OldFPFeaturesState;
- S.FpPragmaStack.CurrentValue = OldOverrides;
- }
+ FPFeaturesStateRAII(Sema &S);
+ ~FPFeaturesStateRAII();
FPOptionsOverride getOverrides() { return OldOverrides; }
private:
Sema& S;
FPOptions OldFPFeaturesState;
FPOptionsOverride OldOverrides;
+ LangOptions::FPEvalMethodKind OldEvalMethod;
+ SourceLocation OldFPPragmaLocation;
};
void addImplicitTypedef(StringRef Name, QualType T);
@@ -1526,7 +1654,18 @@ public:
/// assignment.
llvm::DenseMap<const VarDecl *, int> RefsMinusAssignments;
- Optional<std::unique_ptr<DarwinSDKInfo>> CachedDarwinSDKInfo;
+ /// Indicate RISC-V vector builtin functions enabled or not.
+ bool DeclareRISCVVBuiltins = false;
+
+ /// Indicate RISC-V SiFive vector builtin functions enabled or not.
+ bool DeclareRISCVSiFiveVectorBuiltins = false;
+
+private:
+ std::unique_ptr<sema::RISCVIntrinsicManager> RVIntrinsicManager;
+
+ std::optional<std::unique_ptr<DarwinSDKInfo>> CachedDarwinSDKInfo;
+
+ bool WarnedDarwinSDKInfoMissing = false;
public:
Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer,
@@ -1555,9 +1694,11 @@ public:
ASTContext &getASTContext() const { return Context; }
ASTConsumer &getASTConsumer() const { return Consumer; }
ASTMutationListener *getASTMutationListener() const;
- ExternalSemaSource* getExternalSource() const { return ExternalSource; }
+ ExternalSemaSource *getExternalSource() const { return ExternalSource.get(); }
+
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.
@@ -1635,8 +1776,8 @@ public:
// It is necessary to limit this to rvalue reference to avoid calling this
// function with a bitfield lvalue argument since non-const reference to
// bitfield is not allowed.
- template <typename T, typename = typename std::enable_if<
- !std::is_lvalue_reference<T>::value>::type>
+ template <typename T,
+ typename = std::enable_if_t<!std::is_lvalue_reference<T>::value>>
const ImmediateDiagBuilder &operator<<(T &&V) const {
const DiagnosticBuilder &BaseDiag = *this;
BaseDiag << std::move(V);
@@ -1676,12 +1817,18 @@ public:
};
SemaDiagnosticBuilder(Kind K, SourceLocation Loc, unsigned DiagID,
- FunctionDecl *Fn, Sema &S);
+ const FunctionDecl *Fn, Sema &S);
SemaDiagnosticBuilder(SemaDiagnosticBuilder &&D);
SemaDiagnosticBuilder(const SemaDiagnosticBuilder &) = default;
+
+ // The copy and move assignment operator is defined as deleted pending
+ // further motivation.
+ SemaDiagnosticBuilder &operator=(const SemaDiagnosticBuilder &) = delete;
+ SemaDiagnosticBuilder &operator=(SemaDiagnosticBuilder &&) = delete;
+
~SemaDiagnosticBuilder();
- bool isImmediate() const { return ImmediateDiag.hasValue(); }
+ bool isImmediate() const { return ImmediateDiag.has_value(); }
/// Convertible to bool: True if we immediately emitted an error, false if
/// we didn't emit an error or we created a deferred error.
@@ -1698,9 +1845,9 @@ public:
template <typename T>
friend const SemaDiagnosticBuilder &
operator<<(const SemaDiagnosticBuilder &Diag, const T &Value) {
- if (Diag.ImmediateDiag.hasValue())
+ if (Diag.ImmediateDiag)
*Diag.ImmediateDiag << Value;
- else if (Diag.PartialDiagId.hasValue())
+ else if (Diag.PartialDiagId)
Diag.S.DeviceDeferredDiags[Diag.Fn][*Diag.PartialDiagId].second
<< Value;
return Diag;
@@ -1709,29 +1856,29 @@ public:
// It is necessary to limit this to rvalue reference to avoid calling this
// function with a bitfield lvalue argument since non-const reference to
// bitfield is not allowed.
- template <typename T, typename = typename std::enable_if<
- !std::is_lvalue_reference<T>::value>::type>
+ template <typename T,
+ typename = std::enable_if_t<!std::is_lvalue_reference<T>::value>>
const SemaDiagnosticBuilder &operator<<(T &&V) const {
- if (ImmediateDiag.hasValue())
+ if (ImmediateDiag)
*ImmediateDiag << std::move(V);
- else if (PartialDiagId.hasValue())
+ else if (PartialDiagId)
S.DeviceDeferredDiags[Fn][*PartialDiagId].second << std::move(V);
return *this;
}
friend const SemaDiagnosticBuilder &
operator<<(const SemaDiagnosticBuilder &Diag, const PartialDiagnostic &PD) {
- if (Diag.ImmediateDiag.hasValue())
+ if (Diag.ImmediateDiag)
PD.Emit(*Diag.ImmediateDiag);
- else if (Diag.PartialDiagId.hasValue())
+ else if (Diag.PartialDiagId)
Diag.S.DeviceDeferredDiags[Diag.Fn][*Diag.PartialDiagId].second = PD;
return Diag;
}
void AddFixItHint(const FixItHint &Hint) const {
- if (ImmediateDiag.hasValue())
+ if (ImmediateDiag)
ImmediateDiag->AddFixItHint(Hint);
- else if (PartialDiagId.hasValue())
+ else if (PartialDiagId)
S.DeviceDeferredDiags[Fn][*PartialDiagId].second.AddFixItHint(Hint);
}
@@ -1751,13 +1898,13 @@ public:
Sema &S;
SourceLocation Loc;
unsigned DiagID;
- FunctionDecl *Fn;
+ const FunctionDecl *Fn;
bool ShowCallStack;
// Invariant: At most one of these Optionals has a value.
// FIXME: Switch these to a Variant once that exists.
- llvm::Optional<ImmediateDiagBuilder> ImmediateDiag;
- llvm::Optional<unsigned> PartialDiagId;
+ std::optional<ImmediateDiagBuilder> ImmediateDiag;
+ std::optional<unsigned> PartialDiagId;
};
/// Is the last error level diagnostic immediate. This is used to determined
@@ -1944,9 +2091,9 @@ public:
SourceLocation Loc, DeclarationName Entity);
QualType BuildReferenceType(QualType T, bool LValueRef,
SourceLocation Loc, DeclarationName Entity);
- QualType BuildArrayType(QualType T, ArrayType::ArraySizeModifier ASM,
- Expr *ArraySize, unsigned Quals,
- SourceRange Brackets, DeclarationName Entity);
+ QualType BuildArrayType(QualType T, ArraySizeModifier ASM, Expr *ArraySize,
+ unsigned Quals, SourceRange Brackets,
+ DeclarationName Entity);
QualType BuildVectorType(QualType T, Expr *VecSize, SourceLocation AttrLoc);
QualType BuildExtVectorType(QualType T, Expr *ArraySize,
SourceLocation AttrLoc);
@@ -1960,10 +2107,17 @@ public:
QualType BuildAddressSpaceAttr(QualType &T, Expr *AddrSpace,
SourceLocation AttrLoc);
+ CodeAlignAttr *BuildCodeAlignAttr(const AttributeCommonInfo &CI, Expr *E);
+ bool CheckRebuiltStmtAttributes(ArrayRef<const Attr *> Attrs);
+
bool CheckQualifiedFunctionForTypeId(QualType T, SourceLocation Loc);
bool CheckFunctionReturnType(QualType T, SourceLocation Loc);
+ /// Check an argument list for placeholders that we won't try to
+ /// handle later.
+ bool CheckArgsForPlaceholders(MultiExprArg args);
+
/// Build a function type.
///
/// This routine checks the function type according to C++ rules and
@@ -2007,9 +2161,9 @@ public:
SourceLocation Loc);
QualType BuildWritePipeType(QualType T,
SourceLocation Loc);
- QualType BuildExtIntType(bool IsUnsigned, Expr *BitWidth, SourceLocation Loc);
+ QualType BuildBitIntType(bool IsUnsigned, Expr *BitWidth, SourceLocation Loc);
- TypeSourceInfo *GetTypeForDeclarator(Declarator &D, Scope *S);
+ TypeSourceInfo *GetTypeForDeclarator(Declarator &D);
TypeSourceInfo *GetTypeForDeclaratorCast(Declarator &D, QualType FromTy);
/// Package the given type and TSI into a ParsedType.
@@ -2038,22 +2192,19 @@ public:
const FunctionProtoType *Old, SourceLocation OldLoc,
const FunctionProtoType *New, SourceLocation NewLoc);
bool handlerCanCatch(QualType HandlerType, QualType ExceptionType);
- bool CheckExceptionSpecSubset(const PartialDiagnostic &DiagID,
- const PartialDiagnostic &NestedDiagID,
- const PartialDiagnostic &NoteID,
- const PartialDiagnostic &NoThrowDiagID,
- const FunctionProtoType *Superset,
- SourceLocation SuperLoc,
- const FunctionProtoType *Subset,
- SourceLocation SubLoc);
- bool CheckParamExceptionSpec(const PartialDiagnostic &NestedDiagID,
- const PartialDiagnostic &NoteID,
- const FunctionProtoType *Target,
- SourceLocation TargetLoc,
- const FunctionProtoType *Source,
- SourceLocation SourceLoc);
-
- TypeResult ActOnTypeName(Scope *S, Declarator &D);
+ bool CheckExceptionSpecSubset(
+ const PartialDiagnostic &DiagID, const PartialDiagnostic &NestedDiagID,
+ const PartialDiagnostic &NoteID, const PartialDiagnostic &NoThrowDiagID,
+ const FunctionProtoType *Superset, bool SkipSupersetFirstParameter,
+ SourceLocation SuperLoc, const FunctionProtoType *Subset,
+ bool SkipSubsetFirstParameter, SourceLocation SubLoc);
+ bool CheckParamExceptionSpec(
+ const PartialDiagnostic &NestedDiagID, const PartialDiagnostic &NoteID,
+ const FunctionProtoType *Target, bool SkipTargetFirstParameter,
+ SourceLocation TargetLoc, const FunctionProtoType *Source,
+ bool SkipSourceFirstParameter, SourceLocation SourceLoc);
+
+ TypeResult ActOnTypeName(Declarator &D);
/// The parser has parsed the context-sensitive type 'instancetype'
/// in an Objective-C message declaration. Return the appropriate type.
@@ -2150,6 +2301,8 @@ public:
Default = AcceptSizeless
};
+ enum class AcceptableKind { Visible, Reachable };
+
private:
/// Methods for marking which expressions involve dereferencing a pointer
/// marked with the 'noderef' attribute. Expressions are checked bottom up as
@@ -2168,24 +2321,74 @@ private:
struct ModuleScope {
SourceLocation BeginLoc;
clang::Module *Module = nullptr;
- bool ModuleInterface = false;
- bool ImplicitGlobalModuleFragment = false;
VisibleModuleSet OuterVisibleModules;
};
/// The modules we're currently parsing.
llvm::SmallVector<ModuleScope, 16> ModuleScopes;
+ /// For an interface unit, this is the implicitly imported interface unit.
+ clang::Module *ThePrimaryInterface = nullptr;
+
+ /// The explicit global module fragment of the current translation unit.
+ /// The explicit Global Module Fragment, as specified in C++
+ /// [module.global.frag].
+ clang::Module *TheGlobalModuleFragment = nullptr;
+
+ /// The implicit global module fragments of the current translation unit.
+ ///
+ /// The contents in the implicit global module fragment can't be discarded.
+ clang::Module *TheImplicitGlobalModuleFragment = nullptr;
+
/// Namespace definitions that we will export when they finish.
llvm::SmallPtrSet<const NamespaceDecl*, 8> DeferredExportedNamespaces;
- /// Get the module whose scope we are currently within.
+ /// In a C++ standard module, inline declarations require a definition to be
+ /// present at the end of a definition domain. This set holds the decls to
+ /// be checked at the end of the TU.
+ llvm::SmallPtrSet<const FunctionDecl *, 8> PendingInlineFuncDecls;
+
+ /// Helper function to judge if we are in module purview.
+ /// Return false if we are not in a module.
+ bool isCurrentModulePurview() const;
+
+ /// Enter the scope of the explicit global module fragment.
+ Module *PushGlobalModuleFragment(SourceLocation BeginLoc);
+ /// Leave the scope of the explicit global module fragment.
+ void PopGlobalModuleFragment();
+
+ /// Enter the scope of an implicit global module fragment.
+ Module *PushImplicitGlobalModuleFragment(SourceLocation BeginLoc);
+ /// Leave the scope of an implicit global module fragment.
+ void PopImplicitGlobalModuleFragment();
+
+ VisibleModuleSet VisibleModules;
+
+ /// Cache for module units which is usable for current module.
+ llvm::DenseSet<const Module *> UsableModuleUnitsCache;
+
+ bool isUsableModule(const Module *M);
+
+ bool isAcceptableSlow(const NamedDecl *D, AcceptableKind Kind);
+
+public:
+ /// Get the module unit whose scope we are currently within.
Module *getCurrentModule() const {
return ModuleScopes.empty() ? nullptr : ModuleScopes.back().Module;
}
- VisibleModuleSet VisibleModules;
+ /// Is the module scope we are an implementation unit?
+ bool currentModuleIsImplementation() const {
+ return ModuleScopes.empty()
+ ? false
+ : ModuleScopes.back().Module->isModuleImplementation();
+ }
+
+ /// Is the module scope we are in a C++ Header Unit?
+ bool currentModuleIsHeaderUnit() const {
+ return ModuleScopes.empty() ? false
+ : ModuleScopes.back().Module->isHeaderUnit();
+ }
-public:
/// Get the module owning an entity.
Module *getOwningModule(const Decl *Entity) {
return Entity->getOwningModule();
@@ -2205,7 +2408,20 @@ public:
/// Determine whether a declaration is visible to name lookup.
bool isVisible(const NamedDecl *D) {
- return D->isUnconditionallyVisible() || isVisibleSlow(D);
+ return D->isUnconditionallyVisible() ||
+ isAcceptableSlow(D, AcceptableKind::Visible);
+ }
+
+ /// Determine whether a declaration is reachable.
+ bool isReachable(const NamedDecl *D) {
+ // All visible declarations are reachable.
+ return D->isUnconditionallyVisible() ||
+ isAcceptableSlow(D, AcceptableKind::Reachable);
+ }
+
+ /// Determine whether a declaration is acceptable (visible/reachable).
+ bool isAcceptable(const NamedDecl *D, AcceptableKind Kind) {
+ return Kind == AcceptableKind::Visible ? isVisible(D) : isReachable(D);
}
/// Determine whether any declaration of an entity is visible.
@@ -2214,11 +2430,20 @@ public:
llvm::SmallVectorImpl<Module *> *Modules = nullptr) {
return isVisible(D) || hasVisibleDeclarationSlow(D, Modules);
}
+
bool hasVisibleDeclarationSlow(const NamedDecl *D,
llvm::SmallVectorImpl<Module *> *Modules);
+ /// Determine whether any declaration of an entity is reachable.
+ bool
+ hasReachableDeclaration(const NamedDecl *D,
+ llvm::SmallVectorImpl<Module *> *Modules = nullptr) {
+ return isReachable(D) || hasReachableDeclarationSlow(D, Modules);
+ }
+ bool hasReachableDeclarationSlow(
+ const NamedDecl *D, llvm::SmallVectorImpl<Module *> *Modules = nullptr);
- bool hasVisibleMergedDefinition(NamedDecl *Def);
- bool hasMergedDefinitionInCurrentModule(NamedDecl *Def);
+ bool hasVisibleMergedDefinition(const NamedDecl *Def);
+ bool hasMergedDefinitionInCurrentModule(const NamedDecl *Def);
/// Determine if \p D and \p Suggested have a structurally compatible
/// layout as described in C11 6.2.7/1.
@@ -2233,21 +2458,54 @@ public:
return hasVisibleDefinition(const_cast<NamedDecl*>(D), &Hidden);
}
+ /// Determine if \p D has a reachable definition. If not, suggest a
+ /// declaration that should be made reachable to expose the definition.
+ bool hasReachableDefinition(NamedDecl *D, NamedDecl **Suggested,
+ bool OnlyNeedComplete = false);
+ bool hasReachableDefinition(NamedDecl *D) {
+ NamedDecl *Hidden;
+ return hasReachableDefinition(D, &Hidden);
+ }
+
+ bool hasAcceptableDefinition(NamedDecl *D, NamedDecl **Suggested,
+ AcceptableKind Kind,
+ bool OnlyNeedComplete = false);
+ bool hasAcceptableDefinition(NamedDecl *D, AcceptableKind Kind) {
+ NamedDecl *Hidden;
+ return hasAcceptableDefinition(D, &Hidden, Kind);
+ }
+
/// Determine if the template parameter \p D has a visible default argument.
bool
hasVisibleDefaultArgument(const NamedDecl *D,
llvm::SmallVectorImpl<Module *> *Modules = nullptr);
+ /// Determine if the template parameter \p D has a reachable default argument.
+ bool hasReachableDefaultArgument(
+ const NamedDecl *D, llvm::SmallVectorImpl<Module *> *Modules = nullptr);
+ /// Determine if the template parameter \p D has a reachable default argument.
+ bool hasAcceptableDefaultArgument(const NamedDecl *D,
+ llvm::SmallVectorImpl<Module *> *Modules,
+ Sema::AcceptableKind Kind);
/// Determine if there is a visible declaration of \p D that is an explicit
/// specialization declaration for a specialization of a template. (For a
/// member specialization, use hasVisibleMemberSpecialization.)
bool hasVisibleExplicitSpecialization(
const NamedDecl *D, llvm::SmallVectorImpl<Module *> *Modules = nullptr);
+ /// Determine if there is a reachable declaration of \p D that is an explicit
+ /// specialization declaration for a specialization of a template. (For a
+ /// member specialization, use hasReachableMemberSpecialization.)
+ bool hasReachableExplicitSpecialization(
+ const NamedDecl *D, llvm::SmallVectorImpl<Module *> *Modules = nullptr);
/// Determine if there is a visible declaration of \p D that is a member
/// specialization declaration (as opposed to an instantiated declaration).
bool hasVisibleMemberSpecialization(
const NamedDecl *D, llvm::SmallVectorImpl<Module *> *Modules = nullptr);
+ /// Determine if there is a reachable declaration of \p D that is a member
+ /// specialization declaration (as opposed to an instantiated declaration).
+ bool hasReachableMemberSpecialization(
+ const NamedDecl *D, llvm::SmallVectorImpl<Module *> *Modules = nullptr);
/// Determine if \p A and \p B are equivalent internal linkage declarations
/// from different modules, and thus an ambiguity error can be downgraded to
@@ -2260,6 +2518,10 @@ public:
bool isUsualDeallocationFunction(const CXXMethodDecl *FD);
+ // Check whether the size of array element of type \p EltTy is a multiple of
+ // its alignment and return false if it isn't.
+ bool checkArrayElementAlignment(QualType EltTy, SourceLocation Loc);
+
bool isCompleteType(SourceLocation Loc, QualType T,
CompleteTypeKind Kind = CompleteTypeKind::Default) {
return !RequireCompleteTypeImpl(Loc, T, Kind, nullptr);
@@ -2334,14 +2596,30 @@ public:
const CXXScopeSpec &SS, QualType T,
TagDecl *OwnedTagDecl = nullptr);
- QualType getDecltypeForParenthesizedExpr(Expr *E);
- QualType BuildTypeofExprType(Expr *E, SourceLocation Loc);
+ // Returns the underlying type of a decltype with the given expression.
+ QualType getDecltypeForExpr(Expr *E);
+
+ QualType BuildTypeofExprType(Expr *E, TypeOfKind Kind);
/// If AsUnevaluated is false, E is treated as though it were an evaluated
/// context, such as when building a type for decltype(auto).
- QualType BuildDecltypeType(Expr *E, SourceLocation Loc,
- bool AsUnevaluated = true);
- QualType BuildUnaryTransformType(QualType BaseType,
- UnaryTransformType::UTTKind UKind,
+ QualType BuildDecltypeType(Expr *E, bool AsUnevaluated = true);
+
+ using UTTKind = UnaryTransformType::UTTKind;
+ QualType BuildUnaryTransformType(QualType BaseType, UTTKind UKind,
+ SourceLocation Loc);
+ QualType BuiltinEnumUnderlyingType(QualType BaseType, SourceLocation Loc);
+ QualType BuiltinAddPointer(QualType BaseType, SourceLocation Loc);
+ QualType BuiltinRemovePointer(QualType BaseType, SourceLocation Loc);
+ QualType BuiltinDecay(QualType BaseType, SourceLocation Loc);
+ QualType BuiltinAddReference(QualType BaseType, UTTKind UKind,
+ SourceLocation Loc);
+ QualType BuiltinRemoveExtent(QualType BaseType, UTTKind UKind,
+ SourceLocation Loc);
+ QualType BuiltinRemoveReference(QualType BaseType, UTTKind UKind,
+ SourceLocation Loc);
+ QualType BuiltinChangeCVRQualifiers(QualType BaseType, UTTKind UKind,
+ SourceLocation Loc);
+ QualType BuiltinChangeSignedness(QualType BaseType, UTTKind UKind,
SourceLocation Loc);
//===--------------------------------------------------------------------===//
@@ -2349,13 +2627,11 @@ public:
//
struct SkipBodyInfo {
- SkipBodyInfo()
- : ShouldSkip(false), CheckSameAsPrevious(false), Previous(nullptr),
- New(nullptr) {}
- bool ShouldSkip;
- bool CheckSameAsPrevious;
- NamedDecl *Previous;
- NamedDecl *New;
+ SkipBodyInfo() = default;
+ bool ShouldSkip = false;
+ bool CheckSameAsPrevious = false;
+ NamedDecl *Previous = nullptr;
+ NamedDecl *New = nullptr;
};
DeclGroupPtrTy ConvertDeclToDeclGroup(Decl *Ptr, Decl *OwnedType = nullptr);
@@ -2371,6 +2647,8 @@ public:
bool IsCtorOrDtorName = false,
bool WantNontrivialTypeSourceInfo = false,
bool IsClassTemplateDeductionContext = true,
+ ImplicitTypenameContext AllowImplicitTypename =
+ ImplicitTypenameContext::No,
IdentifierInfo **CorrectedII = nullptr);
TypeSpecifierType isTagName(IdentifierInfo &II, Scope *S);
bool isMicrosoftMissingTypename(const CXXScopeSpec *SS, Scope *S);
@@ -2682,15 +2960,17 @@ public:
LookupResult &Previous);
NamedDecl* ActOnTypedefNameDecl(Scope* S, DeclContext* DC, TypedefNameDecl *D,
LookupResult &Previous, bool &Redeclaration);
- NamedDecl *ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC,
- TypeSourceInfo *TInfo,
- LookupResult &Previous,
- MultiTemplateParamsArg TemplateParamLists,
- bool &AddToScope,
- ArrayRef<BindingDecl *> Bindings = None);
+ NamedDecl *ActOnVariableDeclarator(
+ Scope *S, Declarator &D, DeclContext *DC, TypeSourceInfo *TInfo,
+ LookupResult &Previous, MultiTemplateParamsArg TemplateParamLists,
+ bool &AddToScope, ArrayRef<BindingDecl *> Bindings = std::nullopt);
NamedDecl *
ActOnDecompositionDeclarator(Scope *S, Declarator &D,
MultiTemplateParamsArg TemplateParamLists);
+ void DiagPlaceholderVariableDefinition(SourceLocation Loc);
+ bool DiagRedefinedPlaceholderFieldDecl(SourceLocation Loc,
+ RecordDecl *ClassDecl,
+ const IdentifierInfo *Name);
// Returns true if the variable declaration is a redeclaration
bool CheckVariableDeclaration(VarDecl *NewVD, LookupResult &Previous);
void CheckVariableDeclarationType(VarDecl *NewVD);
@@ -2726,19 +3006,30 @@ public:
// Returns true if the function declaration is a redeclaration
bool CheckFunctionDeclaration(Scope *S,
FunctionDecl *NewFD, LookupResult &Previous,
- bool IsMemberSpecialization);
+ bool IsMemberSpecialization, bool DeclIsDefn);
bool shouldLinkDependentDeclWithPrevious(Decl *D, Decl *OldDecl);
bool canFullyTypeCheckRedeclaration(ValueDecl *NewD, ValueDecl *OldD,
QualType NewT, QualType OldT);
void CheckMain(FunctionDecl *FD, const DeclSpec &D);
void CheckMSVCRTEntryPoint(FunctionDecl *FD);
+ void ActOnHLSLTopLevelFunction(FunctionDecl *FD);
+ void CheckHLSLEntryPoint(FunctionDecl *FD);
+ void CheckHLSLSemanticAnnotation(FunctionDecl *EntryPoint, const Decl *Param,
+ const HLSLAnnotationAttr *AnnotationAttr);
+ void DiagnoseHLSLAttrStageMismatch(
+ const Attr *A, HLSLShaderAttr::ShaderType Stage,
+ std::initializer_list<HLSLShaderAttr::ShaderType> AllowedStages);
Attr *getImplicitCodeSegOrSectionAttrForFunction(const FunctionDecl *FD,
bool IsDefinition);
void CheckFunctionOrTemplateParamDeclarator(Scope *S, Declarator &D);
- Decl *ActOnParamDeclarator(Scope *S, Declarator &D);
+ Decl *ActOnParamDeclarator(Scope *S, Declarator &D,
+ SourceLocation ExplicitThisLoc = {});
ParmVarDecl *BuildParmVarDeclForTypedef(DeclContext *DC,
SourceLocation Loc,
QualType T);
+ QualType AdjustParameterTypeForObjCAutoRefCount(QualType T,
+ SourceLocation NameLoc,
+ TypeSourceInfo *TSInfo);
ParmVarDecl *CheckParameter(DeclContext *DC, SourceLocation StartLoc,
SourceLocation NameLoc, IdentifierInfo *Name,
QualType T, TypeSourceInfo *TSInfo,
@@ -2748,7 +3039,8 @@ public:
Expr *defarg);
void ActOnParamUnparsedDefaultArgument(Decl *param, SourceLocation EqualLoc,
SourceLocation ArgLoc);
- void ActOnParamDefaultArgumentError(Decl *param, SourceLocation EqualLoc);
+ void ActOnParamDefaultArgumentError(Decl *param, SourceLocation EqualLoc,
+ Expr* DefaultArg);
ExprResult ConvertParamDefaultArgument(ParmVarDecl *Param, Expr *DefaultArg,
SourceLocation EqualLoc);
void SetParamDefaultArgument(ParmVarDecl *Param, Expr *DefaultArg,
@@ -2804,11 +3096,11 @@ public:
void ActOnCXXForRangeDecl(Decl *D);
StmtResult ActOnCXXForRangeIdentifier(Scope *S, SourceLocation IdentLoc,
IdentifierInfo *Ident,
- ParsedAttributes &Attrs,
- SourceLocation AttrEnd);
+ ParsedAttributes &Attrs);
void SetDeclDeleted(Decl *dcl, SourceLocation DelLoc);
void SetDeclDefaulted(Decl *dcl, SourceLocation DefaultLoc);
void CheckStaticLocalForDllExport(VarDecl *VD);
+ void CheckThreadLocalForLargeAlignment(VarDecl *VD);
void FinalizeDeclaration(Decl *D);
DeclGroupPtrTy FinalizeDeclaratorGroup(Scope *S, const DeclSpec &DS,
ArrayRef<Decl *> Group);
@@ -2819,6 +3111,18 @@ public:
void ActOnDocumentableDecl(Decl *D);
void ActOnDocumentableDecls(ArrayRef<Decl *> Group);
+ enum class FnBodyKind {
+ /// C++ [dcl.fct.def.general]p1
+ /// function-body:
+ /// ctor-initializer[opt] compound-statement
+ /// function-try-block
+ Other,
+ /// = default ;
+ Default,
+ /// = delete ;
+ Delete
+ };
+
void ActOnFinishKNRParamDeclarations(Scope *S, Declarator &D,
SourceLocation LocAfterDecls);
void CheckForFunctionRedefinition(
@@ -2826,9 +3130,12 @@ public:
SkipBodyInfo *SkipBody = nullptr);
Decl *ActOnStartOfFunctionDef(Scope *S, Declarator &D,
MultiTemplateParamsArg TemplateParamLists,
- SkipBodyInfo *SkipBody = nullptr);
+ SkipBodyInfo *SkipBody = nullptr,
+ FnBodyKind BodyKind = FnBodyKind::Other);
Decl *ActOnStartOfFunctionDef(Scope *S, Decl *D,
- SkipBodyInfo *SkipBody = nullptr);
+ SkipBodyInfo *SkipBody = nullptr,
+ FnBodyKind BodyKind = FnBodyKind::Other);
+ void SetFunctionBodyKind(Decl *D, SourceLocation Loc, FnBodyKind BodyKind);
void ActOnStartTrailingRequiresClause(Scope *S, Declarator &D);
ExprResult ActOnFinishTrailingRequiresClause(ExprResult ConstraintExpr);
ExprResult ActOnRequiresClause(ExprResult ConstraintExpr);
@@ -2856,6 +3163,10 @@ public:
/// \c constexpr in C++11 or has an 'auto' return type in C++14).
bool canSkipFunctionBody(Decl *D);
+ /// Determine whether \param D is function like (function or function
+ /// template) for parsing.
+ bool isDeclaratorFunctionLike(Declarator &D);
+
void computeNRVO(Stmt *Body, sema::FunctionScopeInfo *Scope);
Decl *ActOnFinishFunctionBody(Decl *Decl, Stmt *Body);
Decl *ActOnFinishFunctionBody(Decl *Decl, Stmt *Body, bool IsInstantiation);
@@ -2882,20 +3193,46 @@ public:
SourceLocation AsmLoc,
SourceLocation RParenLoc);
+ Decl *ActOnTopLevelStmtDecl(Stmt *Statement);
+
/// Handle a C++11 empty-declaration and attribute-declaration.
Decl *ActOnEmptyDeclaration(Scope *S, const ParsedAttributesView &AttrList,
SourceLocation SemiLoc);
enum class ModuleDeclKind {
- Interface, ///< 'export module X;'
- Implementation, ///< 'module X;'
+ Interface, ///< 'export module X;'
+ Implementation, ///< 'module X;'
+ PartitionInterface, ///< 'export module X:Y;'
+ PartitionImplementation, ///< 'module X:Y;'
+ };
+
+ /// An enumeration to represent the transition of states in parsing module
+ /// fragments and imports. If we are not parsing a C++20 TU, or we find
+ /// an error in state transition, the state is set to NotACXX20Module.
+ enum class ModuleImportState {
+ FirstDecl, ///< Parsing the first decl in a TU.
+ GlobalFragment, ///< after 'module;' but before 'module X;'
+ ImportAllowed, ///< after 'module X;' but before any non-import decl.
+ ImportFinished, ///< after any non-import decl.
+ PrivateFragmentImportAllowed, ///< after 'module :private;' but before any
+ ///< non-import decl.
+ PrivateFragmentImportFinished, ///< after 'module :private;' but a
+ ///< non-import decl has already been seen.
+ NotACXX20Module ///< Not a C++20 TU, or an invalid state was found.
};
+private:
+ /// The parser has begun a translation unit to be compiled as a C++20
+ /// Header Unit, helper for ActOnStartOfTranslationUnit() only.
+ void HandleStartOfHeaderUnit();
+
+public:
/// The parser has processed a module-declaration that begins the definition
/// of a module interface or implementation.
DeclGroupPtrTy ActOnModuleDecl(SourceLocation StartLoc,
SourceLocation ModuleLoc, ModuleDeclKind MDK,
- ModuleIdPath Path, bool IsFirstDecl);
+ ModuleIdPath Path, ModuleIdPath Partition,
+ ModuleImportState &ImportState);
/// The parser has processed a global-module-fragment declaration that begins
/// the definition of the global module fragment of the current module unit.
@@ -2915,10 +3252,12 @@ public:
/// could be the location of an '@', 'export', or 'import'.
/// \param ExportLoc The location of the 'export' keyword, if any.
/// \param ImportLoc The location of the 'import' keyword.
- /// \param Path The module access path.
+ /// \param Path The module toplevel name as an access path.
+ /// \param IsPartition If the name is for a partition.
DeclResult ActOnModuleImport(SourceLocation StartLoc,
SourceLocation ExportLoc,
- SourceLocation ImportLoc, ModuleIdPath Path);
+ SourceLocation ImportLoc, ModuleIdPath Path,
+ bool IsPartition = false);
DeclResult ActOnModuleImport(SourceLocation StartLoc,
SourceLocation ExportLoc,
SourceLocation ImportLoc, Module *M,
@@ -2955,9 +3294,9 @@ public:
/// Diagnose that the specified declaration needs to be visible but
/// isn't, and suggest a module import that would resolve the problem.
- void diagnoseMissingImport(SourceLocation Loc, NamedDecl *Decl,
+ void diagnoseMissingImport(SourceLocation Loc, const NamedDecl *Decl,
MissingImportKind MIK, bool Recover = true);
- void diagnoseMissingImport(SourceLocation Loc, NamedDecl *Decl,
+ void diagnoseMissingImport(SourceLocation Loc, const NamedDecl *Decl,
SourceLocation DeclLoc, ArrayRef<Module *> Modules,
MissingImportKind MIK, bool Recover);
@@ -2968,8 +3307,9 @@ public:
/// We've found a use of a templated declaration that would trigger an
/// implicit instantiation. Check that any relevant explicit specializations
- /// and partial specializations are visible, and diagnose if not.
+ /// and partial specializations are visible/reachable, and diagnose if not.
void checkSpecializationVisibility(SourceLocation Loc, NamedDecl *Spec);
+ void checkSpecializationReachability(SourceLocation Loc, NamedDecl *Spec);
/// Retrieve a suitable printing policy for diagnostics.
PrintingPolicy getPrintingPolicy() const {
@@ -2985,8 +3325,10 @@ public:
void ActOnTranslationUnitScope(Scope *S);
Decl *ParsedFreeStandingDeclSpec(Scope *S, AccessSpecifier AS, DeclSpec &DS,
+ const ParsedAttributesView &DeclAttrs,
RecordDecl *&AnonRecord);
Decl *ParsedFreeStandingDeclSpec(Scope *S, AccessSpecifier AS, DeclSpec &DS,
+ const ParsedAttributesView &DeclAttrs,
MultiTemplateParamsArg TemplateParams,
bool IsExplicitInstantiation,
RecordDecl *&AnonRecord);
@@ -2996,6 +3338,12 @@ public:
RecordDecl *Record,
const PrintingPolicy &Policy);
+ /// Called once it is known whether
+ /// a tag declaration is an anonymous union or struct.
+ void ActOnDefinedDeclarationSpecifier(Decl *D);
+
+ void DiagPlaceholderFieldDeclDefinitions(RecordDecl *Record);
+
Decl *BuildMicrosoftCAnonymousStruct(Scope *S, DeclSpec &DS,
RecordDecl *Record);
@@ -3029,22 +3377,34 @@ public:
TUK_Friend // Friend declaration: 'friend struct foo;'
};
- Decl *ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK,
- SourceLocation KWLoc, CXXScopeSpec &SS, IdentifierInfo *Name,
- SourceLocation NameLoc, const ParsedAttributesView &Attr,
- AccessSpecifier AS, SourceLocation ModulePrivateLoc,
- MultiTemplateParamsArg TemplateParameterLists, bool &OwnedDecl,
- bool &IsDependent, SourceLocation ScopedEnumKWLoc,
- bool ScopedEnumUsesClassTag, TypeResult UnderlyingType,
- bool IsTypeSpecifier, bool IsTemplateParamOrArg,
- SkipBodyInfo *SkipBody = nullptr);
-
- Decl *ActOnTemplatedFriendTag(Scope *S, SourceLocation FriendLoc,
- unsigned TagSpec, SourceLocation TagLoc,
- CXXScopeSpec &SS, IdentifierInfo *Name,
- SourceLocation NameLoc,
- const ParsedAttributesView &Attr,
- MultiTemplateParamsArg TempParamLists);
+ enum OffsetOfKind {
+ // Not parsing a type within __builtin_offsetof.
+ OOK_Outside,
+ // Parsing a type within __builtin_offsetof.
+ OOK_Builtin,
+ // Parsing a type within macro "offsetof", defined in __buitin_offsetof
+ // To improve our diagnostic message.
+ OOK_Macro,
+ };
+
+ DeclResult ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK,
+ SourceLocation KWLoc, CXXScopeSpec &SS,
+ IdentifierInfo *Name, SourceLocation NameLoc,
+ const ParsedAttributesView &Attr, AccessSpecifier AS,
+ SourceLocation ModulePrivateLoc,
+ MultiTemplateParamsArg TemplateParameterLists,
+ bool &OwnedDecl, bool &IsDependent,
+ SourceLocation ScopedEnumKWLoc,
+ bool ScopedEnumUsesClassTag, TypeResult UnderlyingType,
+ bool IsTypeSpecifier, bool IsTemplateParamOrArg,
+ OffsetOfKind OOK, SkipBodyInfo *SkipBody = nullptr);
+
+ DeclResult ActOnTemplatedFriendTag(Scope *S, SourceLocation FriendLoc,
+ unsigned TagSpec, SourceLocation TagLoc,
+ CXXScopeSpec &SS, IdentifierInfo *Name,
+ SourceLocation NameLoc,
+ const ParsedAttributesView &Attr,
+ MultiTemplateParamsArg TempParamLists);
TypeResult ActOnDependentTag(Scope *S,
unsigned TagSpec,
@@ -3142,9 +3502,8 @@ public:
void ActOnLastBitfield(SourceLocation DeclStart,
SmallVectorImpl<Decl *> &AllIvarDecls);
- Decl *ActOnIvar(Scope *S, SourceLocation DeclStart,
- Declarator &D, Expr *BitfieldWidth,
- tok::ObjCKeywordKind visibility);
+ Decl *ActOnIvar(Scope *S, SourceLocation DeclStart, Declarator &D,
+ Expr *BitWidth, tok::ObjCKeywordKind visibility);
// This is used for both record definitions and ObjC interface declarations.
void ActOnFields(Scope *S, SourceLocation RecLoc, Decl *TagDecl,
@@ -3159,15 +3518,28 @@ public:
/// Perform ODR-like check for C/ObjC when merging tag types from modules.
/// Differently from C++, actually parse the body and reject / error out
/// in case of a structural mismatch.
- bool ActOnDuplicateDefinition(DeclSpec &DS, Decl *Prev,
- SkipBodyInfo &SkipBody);
+ bool ActOnDuplicateDefinition(Decl *Prev, SkipBodyInfo &SkipBody);
+
+ /// Check ODR hashes for C/ObjC when merging types from modules.
+ /// Differently from C++, actually parse the body and reject in case
+ /// of a mismatch.
+ template <typename T,
+ typename = std::enable_if_t<std::is_base_of<NamedDecl, T>::value>>
+ bool ActOnDuplicateODRHashDefinition(T *Duplicate, T *Previous) {
+ if (Duplicate->getODRHash() != Previous->getODRHash())
+ return false;
+
+ // Make the previous decl visible.
+ makeMergedDefinitionVisible(Previous);
+ return true;
+ }
typedef void *SkippedDefinitionContext;
/// Invoked when we enter a tag definition that we're skipping.
SkippedDefinitionContext ActOnTagStartSkippedDefinition(Scope *S, Decl *TD);
- Decl *ActOnObjCContainerStartDefinition(Decl *IDecl);
+ void ActOnObjCContainerStartDefinition(ObjCContainerDecl *IDecl);
/// ActOnStartCXXMemberDeclarations - Invoked when we have parsed a
/// C++ record definition's base-specifiers clause and are starting its
@@ -3191,8 +3563,8 @@ public:
/// scope for parsing/looking-up C constructs.
///
/// Must be followed by a call to \see ActOnObjCReenterContainerContext
- void ActOnObjCTemporaryExitContainerContext(DeclContext *DC);
- void ActOnObjCReenterContainerContext(DeclContext *DC);
+ void ActOnObjCTemporaryExitContainerContext(ObjCContainerDecl *ObjCCtx);
+ void ActOnObjCReenterContainerContext(ObjCContainerDecl *ObjCCtx);
/// ActOnTagDefinitionError - Invoked when there was an unrecoverable
/// error parsing the definition of a tag.
@@ -3239,12 +3611,14 @@ public:
void ActOnReenterFunctionContext(Scope* S, Decl* D);
void ActOnExitFunctionContext();
- DeclContext *getFunctionLevelDeclContext();
+ /// If \p AllowLambda is true, treat lambda as function.
+ DeclContext *getFunctionLevelDeclContext(bool AllowLambda = false) const;
- /// getCurFunctionDecl - If inside of a function body, this returns a pointer
- /// to the function decl for the function being parsed. If we're currently
- /// in a 'block', this returns the containing context.
- FunctionDecl *getCurFunctionDecl();
+ /// Returns a pointer to the innermost enclosing function, or nullptr if the
+ /// current context is not inside a function. If \p AllowLambda is true,
+ /// this can return the call operator of an enclosing lambda, otherwise
+ /// lambdas are skipped when looking for an enclosing function.
+ FunctionDecl *getCurFunctionDecl(bool AllowLambda = false) const;
/// getCurMethodDecl - If inside of a method body, this returns a pointer to
/// the method decl for the method being parsed. If we're currently
@@ -3254,7 +3628,7 @@ public:
/// getCurFunctionOrMethodDecl - Return the Decl for the current ObjC method
/// or C function we're in, otherwise return null. If we're currently
/// in a 'block', this returns the containing context.
- NamedDecl *getCurFunctionOrMethodDecl();
+ NamedDecl *getCurFunctionOrMethodDecl() const;
/// Add this decl to the scope shadowed decl chains.
void PushOnScopeChains(NamedDecl *D, Scope *S, bool AddToContext = true);
@@ -3267,7 +3641,7 @@ public:
/// enclosing namespace set of the context, rather than contained
/// directly within it.
bool isDeclInScope(NamedDecl *D, DeclContext *Ctx, Scope *S = nullptr,
- bool AllowInlineNamespace = false);
+ bool AllowInlineNamespace = false) const;
/// Finds the scope corresponding to the given decl context, if it
/// happens to be an enclosing scope. Otherwise return NULL.
@@ -3343,6 +3717,8 @@ public:
const AttributeCommonInfo &CI,
bool BestCase,
MSInheritanceModel Model);
+ ErrorAttr *mergeErrorAttr(Decl *D, const AttributeCommonInfo &CI,
+ StringRef NewUserDiagnostic);
FormatAttr *mergeFormatAttr(Decl *D, const AttributeCommonInfo &CI,
IdentifierInfo *Format, int FormatIdx,
int FirstArg);
@@ -3368,13 +3744,22 @@ public:
EnforceTCBAttr *mergeEnforceTCBAttr(Decl *D, const EnforceTCBAttr &AL);
EnforceTCBLeafAttr *mergeEnforceTCBLeafAttr(Decl *D,
const EnforceTCBLeafAttr &AL);
+ BTFDeclTagAttr *mergeBTFDeclTagAttr(Decl *D, const BTFDeclTagAttr &AL);
+ HLSLNumThreadsAttr *mergeHLSLNumThreadsAttr(Decl *D,
+ const AttributeCommonInfo &AL,
+ int X, int Y, int Z);
+ HLSLShaderAttr *mergeHLSLShaderAttr(Decl *D, const AttributeCommonInfo &AL,
+ HLSLShaderAttr::ShaderType ShaderType);
+ HLSLParamModifierAttr *
+ mergeHLSLParamModifierAttr(Decl *D, const AttributeCommonInfo &AL,
+ HLSLParamModifierAttr::Spelling Spelling);
void mergeDeclAttributes(NamedDecl *New, Decl *Old,
AvailabilityMergeKind AMK = AMK_Redeclaration);
void MergeTypedefNameDecl(Scope *S, TypedefNameDecl *New,
LookupResult &OldDecls);
bool MergeFunctionDecl(FunctionDecl *New, NamedDecl *&Old, Scope *S,
- bool MergeTypeWithOld);
+ bool MergeTypeWithOld, bool NewDeclIsDefn);
bool MergeCompatibleFunctionDecls(FunctionDecl *New, FunctionDecl *Old,
Scope *S, bool MergeTypeWithOld);
void mergeObjCMethodDecls(ObjCMethodDecl *New, ObjCMethodDecl *Old);
@@ -3416,10 +3801,30 @@ public:
FunctionDecl *New,
const LookupResult &OldDecls,
NamedDecl *&OldDecl,
- bool IsForUsingDecl);
- bool IsOverload(FunctionDecl *New, FunctionDecl *Old, bool IsForUsingDecl,
- bool ConsiderCudaAttrs = true,
- bool ConsiderRequiresClauses = true);
+ bool UseMemberUsingDeclRules);
+ bool IsOverload(FunctionDecl *New, FunctionDecl *Old,
+ bool UseMemberUsingDeclRules, bool ConsiderCudaAttrs = true);
+
+ // Checks whether MD constitutes an override the base class method BaseMD.
+ // When checking for overrides, the object object members are ignored.
+ bool IsOverride(FunctionDecl *MD, FunctionDecl *BaseMD,
+ bool UseMemberUsingDeclRules, bool ConsiderCudaAttrs = true);
+
+ // Calculates whether the expression Constraint depends on an enclosing
+ // template, for the purposes of [temp.friend] p9.
+ // TemplateDepth is the 'depth' of the friend function, which is used to
+ // compare whether a declaration reference is referring to a containing
+ // template, or just the current friend function. A 'lower' TemplateDepth in
+ // the AST refers to a 'containing' template. As the constraint is
+ // uninstantiated, this is relative to the 'top' of the TU.
+ bool
+ ConstraintExpressionDependsOnEnclosingTemplate(const FunctionDecl *Friend,
+ unsigned TemplateDepth,
+ const Expr *Constraint);
+
+ // Calculates whether the friend function depends on an enclosing template for
+ // the purposes of [temp.friend] p9.
+ bool FriendConstraintsDependOnEnclosingTemplate(const FunctionDecl *FD);
enum class AllowedExplicit {
/// Allow no explicit functions to be used.
@@ -3450,9 +3855,22 @@ public:
QualType &ConvertedType);
bool IsBlockPointerConversion(QualType FromType, QualType ToType,
QualType& ConvertedType);
+
+ bool FunctionParamTypesAreEqual(ArrayRef<QualType> Old,
+ ArrayRef<QualType> New,
+ unsigned *ArgPos = nullptr,
+ bool Reversed = false);
+
bool FunctionParamTypesAreEqual(const FunctionProtoType *OldType,
const FunctionProtoType *NewType,
- unsigned *ArgPos = nullptr);
+ unsigned *ArgPos = nullptr,
+ bool Reversed = false);
+
+ bool FunctionNonObjectParamTypesAreEqual(const FunctionDecl *OldFunction,
+ const FunctionDecl *NewFunction,
+ unsigned *ArgPos = nullptr,
+ bool Reversed = false);
+
void HandleFunctionTypeMismatch(PartialDiagnostic &PDiag,
QualType FromType, QualType ToType);
@@ -3475,7 +3893,7 @@ public:
bool IsFunctionConversion(QualType FromType, QualType ToType,
QualType &ResultTy);
bool DiagnoseMultipleUserDefinedConversion(Expr *From, QualType ToType);
- bool isSameOrCompatibleFunctionType(CanQualType Param, CanQualType Arg);
+ bool isSameOrCompatibleFunctionType(QualType Param, QualType Arg);
bool CanPerformAggregateInitializationForOverloadResolution(
const InitializedEntity &Entity, InitListExpr *From);
@@ -3489,10 +3907,11 @@ public:
ExprResult Init,
bool TopLevelOfInitList = false,
bool AllowExplicit = false);
- ExprResult PerformObjectArgumentInitialization(Expr *From,
- NestedNameSpecifier *Qualifier,
- NamedDecl *FoundDecl,
- CXXMethodDecl *Method);
+ ExprResult InitializeExplicitObjectArgument(Sema &S, Expr *Obj,
+ FunctionDecl *Fun);
+ ExprResult PerformImplicitObjectArgumentInitialization(
+ Expr *From, NestedNameSpecifier *Qualifier, NamedDecl *FoundDecl,
+ CXXMethodDecl *Method);
/// Check that the lifetime of the initializer (and its subobjects) is
/// sufficient for initializing the entity, and perform lifetime extension
@@ -3504,18 +3923,33 @@ public:
/// Contexts in which a converted constant expression is required.
enum CCEKind {
- CCEK_CaseValue, ///< Expression in a case label.
- CCEK_Enumerator, ///< Enumerator value with fixed underlying type.
- CCEK_TemplateArg, ///< Value of a non-type template parameter.
- CCEK_ArrayBound, ///< Array bound in array declarator or new-expression.
- CCEK_ExplicitBool ///< Condition in an explicit(bool) specifier.
- };
+ CCEK_CaseValue, ///< Expression in a case label.
+ CCEK_Enumerator, ///< Enumerator value with fixed underlying type.
+ CCEK_TemplateArg, ///< Value of a non-type template parameter.
+ CCEK_ArrayBound, ///< Array bound in array declarator or new-expression.
+ CCEK_ExplicitBool, ///< Condition in an explicit(bool) specifier.
+ CCEK_Noexcept, ///< Condition in a noexcept(bool) specifier.
+ CCEK_StaticAssertMessageSize, ///< Call to size() in a static assert
+ ///< message.
+ CCEK_StaticAssertMessageData, ///< Call to data() in a static assert
+ ///< message.
+ };
+
+ ExprResult BuildConvertedConstantExpression(Expr *From, QualType T,
+ CCEKind CCE,
+ NamedDecl *Dest = nullptr);
+
ExprResult CheckConvertedConstantExpression(Expr *From, QualType T,
llvm::APSInt &Value, CCEKind CCE);
ExprResult CheckConvertedConstantExpression(Expr *From, QualType T,
APValue &Value, CCEKind CCE,
NamedDecl *Dest = nullptr);
+ ExprResult
+ EvaluateConvertedConstantExpression(Expr *E, QualType T, APValue &Value,
+ CCEKind CCE, bool RequireInt,
+ const APValue &PreNarrowingValue);
+
/// Abstract base class used to perform a contextual implicit
/// conversion from an expression to any type passing a filter.
class ContextualImplicitConverter {
@@ -3626,16 +4060,15 @@ public:
using ADLCallKind = CallExpr::ADLCallKind;
- void AddOverloadCandidate(FunctionDecl *Function, DeclAccessPair FoundDecl,
- ArrayRef<Expr *> Args,
- OverloadCandidateSet &CandidateSet,
- bool SuppressUserConversions = false,
- bool PartialOverloading = false,
- bool AllowExplicit = true,
- bool AllowExplicitConversion = false,
- ADLCallKind IsADLCandidate = ADLCallKind::NotADL,
- ConversionSequenceList EarlyConversions = None,
- OverloadCandidateParamOrder PO = {});
+ void AddOverloadCandidate(
+ FunctionDecl *Function, DeclAccessPair FoundDecl, ArrayRef<Expr *> Args,
+ OverloadCandidateSet &CandidateSet, bool SuppressUserConversions = false,
+ bool PartialOverloading = false, bool AllowExplicit = true,
+ bool AllowExplicitConversion = false,
+ ADLCallKind IsADLCandidate = ADLCallKind::NotADL,
+ ConversionSequenceList EarlyConversions = std::nullopt,
+ OverloadCandidateParamOrder PO = {},
+ bool AggregateCandidateDeduction = false);
void AddFunctionCandidates(const UnresolvedSetImpl &Functions,
ArrayRef<Expr *> Args,
OverloadCandidateSet &CandidateSet,
@@ -3650,16 +4083,15 @@ public:
OverloadCandidateSet& CandidateSet,
bool SuppressUserConversion = false,
OverloadCandidateParamOrder PO = {});
- void AddMethodCandidate(CXXMethodDecl *Method,
- DeclAccessPair FoundDecl,
- CXXRecordDecl *ActingContext, QualType ObjectType,
- Expr::Classification ObjectClassification,
- ArrayRef<Expr *> Args,
- OverloadCandidateSet& CandidateSet,
- bool SuppressUserConversions = false,
- bool PartialOverloading = false,
- ConversionSequenceList EarlyConversions = None,
- OverloadCandidateParamOrder PO = {});
+ void
+ AddMethodCandidate(CXXMethodDecl *Method, DeclAccessPair FoundDecl,
+ CXXRecordDecl *ActingContext, QualType ObjectType,
+ Expr::Classification ObjectClassification,
+ ArrayRef<Expr *> Args, OverloadCandidateSet &CandidateSet,
+ bool SuppressUserConversions = false,
+ bool PartialOverloading = false,
+ ConversionSequenceList EarlyConversions = std::nullopt,
+ OverloadCandidateParamOrder PO = {});
void AddMethodTemplateCandidate(FunctionTemplateDecl *MethodTmpl,
DeclAccessPair FoundDecl,
CXXRecordDecl *ActingContext,
@@ -3677,7 +4109,8 @@ public:
OverloadCandidateSet &CandidateSet, bool SuppressUserConversions = false,
bool PartialOverloading = false, bool AllowExplicit = true,
ADLCallKind IsADLCandidate = ADLCallKind::NotADL,
- OverloadCandidateParamOrder PO = {});
+ OverloadCandidateParamOrder PO = {},
+ bool AggregateCandidateDeduction = false);
bool CheckNonDependentConversions(
FunctionTemplateDecl *FunctionTemplate, ArrayRef<QualType> ParamTypes,
ArrayRef<Expr *> Args, OverloadCandidateSet &CandidateSet,
@@ -3725,7 +4158,7 @@ public:
// Emit as a 'note' the specific overload candidate
void NoteOverloadCandidate(
- NamedDecl *Found, FunctionDecl *Fn,
+ const NamedDecl *Found, const FunctionDecl *Fn,
OverloadCandidateRewriteKind RewriteKind = OverloadCandidateRewriteKind(),
QualType DestType = QualType(), bool TakingAddress = false);
@@ -3795,23 +4228,18 @@ public:
bool resolveAndFixAddressOfSingleOverloadCandidate(
ExprResult &SrcExpr, bool DoFunctionPointerConversion = false);
- FunctionDecl *
- ResolveSingleFunctionTemplateSpecialization(OverloadExpr *ovl,
- bool Complain = false,
- DeclAccessPair *Found = nullptr);
+ FunctionDecl *ResolveSingleFunctionTemplateSpecialization(
+ OverloadExpr *ovl, bool Complain = false, DeclAccessPair *Found = nullptr,
+ TemplateSpecCandidateSet *FailedTSC = nullptr);
bool ResolveAndFixSingleFunctionTemplateSpecialization(
- ExprResult &SrcExpr,
- bool DoFunctionPointerConverion = false,
- bool Complain = false,
- SourceRange OpRangeForComplaining = SourceRange(),
- QualType DestTypeForComplaining = QualType(),
- unsigned DiagIDForComplaining = 0);
+ ExprResult &SrcExpr, bool DoFunctionPointerConversion = false,
+ bool Complain = false, SourceRange OpRangeForComplaining = SourceRange(),
+ QualType DestTypeForComplaining = QualType(),
+ unsigned DiagIDForComplaining = 0);
-
- Expr *FixOverloadedFunctionReference(Expr *E,
- DeclAccessPair FoundDecl,
- FunctionDecl *Fn);
+ ExprResult FixOverloadedFunctionReference(Expr *E, DeclAccessPair FoundDecl,
+ FunctionDecl *Fn);
ExprResult FixOverloadedFunctionReference(ExprResult,
DeclAccessPair FoundDecl,
FunctionDecl *Fn);
@@ -3881,13 +4309,15 @@ public:
FunctionDecl *DefaultedFn);
ExprResult CreateOverloadedArraySubscriptExpr(SourceLocation LLoc,
- SourceLocation RLoc,
- Expr *Base,Expr *Idx);
+ SourceLocation RLoc, Expr *Base,
+ MultiExprArg Args);
ExprResult BuildCallToMemberFunction(Scope *S, Expr *MemExpr,
SourceLocation LParenLoc,
MultiExprArg Args,
SourceLocation RParenLoc,
+ Expr *ExecConfig = nullptr,
+ bool IsExecConfig = false,
bool AllowRecovery = false);
ExprResult
BuildCallToObjectOfClassType(Scope *S, Expr *Object, SourceLocation LParenLoc,
@@ -4006,7 +4436,7 @@ public:
ForExternalRedeclaration
};
- RedeclarationKind forRedeclarationInCurContext() {
+ RedeclarationKind forRedeclarationInCurContext() const {
// A declaration with an owning module for linkage can never link against
// anything that is not visible. We don't need to check linkage here; if
// the context has internal linkage, redeclaration lookup won't find things
@@ -4111,8 +4541,8 @@ public:
= NotForRedeclaration);
bool LookupBuiltin(LookupResult &R);
void LookupNecessaryTypesForBuiltin(Scope *S, unsigned ID);
- bool LookupName(LookupResult &R, Scope *S,
- bool AllowBuiltinCreation = false);
+ bool LookupName(LookupResult &R, Scope *S, bool AllowBuiltinCreation = false,
+ bool ForceNoCPlusPlus = false);
bool LookupQualifiedName(LookupResult &R, DeclContext *LookupCtx,
bool InUnqualifiedLookup = false);
bool LookupQualifiedName(LookupResult &R, DeclContext *LookupCtx,
@@ -4160,7 +4590,7 @@ public:
TemplateDiscarded, // Discarded due to uninstantiated templates
Unknown,
};
- FunctionEmissionStatus getEmissionStatus(FunctionDecl *Decl,
+ FunctionEmissionStatus getEmissionStatus(const FunctionDecl *Decl,
bool Final = false);
// Whether the callee should be ignored in CUDA/HIP/OpenMP host/device check.
@@ -4258,6 +4688,10 @@ public:
bool ConsiderLinkage, bool AllowInlineNamespace);
bool CheckRedeclarationModuleOwnership(NamedDecl *New, NamedDecl *Old);
+ bool CheckRedeclarationExported(NamedDecl *New, NamedDecl *Old);
+ bool CheckRedeclarationInModule(NamedDecl *New, NamedDecl *Old);
+ bool IsRedefinitionInModule(const NamedDecl *New,
+ const NamedDecl *Old) const;
void DiagnoseAmbiguousLookup(LookupResult &Result);
//@}
@@ -4289,8 +4723,38 @@ public:
// Helper for delayed processing of attributes.
void ProcessDeclAttributeDelayed(Decl *D,
const ParsedAttributesView &AttrList);
- void ProcessDeclAttributeList(Scope *S, Decl *D, const ParsedAttributesView &AL,
- bool IncludeCXX11Attributes = true);
+
+ // Options for ProcessDeclAttributeList().
+ struct ProcessDeclAttributeOptions {
+ ProcessDeclAttributeOptions()
+ : IncludeCXX11Attributes(true), IgnoreTypeAttributes(false) {}
+
+ ProcessDeclAttributeOptions WithIncludeCXX11Attributes(bool Val) {
+ ProcessDeclAttributeOptions Result = *this;
+ Result.IncludeCXX11Attributes = Val;
+ return Result;
+ }
+
+ ProcessDeclAttributeOptions WithIgnoreTypeAttributes(bool Val) {
+ ProcessDeclAttributeOptions Result = *this;
+ Result.IgnoreTypeAttributes = Val;
+ return Result;
+ }
+
+ // Should C++11 attributes be processed?
+ bool IncludeCXX11Attributes;
+
+ // Should any type attributes encountered be ignored?
+ // If this option is false, a diagnostic will be emitted for any type
+ // attributes of a kind that does not "slide" from the declaration to
+ // the decl-specifier-seq.
+ bool IgnoreTypeAttributes;
+ };
+
+ void ProcessDeclAttributeList(Scope *S, Decl *D,
+ const ParsedAttributesView &AttrList,
+ const ProcessDeclAttributeOptions &Options =
+ ProcessDeclAttributeOptions());
bool ProcessAccessDeclAttributeList(AccessSpecDecl *ASDecl,
const ParsedAttributesView &AttrList);
@@ -4300,8 +4764,10 @@ public:
/// such as checking whether a parameter was properly specified, or the
/// correct number of arguments were passed, etc. Returns true if the
/// attribute has been diagnosed.
- bool checkCommonAttributeFeatures(const Decl *D, const ParsedAttr &A);
- bool checkCommonAttributeFeatures(const Stmt *S, const ParsedAttr &A);
+ bool checkCommonAttributeFeatures(const Decl *D, const ParsedAttr &A,
+ bool SkipArgCountCheck = false);
+ bool checkCommonAttributeFeatures(const Stmt *S, const ParsedAttr &A,
+ bool SkipArgCountCheck = false);
/// Determine if type T is a valid subject for a nonnull and similar
/// attributes. By default, we look through references (the behavior used by
@@ -4310,27 +4776,49 @@ public:
bool isValidPointerAttrType(QualType T, bool RefOkay = false);
bool CheckRegparmAttr(const ParsedAttr &attr, unsigned &value);
+
+ /// Check validaty of calling convention attribute \p attr. If \p FD
+ /// is not null pointer, use \p FD to determine the CUDA/HIP host/device
+ /// target. Otherwise, it is specified by \p CFT.
bool CheckCallingConvAttr(const ParsedAttr &attr, CallingConv &CC,
- const FunctionDecl *FD = nullptr);
+ const FunctionDecl *FD = nullptr,
+ CUDAFunctionTarget CFT = CFT_InvalidTarget);
bool CheckAttrTarget(const ParsedAttr &CurrAttr);
bool CheckAttrNoArgs(const ParsedAttr &CurrAttr);
+ bool checkStringLiteralArgumentAttr(const AttributeCommonInfo &CI,
+ const Expr *E, StringRef &Str,
+ SourceLocation *ArgLocation = nullptr);
bool checkStringLiteralArgumentAttr(const ParsedAttr &Attr, unsigned ArgNum,
StringRef &Str,
SourceLocation *ArgLocation = nullptr);
llvm::Error isValidSectionSpecifier(StringRef Str);
bool checkSectionName(SourceLocation LiteralLoc, StringRef Str);
bool checkTargetAttr(SourceLocation LiteralLoc, StringRef Str);
+ bool checkTargetVersionAttr(SourceLocation LiteralLoc, StringRef &Str,
+ bool &isDefault);
+ bool
+ checkTargetClonesAttrString(SourceLocation LiteralLoc, StringRef Str,
+ const StringLiteral *Literal, bool &HasDefault,
+ bool &HasCommas, bool &HasNotDefault,
+ SmallVectorImpl<SmallString<64>> &StringsBuffer);
bool checkMSInheritanceAttrOnDefinition(
CXXRecordDecl *RD, SourceRange Range, bool BestCase,
MSInheritanceModel SemanticSpelling);
void CheckAlignasUnderalignment(Decl *D);
+ bool CheckNoInlineAttr(const Stmt *OrigSt, const Stmt *CurSt,
+ const AttributeCommonInfo &A);
+ bool CheckAlwaysInlineAttr(const Stmt *OrigSt, const Stmt *CurSt,
+ const AttributeCommonInfo &A);
+
+ bool CheckCountedByAttr(Scope *Scope, const FieldDecl *FD);
+
/// Adjust the calling convention of a method to be the ABI default if it
/// wasn't specified explicitly. This handles method types formed from
/// function type typedefs and typename template arguments.
- void adjustMemberFunctionCC(QualType &T, bool IsStatic, bool IsCtorOrDtor,
- SourceLocation Loc);
+ void adjustMemberFunctionCC(QualType &T, bool HasThisPointer,
+ bool IsCtorOrDtor, SourceLocation Loc);
// Check if there is an explicit attribute, but only look through parens.
// The intent is to look for an attribute on the current declarator, but not
@@ -4341,10 +4829,32 @@ public:
/// Valid types should not have multiple attributes with different CCs.
const AttributedType *getCallingConvAttributedType(QualType T) const;
+ /// Check whether a nullability type specifier can be added to the given
+ /// type through some means not written in source (e.g. API notes).
+ ///
+ /// \param Type The type to which the nullability specifier will be
+ /// added. On success, this type will be updated appropriately.
+ ///
+ /// \param Nullability The nullability specifier to add.
+ ///
+ /// \param DiagLoc The location to use for diagnostics.
+ ///
+ /// \param AllowArrayTypes Whether to accept nullability specifiers on an
+ /// array type (e.g., because it will decay to a pointer).
+ ///
+ /// \param OverrideExisting Whether to override an existing, locally-specified
+ /// nullability specifier rather than complaining about the conflict.
+ ///
+ /// \returns true if nullability cannot be applied, false otherwise.
+ bool CheckImplicitNullabilityTypeSpecifier(QualType &Type,
+ NullabilityKind Nullability,
+ SourceLocation DiagLoc,
+ bool AllowArrayTypes,
+ bool OverrideExisting);
+
/// Process the attributes before creating an attributed statement. Returns
/// the semantic attributes that have been processed.
- void ProcessStmtAttributes(Stmt *Stmt,
- const ParsedAttributesWithRange &InAttrs,
+ void ProcessStmtAttributes(Stmt *Stmt, const ParsedAttributes &InAttrs,
SmallVectorImpl<const Attr *> &OutAttrs);
void WarnConflictingTypedMethods(ObjCMethodDecl *Method,
@@ -4686,15 +5196,16 @@ public:
StmtResult BuildAttributedStmt(SourceLocation AttrsLoc,
ArrayRef<const Attr *> Attrs, Stmt *SubStmt);
- StmtResult ActOnAttributedStmt(const ParsedAttributesWithRange &AttrList,
+ StmtResult ActOnAttributedStmt(const ParsedAttributes &AttrList,
Stmt *SubStmt);
class ConditionResult;
- StmtResult ActOnIfStmt(SourceLocation IfLoc, bool IsConstexpr,
+
+ StmtResult ActOnIfStmt(SourceLocation IfLoc, IfStatementKind StatementKind,
SourceLocation LParenLoc, Stmt *InitStmt,
ConditionResult Cond, SourceLocation RParenLoc,
Stmt *ThenVal, SourceLocation ElseLoc, Stmt *ElseVal);
- StmtResult BuildIfStmt(SourceLocation IfLoc, bool IsConstexpr,
+ StmtResult BuildIfStmt(SourceLocation IfLoc, IfStatementKind StatementKind,
SourceLocation LParenLoc, Stmt *InitStmt,
ConditionResult Cond, SourceLocation RParenLoc,
Stmt *ThenVal, SourceLocation ElseLoc, Stmt *ElseVal);
@@ -4799,7 +5310,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);
@@ -4891,15 +5403,21 @@ public:
/// of it.
void MarkUnusedFileScopedDecl(const DeclaratorDecl *D);
+ typedef llvm::function_ref<void(SourceLocation Loc, PartialDiagnostic PD)>
+ DiagReceiverTy;
+
/// DiagnoseUnusedExprResult - If the statement passed in is an expression
/// whose result is unused, warn.
- void DiagnoseUnusedExprResult(const Stmt *S);
+ void DiagnoseUnusedExprResult(const Stmt *S, unsigned DiagID);
void DiagnoseUnusedNestedTypedefs(const RecordDecl *D);
+ void DiagnoseUnusedNestedTypedefs(const RecordDecl *D,
+ DiagReceiverTy DiagReceiver);
void DiagnoseUnusedDecl(const NamedDecl *ND);
+ void DiagnoseUnusedDecl(const NamedDecl *ND, DiagReceiverTy DiagReceiver);
/// If VD is set but not otherwise used, diagnose, for a parameter or a
/// variable.
- void DiagnoseUnusedButSetDecl(const VarDecl *VD);
+ void DiagnoseUnusedButSetDecl(const VarDecl *VD, DiagReceiverTy DiagReceiver);
/// Emit \p DiagID if statement located on \p StmtLoc has a suspicious null
/// statement as a \p Body, and it is located on the same line.
@@ -4920,6 +5438,11 @@ public:
void DiagnoseSelfMove(const Expr *LHSExpr, const Expr *RHSExpr,
SourceLocation OpLoc);
+ /// Returns a field in a CXXRecordDecl that has the same name as the decl \p
+ /// SelfAssigned when inside a CXXMethodDecl.
+ const FieldDecl *
+ getSelfAssignmentClassMemberCandidate(const ValueDecl *SelfAssigned);
+
/// Warn if we're implicitly casting from a _Nullable pointer type to a
/// _Nonnull one.
void diagnoseNullableToNonnullConversion(QualType DstType, QualType SrcType,
@@ -4963,17 +5486,28 @@ public:
// Expression Parsing Callbacks: SemaExpr.cpp.
bool CanUseDecl(NamedDecl *D, bool TreatUnavailableAsInvalid);
+ // A version of DiagnoseUseOfDecl that should be used if overload resolution
+ // has been used to find this declaration, which means we don't have to bother
+ // checking the trailing requires clause.
+ bool DiagnoseUseOfOverloadedDecl(NamedDecl *D, SourceLocation Loc) {
+ return DiagnoseUseOfDecl(
+ D, Loc, /*UnknownObjCClass=*/nullptr, /*ObjCPropertyAccess=*/false,
+ /*AvoidPartialAvailabilityChecks=*/false, /*ClassReceiver=*/nullptr,
+ /*SkipTrailingRequiresClause=*/true);
+ }
+
bool DiagnoseUseOfDecl(NamedDecl *D, ArrayRef<SourceLocation> Locs,
const ObjCInterfaceDecl *UnknownObjCClass = nullptr,
bool ObjCPropertyAccess = false,
bool AvoidPartialAvailabilityChecks = false,
- ObjCInterfaceDecl *ClassReciever = nullptr);
+ ObjCInterfaceDecl *ClassReciever = nullptr,
+ bool SkipTrailingRequiresClause = false);
void NoteDeletedFunction(FunctionDecl *FD);
void NoteDeletedInheritingConstructor(CXXConstructorDecl *CD);
bool DiagnosePropertyAccessorMismatch(ObjCPropertyDecl *PD,
ObjCMethodDecl *Getter,
SourceLocation Loc);
- void DiagnoseSentinelCalls(NamedDecl *D, SourceLocation Loc,
+ void DiagnoseSentinelCalls(const NamedDecl *D, SourceLocation Loc,
ArrayRef<Expr *> Args);
void PushExpressionEvaluationContext(
@@ -4990,6 +5524,7 @@ public:
void DiscardCleanupsInEvaluationContext();
ExprResult TransformToPotentiallyEvaluated(Expr *E);
+ TypeSourceInfo *TransformToPotentiallyEvaluated(TypeSourceInfo *TInfo);
ExprResult HandleExprEvaluationContextForTypeof(Expr *E);
ExprResult CheckUnevaluatedOperand(Expr *E);
@@ -5016,7 +5551,7 @@ public:
void MarkDeclRefReferenced(DeclRefExpr *E, const Expr *Base = nullptr);
void MarkMemberReferenced(MemberExpr *E);
void MarkFunctionParmPackReferenced(FunctionParmPackExpr *E);
- void MarkCaptureUsedInEnclosingContext(VarDecl *Capture, SourceLocation Loc,
+ void MarkCaptureUsedInEnclosingContext(ValueDecl *Capture, SourceLocation Loc,
unsigned CapturingScopeIndex);
ExprResult CheckLValueToRValueConversionOperand(Expr *E);
@@ -5059,30 +5594,31 @@ public:
///
/// \returns true if an error occurred (i.e., the variable cannot be
/// captured) and false if the capture succeeded.
- bool tryCaptureVariable(VarDecl *Var, SourceLocation Loc, TryCaptureKind Kind,
- SourceLocation EllipsisLoc, bool BuildAndDiagnose,
- QualType &CaptureType,
+ bool tryCaptureVariable(ValueDecl *Var, SourceLocation Loc,
+ TryCaptureKind Kind, SourceLocation EllipsisLoc,
+ bool BuildAndDiagnose, QualType &CaptureType,
QualType &DeclRefType,
const unsigned *const FunctionScopeIndexToStopAt);
/// Try to capture the given variable.
- bool tryCaptureVariable(VarDecl *Var, SourceLocation Loc,
+ bool tryCaptureVariable(ValueDecl *Var, SourceLocation Loc,
TryCaptureKind Kind = TryCapture_Implicit,
SourceLocation EllipsisLoc = SourceLocation());
/// Checks if the variable must be captured.
- bool NeedToCaptureVariable(VarDecl *Var, SourceLocation Loc);
+ bool NeedToCaptureVariable(ValueDecl *Var, SourceLocation Loc);
/// Given a variable, determine the type that a reference to that
/// variable will have in the given scope.
- QualType getCapturedDeclRefType(VarDecl *Var, SourceLocation Loc);
+ QualType getCapturedDeclRefType(ValueDecl *Var, SourceLocation Loc);
/// Mark all of the declarations referenced within a particular AST node as
/// referenced. Used when template instantiation instantiates a non-dependent
/// type -- entities referenced by the type are now referenced.
void MarkDeclarationsReferencedInType(SourceLocation Loc, QualType T);
- void MarkDeclarationsReferencedInExpr(Expr *E,
- bool SkipLocalVariables = false);
+ void MarkDeclarationsReferencedInExpr(
+ Expr *E, bool SkipLocalVariables = false,
+ ArrayRef<const Expr *> StopAt = std::nullopt);
/// Try to recover by turning the given expression into a
/// call. Returns true if recovery was attempted or an error was
@@ -5099,6 +5635,16 @@ public:
/// conversion.
ExprResult tryConvertExprToType(Expr *E, QualType Ty);
+ /// Conditionally issue a diagnostic based on the statements's reachability
+ /// analysis.
+ ///
+ /// \param Stmts If Stmts is non-empty, delay reporting the diagnostic until
+ /// the function body is parsed, and then do a basic reachability analysis to
+ /// determine if the statement is reachable. If it is unreachable, the
+ /// diagnostic will not be emitted.
+ bool DiagIfReachable(SourceLocation Loc, ArrayRef<const Stmt *> Stmts,
+ const PartialDiagnostic &PD);
+
/// Conditionally issue a diagnostic based on the current
/// evaluation context.
///
@@ -5127,13 +5673,15 @@ public:
DeclarationNameInfo &NameInfo,
const TemplateArgumentListInfo *&TemplateArgs);
- bool DiagnoseDependentMemberLookup(LookupResult &R);
+ bool DiagnoseDependentMemberLookup(const LookupResult &R);
bool
DiagnoseEmptyLookup(Scope *S, CXXScopeSpec &SS, LookupResult &R,
CorrectionCandidateCallback &CCC,
TemplateArgumentListInfo *ExplicitTemplateArgs = nullptr,
- ArrayRef<Expr *> Args = None, TypoExpr **Out = nullptr);
+ ArrayRef<Expr *> Args = std::nullopt,
+ DeclContext *LookupCtx = nullptr,
+ TypoExpr **Out = nullptr);
DeclResult LookupIvarInObjCMethod(LookupResult &Lookup, Scope *S,
IdentifierInfo *II);
@@ -5221,8 +5769,12 @@ public:
SourceLocation LitEndLoc,
TemplateArgumentListInfo *ExplicitTemplateArgs = nullptr);
- ExprResult BuildPredefinedExpr(SourceLocation Loc,
- PredefinedExpr::IdentKind IK);
+ // ExpandFunctionLocalPredefinedMacros - Returns a new vector of Tokens,
+ // where Tokens representing function local predefined macros (such as
+ // __FUNCTION__) are replaced (expanded) with string-literal Tokens.
+ std::vector<Token> ExpandFunctionLocalPredefinedMacros(ArrayRef<Token> Toks);
+
+ ExprResult BuildPredefinedExpr(SourceLocation Loc, PredefinedIdentKind IK);
ExprResult ActOnPredefinedExpr(SourceLocation Loc, tok::TokenKind Kind);
ExprResult ActOnIntegerConstant(SourceLocation Loc, uint64_t Val);
@@ -5250,30 +5802,54 @@ public:
ExprResult ActOnStringLiteral(ArrayRef<Token> StringToks,
Scope *UDLScope = nullptr);
+ ExprResult ActOnUnevaluatedStringLiteral(ArrayRef<Token> StringToks);
+
+ /// ControllingExprOrType is either an opaque pointer coming out of a
+ /// ParsedType or an Expr *. FIXME: it'd be better to split this interface
+ /// into two so we don't take a void *, but that's awkward because one of
+ /// the operands is either a ParsedType or an Expr *, which doesn't lend
+ /// itself to generic code very well.
ExprResult ActOnGenericSelectionExpr(SourceLocation KeyLoc,
SourceLocation DefaultLoc,
SourceLocation RParenLoc,
- Expr *ControllingExpr,
+ bool PredicateIsExpr,
+ void *ControllingExprOrType,
ArrayRef<ParsedType> ArgTypes,
ArrayRef<Expr *> ArgExprs);
+ /// ControllingExprOrType is either a TypeSourceInfo * or an Expr *. FIXME:
+ /// it'd be better to split this interface into two so we don't take a
+ /// void *, but see the FIXME on ActOnGenericSelectionExpr as to why that
+ /// isn't a trivial change.
ExprResult CreateGenericSelectionExpr(SourceLocation KeyLoc,
SourceLocation DefaultLoc,
SourceLocation RParenLoc,
- Expr *ControllingExpr,
+ bool PredicateIsExpr,
+ void *ControllingExprOrType,
ArrayRef<TypeSourceInfo *> Types,
ArrayRef<Expr *> Exprs);
// Binary/Unary Operators. 'Tok' is the token for the operator.
ExprResult CreateBuiltinUnaryOp(SourceLocation OpLoc, UnaryOperatorKind Opc,
- Expr *InputExpr);
- ExprResult BuildUnaryOp(Scope *S, SourceLocation OpLoc,
- UnaryOperatorKind Opc, Expr *Input);
- ExprResult ActOnUnaryOp(Scope *S, SourceLocation OpLoc,
- tok::TokenKind Op, Expr *Input);
+ Expr *InputExpr, bool IsAfterAmp = false);
+ ExprResult BuildUnaryOp(Scope *S, SourceLocation OpLoc, UnaryOperatorKind Opc,
+ Expr *Input, bool IsAfterAmp = false);
+ ExprResult ActOnUnaryOp(Scope *S, SourceLocation OpLoc, tok::TokenKind Op,
+ Expr *Input, bool IsAfterAmp = false);
bool isQualifiedMemberAccess(Expr *E);
+ bool CheckUseOfCXXMethodAsAddressOfOperand(SourceLocation OpLoc,
+ const Expr *Op,
+ const CXXMethodDecl *MD);
+
QualType CheckAddressOfOperand(ExprResult &Operand, SourceLocation OpLoc);
+ bool CheckTypeTraitArity(unsigned Arity, SourceLocation Loc, size_t N);
+
+ bool ActOnAlignasTypeArgument(StringRef KWName, ParsedType Ty,
+ SourceLocation OpLoc, SourceRange R);
+ bool CheckAlignasTypeArgument(StringRef KWName, TypeSourceInfo *TInfo,
+ SourceLocation OpLoc, SourceRange R);
+
ExprResult CreateUnaryExprOrTypeTraitExpr(TypeSourceInfo *TInfo,
SourceLocation OpLoc,
UnaryExprOrTypeTrait ExprKind,
@@ -5292,7 +5868,8 @@ public:
bool CheckUnaryExprOrTypeTraitOperand(Expr *E, UnaryExprOrTypeTrait ExprKind);
bool CheckUnaryExprOrTypeTraitOperand(QualType ExprType, SourceLocation OpLoc,
SourceRange ExprRange,
- UnaryExprOrTypeTrait ExprKind);
+ UnaryExprOrTypeTrait ExprKind,
+ StringRef KWName);
ExprResult ActOnSizeofParameterPackExpr(Scope *S,
SourceLocation OpLoc,
IdentifierInfo &Name,
@@ -5302,7 +5879,8 @@ public:
tok::TokenKind Kind, Expr *Input);
ExprResult ActOnArraySubscriptExpr(Scope *S, Expr *Base, SourceLocation LLoc,
- Expr *Idx, SourceLocation RLoc);
+ MultiExprArg ArgExprs,
+ SourceLocation RLoc);
ExprResult CreateBuiltinArraySubscriptExpr(Expr *Base, SourceLocation LLoc,
Expr *Idx, SourceLocation RLoc);
@@ -5556,14 +6134,14 @@ public:
ExprResult BuildVAArgExpr(SourceLocation BuiltinLoc, Expr *E,
TypeSourceInfo *TInfo, SourceLocation RPLoc);
- // __builtin_LINE(), __builtin_FUNCTION(), __builtin_FILE(),
- // __builtin_COLUMN()
- ExprResult ActOnSourceLocExpr(SourceLocExpr::IdentKind Kind,
+ // __builtin_LINE(), __builtin_FUNCTION(), __builtin_FUNCSIG(),
+ // __builtin_FILE(), __builtin_COLUMN(), __builtin_source_location()
+ ExprResult ActOnSourceLocExpr(SourceLocIdentKind Kind,
SourceLocation BuiltinLoc,
SourceLocation RPLoc);
// Build a potentially resolved SourceLocExpr.
- ExprResult BuildSourceLocExpr(SourceLocExpr::IdentKind Kind,
+ ExprResult BuildSourceLocExpr(SourceLocIdentKind Kind, QualType ResultTy,
SourceLocation BuiltinLoc, SourceLocation RPLoc,
DeclContext *ParentContext);
@@ -5644,6 +6222,12 @@ public:
SourceLocation BuiltinLoc,
SourceLocation RParenLoc);
+ //===---------------------------- HLSL Features -------------------------===//
+ Decl *ActOnStartHLSLBuffer(Scope *BufferScope, bool CBuffer,
+ SourceLocation KwLoc, IdentifierInfo *Ident,
+ SourceLocation IdentLoc, SourceLocation LBrace);
+ void ActOnFinishHLSLBuffer(Decl *Dcl, SourceLocation RBrace);
+
//===---------------------------- C++ Features --------------------------===//
// Act on C++ namespaces
@@ -5652,17 +6236,18 @@ public:
SourceLocation IdentLoc, IdentifierInfo *Ident,
SourceLocation LBrace,
const ParsedAttributesView &AttrList,
- UsingDirectiveDecl *&UsingDecl);
+ UsingDirectiveDecl *&UsingDecl, bool IsNested);
void ActOnFinishNamespaceDef(Decl *Dcl, SourceLocation RBrace);
NamespaceDecl *getStdNamespace() const;
NamespaceDecl *getOrCreateStdNamespace();
- NamespaceDecl *lookupStdExperimentalNamespace();
-
CXXRecordDecl *getStdBadAlloc() const;
EnumDecl *getStdAlignValT() const;
+ ValueDecl *tryLookupUnambiguousFieldDecl(RecordDecl *ClassDecl,
+ const IdentifierInfo *MemberOrBase);
+
private:
// A cache representing if we've fully checked the various comparison category
// types stored in ASTContext. The bit-index corresponds to the integer value
@@ -5755,7 +6340,8 @@ public:
NamedDecl *BuildUsingEnumDeclaration(Scope *S, AccessSpecifier AS,
SourceLocation UsingLoc,
SourceLocation EnumLoc,
- SourceLocation NameLoc, EnumDecl *ED);
+ SourceLocation NameLoc,
+ TypeSourceInfo *EnumType, EnumDecl *ED);
NamedDecl *BuildUsingPackDecl(NamedDecl *InstantiatedFrom,
ArrayRef<NamedDecl *> Expansions);
@@ -5775,7 +6361,9 @@ public:
const ParsedAttributesView &AttrList);
Decl *ActOnUsingEnumDeclaration(Scope *CurScope, AccessSpecifier AS,
SourceLocation UsingLoc,
- SourceLocation EnumLoc, const DeclSpec &);
+ SourceLocation EnumLoc,
+ SourceLocation IdentLoc, IdentifierInfo &II,
+ CXXScopeSpec *SS = nullptr);
Decl *ActOnAliasDeclaration(Scope *CurScope, AccessSpecifier AS,
MultiTemplateParamsArg TemplateParams,
SourceLocation UsingLoc, UnqualifiedId &Name,
@@ -5786,36 +6374,33 @@ public:
/// including handling of its default argument expressions.
///
/// \param ConstructKind - a CXXConstructExpr::ConstructionKind
- ExprResult
- BuildCXXConstructExpr(SourceLocation ConstructLoc, QualType DeclInitType,
- NamedDecl *FoundDecl,
- CXXConstructorDecl *Constructor, MultiExprArg Exprs,
- bool HadMultipleCandidates, bool IsListInitialization,
- bool IsStdInitListInitialization,
- bool RequiresZeroInit, unsigned ConstructKind,
- SourceRange ParenRange);
+ ExprResult BuildCXXConstructExpr(
+ SourceLocation ConstructLoc, QualType DeclInitType, NamedDecl *FoundDecl,
+ CXXConstructorDecl *Constructor, MultiExprArg Exprs,
+ bool HadMultipleCandidates, bool IsListInitialization,
+ bool IsStdInitListInitialization, bool RequiresZeroInit,
+ CXXConstructionKind ConstructKind, SourceRange ParenRange);
/// Build a CXXConstructExpr whose constructor has already been resolved if
/// it denotes an inherited constructor.
- ExprResult
- BuildCXXConstructExpr(SourceLocation ConstructLoc, QualType DeclInitType,
- CXXConstructorDecl *Constructor, bool Elidable,
- MultiExprArg Exprs,
- bool HadMultipleCandidates, bool IsListInitialization,
- bool IsStdInitListInitialization,
- bool RequiresZeroInit, unsigned ConstructKind,
- SourceRange ParenRange);
+ ExprResult BuildCXXConstructExpr(
+ SourceLocation ConstructLoc, QualType DeclInitType,
+ CXXConstructorDecl *Constructor, bool Elidable, MultiExprArg Exprs,
+ bool HadMultipleCandidates, bool IsListInitialization,
+ bool IsStdInitListInitialization, bool RequiresZeroInit,
+ CXXConstructionKind ConstructKind, SourceRange ParenRange);
// FIXME: Can we remove this and have the above BuildCXXConstructExpr check if
// the constructor can be elidable?
- ExprResult
- BuildCXXConstructExpr(SourceLocation ConstructLoc, QualType DeclInitType,
- NamedDecl *FoundDecl,
- CXXConstructorDecl *Constructor, bool Elidable,
- MultiExprArg Exprs, bool HadMultipleCandidates,
- bool IsListInitialization,
- bool IsStdInitListInitialization, bool RequiresZeroInit,
- unsigned ConstructKind, SourceRange ParenRange);
+ ExprResult BuildCXXConstructExpr(
+ SourceLocation ConstructLoc, QualType DeclInitType, NamedDecl *FoundDecl,
+ CXXConstructorDecl *Constructor, bool Elidable, MultiExprArg Exprs,
+ bool HadMultipleCandidates, bool IsListInitialization,
+ bool IsStdInitListInitialization, bool RequiresZeroInit,
+ CXXConstructionKind ConstructKind, SourceRange ParenRange);
+
+ ExprResult ConvertMemberDefaultInitExpression(FieldDecl *FD, Expr *InitExpr,
+ SourceLocation InitLoc);
ExprResult BuildCXXDefaultInitExpr(SourceLocation Loc, FieldDecl *Field);
@@ -5823,13 +6408,13 @@ public:
/// Instantiate or parse a C++ default argument expression as necessary.
/// Return true on error.
bool CheckCXXDefaultArgExpr(SourceLocation CallLoc, FunctionDecl *FD,
- ParmVarDecl *Param);
+ ParmVarDecl *Param, Expr *Init = nullptr,
+ bool SkipImmediateInvocations = true);
/// BuildCXXDefaultArgExpr - Creates a CXXDefaultArgExpr, instantiating
/// the default expr if needed.
- ExprResult BuildCXXDefaultArgExpr(SourceLocation CallLoc,
- FunctionDecl *FD,
- ParmVarDecl *Param);
+ ExprResult BuildCXXDefaultArgExpr(SourceLocation CallLoc, FunctionDecl *FD,
+ ParmVarDecl *Param, Expr *Init = nullptr);
/// FinalizeVarWithDestructor - Prepare for calling destructor on the
/// constructed variable.
@@ -5909,7 +6494,7 @@ public:
/// Check the given noexcept-specifier, convert its expression, and compute
/// the appropriate ExceptionSpecificationType.
- ExprResult ActOnNoexceptSpec(SourceLocation NoexceptLoc, Expr *NoexceptExpr,
+ ExprResult ActOnNoexceptSpec(Expr *NoexceptExpr,
ExceptionSpecificationType &EST);
/// Check the given exception-specification and update the
@@ -6072,6 +6657,13 @@ public:
/// invocation.
ExprResult CheckForImmediateInvocation(ExprResult E, FunctionDecl *Decl);
+ bool CheckImmediateEscalatingFunctionDefinition(
+ FunctionDecl *FD, const sema::FunctionScopeInfo *FSI);
+
+ void MarkExpressionAsImmediateEscalating(Expr *E);
+
+ void DiagnoseImmediateEscalatingReason(FunctionDecl *FD);
+
bool CompleteConstructorCall(CXXConstructorDecl *Constructor,
QualType DeclInitType, MultiExprArg ArgsPtr,
SourceLocation Loc,
@@ -6086,11 +6678,9 @@ public:
ParsedType getConstructorName(IdentifierInfo &II, SourceLocation NameLoc,
Scope *S, CXXScopeSpec &SS,
bool EnteringContext);
- ParsedType getDestructorName(SourceLocation TildeLoc,
- IdentifierInfo &II, SourceLocation NameLoc,
+ ParsedType getDestructorName(IdentifierInfo &II, SourceLocation NameLoc,
Scope *S, CXXScopeSpec &SS,
- ParsedType ObjectType,
- bool EnteringContext);
+ ParsedType ObjectType, bool EnteringContext);
ParsedType getDestructorTypeForDecltype(const DeclSpec &DS,
ParsedType ObjectType);
@@ -6105,6 +6695,13 @@ public:
// AltiVecPixel and AltiVecBool when -faltivec-src-compat=xl is specified.
bool ShouldSplatAltivecScalarInCast(const VectorType *VecTy);
+ // Checks if the -faltivec-src-compat=gcc option is specified.
+ // If so, AltiVecVector, AltiVecBool and AltiVecPixel types are
+ // treated the same way as they are when trying to initialize
+ // these vectors on gcc (an error is emitted).
+ bool CheckAltivecInitFromScalar(SourceRange R, QualType VecTy,
+ QualType SrcTy);
+
/// ActOnCXXNamedCast - Parse
/// {dynamic,static,reinterpret,const,addrspace}_cast's.
ExprResult ActOnCXXNamedCast(SourceLocation OpLoc,
@@ -6170,7 +6767,7 @@ public:
BinaryOperatorKind Operator,
SourceLocation EllipsisLoc, Expr *RHS,
SourceLocation RParenLoc,
- Optional<unsigned> NumExpansions);
+ std::optional<unsigned> NumExpansions);
ExprResult BuildEmptyCXXFoldExpr(SourceLocation EllipsisLoc,
BinaryOperatorKind Operator);
@@ -6277,16 +6874,12 @@ public:
SourceLocation PlacementRParen,
SourceRange TypeIdParens, Declarator &D,
Expr *Initializer);
- ExprResult BuildCXXNew(SourceRange Range, bool UseGlobal,
- SourceLocation PlacementLParen,
- MultiExprArg PlacementArgs,
- SourceLocation PlacementRParen,
- SourceRange TypeIdParens,
- QualType AllocType,
- TypeSourceInfo *AllocTypeInfo,
- Optional<Expr *> ArraySize,
- SourceRange DirectInitRange,
- Expr *Initializer);
+ ExprResult
+ BuildCXXNew(SourceRange Range, bool UseGlobal, SourceLocation PlacementLParen,
+ MultiExprArg PlacementArgs, SourceLocation PlacementRParen,
+ SourceRange TypeIdParens, QualType AllocType,
+ TypeSourceInfo *AllocTypeInfo, std::optional<Expr *> ArraySize,
+ SourceRange DirectInitRange, Expr *Initializer);
/// Determine whether \p FD is an aligned allocation or deallocation
/// function that is unavailable.
@@ -6327,8 +6920,9 @@ public:
ArrayRef<QualType> Params);
bool FindDeallocationFunction(SourceLocation StartLoc, CXXRecordDecl *RD,
- DeclarationName Name, FunctionDecl* &Operator,
- bool Diagnose = true);
+ DeclarationName Name, FunctionDecl *&Operator,
+ bool Diagnose = true, bool WantSize = false,
+ bool WantAligned = false);
FunctionDecl *FindUsualDeallocationFunction(SourceLocation StartLoc,
bool CanProvideSize,
bool Overaligned,
@@ -6431,7 +7025,8 @@ public:
Expr, Expr ? Expr->getExprLoc() : SourceLocation(), DiscardedValue);
}
ExprResult ActOnFinishFullExpr(Expr *Expr, SourceLocation CC,
- bool DiscardedValue, bool IsConstexpr = false);
+ bool DiscardedValue, bool IsConstexpr = false,
+ bool IsTemplateArgument = false);
StmtResult ActOnFinishFullStmt(Stmt *Stmt);
// Marks SS invalid if it represents an incomplete type.
@@ -6503,9 +7098,6 @@ public:
}
};
- bool isNonTypeNestedNameSpecifier(Scope *S, CXXScopeSpec &SS,
- NestedNameSpecInfo &IdInfo);
-
bool BuildCXXNestedNameSpecifier(Scope *S,
NestedNameSpecInfo &IdInfo,
bool EnteringContext,
@@ -6530,9 +7122,6 @@ public:
/// output parameter (containing the full nested-name-specifier,
/// including this new type).
///
- /// \param ErrorRecoveryLookup If true, then this method is called to improve
- /// error recovery. In this case do not emit error message.
- ///
/// \param IsCorrectedToColon If not null, suggestions to replace '::' -> ':'
/// are allowed. The bool value pointed by this parameter is set to 'true'
/// if the identifier is treated as if it was followed by ':', not '::'.
@@ -6544,7 +7133,6 @@ public:
NestedNameSpecInfo &IdInfo,
bool EnteringContext,
CXXScopeSpec &SS,
- bool ErrorRecoveryLookup = false,
bool *IsCorrectedToColon = nullptr,
bool OnlyNamespace = false);
@@ -6558,6 +7146,8 @@ public:
NestedNameSpecInfo &IdInfo,
bool EnteringContext);
+ bool IsInvalidSMECallConversion(QualType FromType, QualType ToType);
+
/// The parser has parsed a nested-name-specifier
/// 'template[opt] template-name < template-args >::'.
///
@@ -6647,33 +7237,37 @@ public:
/// Create a new lambda closure type.
CXXRecordDecl *createLambdaClosureType(SourceRange IntroducerRange,
TypeSourceInfo *Info,
- bool KnownDependent,
+ unsigned LambdaDependencyKind,
LambdaCaptureDefault CaptureDefault);
- /// Start the definition of a lambda expression.
- CXXMethodDecl *startLambdaDefinition(CXXRecordDecl *Class,
- SourceRange IntroducerRange,
- TypeSourceInfo *MethodType,
- SourceLocation EndLoc,
- ArrayRef<ParmVarDecl *> Params,
- ConstexprSpecKind ConstexprKind,
- Expr *TrailingRequiresClause);
-
/// Number lambda for linkage purposes if necessary.
- void handleLambdaNumbering(
- CXXRecordDecl *Class, CXXMethodDecl *Method,
- Optional<std::tuple<bool, unsigned, unsigned, Decl *>> Mangling = None);
+ void handleLambdaNumbering(CXXRecordDecl *Class, CXXMethodDecl *Method,
+ std::optional<CXXRecordDecl::LambdaNumbering>
+ NumberingOverride = std::nullopt);
/// Endow the lambda scope info with the relevant properties.
- void buildLambdaScope(sema::LambdaScopeInfo *LSI,
- CXXMethodDecl *CallOperator,
+ void buildLambdaScope(sema::LambdaScopeInfo *LSI, CXXMethodDecl *CallOperator,
SourceRange IntroducerRange,
LambdaCaptureDefault CaptureDefault,
- SourceLocation CaptureDefaultLoc,
- bool ExplicitParams,
- bool ExplicitResultType,
+ SourceLocation CaptureDefaultLoc, bool ExplicitParams,
bool Mutable);
+ CXXMethodDecl *CreateLambdaCallOperator(SourceRange IntroducerRange,
+ CXXRecordDecl *Class);
+
+ void AddTemplateParametersToLambdaCallOperator(
+ CXXMethodDecl *CallOperator, CXXRecordDecl *Class,
+ TemplateParameterList *TemplateParams);
+
+ void CompleteLambdaCallOperator(
+ CXXMethodDecl *Method, SourceLocation LambdaLoc,
+ SourceLocation CallOperatorLoc, Expr *TrailingRequiresClause,
+ TypeSourceInfo *MethodTyInfo, ConstexprSpecKind ConstexprKind,
+ StorageClass SC, ArrayRef<ParmVarDecl *> Params,
+ bool HasExplicitResultType);
+
+ void DiagnoseInvalidExplicitObjectParameterInLambda(CXXMethodDecl *Method);
+
/// Perform initialization analysis of the init-capture and perform
/// any implicit conversions such as an lvalue-to-rvalue conversion if
/// not being used to initialize a reference.
@@ -6681,54 +7275,62 @@ public:
SourceLocation Loc, bool ByRef, SourceLocation EllipsisLoc,
IdentifierInfo *Id, LambdaCaptureInitKind InitKind, Expr *&Init) {
return ParsedType::make(buildLambdaInitCaptureInitialization(
- Loc, ByRef, EllipsisLoc, None, Id,
+ Loc, ByRef, EllipsisLoc, std::nullopt, Id,
InitKind != LambdaCaptureInitKind::CopyInit, Init));
}
QualType buildLambdaInitCaptureInitialization(
SourceLocation Loc, bool ByRef, SourceLocation EllipsisLoc,
- Optional<unsigned> NumExpansions, IdentifierInfo *Id, bool DirectInit,
- Expr *&Init);
+ std::optional<unsigned> NumExpansions, IdentifierInfo *Id,
+ bool DirectInit, Expr *&Init);
/// Create a dummy variable within the declcontext of the lambda's
/// call operator, for name lookup purposes for a lambda init capture.
///
/// CodeGen handles emission of lambda captures, ignoring these dummy
/// variables appropriately.
- VarDecl *createLambdaInitCaptureVarDecl(SourceLocation Loc,
- QualType InitCaptureType,
- SourceLocation EllipsisLoc,
- IdentifierInfo *Id,
- unsigned InitStyle, Expr *Init);
+ VarDecl *createLambdaInitCaptureVarDecl(
+ SourceLocation Loc, QualType InitCaptureType, SourceLocation EllipsisLoc,
+ IdentifierInfo *Id, unsigned InitStyle, Expr *Init, DeclContext *DeclCtx);
/// Add an init-capture to a lambda scope.
- void addInitCapture(sema::LambdaScopeInfo *LSI, VarDecl *Var);
+ void addInitCapture(sema::LambdaScopeInfo *LSI, VarDecl *Var, bool ByRef);
/// Note that we have finished the explicit captures for the
/// given lambda.
void finishLambdaExplicitCaptures(sema::LambdaScopeInfo *LSI);
- /// \brief This is called after parsing the explicit template parameter list
+ /// Deduce a block or lambda's return type based on the return
+ /// statements present in the body.
+ void deduceClosureReturnType(sema::CapturingScopeInfo &CSI);
+
+ /// Once the Lambdas capture are known, we can start to create the closure,
+ /// call operator method, and keep track of the captures.
+ /// We do the capture lookup here, but they are not actually captured until
+ /// after we know what the qualifiers of the call operator are.
+ void ActOnLambdaExpressionAfterIntroducer(LambdaIntroducer &Intro,
+ Scope *CurContext);
+
+ /// This is called after parsing the explicit template parameter list
/// on a lambda (if it exists) in C++2a.
- void ActOnLambdaExplicitTemplateParameterList(SourceLocation LAngleLoc,
+ void ActOnLambdaExplicitTemplateParameterList(LambdaIntroducer &Intro,
+ SourceLocation LAngleLoc,
ArrayRef<NamedDecl *> TParams,
SourceLocation RAngleLoc,
ExprResult RequiresClause);
- /// Introduce the lambda parameters into scope.
- void addLambdaParameters(
- ArrayRef<LambdaIntroducer::LambdaCapture> Captures,
- CXXMethodDecl *CallOperator, Scope *CurScope);
+ void ActOnLambdaClosureQualifiers(LambdaIntroducer &Intro,
+ SourceLocation MutableLoc);
- /// Deduce a block or lambda's return type based on the return
- /// statements present in the body.
- void deduceClosureReturnType(sema::CapturingScopeInfo &CSI);
+ void ActOnLambdaClosureParameters(
+ Scope *LambdaScope,
+ MutableArrayRef<DeclaratorChunk::ParamInfo> ParamInfo);
/// ActOnStartOfLambdaDefinition - This is called just before we start
/// parsing the body of a lambda; it analyzes the explicit captures and
/// arguments, and sets up various data-structures for the body of the
/// lambda.
void ActOnStartOfLambdaDefinition(LambdaIntroducer &Intro,
- Declarator &ParamInfo, Scope *CurScope);
+ Declarator &ParamInfo, const DeclSpec &DS);
/// ActOnLambdaError - If there is an error parsing a lambda, this callback
/// is invoked to pop the information about the lambda.
@@ -6737,8 +7339,7 @@ public:
/// ActOnLambdaExpr - This is called when the body of a lambda expression
/// was successfully completed.
- ExprResult ActOnLambdaExpr(SourceLocation StartLoc, Stmt *Body,
- Scope *CurScope);
+ ExprResult ActOnLambdaExpr(SourceLocation StartLoc, Stmt *Body);
/// Does copying/destroying the captured variable have side effects?
bool CaptureHasSideEffects(const sema::Capture &From);
@@ -6792,6 +7393,17 @@ public:
CXXConversionDecl *Conv,
Expr *Src);
+ sema::LambdaScopeInfo *RebuildLambdaScopeInfo(CXXMethodDecl *CallOperator);
+
+ class LambdaScopeForCallOperatorInstantiationRAII
+ : private FunctionScopeRAII {
+ public:
+ LambdaScopeForCallOperatorInstantiationRAII(
+ Sema &SemasRef, FunctionDecl *FD, MultiLevelTemplateArgumentList MLTAL,
+ LocalInstantiationScope &Scope,
+ bool ShouldAddDeclsFromParentScope = true);
+ };
+
/// Check whether the given expression is a valid constraint expression.
/// A diagnostic is emitted if it is not, false is returned, and
/// PossibleNonPrimary will be set to true if the failure might be due to a
@@ -6815,7 +7427,88 @@ private:
llvm::ContextualFoldingSet<ConstraintSatisfaction, const ASTContext &>
SatisfactionCache;
+ /// Introduce the instantiated local variables into the local
+ /// instantiation scope.
+ void addInstantiatedLocalVarsToScope(FunctionDecl *Function,
+ const FunctionDecl *PatternDecl,
+ LocalInstantiationScope &Scope);
+ /// Introduce the instantiated function parameters into the local
+ /// instantiation scope, and set the parameter names to those used
+ /// in the template.
+ bool addInstantiatedParametersToScope(
+ FunctionDecl *Function, const FunctionDecl *PatternDecl,
+ LocalInstantiationScope &Scope,
+ const MultiLevelTemplateArgumentList &TemplateArgs);
+
+ /// Introduce the instantiated captures of the lambda into the local
+ /// instantiation scope.
+ bool addInstantiatedCapturesToScope(
+ FunctionDecl *Function, const FunctionDecl *PatternDecl,
+ LocalInstantiationScope &Scope,
+ const MultiLevelTemplateArgumentList &TemplateArgs);
+
+ /// used by SetupConstraintCheckingTemplateArgumentsAndScope to recursively(in
+ /// the case of lambdas) set up the LocalInstantiationScope of the current
+ /// function.
+ bool SetupConstraintScope(
+ FunctionDecl *FD, std::optional<ArrayRef<TemplateArgument>> TemplateArgs,
+ MultiLevelTemplateArgumentList MLTAL, LocalInstantiationScope &Scope);
+
+ /// Used during constraint checking, sets up the constraint template argument
+ /// lists, and calls SetupConstraintScope to set up the
+ /// LocalInstantiationScope to have the proper set of ParVarDecls configured.
+ std::optional<MultiLevelTemplateArgumentList>
+ SetupConstraintCheckingTemplateArgumentsAndScope(
+ FunctionDecl *FD, std::optional<ArrayRef<TemplateArgument>> TemplateArgs,
+ LocalInstantiationScope &Scope);
+
+private:
+ // The current stack of constraint satisfactions, so we can exit-early.
+ using SatisfactionStackEntryTy =
+ std::pair<const NamedDecl *, llvm::FoldingSetNodeID>;
+ llvm::SmallVector<SatisfactionStackEntryTy, 10>
+ SatisfactionStack;
+
public:
+ void PushSatisfactionStackEntry(const NamedDecl *D,
+ const llvm::FoldingSetNodeID &ID) {
+ const NamedDecl *Can = cast<NamedDecl>(D->getCanonicalDecl());
+ SatisfactionStack.emplace_back(Can, ID);
+ }
+
+ void PopSatisfactionStackEntry() { SatisfactionStack.pop_back(); }
+
+ bool SatisfactionStackContains(const NamedDecl *D,
+ const llvm::FoldingSetNodeID &ID) const {
+ const NamedDecl *Can = cast<NamedDecl>(D->getCanonicalDecl());
+ return llvm::find(SatisfactionStack,
+ SatisfactionStackEntryTy{Can, ID}) !=
+ SatisfactionStack.end();
+ }
+
+ // Resets the current SatisfactionStack for cases where we are instantiating
+ // constraints as a 'side effect' of normal instantiation in a way that is not
+ // indicative of recursive definition.
+ class SatisfactionStackResetRAII {
+ llvm::SmallVector<SatisfactionStackEntryTy, 10>
+ BackupSatisfactionStack;
+ Sema &SemaRef;
+
+ public:
+ SatisfactionStackResetRAII(Sema &S) : SemaRef(S) {
+ SemaRef.SwapSatisfactionStack(BackupSatisfactionStack);
+ }
+
+ ~SatisfactionStackResetRAII() {
+ SemaRef.SwapSatisfactionStack(BackupSatisfactionStack);
+ }
+ };
+
+ void SwapSatisfactionStack(
+ llvm::SmallVectorImpl<SatisfactionStackEntryTy> &NewSS) {
+ SatisfactionStack.swap(NewSS);
+ }
+
const NormalizedConstraint *
getNormalizedAssociatedConstraints(
NamedDecl *ConstrainedDecl, ArrayRef<const Expr *> AssociatedConstraints);
@@ -6828,8 +7521,8 @@ public:
/// at least constrained than D2, and false otherwise.
///
/// \returns true if an error occurred, false otherwise.
- bool IsAtLeastAsConstrained(NamedDecl *D1, ArrayRef<const Expr *> AC1,
- NamedDecl *D2, ArrayRef<const Expr *> AC2,
+ bool IsAtLeastAsConstrained(NamedDecl *D1, MutableArrayRef<const Expr *> AC1,
+ NamedDecl *D2, MutableArrayRef<const Expr *> AC2,
bool &Result);
/// If D1 was not at least as constrained as D2, but would've been if a pair
@@ -6845,8 +7538,8 @@ public:
/// check (either a concept or a constrained entity).
/// \param ConstraintExprs a list of constraint expressions, treated as if
/// they were 'AND'ed together.
- /// \param TemplateArgs the list of template arguments to substitute into the
- /// constraint expression.
+ /// \param TemplateArgLists the list of template arguments to substitute into
+ /// the constraint expression.
/// \param TemplateIDRange The source range of the template id that
/// caused the constraints check.
/// \param Satisfaction if true is returned, will contain details of the
@@ -6856,13 +7549,46 @@ public:
/// false otherwise.
bool CheckConstraintSatisfaction(
const NamedDecl *Template, ArrayRef<const Expr *> ConstraintExprs,
- ArrayRef<TemplateArgument> TemplateArgs,
+ const MultiLevelTemplateArgumentList &TemplateArgLists,
+ SourceRange TemplateIDRange, ConstraintSatisfaction &Satisfaction) {
+ llvm::SmallVector<Expr *, 4> Converted;
+ return CheckConstraintSatisfaction(Template, ConstraintExprs, Converted,
+ TemplateArgLists, TemplateIDRange,
+ Satisfaction);
+ }
+
+ /// \brief Check whether the given list of constraint expressions are
+ /// satisfied (as if in a 'conjunction') given template arguments.
+ /// Additionally, takes an empty list of Expressions which is populated with
+ /// the instantiated versions of the ConstraintExprs.
+ /// \param Template the template-like entity that triggered the constraints
+ /// check (either a concept or a constrained entity).
+ /// \param ConstraintExprs a list of constraint expressions, treated as if
+ /// they were 'AND'ed together.
+ /// \param ConvertedConstraints a out parameter that will get populated with
+ /// the instantiated version of the ConstraintExprs if we successfully checked
+ /// satisfaction.
+ /// \param TemplateArgList the multi-level list of template arguments to
+ /// substitute into the constraint expression. This should be relative to the
+ /// top-level (hence multi-level), since we need to instantiate fully at the
+ /// time of checking.
+ /// \param TemplateIDRange The source range of the template id that
+ /// caused the constraints check.
+ /// \param Satisfaction if true is returned, will contain details of the
+ /// satisfaction, with enough information to diagnose an unsatisfied
+ /// expression.
+ /// \returns true if an error occurred and satisfaction could not be checked,
+ /// false otherwise.
+ bool CheckConstraintSatisfaction(
+ const NamedDecl *Template, ArrayRef<const Expr *> ConstraintExprs,
+ llvm::SmallVectorImpl<Expr *> &ConvertedConstraints,
+ const MultiLevelTemplateArgumentList &TemplateArgList,
SourceRange TemplateIDRange, ConstraintSatisfaction &Satisfaction);
/// \brief Check whether the given non-dependent constraint expression is
/// satisfied. Returns false and updates Satisfaction with the satisfaction
/// verdict if successful, emits a diagnostic and returns true if an error
- /// occured and satisfaction could not be determined.
+ /// occurred and satisfaction could not be determined.
///
/// \returns true if an error occurred, false otherwise.
bool CheckConstraintSatisfaction(const Expr *ConstraintExpr,
@@ -6871,13 +7597,13 @@ public:
/// Check whether the given function decl's trailing requires clause is
/// satisfied, if any. Returns false and updates Satisfaction with the
/// satisfaction verdict if successful, emits a diagnostic and returns true if
- /// an error occured and satisfaction could not be determined.
+ /// an error occurred and satisfaction could not be determined.
///
/// \returns true if an error occurred, false otherwise.
bool CheckFunctionConstraints(const FunctionDecl *FD,
ConstraintSatisfaction &Satisfaction,
- SourceLocation UsageLoc = SourceLocation());
-
+ SourceLocation UsageLoc = SourceLocation(),
+ bool ForOverloadResolution = false);
/// \brief Ensure that the given template arguments satisfy the constraints
/// associated with the given template, emitting a diagnostic if they do not.
@@ -6892,9 +7618,10 @@ public:
///
/// \returns true if the constrains are not satisfied or could not be checked
/// for satisfaction, false if the constraints are satisfied.
- bool EnsureTemplateArgumentListConstraints(TemplateDecl *Template,
- ArrayRef<TemplateArgument> TemplateArgs,
- SourceRange TemplateIDRange);
+ bool EnsureTemplateArgumentListConstraints(
+ TemplateDecl *Template,
+ const MultiLevelTemplateArgumentList &TemplateArgs,
+ SourceRange TemplateIDRange);
/// \brief Emit diagnostics explaining why a constraint expression was deemed
/// unsatisfied.
@@ -7052,8 +7779,9 @@ public:
bool SetDelegatingInitializer(CXXConstructorDecl *Constructor,
CXXCtorInitializer *Initializer);
- bool SetCtorInitializers(CXXConstructorDecl *Constructor, bool AnyErrors,
- ArrayRef<CXXCtorInitializer *> Initializers = None);
+ bool SetCtorInitializers(
+ CXXConstructorDecl *Constructor, bool AnyErrors,
+ ArrayRef<CXXCtorInitializer *> Initializers = std::nullopt);
void SetIvarInitializers(ObjCImplementationDecl *ObjCImplementation);
@@ -7178,15 +7906,17 @@ public:
void UnmarkAsLateParsedTemplate(FunctionDecl *FD);
bool IsInsideALocalClassWithinATemplateFunction();
+ bool EvaluateStaticAssertMessageAsString(Expr *Message, std::string &Result,
+ ASTContext &Ctx,
+ bool ErrorOnInvalidMessage);
Decl *ActOnStaticAssertDeclaration(SourceLocation StaticAssertLoc,
Expr *AssertExpr,
Expr *AssertMessageExpr,
SourceLocation RParenLoc);
Decl *BuildStaticAssertDeclaration(SourceLocation StaticAssertLoc,
- Expr *AssertExpr,
- StringLiteral *AssertMessageExpr,
- SourceLocation RParenLoc,
- bool Failed);
+ Expr *AssertExpr, Expr *AssertMessageExpr,
+ SourceLocation RParenLoc, bool Failed);
+ void DiagnoseStaticAssertDetails(const Expr *E);
FriendDecl *CheckFriendTypeDecl(SourceLocation LocStart,
SourceLocation FriendLoc,
@@ -7205,14 +7935,15 @@ public:
void CheckConversionDeclarator(Declarator &D, QualType &R,
StorageClass& SC);
Decl *ActOnConversionDeclarator(CXXConversionDecl *Conversion);
- void CheckDeductionGuideDeclarator(Declarator &D, QualType &R,
+ bool CheckDeductionGuideDeclarator(Declarator &D, QualType &R,
StorageClass &SC);
void CheckDeductionGuideTemplate(FunctionTemplateDecl *TD);
void CheckExplicitlyDefaultedFunction(Scope *S, FunctionDecl *MD);
bool CheckExplicitlyDefaultedSpecialMember(CXXMethodDecl *MD,
- CXXSpecialMember CSM);
+ CXXSpecialMember CSM,
+ SourceLocation DefaultLoc);
void CheckDelayedMemberExceptionSpecs();
bool CheckExplicitlyDefaultedComparison(Scope *S, FunctionDecl *MD,
@@ -7222,6 +7953,13 @@ public:
void DefineDefaultedComparison(SourceLocation Loc, FunctionDecl *FD,
DefaultedComparisonKind DCK);
+ void CheckExplicitObjectMemberFunction(Declarator &D, DeclarationName Name,
+ QualType R, bool IsLambda,
+ DeclContext *DC = nullptr);
+ void CheckExplicitObjectMemberFunction(DeclContext *DC, Declarator &D,
+ DeclarationName Name, QualType R);
+ void CheckExplicitObjectLambda(Declarator &D);
+
//===--------------------------------------------------------------------===//
// C++ Derived Classes
//
@@ -7233,11 +7971,9 @@ public:
TypeSourceInfo *TInfo,
SourceLocation EllipsisLoc);
- BaseResult ActOnBaseSpecifier(Decl *classdecl,
- SourceRange SpecifierRange,
- ParsedAttributes &Attrs,
- bool Virtual, AccessSpecifier Access,
- ParsedType basetype,
+ BaseResult ActOnBaseSpecifier(Decl *classdecl, SourceRange SpecifierRange,
+ const ParsedAttributesView &Attrs, bool Virtual,
+ AccessSpecifier Access, ParsedType basetype,
SourceLocation BaseLoc,
SourceLocation EllipsisLoc);
@@ -7275,6 +8011,10 @@ public:
bool CheckOverridingFunctionReturnType(const CXXMethodDecl *New,
const CXXMethodDecl *Old);
+ // Check that the overriding method has no explicit object parameter.
+ bool CheckExplicitObjectOverride(CXXMethodDecl *New,
+ const CXXMethodDecl *Old);
+
/// CheckOverridingFunctionExceptionSpec - Checks whether the exception
/// spec is a subset of base spec.
bool CheckOverridingFunctionExceptionSpec(const CXXMethodDecl *New,
@@ -7342,10 +8082,16 @@ public:
CheckStructuredBindingMemberAccess(SourceLocation UseLoc,
CXXRecordDecl *DecomposedClass,
DeclAccessPair Field);
+ AccessResult CheckMemberOperatorAccess(SourceLocation Loc, Expr *ObjectExpr,
+ const SourceRange &,
+ DeclAccessPair FoundDecl);
AccessResult CheckMemberOperatorAccess(SourceLocation Loc,
Expr *ObjectExpr,
Expr *ArgExpr,
DeclAccessPair FoundDecl);
+ AccessResult CheckMemberOperatorAccess(SourceLocation Loc, Expr *ObjectExpr,
+ ArrayRef<Expr *> ArgExprs,
+ DeclAccessPair FoundDecl);
AccessResult CheckAddressOfMemberAccess(Expr *OvlExpr,
DeclAccessPair FoundDecl);
AccessResult CheckBaseClassAccess(SourceLocation AccessLoc,
@@ -7439,17 +8185,17 @@ public:
RequiredTemplateKind(SourceLocation TemplateKWLoc = SourceLocation())
: TemplateKW(TemplateKWLoc) {}
/// Template name is unconditionally required.
- RequiredTemplateKind(TemplateNameIsRequiredTag) : TemplateKW() {}
+ RequiredTemplateKind(TemplateNameIsRequiredTag) {}
SourceLocation getTemplateKeywordLoc() const {
- return TemplateKW.getValueOr(SourceLocation());
+ return TemplateKW.value_or(SourceLocation());
}
bool hasTemplateKeyword() const { return getTemplateKeywordLoc().isValid(); }
bool isRequired() const { return TemplateKW != SourceLocation(); }
explicit operator bool() const { return isRequired(); }
private:
- llvm::Optional<SourceLocation> TemplateKW;
+ std::optional<SourceLocation> TemplateKW;
};
enum class AssumedTemplateKind {
@@ -7494,7 +8240,7 @@ public:
/// Determine whether a particular identifier might be the name in a C++1z
/// deduction-guide declaration.
bool isDeductionGuideName(Scope *S, const IdentifierInfo &Name,
- SourceLocation NameLoc,
+ SourceLocation NameLoc, CXXScopeSpec &SS,
ParsedTemplateTy *Template = nullptr);
bool DiagnoseUnknownTemplateName(const IdentifierInfo &II,
@@ -7524,6 +8270,8 @@ public:
SourceLocation EqualLoc,
ParsedType DefaultArg, bool HasTypeConstraint);
+ bool CheckTypeConstraint(TemplateIdAnnotation *TypeConstraint);
+
bool ActOnTypeConstraint(const CXXScopeSpec &SS,
TemplateIdAnnotation *TypeConstraint,
TemplateTypeParmDecl *ConstrainedParameter,
@@ -7542,7 +8290,8 @@ public:
SourceLocation EllipsisLoc);
bool AttachTypeConstraint(AutoTypeLoc TL,
- NonTypeTemplateParmDecl *ConstrainedParameter,
+ NonTypeTemplateParmDecl *NewConstrainedParm,
+ NonTypeTemplateParmDecl *OrigConstrainedParm,
SourceLocation EllipsisLoc);
bool RequireStructuralType(QualType T, SourceLocation Loc);
@@ -7634,7 +8383,9 @@ public:
TemplateTy Template, IdentifierInfo *TemplateII,
SourceLocation TemplateIILoc, SourceLocation LAngleLoc,
ASTTemplateArgsPtr TemplateArgs, SourceLocation RAngleLoc,
- bool IsCtorOrDtorName = false, bool IsClassName = false);
+ bool IsCtorOrDtorName = false, bool IsClassName = false,
+ ImplicitTypenameContext AllowImplicitTypename =
+ ImplicitTypenameContext::No);
/// Parsed an elaborated-type-specifier that refers to a template-id,
/// such as \c class T::template apply<U>.
@@ -7724,9 +8475,9 @@ public:
SourceLocation PrevPtOfInstantiation,
bool &SuppressNew);
- bool CheckDependentFunctionTemplateSpecialization(FunctionDecl *FD,
- const TemplateArgumentListInfo &ExplicitTemplateArgs,
- LookupResult &Previous);
+ bool CheckDependentFunctionTemplateSpecialization(
+ FunctionDecl *FD, const TemplateArgumentListInfo *ExplicitTemplateArgs,
+ LookupResult &Previous);
bool CheckFunctionTemplateSpecialization(
FunctionDecl *FD, TemplateArgumentListInfo *ExplicitTemplateArgs,
@@ -7753,14 +8504,13 @@ public:
SourceLocation TemplateLoc,
Declarator &D);
- TemplateArgumentLoc
- SubstDefaultTemplateArgumentIfAvailable(TemplateDecl *Template,
- SourceLocation TemplateLoc,
- SourceLocation RAngleLoc,
- Decl *Param,
- SmallVectorImpl<TemplateArgument>
- &Converted,
- bool &HasDefaultArg);
+ TemplateArgumentLoc SubstDefaultTemplateArgumentIfAvailable(
+ TemplateDecl *Template, SourceLocation TemplateLoc,
+ SourceLocation RAngleLoc, Decl *Param,
+ ArrayRef<TemplateArgument> SugaredConverted,
+ ArrayRef<TemplateArgument> CanonicalConverted, bool &HasDefaultArg);
+
+ SourceLocation getTopMostPointOfInstantiation(const NamedDecl *) const;
/// Specifies the context in which a particular template
/// argument is being checked.
@@ -7778,16 +8528,15 @@ public:
CTAK_DeducedFromArrayBound
};
- bool CheckTemplateArgument(NamedDecl *Param,
- TemplateArgumentLoc &Arg,
- NamedDecl *Template,
- SourceLocation TemplateLoc,
- SourceLocation RAngleLoc,
- unsigned ArgumentPackIndex,
- SmallVectorImpl<TemplateArgument> &Converted,
- CheckTemplateArgumentKind CTAK = CTAK_Specified);
-
- /// Check that the given template arguments can be be provided to
+ bool
+ CheckTemplateArgument(NamedDecl *Param, TemplateArgumentLoc &Arg,
+ NamedDecl *Template, SourceLocation TemplateLoc,
+ SourceLocation RAngleLoc, unsigned ArgumentPackIndex,
+ SmallVectorImpl<TemplateArgument> &SugaredConverted,
+ SmallVectorImpl<TemplateArgument> &CanonicalConverted,
+ CheckTemplateArgumentKind CTAK);
+
+ /// Check that the given template arguments can be provided to
/// the given template, converting the arguments along the way.
///
/// \param Template The template to which the template arguments are being
@@ -7811,39 +8560,45 @@ public:
/// contain the converted forms of the template arguments as written.
/// Otherwise, \p TemplateArgs will not be modified.
///
- /// \param ConstraintsNotSatisfied If provided, and an error occured, will
+ /// \param ConstraintsNotSatisfied If provided, and an error occurred, will
/// receive true if the cause for the error is the associated constraints of
/// the template not being satisfied by the template arguments.
///
/// \returns true if an error occurred, false otherwise.
- bool CheckTemplateArgumentList(TemplateDecl *Template,
- SourceLocation TemplateLoc,
- TemplateArgumentListInfo &TemplateArgs,
- bool PartialTemplateArgs,
- SmallVectorImpl<TemplateArgument> &Converted,
- bool UpdateArgsWithConversions = true,
- bool *ConstraintsNotSatisfied = nullptr);
-
- bool CheckTemplateTypeArgument(TemplateTypeParmDecl *Param,
- TemplateArgumentLoc &Arg,
- SmallVectorImpl<TemplateArgument> &Converted);
+ bool CheckTemplateArgumentList(
+ TemplateDecl *Template, SourceLocation TemplateLoc,
+ TemplateArgumentListInfo &TemplateArgs, bool PartialTemplateArgs,
+ SmallVectorImpl<TemplateArgument> &SugaredConverted,
+ SmallVectorImpl<TemplateArgument> &CanonicalConverted,
+ bool UpdateArgsWithConversions = true,
+ bool *ConstraintsNotSatisfied = nullptr);
+
+ bool CheckTemplateTypeArgument(
+ TemplateTypeParmDecl *Param, TemplateArgumentLoc &Arg,
+ SmallVectorImpl<TemplateArgument> &SugaredConverted,
+ SmallVectorImpl<TemplateArgument> &CanonicalConverted);
bool CheckTemplateArgument(TypeSourceInfo *Arg);
ExprResult CheckTemplateArgument(NonTypeTemplateParmDecl *Param,
QualType InstantiatedParamType, Expr *Arg,
- TemplateArgument &Converted,
- CheckTemplateArgumentKind CTAK = CTAK_Specified);
+ TemplateArgument &SugaredConverted,
+ TemplateArgument &CanonicalConverted,
+ CheckTemplateArgumentKind CTAK);
bool CheckTemplateTemplateArgument(TemplateTemplateParmDecl *Param,
TemplateParameterList *Params,
TemplateArgumentLoc &Arg);
+ void NoteTemplateLocation(const NamedDecl &Decl,
+ std::optional<SourceRange> ParamRange = {});
+ void NoteTemplateParameterLocation(const NamedDecl &Decl);
+
ExprResult
BuildExpressionFromDeclTemplateArgument(const TemplateArgument &Arg,
QualType ParamType,
SourceLocation Loc);
ExprResult
- BuildExpressionFromIntegralTemplateArgument(const TemplateArgument &Arg,
- SourceLocation Loc);
+ BuildExpressionFromNonTypeTemplateArgument(const TemplateArgument &Arg,
+ SourceLocation Loc);
/// Enumeration describing how template parameter lists are compared
/// for equality.
@@ -7876,15 +8631,83 @@ public:
/// template<int Value> struct integer_c;
/// X<integer_c> xic;
/// \endcode
- TPL_TemplateTemplateArgumentMatch
+ TPL_TemplateTemplateArgumentMatch,
+
+ /// We are determining whether the template-parameters are equivalent
+ /// according to C++ [temp.over.link]/6. This comparison does not consider
+ /// constraints.
+ ///
+ /// \code
+ /// template<C1 T> void f(T);
+ /// template<C2 T> void f(T);
+ /// \endcode
+ TPL_TemplateParamsEquivalent,
+ };
+
+ // A struct to represent the 'new' declaration, which is either itself just
+ // the named decl, or the important information we need about it in order to
+ // do constraint comparisons.
+ class TemplateCompareNewDeclInfo {
+ const NamedDecl *ND = nullptr;
+ const DeclContext *DC = nullptr;
+ const DeclContext *LexicalDC = nullptr;
+ SourceLocation Loc;
+
+ public:
+ TemplateCompareNewDeclInfo(const NamedDecl *ND) : ND(ND) {}
+ TemplateCompareNewDeclInfo(const DeclContext *DeclCtx,
+ const DeclContext *LexicalDeclCtx,
+ SourceLocation Loc)
+
+ : DC(DeclCtx), LexicalDC(LexicalDeclCtx), Loc(Loc) {
+ assert(DC && LexicalDC &&
+ "Constructor only for cases where we have the information to put "
+ "in here");
+ }
+
+ // If this was constructed with no information, we cannot do substitution
+ // for constraint comparison, so make sure we can check that.
+ bool isInvalid() const { return !ND && !DC; }
+
+ const NamedDecl *getDecl() const { return ND; }
+
+ bool ContainsDecl(const NamedDecl *ND) const { return this->ND == ND; }
+
+ const DeclContext *getLexicalDeclContext() const {
+ return ND ? ND->getLexicalDeclContext() : LexicalDC;
+ }
+
+ const DeclContext *getDeclContext() const {
+ return ND ? ND->getDeclContext() : DC;
+ }
+
+ SourceLocation getLocation() const { return ND ? ND->getLocation() : Loc; }
};
- bool TemplateParameterListsAreEqual(TemplateParameterList *New,
- TemplateParameterList *Old,
- bool Complain,
- TemplateParameterListEqualKind Kind,
- SourceLocation TemplateArgLoc
- = SourceLocation());
+ bool TemplateParameterListsAreEqual(
+ const TemplateCompareNewDeclInfo &NewInstFrom, TemplateParameterList *New,
+ const NamedDecl *OldInstFrom, TemplateParameterList *Old, bool Complain,
+ TemplateParameterListEqualKind Kind,
+ SourceLocation TemplateArgLoc = SourceLocation());
+
+ bool TemplateParameterListsAreEqual(
+ TemplateParameterList *New, TemplateParameterList *Old, bool Complain,
+ TemplateParameterListEqualKind Kind,
+ SourceLocation TemplateArgLoc = SourceLocation()) {
+ return TemplateParameterListsAreEqual(nullptr, New, nullptr, Old, Complain,
+ Kind, TemplateArgLoc);
+ }
+
+ // Calculates whether two constraint expressions are equal irrespective of a
+ // difference in 'depth'. This takes a pair of optional 'NamedDecl's 'Old' and
+ // 'New', which are the "source" of the constraint, since this is necessary
+ // for figuring out the relative 'depth' of the constraint. The depth of the
+ // 'primary template' and the 'instantiated from' templates aren't necessarily
+ // the same, such as a case when one is a 'friend' defined in a class.
+ bool AreConstraintExpressionsEqual(const NamedDecl *Old,
+ const Expr *OldConstr,
+ const TemplateCompareNewDeclInfo &New,
+ const Expr *NewConstr);
bool CheckTemplateDeclScope(Scope *S, TemplateParameterList *TemplateParams);
@@ -7896,10 +8719,11 @@ public:
/// \param SS the nested-name-specifier following the typename (e.g., 'T::').
/// \param II the identifier we're retrieving (e.g., 'type' in the example).
/// \param IdLoc the location of the identifier.
- TypeResult
- ActOnTypenameType(Scope *S, SourceLocation TypenameLoc,
- const CXXScopeSpec &SS, const IdentifierInfo &II,
- SourceLocation IdLoc);
+ /// \param IsImplicitTypename context where T::type refers to a type.
+ TypeResult ActOnTypenameType(
+ Scope *S, SourceLocation TypenameLoc, const CXXScopeSpec &SS,
+ const IdentifierInfo &II, SourceLocation IdLoc,
+ ImplicitTypenameContext IsImplicitTypename = ImplicitTypenameContext::No);
/// Called when the parser has parsed a C++ typename
/// specifier that ends in a template-id, e.g.,
@@ -7967,6 +8791,9 @@ public:
Scope *S, MultiTemplateParamsArg TemplateParameterLists,
IdentifierInfo *Name, SourceLocation NameLoc, Expr *ConstraintExpr);
+ void CheckConceptRedefinition(ConceptDecl *NewDecl, LookupResult &Previous,
+ bool &AddToScope);
+
RequiresExprBodyDecl *
ActOnStartRequiresExpr(SourceLocation RequiresKWLoc,
ArrayRef<ParmVarDecl *> LocalParameters,
@@ -7998,11 +8825,13 @@ public:
concepts::Requirement::SubstitutionDiagnostic *SubstDiag);
concepts::NestedRequirement *BuildNestedRequirement(Expr *E);
concepts::NestedRequirement *
- BuildNestedRequirement(
- concepts::Requirement::SubstitutionDiagnostic *SubstDiag);
+ BuildNestedRequirement(StringRef InvalidConstraintEntity,
+ const ASTConstraintSatisfaction &Satisfaction);
ExprResult ActOnRequiresExpr(SourceLocation RequiresKWLoc,
RequiresExprBodyDecl *Body,
+ SourceLocation LParenLoc,
ArrayRef<ParmVarDecl *> LocalParameters,
+ SourceLocation RParenLoc,
ArrayRef<concepts::Requirement *> Requirements,
SourceLocation ClosingBraceLoc);
@@ -8065,6 +8894,9 @@ public:
/// The type of an exception.
UPPC_ExceptionType,
+ /// Explicit specialization.
+ UPPC_ExplicitSpecialization,
+
/// Partial specialization.
UPPC_PartialSpecialization,
@@ -8249,14 +9081,13 @@ public:
/// expansion.
TypeSourceInfo *CheckPackExpansion(TypeSourceInfo *Pattern,
SourceLocation EllipsisLoc,
- Optional<unsigned> NumExpansions);
+ std::optional<unsigned> NumExpansions);
/// Construct a pack expansion type from the pattern of the pack
/// expansion.
- QualType CheckPackExpansion(QualType Pattern,
- SourceRange PatternRange,
+ QualType CheckPackExpansion(QualType Pattern, SourceRange PatternRange,
SourceLocation EllipsisLoc,
- Optional<unsigned> NumExpansions);
+ std::optional<unsigned> NumExpansions);
/// Invoked when parsing an expression followed by an ellipsis, which
/// creates a pack expansion.
@@ -8275,7 +9106,7 @@ public:
///
/// \param EllipsisLoc The location of the ellipsis.
ExprResult CheckPackExpansion(Expr *Pattern, SourceLocation EllipsisLoc,
- Optional<unsigned> NumExpansions);
+ std::optional<unsigned> NumExpansions);
/// Determine whether we could expand a pack expansion with the
/// given set of parameter packs into separate arguments by repeatedly
@@ -8311,13 +9142,11 @@ public:
/// are to be instantiated with arguments of different lengths), false
/// otherwise. If false, \c ShouldExpand (and possibly \c NumExpansions)
/// must be set.
- bool CheckParameterPacksForExpansion(SourceLocation EllipsisLoc,
- SourceRange PatternRange,
- ArrayRef<UnexpandedParameterPack> Unexpanded,
- const MultiLevelTemplateArgumentList &TemplateArgs,
- bool &ShouldExpand,
- bool &RetainExpansion,
- Optional<unsigned> &NumExpansions);
+ bool CheckParameterPacksForExpansion(
+ SourceLocation EllipsisLoc, SourceRange PatternRange,
+ ArrayRef<UnexpandedParameterPack> Unexpanded,
+ const MultiLevelTemplateArgumentList &TemplateArgs, bool &ShouldExpand,
+ bool &RetainExpansion, std::optional<unsigned> &NumExpansions);
/// Determine the number of arguments in the given pack expansion
/// type.
@@ -8326,8 +9155,8 @@ public:
/// consistent across all of the unexpanded parameter packs in its pattern.
///
/// Returns an empty Optional if the type can't be expanded.
- Optional<unsigned> getNumArgumentsInExpansion(QualType T,
- const MultiLevelTemplateArgumentList &TemplateArgs);
+ std::optional<unsigned> getNumArgumentsInExpansion(
+ QualType T, const MultiLevelTemplateArgumentList &TemplateArgs);
/// Determine whether the given declarator contains any unexpanded
/// parameter packs.
@@ -8355,9 +9184,8 @@ public:
/// \param NumExpansions Will be set to the number of expansions that will
/// be generated from this pack expansion, if known a priori.
TemplateArgumentLoc getTemplateArgumentPackExpansionPattern(
- TemplateArgumentLoc OrigLoc,
- SourceLocation &Ellipsis,
- Optional<unsigned> &NumExpansions) const;
+ TemplateArgumentLoc OrigLoc, SourceLocation &Ellipsis,
+ std::optional<unsigned> &NumExpansions) const;
/// Given a template argument that contains an unexpanded parameter pack, but
/// which has already been substituted, attempt to determine the number of
@@ -8365,7 +9193,7 @@ public:
///
/// This is intended for use when transforming 'sizeof...(Arg)' in order to
/// avoid actually expanding the pack where possible.
- Optional<unsigned> getFullyPackExpandedSize(TemplateArgument Arg);
+ std::optional<unsigned> getFullyPackExpandedSize(TemplateArgument Arg);
//===--------------------------------------------------------------------===//
// C++ Template Argument Deduction (C++ [temp.deduct])
@@ -8439,7 +9267,9 @@ public:
/// Deduction failed; that's all we know.
TDK_MiscellaneousDeductionFailure,
/// CUDA Target attributes do not match.
- TDK_CUDATargetMismatch
+ TDK_CUDATargetMismatch,
+ /// Some error which was already diagnosed.
+ TDK_AlreadyDiagnosed
};
TemplateDeductionResult
@@ -8487,7 +9317,8 @@ public:
FunctionTemplateDecl *FunctionTemplate,
TemplateArgumentListInfo *ExplicitTemplateArgs, ArrayRef<Expr *> Args,
FunctionDecl *&Specialization, sema::TemplateDeductionInfo &Info,
- bool PartialOverloading,
+ bool PartialOverloading, bool AggregateDeductionCandidate,
+ QualType ObjectType, Expr::Classification ObjectClassification,
llvm::function_ref<bool(ArrayRef<QualType>)> CheckNonDependent);
TemplateDeductionResult
@@ -8498,11 +9329,10 @@ public:
sema::TemplateDeductionInfo &Info,
bool IsAddressOfFunction = false);
- TemplateDeductionResult
- DeduceTemplateArguments(FunctionTemplateDecl *FunctionTemplate,
- QualType ToType,
- CXXConversionDecl *&Specialization,
- sema::TemplateDeductionInfo &Info);
+ TemplateDeductionResult DeduceTemplateArguments(
+ FunctionTemplateDecl *FunctionTemplate, QualType ObjectType,
+ Expr::Classification ObjectClassification, QualType ToType,
+ CXXConversionDecl *&Specialization, sema::TemplateDeductionInfo &Info);
TemplateDeductionResult
DeduceTemplateArguments(FunctionTemplateDecl *FunctionTemplate,
@@ -8516,35 +9346,42 @@ public:
/// Substitute Replacement for auto in TypeWithAuto
TypeSourceInfo* SubstAutoTypeSourceInfo(TypeSourceInfo *TypeWithAuto,
QualType Replacement);
+
+ // Substitute auto in TypeWithAuto for a Dependent auto type
+ QualType SubstAutoTypeDependent(QualType TypeWithAuto);
+
+ // Substitute auto in TypeWithAuto for a Dependent auto type
+ TypeSourceInfo *
+ SubstAutoTypeSourceInfoDependent(TypeSourceInfo *TypeWithAuto);
+
/// Completely replace the \c auto in \p TypeWithAuto by
/// \p Replacement. This does not retain any \c auto type sugar.
QualType ReplaceAutoType(QualType TypeWithAuto, QualType Replacement);
TypeSourceInfo *ReplaceAutoTypeSourceInfo(TypeSourceInfo *TypeWithAuto,
QualType Replacement);
- /// Result type of DeduceAutoType.
- enum DeduceAutoResult {
- DAR_Succeeded,
- DAR_Failed,
- DAR_FailedAlreadyDiagnosed
- };
-
- DeduceAutoResult
- DeduceAutoType(TypeSourceInfo *AutoType, Expr *&Initializer, QualType &Result,
- Optional<unsigned> DependentDeductionDepth = None,
- bool IgnoreConstraints = false);
- DeduceAutoResult
- DeduceAutoType(TypeLoc AutoTypeLoc, Expr *&Initializer, QualType &Result,
- Optional<unsigned> DependentDeductionDepth = None,
- bool IgnoreConstraints = false);
+ TemplateDeductionResult
+ DeduceAutoType(TypeLoc AutoTypeLoc, Expr *Initializer, QualType &Result,
+ sema::TemplateDeductionInfo &Info,
+ bool DependentDeduction = false,
+ bool IgnoreConstraints = false,
+ TemplateSpecCandidateSet *FailedTSC = nullptr);
void DiagnoseAutoDeductionFailure(VarDecl *VDecl, Expr *Init);
bool DeduceReturnType(FunctionDecl *FD, SourceLocation Loc,
bool Diagnose = true);
+ bool CheckIfFunctionSpecializationIsImmediate(FunctionDecl *FD,
+ SourceLocation Loc);
+
/// Declare implicit deduction guides for a class template if we've
/// not already done so.
void DeclareImplicitDeductionGuides(TemplateDecl *Template,
SourceLocation Loc);
+ FunctionTemplateDecl *DeclareImplicitDeductionGuideFromInitList(
+ TemplateDecl *Template, MutableArrayRef<QualType> ParamTypes,
+ SourceLocation Loc);
+ llvm::DenseMap<unsigned, CXXDeductionGuideDecl *>
+ AggregateDeductionCandidates;
QualType DeduceTemplateSpecializationFromInitializer(
TypeSourceInfo *TInfo, const InitializedEntity &Entity,
@@ -8558,8 +9395,8 @@ public:
TypeLoc getReturnTypeLoc(FunctionDecl *FD) const;
bool DeduceFunctionTypeFromReturnExpr(FunctionDecl *FD,
- SourceLocation ReturnLoc,
- Expr *&RetExpr, AutoType *AT);
+ SourceLocation ReturnLoc, Expr *RetExpr,
+ const AutoType *AT);
FunctionTemplateDecl *getMoreSpecializedTemplate(
FunctionTemplateDecl *FT1, FunctionTemplateDecl *FT2, SourceLocation Loc,
@@ -8613,11 +9450,12 @@ public:
// C++ Template Instantiation
//
- MultiLevelTemplateArgumentList
- getTemplateInstantiationArgs(NamedDecl *D,
- const TemplateArgumentList *Innermost = nullptr,
- bool RelativeToPrimary = false,
- const FunctionDecl *Pattern = nullptr);
+ MultiLevelTemplateArgumentList getTemplateInstantiationArgs(
+ const NamedDecl *D, const DeclContext *DC = nullptr, bool Final = false,
+ const TemplateArgumentList *Innermost = nullptr,
+ bool RelativeToPrimary = false, const FunctionDecl *Pattern = nullptr,
+ bool ForConstraintInstantiation = false,
+ bool SkipForSpecialization = false);
/// A context in which code is being synthesized (where a source location
/// alone is not sufficient to identify the context). This covers template
@@ -8652,6 +9490,9 @@ public:
/// a TemplateDecl.
DeducedTemplateArgumentSubstitution,
+ /// We are substituting into a lambda expression.
+ LambdaExpressionSubstitution,
+
/// We are substituting prior template arguments into a new
/// template parameter. The template parameter itself is either a
/// NonTypeTemplateParmDecl or a TemplateTemplateParmDecl.
@@ -8699,6 +9540,9 @@ public:
// We are normalizing a constraint expression.
ConstraintNormalization,
+ // Instantiating a Requires Expression parameter clause.
+ RequirementParameterInstantiation,
+
// We are substituting into the parameter mapping of an atomic constraint
// during normalization.
ParameterMappingSubstitution,
@@ -8712,11 +9556,18 @@ public:
/// We are marking a class as __dllexport.
MarkingClassDllexported,
+ /// We are building an implied call from __builtin_dump_struct. The
+ /// arguments are in CallArgs.
+ BuildingBuiltinDumpStructCall,
+
/// Added for Template instantiation observation.
/// Memoization means we are _not_ instantiating a template because
/// it is already instantiated (but we entered a context where we
/// would have had to if it was not already instantiated).
- Memoization
+ Memoization,
+
+ /// We are building deduction guides for a class.
+ BuildingDeductionGuides,
} Kind;
/// Was the enclosing context a non-instantiation SFINAE context?
@@ -8733,9 +9584,14 @@ public:
/// arguments.
NamedDecl *Template;
- /// The list of template arguments we are substituting, if they
- /// are not part of the entity.
- const TemplateArgument *TemplateArgs;
+ union {
+ /// The list of template arguments we are substituting, if they
+ /// are not part of the entity.
+ const TemplateArgument *TemplateArgs;
+
+ /// The list of argument expressions in a synthesized call.
+ const Expr *const *CallArgs;
+ };
// FIXME: Wrap this union around more members, or perhaps store the
// kind-specific members in the RAII object owning the context.
@@ -8743,6 +9599,9 @@ public:
/// The number of template arguments in TemplateArgs.
unsigned NumTemplateArgs;
+ /// The number of expressions in CallArgs.
+ unsigned NumCallArgs;
+
/// The special member being declared or defined.
CXXSpecialMember SpecialMember;
};
@@ -9016,6 +9875,18 @@ public:
concepts::NestedRequirement *Req, ConstraintsCheck,
SourceRange InstantiationRange = SourceRange());
+ /// \brief Note that we are checking a requires clause.
+ InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation,
+ const RequiresExpr *E,
+ sema::TemplateDeductionInfo &DeductionInfo,
+ SourceRange InstantiationRange);
+
+ struct BuildingDeductionGuidesTag {};
+ /// \brief Note that we are building deduction guides.
+ InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation,
+ TemplateDecl *Entity, BuildingDeductionGuidesTag,
+ SourceRange InstantiationRange = SourceRange());
+
/// Note that we have finished instantiating this template.
void Clear();
@@ -9040,7 +9911,7 @@ public:
Sema &SemaRef, CodeSynthesisContext::SynthesisKind Kind,
SourceLocation PointOfInstantiation, SourceRange InstantiationRange,
Decl *Entity, NamedDecl *Template = nullptr,
- ArrayRef<TemplateArgument> TemplateArgs = None,
+ ArrayRef<TemplateArgument> TemplateArgs = std::nullopt,
sema::TemplateDeductionInfo *DeductionInfo = nullptr);
InstantiatingTemplate(const InstantiatingTemplate&) = delete;
@@ -9078,14 +9949,81 @@ public:
/// Otherwise, contains a pointer that, if non-NULL, contains the nearest
/// template-deduction context object, which can be used to capture
/// diagnostics that will be suppressed.
- Optional<sema::TemplateDeductionInfo *> isSFINAEContext() const;
+ std::optional<sema::TemplateDeductionInfo *> isSFINAEContext() const;
+
+ /// Whether the AST is currently being rebuilt to correct immediate
+ /// invocations. Immediate invocation candidates and references to consteval
+ /// functions aren't tracked when this is set.
+ bool RebuildingImmediateInvocation = false;
+
+ /// Used to change context to isConstantEvaluated without pushing a heavy
+ /// ExpressionEvaluationContextRecord object.
+ bool isConstantEvaluatedOverride = false;
+
+ const ExpressionEvaluationContextRecord &currentEvaluationContext() const {
+ assert(!ExprEvalContexts.empty() &&
+ "Must be in an expression evaluation context");
+ return ExprEvalContexts.back();
+ };
+
+ bool isConstantEvaluatedContext() const {
+ return currentEvaluationContext().isConstantEvaluated() ||
+ isConstantEvaluatedOverride;
+ }
+
+ bool isAlwaysConstantEvaluatedContext() const {
+ const ExpressionEvaluationContextRecord &Ctx = currentEvaluationContext();
+ return (Ctx.isConstantEvaluated() || isConstantEvaluatedOverride) &&
+ !Ctx.InConditionallyConstantEvaluateContext;
+ }
/// Determines whether we are currently in a context that
/// is not evaluated as per C++ [expr] p5.
bool isUnevaluatedContext() const {
+ return currentEvaluationContext().isUnevaluated();
+ }
+
+ bool isImmediateFunctionContext() const {
+ return currentEvaluationContext().isImmediateFunctionContext();
+ }
+
+ bool isCheckingDefaultArgumentOrInitializer() const {
+ const ExpressionEvaluationContextRecord &Ctx = currentEvaluationContext();
+ return (Ctx.Context ==
+ ExpressionEvaluationContext::PotentiallyEvaluatedIfUsed) ||
+ Ctx.IsCurrentlyCheckingDefaultArgumentOrInitializer;
+ }
+
+ std::optional<ExpressionEvaluationContextRecord::InitializationContext>
+ InnermostDeclarationWithDelayedImmediateInvocations() const {
+ assert(!ExprEvalContexts.empty() &&
+ "Must be in an expression evaluation context");
+ for (const auto &Ctx : llvm::reverse(ExprEvalContexts)) {
+ if (Ctx.Context == ExpressionEvaluationContext::PotentiallyEvaluated &&
+ Ctx.DelayedDefaultInitializationContext)
+ return Ctx.DelayedDefaultInitializationContext;
+ if (Ctx.isConstantEvaluated() || Ctx.isImmediateFunctionContext() ||
+ Ctx.isUnevaluated())
+ break;
+ }
+ return std::nullopt;
+ }
+
+ std::optional<ExpressionEvaluationContextRecord::InitializationContext>
+ OutermostDeclarationWithDelayedImmediateInvocations() const {
assert(!ExprEvalContexts.empty() &&
"Must be in an expression evaluation context");
- return ExprEvalContexts.back().isUnevaluated();
+ std::optional<ExpressionEvaluationContextRecord::InitializationContext> Res;
+ for (auto &Ctx : llvm::reverse(ExprEvalContexts)) {
+ if (Ctx.Context == ExpressionEvaluationContext::PotentiallyEvaluated &&
+ !Ctx.DelayedDefaultInitializationContext && Res)
+ break;
+ if (Ctx.isConstantEvaluated() || Ctx.isImmediateFunctionContext() ||
+ Ctx.isUnevaluated())
+ break;
+ Res = Ctx.DelayedDefaultInitializationContext;
+ }
+ return Res;
}
/// RAII class used to determine whether SFINAE has
@@ -9188,14 +10126,21 @@ public:
/// eagerly.
SmallVector<PendingImplicitInstantiation, 1> LateParsedInstantiations;
+ SmallVector<SmallVector<VTableUse, 16>, 8> SavedVTableUses;
+ SmallVector<std::deque<PendingImplicitInstantiation>, 8>
+ SavedPendingInstantiations;
+
class GlobalEagerInstantiationScope {
public:
GlobalEagerInstantiationScope(Sema &S, bool Enabled)
: S(S), Enabled(Enabled) {
if (!Enabled) return;
- SavedPendingInstantiations.swap(S.PendingInstantiations);
- SavedVTableUses.swap(S.VTableUses);
+ S.SavedPendingInstantiations.emplace_back();
+ S.SavedPendingInstantiations.back().swap(S.PendingInstantiations);
+
+ S.SavedVTableUses.emplace_back();
+ S.SavedVTableUses.back().swap(S.VTableUses);
}
void perform() {
@@ -9211,26 +10156,28 @@ public:
// Restore the set of pending vtables.
assert(S.VTableUses.empty() &&
"VTableUses should be empty before it is discarded.");
- S.VTableUses.swap(SavedVTableUses);
+ S.VTableUses.swap(S.SavedVTableUses.back());
+ S.SavedVTableUses.pop_back();
// Restore the set of pending implicit instantiations.
if (S.TUKind != TU_Prefix || !S.LangOpts.PCHInstantiateTemplates) {
assert(S.PendingInstantiations.empty() &&
"PendingInstantiations should be empty before it is discarded.");
- S.PendingInstantiations.swap(SavedPendingInstantiations);
+ S.PendingInstantiations.swap(S.SavedPendingInstantiations.back());
+ S.SavedPendingInstantiations.pop_back();
} else {
// Template instantiations in the PCH may be delayed until the TU.
- S.PendingInstantiations.swap(SavedPendingInstantiations);
- S.PendingInstantiations.insert(S.PendingInstantiations.end(),
- SavedPendingInstantiations.begin(),
- SavedPendingInstantiations.end());
+ S.PendingInstantiations.swap(S.SavedPendingInstantiations.back());
+ S.PendingInstantiations.insert(
+ S.PendingInstantiations.end(),
+ S.SavedPendingInstantiations.back().begin(),
+ S.SavedPendingInstantiations.back().end());
+ S.SavedPendingInstantiations.pop_back();
}
}
private:
Sema &S;
- SmallVector<VTableUse, 16> SavedVTableUses;
- std::deque<PendingImplicitInstantiation> SavedPendingInstantiations;
bool Enabled;
};
@@ -9307,32 +10254,54 @@ public:
const MultiLevelTemplateArgumentList &TemplateArgs,
SourceLocation Loc, DeclarationName Entity);
- TypeSourceInfo *SubstFunctionDeclType(TypeSourceInfo *T,
- const MultiLevelTemplateArgumentList &TemplateArgs,
- SourceLocation Loc,
- DeclarationName Entity,
- CXXRecordDecl *ThisContext,
- Qualifiers ThisTypeQuals);
+ TypeSourceInfo *SubstFunctionDeclType(
+ TypeSourceInfo *T, const MultiLevelTemplateArgumentList &TemplateArgs,
+ SourceLocation Loc, DeclarationName Entity, CXXRecordDecl *ThisContext,
+ Qualifiers ThisTypeQuals, bool EvaluateConstraints = true);
void SubstExceptionSpec(FunctionDecl *New, const FunctionProtoType *Proto,
const MultiLevelTemplateArgumentList &Args);
bool SubstExceptionSpec(SourceLocation Loc,
FunctionProtoType::ExceptionSpecInfo &ESI,
SmallVectorImpl<QualType> &ExceptionStorage,
const MultiLevelTemplateArgumentList &Args);
- ParmVarDecl *SubstParmVarDecl(ParmVarDecl *D,
- const MultiLevelTemplateArgumentList &TemplateArgs,
- int indexAdjustment,
- Optional<unsigned> NumExpansions,
- bool ExpectParameterPack);
+ ParmVarDecl *
+ SubstParmVarDecl(ParmVarDecl *D,
+ const MultiLevelTemplateArgumentList &TemplateArgs,
+ int indexAdjustment, std::optional<unsigned> NumExpansions,
+ bool ExpectParameterPack, bool EvaluateConstraints = true);
bool SubstParmTypes(SourceLocation Loc, ArrayRef<ParmVarDecl *> Params,
const FunctionProtoType::ExtParameterInfo *ExtParamInfos,
const MultiLevelTemplateArgumentList &TemplateArgs,
SmallVectorImpl<QualType> &ParamTypes,
SmallVectorImpl<ParmVarDecl *> *OutParams,
ExtParameterInfoBuilder &ParamInfos);
+ bool SubstDefaultArgument(SourceLocation Loc, ParmVarDecl *Param,
+ const MultiLevelTemplateArgumentList &TemplateArgs,
+ bool ForCallExpr = false);
ExprResult SubstExpr(Expr *E,
const MultiLevelTemplateArgumentList &TemplateArgs);
+ // A RAII type used by the TemplateDeclInstantiator and TemplateInstantiator
+ // to disable constraint evaluation, then restore the state.
+ template <typename InstTy> struct ConstraintEvalRAII {
+ InstTy &TI;
+ bool OldValue;
+
+ ConstraintEvalRAII(InstTy &TI)
+ : TI(TI), OldValue(TI.getEvaluateConstraints()) {
+ TI.setEvaluateConstraints(false);
+ }
+ ~ConstraintEvalRAII() { TI.setEvaluateConstraints(OldValue); }
+ };
+
+ // Must be used instead of SubstExpr at 'constraint checking' time.
+ ExprResult
+ SubstConstraintExpr(Expr *E,
+ const MultiLevelTemplateArgumentList &TemplateArgs);
+ // Unlike the above, this does not evaluates constraints.
+ ExprResult SubstConstraintExprWithoutSatisfaction(
+ Expr *E, const MultiLevelTemplateArgumentList &TemplateArgs);
+
/// Substitute the given template arguments into a list of
/// expressions, expanding pack expansions if required.
///
@@ -9355,14 +10324,14 @@ public:
TemplateParameterList *
SubstTemplateParams(TemplateParameterList *Params, DeclContext *Owner,
- const MultiLevelTemplateArgumentList &TemplateArgs);
+ const MultiLevelTemplateArgumentList &TemplateArgs,
+ bool EvaluateConstraints = true);
bool
SubstTemplateArguments(ArrayRef<TemplateArgumentLoc> Args,
const MultiLevelTemplateArgumentList &TemplateArgs,
TemplateArgumentListInfo &Outputs);
-
Decl *SubstDecl(Decl *D, DeclContext *Owner,
const MultiLevelTemplateArgumentList &TemplateArgs);
@@ -9412,6 +10381,7 @@ public:
const Decl *Pattern, Decl *Inst,
LateInstantiatedAttrVec *LateAttrs = nullptr,
LocalInstantiationScope *OuterMostScope = nullptr);
+ void updateAttrsForLateParsedTemplate(const Decl *Pattern, Decl *Inst);
void
InstantiateAttrsForDecl(const MultiLevelTemplateArgumentList &TemplateArgs,
@@ -9451,9 +10421,10 @@ public:
SubstTemplateName(NestedNameSpecifierLoc QualifierLoc, TemplateName Name,
SourceLocation Loc,
const MultiLevelTemplateArgumentList &TemplateArgs);
- bool Subst(const TemplateArgumentLoc *Args, unsigned NumArgs,
- TemplateArgumentListInfo &Result,
- const MultiLevelTemplateArgumentList &TemplateArgs);
+
+ bool SubstTypeConstraint(TemplateTypeParmDecl *Inst, const TypeConstraint *TC,
+ const MultiLevelTemplateArgumentList &TemplateArgs,
+ bool EvaluateConstraint);
bool InstantiateDefaultArgument(SourceLocation CallLoc, FunctionDecl *FD,
ParmVarDecl *Param);
@@ -9503,6 +10474,9 @@ public:
const CXXConstructorDecl *Tmpl,
const MultiLevelTemplateArgumentList &TemplateArgs);
+ ExplicitSpecifier instantiateExplicitSpecifier(
+ const MultiLevelTemplateArgumentList &TemplateArgs, ExplicitSpecifier ES);
+
NamedDecl *FindInstantiatedDecl(SourceLocation Loc, NamedDecl *D,
const MultiLevelTemplateArgumentList &TemplateArgs,
bool FindingInstantiatedContext = false);
@@ -9535,14 +10509,14 @@ public:
SourceLocation rAngleLoc);
void popObjCTypeParamList(Scope *S, ObjCTypeParamList *typeParamList);
- Decl *ActOnStartClassInterface(
+ ObjCInterfaceDecl *ActOnStartClassInterface(
Scope *S, SourceLocation AtInterfaceLoc, IdentifierInfo *ClassName,
SourceLocation ClassLoc, ObjCTypeParamList *typeParamList,
IdentifierInfo *SuperName, SourceLocation SuperLoc,
ArrayRef<ParsedType> SuperTypeArgs, SourceRange SuperTypeArgsRange,
Decl *const *ProtoRefs, unsigned NumProtoRefs,
const SourceLocation *ProtoLocs, SourceLocation EndProtoLoc,
- const ParsedAttributesView &AttrList);
+ const ParsedAttributesView &AttrList, SkipBodyInfo *SkipBody);
void ActOnSuperClassOfClassInterface(Scope *S,
SourceLocation AtInterfaceLoc,
@@ -9569,13 +10543,14 @@ public:
SourceLocation &PLoc, SourceLocation PrevLoc,
const ObjCList<ObjCProtocolDecl> &PList);
- Decl *ActOnStartProtocolInterface(
+ ObjCProtocolDecl *ActOnStartProtocolInterface(
SourceLocation AtProtoInterfaceLoc, IdentifierInfo *ProtocolName,
SourceLocation ProtocolLoc, Decl *const *ProtoRefNames,
unsigned NumProtoRefs, const SourceLocation *ProtoLocs,
- SourceLocation EndProtoLoc, const ParsedAttributesView &AttrList);
+ SourceLocation EndProtoLoc, const ParsedAttributesView &AttrList,
+ SkipBodyInfo *SkipBody);
- Decl *ActOnStartCategoryInterface(
+ ObjCCategoryDecl *ActOnStartCategoryInterface(
SourceLocation AtInterfaceLoc, IdentifierInfo *ClassName,
SourceLocation ClassLoc, ObjCTypeParamList *typeParamList,
IdentifierInfo *CategoryName, SourceLocation CategoryLoc,
@@ -9583,19 +10558,15 @@ public:
const SourceLocation *ProtoLocs, SourceLocation EndProtoLoc,
const ParsedAttributesView &AttrList);
- Decl *ActOnStartClassImplementation(SourceLocation AtClassImplLoc,
- IdentifierInfo *ClassName,
- SourceLocation ClassLoc,
- IdentifierInfo *SuperClassname,
- SourceLocation SuperClassLoc,
- const ParsedAttributesView &AttrList);
+ ObjCImplementationDecl *ActOnStartClassImplementation(
+ SourceLocation AtClassImplLoc, IdentifierInfo *ClassName,
+ SourceLocation ClassLoc, IdentifierInfo *SuperClassname,
+ SourceLocation SuperClassLoc, const ParsedAttributesView &AttrList);
- Decl *ActOnStartCategoryImplementation(SourceLocation AtCatImplLoc,
- IdentifierInfo *ClassName,
- SourceLocation ClassLoc,
- IdentifierInfo *CatName,
- SourceLocation CatLoc,
- const ParsedAttributesView &AttrList);
+ ObjCCategoryImplDecl *ActOnStartCategoryImplementation(
+ SourceLocation AtCatImplLoc, IdentifierInfo *ClassName,
+ SourceLocation ClassLoc, IdentifierInfo *CatName, SourceLocation CatLoc,
+ const ParsedAttributesView &AttrList);
DeclGroupPtrTy ActOnFinishObjCImplementation(Decl *ObjCImpDecl,
ArrayRef<Decl *> Decls);
@@ -9669,16 +10640,12 @@ public:
bool FailOnError = false);
/// Build an Objective-C object pointer type.
- QualType BuildObjCObjectType(QualType BaseType,
- SourceLocation Loc,
- SourceLocation TypeArgsLAngleLoc,
- ArrayRef<TypeSourceInfo *> TypeArgs,
- SourceLocation TypeArgsRAngleLoc,
- SourceLocation ProtocolLAngleLoc,
- ArrayRef<ObjCProtocolDecl *> Protocols,
- ArrayRef<SourceLocation> ProtocolLocs,
- SourceLocation ProtocolRAngleLoc,
- bool FailOnError = false);
+ QualType BuildObjCObjectType(
+ QualType BaseType, SourceLocation Loc, SourceLocation TypeArgsLAngleLoc,
+ ArrayRef<TypeSourceInfo *> TypeArgs, SourceLocation TypeArgsRAngleLoc,
+ SourceLocation ProtocolLAngleLoc, ArrayRef<ObjCProtocolDecl *> Protocols,
+ ArrayRef<SourceLocation> ProtocolLocs, SourceLocation ProtocolRAngleLoc,
+ bool FailOnError, bool Rebuilding);
/// Ensure attributes are consistent with type.
/// \param [in, out] Attributes The attributes to check; they will
@@ -9703,8 +10670,8 @@ public:
ObjCInterfaceDecl *ID);
Decl *ActOnAtEnd(Scope *S, SourceRange AtEnd,
- ArrayRef<Decl *> allMethods = None,
- ArrayRef<DeclGroupPtrTy> allTUVars = None);
+ ArrayRef<Decl *> allMethods = std::nullopt,
+ ArrayRef<DeclGroupPtrTy> allTUVars = std::nullopt);
Decl *ActOnProperty(Scope *S, SourceLocation AtLoc,
SourceLocation LParenLoc,
@@ -9950,6 +10917,12 @@ public:
SourceLocation IncludeLoc);
void DiagnoseUnterminatedPragmaAlignPack();
+ /// ActOnPragmaMSStrictGuardStackCheck - Called on well formed \#pragma
+ /// strict_gs_check.
+ void ActOnPragmaMSStrictGuardStackCheck(SourceLocation PragmaLocation,
+ PragmaMsStackAction Action,
+ bool Value);
+
/// ActOnPragmaMSStruct - Called on well formed \#pragma ms_struct [on|off].
void ActOnPragmaMSStruct(PragmaMSStructKind Kind);
@@ -9998,9 +10971,18 @@ public:
void ActOnPragmaMSInitSeg(SourceLocation PragmaLocation,
StringLiteral *SegmentName);
+ /// Called on well-formed \#pragma alloc_text().
+ void ActOnPragmaMSAllocText(
+ SourceLocation PragmaLocation, StringRef Section,
+ const SmallVector<std::tuple<IdentifierInfo *, SourceLocation>>
+ &Functions);
+
/// Called on #pragma clang __debug dump II
void ActOnPragmaDump(Scope *S, SourceLocation Loc, IdentifierInfo *II);
+ /// Called on #pragma clang __debug dump E
+ void ActOnPragmaDump(Expr *E);
+
/// ActOnPragmaDetectMismatch - Call on well-formed \#pragma detect_mismatch
void ActOnPragmaDetectMismatch(SourceLocation Loc, StringRef Name,
StringRef Value);
@@ -10013,6 +10995,9 @@ public:
!CurFPFeatures.getAllowApproxFunc();
}
+ void ActOnPragmaFPEvalMethod(SourceLocation Loc,
+ LangOptions::FPEvalMethodKind Value);
+
/// ActOnPragmaFloatControl - Call on well-formed \#pragma float_control
void ActOnPragmaFloatControl(SourceLocation Loc, PragmaMsStackAction Action,
PragmaFloatControlKind Value);
@@ -10026,9 +11011,9 @@ public:
void ActOnPragmaVisibility(const IdentifierInfo* VisType,
SourceLocation PragmaLoc);
- NamedDecl *DeclClonePragmaWeak(NamedDecl *ND, IdentifierInfo *II,
+ NamedDecl *DeclClonePragmaWeak(NamedDecl *ND, const IdentifierInfo *II,
SourceLocation Loc);
- void DeclApplyPragmaWeak(Scope *S, NamedDecl *ND, WeakInfo &W);
+ void DeclApplyPragmaWeak(Scope *S, NamedDecl *ND, const WeakInfo &W);
/// ActOnPragmaWeakID - Called on well formed \#pragma weak ident.
void ActOnPragmaWeakID(IdentifierInfo* WeakName,
@@ -10057,18 +11042,26 @@ public:
/// Called on well formed
/// \#pragma clang fp reassociate
- void ActOnPragmaFPReassociate(SourceLocation Loc, bool IsEnabled);
+ /// or
+ /// \#pragma clang fp reciprocal
+ void ActOnPragmaFPValueChangingOption(SourceLocation Loc, PragmaFPKind Kind,
+ bool IsEnabled);
/// ActOnPragmaFenvAccess - Called on well formed
/// \#pragma STDC FENV_ACCESS
void ActOnPragmaFEnvAccess(SourceLocation Loc, bool IsEnabled);
+ /// ActOnPragmaCXLimitedRange - Called on well formed
+ /// \#pragma STDC CX_LIMITED_RANGE
+ void ActOnPragmaCXLimitedRange(SourceLocation Loc,
+ LangOptions::ComplexRangeKind Range);
+
/// Called on well formed '\#pragma clang fp' that has option 'exceptions'.
void ActOnPragmaFPExceptions(SourceLocation Loc,
LangOptions::FPExceptionModeKind);
/// Called to set constant rounding mode for floating point operations.
- void setRoundingMode(SourceLocation Loc, llvm::RoundingMode);
+ void ActOnPragmaFEnvRound(SourceLocation Loc, llvm::RoundingMode);
/// Called to set exception behavior for floating point operations.
void setExceptionMode(SourceLocation Loc, LangOptions::FPExceptionModeKind);
@@ -10120,6 +11113,14 @@ public:
/// Called on well formed \#pragma clang optimize.
void ActOnPragmaOptimize(bool On, SourceLocation PragmaLoc);
+ /// #pragma optimize("[optimization-list]", on | off).
+ void ActOnPragmaMSOptimize(SourceLocation Loc, bool IsOn);
+
+ /// Call on well formed \#pragma function.
+ void
+ ActOnPragmaMSFunction(SourceLocation Loc,
+ const llvm::SmallVectorImpl<StringRef> &NoBuiltins);
+
/// Get the location for the currently active "\#pragma clang optimize
/// off". If this location is invalid, then the state of the pragma is "on".
SourceLocation getOptimizeOffPragmaLocation() const {
@@ -10131,11 +11132,26 @@ public:
/// with attribute optnone.
void AddRangeBasedOptnone(FunctionDecl *FD);
+ /// Only called on function definitions; if there is a `#pragma alloc_text`
+ /// that decides which code section the function should be in, add
+ /// attribute section to the function.
+ void AddSectionMSAllocText(FunctionDecl *FD);
+
/// Adds the 'optnone' attribute to the function declaration if there
/// are no conflicts; Loc represents the location causing the 'optnone'
/// attribute to be added (usually because of a pragma).
void AddOptnoneAttributeIfNoConflicts(FunctionDecl *FD, SourceLocation Loc);
+ /// Only called on function definitions; if there is a MSVC #pragma optimize
+ /// in scope, consider changing the function's attributes based on the
+ /// optimization list passed to the pragma.
+ void ModifyFnAttributesMSPragmaOptimize(FunctionDecl *FD);
+
+ /// Only called on function definitions; if there is a pragma in scope
+ /// with the effect of a range-based no_builtin, consider marking the function
+ /// with attribute no_builtin.
+ void AddImplicitMSFunctionNoBuiltinAttr(FunctionDecl *FD);
+
/// AddAlignedAttr - Adds an aligned attribute to a particular declaration.
void AddAlignedAttr(Decl *D, const AttributeCommonInfo &CI, Expr *E,
bool IsPackExpansion);
@@ -10160,10 +11176,23 @@ public:
void AddAnnotationAttr(Decl *D, const AttributeCommonInfo &CI,
StringRef Annot, MutableArrayRef<Expr *> Args);
+ /// ConstantFoldAttrArgs - Folds attribute arguments into ConstantExprs
+ /// (unless they are value dependent or type dependent). Returns false
+ /// and emits a diagnostic if one or more of the arguments could not be
+ /// folded into a constant.
+ bool ConstantFoldAttrArgs(const AttributeCommonInfo &CI,
+ MutableArrayRef<Expr *> Args);
+
+ /// Create an CUDALaunchBoundsAttr attribute.
+ CUDALaunchBoundsAttr *CreateLaunchBoundsAttr(const AttributeCommonInfo &CI,
+ Expr *MaxThreads,
+ Expr *MinBlocks,
+ Expr *MaxBlocks);
+
/// AddLaunchBoundsAttr - Adds a launch_bounds attribute to a particular
/// declaration.
void AddLaunchBoundsAttr(Decl *D, const AttributeCommonInfo &CI,
- Expr *MaxThreads, Expr *MinBlocks);
+ Expr *MaxThreads, Expr *MinBlocks, Expr *MaxBlocks);
/// AddModeAttr - Adds a mode attribute to a particular declaration.
void AddModeAttr(Decl *D, const AttributeCommonInfo &CI, IdentifierInfo *Name,
@@ -10176,11 +11205,21 @@ public:
void AddXConsumedAttr(Decl *D, const AttributeCommonInfo &CI,
RetainOwnershipKind K, bool IsTemplateInstantiation);
+ /// Create an AMDGPUWavesPerEUAttr attribute.
+ AMDGPUFlatWorkGroupSizeAttr *
+ CreateAMDGPUFlatWorkGroupSizeAttr(const AttributeCommonInfo &CI, Expr *Min,
+ Expr *Max);
+
/// addAMDGPUFlatWorkGroupSizeAttr - Adds an amdgpu_flat_work_group_size
/// attribute to a particular declaration.
void addAMDGPUFlatWorkGroupSizeAttr(Decl *D, const AttributeCommonInfo &CI,
Expr *Min, Expr *Max);
+ /// Create an AMDGPUWavesPerEUAttr attribute.
+ AMDGPUWavesPerEUAttr *
+ CreateAMDGPUWavesPerEUAttr(const AttributeCommonInfo &CI, Expr *Min,
+ Expr *Max);
+
/// addAMDGPUWavePersEUAttr - Adds an amdgpu_waves_per_eu attribute to a
/// particular declaration.
void addAMDGPUWavesPerEUAttr(Decl *D, const AttributeCommonInfo &CI,
@@ -10189,7 +11228,7 @@ public:
bool checkNSReturnsRetainedReturnType(SourceLocation loc, QualType type);
//===--------------------------------------------------------------------===//
- // C++ Coroutines TS
+ // C++ Coroutines
//
bool ActOnCoroutineBodyStart(Scope *S, SourceLocation KwLoc,
StringRef Keyword);
@@ -10197,10 +11236,13 @@ public:
ExprResult ActOnCoyieldExpr(Scope *S, SourceLocation KwLoc, Expr *E);
StmtResult ActOnCoreturnStmt(Scope *S, SourceLocation KwLoc, Expr *E);
- ExprResult BuildResolvedCoawaitExpr(SourceLocation KwLoc, Expr *E,
- bool IsImplicit = false);
- ExprResult BuildUnresolvedCoawaitExpr(SourceLocation KwLoc, Expr *E,
- UnresolvedLookupExpr* Lookup);
+ ExprResult BuildOperatorCoawaitLookupExpr(Scope *S, SourceLocation Loc);
+ ExprResult BuildOperatorCoawaitCall(SourceLocation Loc, Expr *E,
+ UnresolvedLookupExpr *Lookup);
+ ExprResult BuildResolvedCoawaitExpr(SourceLocation KwLoc, Expr *Operand,
+ Expr *Awaiter, bool IsImplicit = false);
+ ExprResult BuildUnresolvedCoawaitExpr(SourceLocation KwLoc, Expr *Operand,
+ UnresolvedLookupExpr *Lookup);
ExprResult BuildCoyieldExpr(SourceLocation KwLoc, Expr *E);
StmtResult BuildCoreturnStmt(SourceLocation KwLoc, Expr *E,
bool IsImplicit = false);
@@ -10208,6 +11250,19 @@ public:
bool buildCoroutineParameterMoves(SourceLocation Loc);
VarDecl *buildCoroutinePromise(SourceLocation Loc);
void CheckCompletedCoroutineBody(FunctionDecl *FD, Stmt *&Body);
+
+ // Heuristically tells if the function is `get_return_object` member of a
+ // coroutine promise_type by matching the function name.
+ static bool CanBeGetReturnObject(const FunctionDecl *FD);
+ static bool CanBeGetReturnTypeOnAllocFailure(const FunctionDecl *FD);
+
+ // As a clang extension, enforces that a non-coroutine function must be marked
+ // with [[clang::coro_wrapper]] if it returns a type marked with
+ // [[clang::coro_return_type]].
+ // Expects that FD is not a coroutine.
+ void CheckCoroutineWrapper(FunctionDecl *FD);
+ /// Lookup 'coroutine_traits' in std namespace and std::experimental
+ /// namespace. The namespace found is recorded in Namespace.
ClassTemplateDecl *lookupCoroutineTraits(SourceLocation KwLoc,
SourceLocation FuncLoc);
/// Check that the expression co_await promise.final_suspend() shall not be
@@ -10234,6 +11289,9 @@ private:
/// The directive kind, `begin declare target` or `declare target`.
OpenMPDirectiveKind Kind;
+ /// The directive with indirect clause.
+ std::optional<Expr *> Indirect;
+
/// The directive location.
SourceLocation Loc;
@@ -10247,10 +11305,7 @@ private:
/// Initialization of data-sharing attributes stack.
void InitDataSharingAttributesStack();
void DestroyDataSharingAttributesStack();
- ExprResult
- VerifyPositiveIntegerConstantInClause(Expr *Op, OpenMPClauseKind CKind,
- bool StrictlyPositive = true,
- bool SuppressExprDiags = false);
+
/// Returns OpenMP nesting level for current directive.
unsigned getOpenMPNestingLevel() const;
@@ -10314,6 +11369,26 @@ private:
/// All `omp assumes` we encountered so far.
SmallVector<AssumptionAttr *, 4> OMPAssumeGlobal;
+ /// OMPD_loop is mapped to OMPD_for, OMPD_distribute or OMPD_simd depending
+ /// on the parameter of the bind clause. In the methods for the
+ /// mapped directives, check the parameters of the lastprivate clause.
+ bool checkLastPrivateForMappedDirectives(ArrayRef<OMPClause *> Clauses);
+ /// Depending on the bind clause of OMPD_loop map the directive to new
+ /// directives.
+ /// 1) loop bind(parallel) --> OMPD_for
+ /// 2) loop bind(teams) --> OMPD_distribute
+ /// 3) loop bind(thread) --> OMPD_simd
+ /// This is being handled in Sema instead of Codegen because of the need for
+ /// rigorous semantic checking in the new mapped directives.
+ bool mapLoopConstruct(llvm::SmallVector<OMPClause *> &ClausesWithoutBind,
+ ArrayRef<OMPClause *> Clauses,
+ OpenMPBindClauseKind &BindKind,
+ OpenMPDirectiveKind &Kind,
+ OpenMPDirectiveKind &PrevMappedDirective,
+ SourceLocation StartLoc, SourceLocation EndLoc,
+ const DeclarationNameInfo &DirName,
+ OpenMPDirectiveKind CancelRegion);
+
public:
/// The declarator \p D defines a function in the scope \p S which is nested
/// in an `omp begin/end declare variant` scope. In this method we create a
@@ -10336,6 +11411,11 @@ public:
return !OMPDeclareVariantScopes.empty();
}
+ ExprResult
+ VerifyPositiveIntegerConstantInClause(Expr *Op, OpenMPClauseKind CKind,
+ bool StrictlyPositive = true,
+ bool SuppressExprDiags = false);
+
/// Given the potential call expression \p Call, determine if there is a
/// specialization via the OpenMP declare variant mechanism available. If
/// there is, return the specialized call expression, otherwise return the
@@ -10376,6 +11456,13 @@ public:
/// constructs.
VarDecl *isOpenMPCapturedDecl(ValueDecl *D, bool CheckScopeInfo = false,
unsigned StopAt = 0);
+
+ /// The member expression(this->fd) needs to be rebuilt in the template
+ /// instantiation to generate private copy for OpenMP when default
+ /// clause is used. The function will return true if default
+ /// cluse is used.
+ bool isOpenMPRebuildMemberExpr(ValueDecl *D);
+
ExprResult getOpenMPCapturedExpr(VarDecl *Capture, ExprValueKind VK,
ExprObjectKind OK, SourceLocation Loc);
@@ -10430,6 +11517,12 @@ public:
/// \param Init First part of the for loop.
void ActOnOpenMPLoopInitialization(SourceLocation ForLoc, Stmt *Init);
+ /// Called on well-formed '\#pragma omp metadirective' after parsing
+ /// of the associated statement.
+ StmtResult ActOnOpenMPMetaDirective(ArrayRef<OMPClause *> Clauses,
+ Stmt *AStmt, SourceLocation StartLoc,
+ SourceLocation EndLoc);
+
// OpenMP directives and clauses.
/// Called on correct id-expression from the '#pragma omp
/// threadprivate'.
@@ -10452,7 +11545,7 @@ public:
/// Called on well-formed '#pragma omp [begin] assume[s]'.
void ActOnOpenMPAssumesDirective(SourceLocation Loc,
OpenMPDirectiveKind DKind,
- ArrayRef<StringRef> Assumptions,
+ ArrayRef<std::string> Assumptions,
bool SkippedClauses);
/// Check if there is an active global `omp begin assumes` directive.
@@ -10510,6 +11603,7 @@ public:
QualType MapperType,
SourceLocation StartLoc,
DeclarationName VN);
+ void ActOnOpenMPIteratorVarDecl(VarDecl *VD);
bool isOpenMPDeclareMapperVarDeclAllowed(const VarDecl *VD) const;
const ValueDecl *getOpenMPDeclareMapperVarName() const;
@@ -10525,6 +11619,10 @@ public:
/// encountered.
void ActOnFinishedOpenMPDeclareTargetContext(DeclareTargetContextInfo &DTCI);
+ /// Report unterminated 'omp declare target' or 'omp begin declare target' at
+ /// the end of a compilation unit.
+ void DiagnoseUnterminatedOpenMPDeclareTarget();
+
/// Searches for the provided declaration name for OpenMP declare target
/// directive.
NamedDecl *lookupOpenMPDeclareTargetName(Scope *CurScope,
@@ -10534,17 +11632,26 @@ 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
checkDeclIsAllowedInOpenMPTarget(Expr *E, Decl *D,
SourceLocation IdLoc = SourceLocation());
+
+ /// Adds OMPDeclareTargetDeclAttr to referenced variables in declare target
+ /// directive.
+ void ActOnOpenMPDeclareTargetInitializer(Decl *D);
+
/// Finishes analysis of the deferred functions calls that may be declared as
/// host/nohost during device/host compilation.
void finalizeOpenMPDelayedAnalysis(const FunctionDecl *Caller,
const FunctionDecl *Callee,
SourceLocation Loc);
+
+ /// Return true if currently in OpenMP task with untied clause context.
+ bool isInOpenMPTaskUntiedContext() const;
+
/// Return true inside OpenMP declare target region.
bool isInOpenMPDeclareTargetContext() const {
return !DeclareTargetNesting.empty();
@@ -10562,6 +11669,11 @@ public:
/// an OpenMP loop directive.
StmtResult ActOnOpenMPCanonicalLoop(Stmt *AStmt);
+ /// Process a canonical OpenMP loop nest that can either be a canonical
+ /// literal loop (ForStmt or CXXForRangeStmt), or the generated loop of an
+ /// OpenMP loop transformation construct.
+ StmtResult ActOnOpenMPLoopnest(Stmt *AStmt);
+
/// End of OpenMP region.
///
/// \param S Statement associated with the current OpenMP region.
@@ -10572,7 +11684,8 @@ public:
StmtResult ActOnOpenMPExecutableDirective(
OpenMPDirectiveKind Kind, const DeclarationNameInfo &DirName,
OpenMPDirectiveKind CancelRegion, ArrayRef<OMPClause *> Clauses,
- Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc);
+ Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc,
+ OpenMPDirectiveKind PrevMappedDirective = llvm::omp::OMPD_unknown);
/// Called on well-formed '\#pragma omp parallel' after parsing
/// of the associated statement.
StmtResult ActOnOpenMPParallelDirective(ArrayRef<OMPClause *> Clauses,
@@ -10618,6 +11731,11 @@ public:
/// associated statement.
StmtResult ActOnOpenMPSectionDirective(Stmt *AStmt, SourceLocation StartLoc,
SourceLocation EndLoc);
+ /// Called on well-formed '\#pragma omp scope' after parsing of the
+ /// associated statement.
+ StmtResult ActOnOpenMPScopeDirective(ArrayRef<OMPClause *> Clauses,
+ Stmt *AStmt, SourceLocation StartLoc,
+ SourceLocation EndLoc);
/// Called on well-formed '\#pragma omp single' after parsing of the
/// associated statement.
StmtResult ActOnOpenMPSingleDirective(ArrayRef<OMPClause *> Clauses,
@@ -10649,6 +11767,12 @@ public:
Stmt *AStmt,
SourceLocation StartLoc,
SourceLocation EndLoc);
+ /// Called on well-formed '\#pragma omp parallel masked' after
+ /// parsing of the associated statement.
+ StmtResult ActOnOpenMPParallelMaskedDirective(ArrayRef<OMPClause *> Clauses,
+ Stmt *AStmt,
+ SourceLocation StartLoc,
+ SourceLocation EndLoc);
/// Called on well-formed '\#pragma omp parallel sections' after
/// parsing of the associated statement.
StmtResult ActOnOpenMPParallelSectionsDirective(ArrayRef<OMPClause *> Clauses,
@@ -10663,11 +11787,19 @@ public:
/// Called on well-formed '\#pragma omp taskyield'.
StmtResult ActOnOpenMPTaskyieldDirective(SourceLocation StartLoc,
SourceLocation EndLoc);
+ /// Called on well-formed '\#pragma omp error'.
+ /// Error direcitive is allowed in both declared and excutable contexts.
+ /// Adding InExContext to identify which context is called from.
+ StmtResult ActOnOpenMPErrorDirective(ArrayRef<OMPClause *> Clauses,
+ SourceLocation StartLoc,
+ SourceLocation EndLoc,
+ bool InExContext = true);
/// Called on well-formed '\#pragma omp barrier'.
StmtResult ActOnOpenMPBarrierDirective(SourceLocation StartLoc,
SourceLocation EndLoc);
/// Called on well-formed '\#pragma omp taskwait'.
- StmtResult ActOnOpenMPTaskwaitDirective(SourceLocation StartLoc,
+ StmtResult ActOnOpenMPTaskwaitDirective(ArrayRef<OMPClause *> Clauses,
+ SourceLocation StartLoc,
SourceLocation EndLoc);
/// Called on well-formed '\#pragma omp taskgroup'.
StmtResult ActOnOpenMPTaskgroupDirective(ArrayRef<OMPClause *> Clauses,
@@ -10733,6 +11865,26 @@ public:
StmtResult ActOnOpenMPTeamsDirective(ArrayRef<OMPClause *> Clauses,
Stmt *AStmt, SourceLocation StartLoc,
SourceLocation EndLoc);
+ /// Called on well-formed '\#pragma omp teams loop' after parsing of the
+ /// associated statement.
+ StmtResult ActOnOpenMPTeamsGenericLoopDirective(
+ ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
+ SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA);
+ /// Called on well-formed '\#pragma omp target teams loop' after parsing of
+ /// the associated statement.
+ StmtResult ActOnOpenMPTargetTeamsGenericLoopDirective(
+ ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
+ SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA);
+ /// Called on well-formed '\#pragma omp parallel loop' after parsing of the
+ /// associated statement.
+ StmtResult ActOnOpenMPParallelGenericLoopDirective(
+ ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
+ SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA);
+ /// Called on well-formed '\#pragma omp target parallel loop' after parsing
+ /// of the associated statement.
+ StmtResult ActOnOpenMPTargetParallelGenericLoopDirective(
+ ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
+ SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA);
/// Called on well-formed '\#pragma omp cancellation point'.
StmtResult
ActOnOpenMPCancellationPointDirective(SourceLocation StartLoc,
@@ -10774,6 +11926,26 @@ public:
StmtResult ActOnOpenMPParallelMasterTaskLoopSimdDirective(
ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA);
+ /// Called on well-formed '\#pragma omp masked taskloop' after parsing of the
+ /// associated statement.
+ StmtResult ActOnOpenMPMaskedTaskLoopDirective(
+ ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
+ SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA);
+ /// Called on well-formed '\#pragma omp masked taskloop simd' after parsing of
+ /// the associated statement.
+ StmtResult ActOnOpenMPMaskedTaskLoopSimdDirective(
+ ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
+ SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA);
+ /// Called on well-formed '\#pragma omp parallel masked taskloop' after
+ /// parsing of the associated statement.
+ StmtResult ActOnOpenMPParallelMaskedTaskLoopDirective(
+ ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
+ SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA);
+ /// Called on well-formed '\#pragma omp parallel masked taskloop simd' after
+ /// parsing of the associated statement.
+ StmtResult ActOnOpenMPParallelMaskedTaskLoopSimdDirective(
+ ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
+ SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA);
/// Called on well-formed '\#pragma omp distribute' after parsing
/// of the associated statement.
StmtResult
@@ -10872,6 +12044,12 @@ public:
Stmt *AStmt, SourceLocation StartLoc,
SourceLocation EndLoc);
+ /// Called on well-formed '\#pragma omp loop' after parsing of the
+ /// associated statement.
+ StmtResult ActOnOpenMPGenericLoopDirective(
+ ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
+ SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA);
+
/// Checks correctness of linear modifiers.
bool CheckOpenMPLinearModifier(OpenMPLinearClauseKind LinKind,
SourceLocation LinLoc);
@@ -10896,11 +12074,15 @@ public:
/// \param VariantRef Expression that references the variant function, which
/// must be used instead of the original one, specified in \p DG.
/// \param TI The trait info object representing the match clause.
- /// \returns None, if the function/variant function are not compatible with
- /// the pragma, pair of original function/variant ref expression otherwise.
- Optional<std::pair<FunctionDecl *, Expr *>>
+ /// \param NumAppendArgs The number of omp_interop_t arguments to account for
+ /// in checking.
+ /// \returns std::nullopt, if the function/variant function are not compatible
+ /// with the pragma, pair of original function/variant ref expression
+ /// otherwise.
+ std::optional<std::pair<FunctionDecl *, Expr *>>
checkOpenMPDeclareVariantFunction(DeclGroupPtrTy DG, Expr *VariantRef,
- OMPTraitInfo &TI, SourceRange SR);
+ OMPTraitInfo &TI, unsigned NumAppendArgs,
+ SourceRange SR);
/// Called on well-formed '\#pragma omp declare variant' after parsing of
/// the associated method/function.
@@ -10909,8 +12091,18 @@ public:
/// \param VariantRef Expression that references the variant function, which
/// must be used instead of the original one, specified in \p DG.
/// \param TI The context traits associated with the function variant.
- void ActOnOpenMPDeclareVariantDirective(FunctionDecl *FD, Expr *VariantRef,
- OMPTraitInfo &TI, SourceRange SR);
+ /// \param AdjustArgsNothing The list of 'nothing' arguments.
+ /// \param AdjustArgsNeedDevicePtr The list of 'need_device_ptr' arguments.
+ /// \param AppendArgs The list of 'append_args' arguments.
+ /// \param AdjustArgsLoc The Location of an 'adjust_args' clause.
+ /// \param AppendArgsLoc The Location of an 'append_args' clause.
+ /// \param SR The SourceRange of the 'declare variant' directive.
+ void ActOnOpenMPDeclareVariantDirective(
+ FunctionDecl *FD, Expr *VariantRef, OMPTraitInfo &TI,
+ ArrayRef<Expr *> AdjustArgsNothing,
+ ArrayRef<Expr *> AdjustArgsNeedDevicePtr,
+ ArrayRef<OMPInteropInfo> AppendArgs, SourceLocation AdjustArgsLoc,
+ SourceLocation AppendArgsLoc, SourceRange SR);
OMPClause *ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind,
Expr *Expr,
@@ -10938,6 +12130,10 @@ public:
SourceLocation StartLoc,
SourceLocation LParenLoc,
SourceLocation EndLoc);
+ /// Called on well-formed 'align' clause.
+ OMPClause *ActOnOpenMPAlignClause(Expr *Alignment, SourceLocation StartLoc,
+ SourceLocation LParenLoc,
+ SourceLocation EndLoc);
/// Called on well-formed 'safelen' clause.
OMPClause *ActOnOpenMPSafelenClause(Expr *Length,
SourceLocation StartLoc,
@@ -10970,12 +12166,16 @@ public:
SourceLocation LParenLoc = SourceLocation(),
Expr *NumForLoops = nullptr);
/// Called on well-formed 'grainsize' clause.
- OMPClause *ActOnOpenMPGrainsizeClause(Expr *Size, SourceLocation StartLoc,
+ OMPClause *ActOnOpenMPGrainsizeClause(OpenMPGrainsizeClauseModifier Modifier,
+ Expr *Size, SourceLocation StartLoc,
SourceLocation LParenLoc,
+ SourceLocation ModifierLoc,
SourceLocation EndLoc);
/// Called on well-formed 'num_tasks' clause.
- OMPClause *ActOnOpenMPNumTasksClause(Expr *NumTasks, SourceLocation StartLoc,
+ OMPClause *ActOnOpenMPNumTasksClause(OpenMPNumTasksClauseModifier Modifier,
+ Expr *NumTasks, SourceLocation StartLoc,
SourceLocation LParenLoc,
+ SourceLocation ModifierLoc,
SourceLocation EndLoc);
/// Called on well-formed 'hint' clause.
OMPClause *ActOnOpenMPHintClause(Expr *Hint, SourceLocation StartLoc,
@@ -10992,6 +12192,10 @@ public:
SourceLocation StartLoc,
SourceLocation LParenLoc,
SourceLocation EndLoc);
+ /// Called on well-formed 'when' clause.
+ OMPClause *ActOnOpenMPWhenClause(OMPTraitInfo &TI, SourceLocation StartLoc,
+ SourceLocation LParenLoc,
+ SourceLocation EndLoc);
/// Called on well-formed 'default' clause.
OMPClause *ActOnOpenMPDefaultClause(llvm::omp::DefaultKind Kind,
SourceLocation KindLoc,
@@ -11005,10 +12209,11 @@ public:
SourceLocation LParenLoc,
SourceLocation EndLoc);
/// Called on well-formed 'order' clause.
- OMPClause *ActOnOpenMPOrderClause(OpenMPOrderClauseKind Kind,
- SourceLocation KindLoc,
+ OMPClause *ActOnOpenMPOrderClause(OpenMPOrderClauseModifier Modifier,
+ OpenMPOrderClauseKind Kind,
SourceLocation StartLoc,
SourceLocation LParenLoc,
+ SourceLocation MLoc, SourceLocation KindLoc,
SourceLocation EndLoc);
/// Called on well-formed 'update' clause.
OMPClause *ActOnOpenMPUpdateClause(OpenMPDependClauseKind Kind,
@@ -11052,6 +12257,16 @@ public:
/// Called on well-formed 'capture' clause.
OMPClause *ActOnOpenMPCaptureClause(SourceLocation StartLoc,
SourceLocation EndLoc);
+ /// Called on well-formed 'compare' clause.
+ OMPClause *ActOnOpenMPCompareClause(SourceLocation StartLoc,
+ SourceLocation EndLoc);
+ /// Called on well-formed 'fail' clause.
+ OMPClause *ActOnOpenMPFailClause(SourceLocation StartLoc,
+ SourceLocation EndLoc);
+ OMPClause *ActOnOpenMPFailClause(
+ OpenMPClauseKind Kind, SourceLocation KindLoc,
+ SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc);
+
/// Called on well-formed 'seq_cst' clause.
OMPClause *ActOnOpenMPSeqCstClause(SourceLocation StartLoc,
SourceLocation EndLoc);
@@ -11069,12 +12284,10 @@ public:
SourceLocation EndLoc);
/// Called on well-formed 'init' clause.
- OMPClause *ActOnOpenMPInitClause(Expr *InteropVar, ArrayRef<Expr *> PrefExprs,
- bool IsTarget, bool IsTargetSync,
- SourceLocation StartLoc,
- SourceLocation LParenLoc,
- SourceLocation VarLoc,
- SourceLocation EndLoc);
+ OMPClause *
+ ActOnOpenMPInitClause(Expr *InteropVar, OMPInteropInfo &InteropInfo,
+ SourceLocation StartLoc, SourceLocation LParenLoc,
+ SourceLocation VarLoc, SourceLocation EndLoc);
/// Called on well-formed 'use' clause.
OMPClause *ActOnOpenMPUseClause(Expr *InteropVar, SourceLocation StartLoc,
@@ -11130,16 +12343,54 @@ public:
OpenMPAtomicDefaultMemOrderClauseKind Kind, SourceLocation KindLoc,
SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc);
- OMPClause *ActOnOpenMPVarListClause(
- OpenMPClauseKind Kind, ArrayRef<Expr *> Vars, Expr *DepModOrTailExpr,
- const OMPVarListLocTy &Locs, SourceLocation ColonLoc,
- CXXScopeSpec &ReductionOrMapperIdScopeSpec,
- DeclarationNameInfo &ReductionOrMapperId, int ExtraModifier,
- ArrayRef<OpenMPMapModifierKind> MapTypeModifiers,
- ArrayRef<SourceLocation> MapTypeModifiersLoc, bool IsMapTypeImplicit,
- SourceLocation ExtraModifierLoc,
- ArrayRef<OpenMPMotionModifierKind> MotionModifiers,
- ArrayRef<SourceLocation> MotionModifiersLoc);
+ /// Called on well-formed 'at' clause.
+ OMPClause *ActOnOpenMPAtClause(OpenMPAtClauseKind Kind,
+ SourceLocation KindLoc,
+ SourceLocation StartLoc,
+ SourceLocation LParenLoc,
+ SourceLocation EndLoc);
+
+ /// Called on well-formed 'severity' clause.
+ OMPClause *ActOnOpenMPSeverityClause(OpenMPSeverityClauseKind Kind,
+ SourceLocation KindLoc,
+ SourceLocation StartLoc,
+ SourceLocation LParenLoc,
+ SourceLocation EndLoc);
+
+ /// Called on well-formed 'message' clause.
+ /// passing string for message.
+ OMPClause *ActOnOpenMPMessageClause(Expr *MS, SourceLocation StartLoc,
+ SourceLocation LParenLoc,
+ SourceLocation EndLoc);
+
+ /// Data used for processing a list of variables in OpenMP clauses.
+ struct OpenMPVarListDataTy final {
+ Expr *DepModOrTailExpr = nullptr;
+ Expr *IteratorExpr = nullptr;
+ SourceLocation ColonLoc;
+ SourceLocation RLoc;
+ CXXScopeSpec ReductionOrMapperIdScopeSpec;
+ DeclarationNameInfo ReductionOrMapperId;
+ int ExtraModifier = -1; ///< Additional modifier for linear, map, depend or
+ ///< lastprivate clause.
+ SmallVector<OpenMPMapModifierKind, NumberOfOMPMapClauseModifiers>
+ MapTypeModifiers;
+ SmallVector<SourceLocation, NumberOfOMPMapClauseModifiers>
+ MapTypeModifiersLoc;
+ SmallVector<OpenMPMotionModifierKind, NumberOfOMPMotionModifiers>
+ MotionModifiers;
+ SmallVector<SourceLocation, NumberOfOMPMotionModifiers> MotionModifiersLoc;
+ bool IsMapTypeImplicit = false;
+ SourceLocation ExtraModifierLoc;
+ SourceLocation OmpAllMemoryLoc;
+ SourceLocation
+ StepModifierLoc; /// 'step' modifier location for linear clause
+ };
+
+ OMPClause *ActOnOpenMPVarListClause(OpenMPClauseKind Kind,
+ ArrayRef<Expr *> Vars,
+ const OMPVarListLocTy &Locs,
+ OpenMPVarListDataTy &Data);
/// Called on well-formed 'inclusive' clause.
OMPClause *ActOnOpenMPInclusiveClause(ArrayRef<Expr *> VarList,
SourceLocation StartLoc,
@@ -11182,27 +12433,27 @@ public:
SourceLocation ModifierLoc, SourceLocation ColonLoc,
SourceLocation EndLoc, CXXScopeSpec &ReductionIdScopeSpec,
const DeclarationNameInfo &ReductionId,
- ArrayRef<Expr *> UnresolvedReductions = llvm::None);
+ ArrayRef<Expr *> UnresolvedReductions = std::nullopt);
/// Called on well-formed 'task_reduction' clause.
OMPClause *ActOnOpenMPTaskReductionClause(
ArrayRef<Expr *> VarList, SourceLocation StartLoc,
SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc,
CXXScopeSpec &ReductionIdScopeSpec,
const DeclarationNameInfo &ReductionId,
- ArrayRef<Expr *> UnresolvedReductions = llvm::None);
+ ArrayRef<Expr *> UnresolvedReductions = std::nullopt);
/// Called on well-formed 'in_reduction' clause.
OMPClause *ActOnOpenMPInReductionClause(
ArrayRef<Expr *> VarList, SourceLocation StartLoc,
SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc,
CXXScopeSpec &ReductionIdScopeSpec,
const DeclarationNameInfo &ReductionId,
- ArrayRef<Expr *> UnresolvedReductions = llvm::None);
+ ArrayRef<Expr *> UnresolvedReductions = std::nullopt);
/// Called on well-formed 'linear' clause.
- OMPClause *
- ActOnOpenMPLinearClause(ArrayRef<Expr *> VarList, Expr *Step,
- SourceLocation StartLoc, SourceLocation LParenLoc,
- OpenMPLinearClauseKind LinKind, SourceLocation LinLoc,
- SourceLocation ColonLoc, SourceLocation EndLoc);
+ OMPClause *ActOnOpenMPLinearClause(
+ ArrayRef<Expr *> VarList, Expr *Step, SourceLocation StartLoc,
+ SourceLocation LParenLoc, OpenMPLinearClauseKind LinKind,
+ SourceLocation LinLoc, SourceLocation ColonLoc,
+ SourceLocation StepModifierLoc, SourceLocation EndLoc);
/// Called on well-formed 'aligned' clause.
OMPClause *ActOnOpenMPAlignedClause(ArrayRef<Expr *> VarList,
Expr *Alignment,
@@ -11230,11 +12481,12 @@ public:
SourceLocation LParenLoc,
SourceLocation EndLoc);
/// Called on well-formed 'depend' clause.
- OMPClause *
- ActOnOpenMPDependClause(Expr *DepModifier, OpenMPDependClauseKind DepKind,
- SourceLocation DepLoc, SourceLocation ColonLoc,
- ArrayRef<Expr *> VarList, SourceLocation StartLoc,
- SourceLocation LParenLoc, SourceLocation EndLoc);
+ OMPClause *ActOnOpenMPDependClause(const OMPDependClause::DependDataTy &Data,
+ Expr *DepModifier,
+ ArrayRef<Expr *> VarList,
+ SourceLocation StartLoc,
+ SourceLocation LParenLoc,
+ SourceLocation EndLoc);
/// Called on well-formed 'device' clause.
OMPClause *ActOnOpenMPDeviceClause(OpenMPDeviceClauseModifier Modifier,
Expr *Device, SourceLocation StartLoc,
@@ -11242,15 +12494,14 @@ public:
SourceLocation ModifierLoc,
SourceLocation EndLoc);
/// Called on well-formed 'map' clause.
- OMPClause *
- ActOnOpenMPMapClause(ArrayRef<OpenMPMapModifierKind> MapTypeModifiers,
- ArrayRef<SourceLocation> MapTypeModifiersLoc,
- CXXScopeSpec &MapperIdScopeSpec,
- DeclarationNameInfo &MapperId,
- OpenMPMapClauseKind MapType, bool IsMapTypeImplicit,
- SourceLocation MapLoc, SourceLocation ColonLoc,
- ArrayRef<Expr *> VarList, const OMPVarListLocTy &Locs,
- ArrayRef<Expr *> UnresolvedMappers = llvm::None);
+ OMPClause *ActOnOpenMPMapClause(
+ Expr *IteratorModifier, ArrayRef<OpenMPMapModifierKind> MapTypeModifiers,
+ ArrayRef<SourceLocation> MapTypeModifiersLoc,
+ CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId,
+ OpenMPMapClauseKind MapType, bool IsMapTypeImplicit,
+ SourceLocation MapLoc, SourceLocation ColonLoc, ArrayRef<Expr *> VarList,
+ const OMPVarListLocTy &Locs, bool NoDiagnose = false,
+ ArrayRef<Expr *> UnresolvedMappers = std::nullopt);
/// Called on well-formed 'num_teams' clause.
OMPClause *ActOnOpenMPNumTeamsClause(Expr *NumTeams, SourceLocation StartLoc,
SourceLocation LParenLoc,
@@ -11281,7 +12532,7 @@ public:
CXXScopeSpec &MapperIdScopeSpec,
DeclarationNameInfo &MapperId, SourceLocation ColonLoc,
ArrayRef<Expr *> VarList, const OMPVarListLocTy &Locs,
- ArrayRef<Expr *> UnresolvedMappers = llvm::None);
+ ArrayRef<Expr *> UnresolvedMappers = std::nullopt);
/// Called on well-formed 'from' clause.
OMPClause *
ActOnOpenMPFromClause(ArrayRef<OpenMPMotionModifierKind> MotionModifiers,
@@ -11289,7 +12540,7 @@ public:
CXXScopeSpec &MapperIdScopeSpec,
DeclarationNameInfo &MapperId, SourceLocation ColonLoc,
ArrayRef<Expr *> VarList, const OMPVarListLocTy &Locs,
- ArrayRef<Expr *> UnresolvedMappers = llvm::None);
+ ArrayRef<Expr *> UnresolvedMappers = std::nullopt);
/// Called on well-formed 'use_device_ptr' clause.
OMPClause *ActOnOpenMPUseDevicePtrClause(ArrayRef<Expr *> VarList,
const OMPVarListLocTy &Locs);
@@ -11299,6 +12550,9 @@ public:
/// Called on well-formed 'is_device_ptr' clause.
OMPClause *ActOnOpenMPIsDevicePtrClause(ArrayRef<Expr *> VarList,
const OMPVarListLocTy &Locs);
+ /// Called on well-formed 'has_device_addr' clause.
+ OMPClause *ActOnOpenMPHasDeviceAddrClause(ArrayRef<Expr *> VarList,
+ const OMPVarListLocTy &Locs);
/// Called on well-formed 'nontemporal' clause.
OMPClause *ActOnOpenMPNontemporalClause(ArrayRef<Expr *> VarList,
SourceLocation StartLoc,
@@ -11325,6 +12579,34 @@ public:
SourceLocation ColonLoc,
SourceLocation EndLoc, Expr *Modifier,
ArrayRef<Expr *> Locators);
+ /// Called on a well-formed 'bind' clause.
+ OMPClause *ActOnOpenMPBindClause(OpenMPBindClauseKind Kind,
+ SourceLocation KindLoc,
+ SourceLocation StartLoc,
+ SourceLocation LParenLoc,
+ SourceLocation EndLoc);
+
+ /// Called on a well-formed 'ompx_dyn_cgroup_mem' clause.
+ OMPClause *ActOnOpenMPXDynCGroupMemClause(Expr *Size, SourceLocation StartLoc,
+ SourceLocation LParenLoc,
+ SourceLocation EndLoc);
+
+ /// Called on well-formed 'doacross' clause.
+ OMPClause *
+ ActOnOpenMPDoacrossClause(OpenMPDoacrossClauseModifier DepType,
+ SourceLocation DepLoc, SourceLocation ColonLoc,
+ ArrayRef<Expr *> VarList, SourceLocation StartLoc,
+ SourceLocation LParenLoc, SourceLocation EndLoc);
+
+ /// Called on a well-formed 'ompx_attribute' clause.
+ OMPClause *ActOnOpenMPXAttributeClause(ArrayRef<const Attr *> Attrs,
+ SourceLocation StartLoc,
+ SourceLocation LParenLoc,
+ SourceLocation EndLoc);
+
+ /// Called on a well-formed 'ompx_bare' clause.
+ OMPClause *ActOnOpenMPXBareClause(SourceLocation StartLoc,
+ SourceLocation EndLoc);
/// The kind of conversion being performed.
enum CheckedConversionKind {
@@ -11508,6 +12790,12 @@ public:
/// extension.
IncompatibleFunctionPointer,
+ /// IncompatibleFunctionPointerStrict - The assignment is between two
+ /// function pointer types that are not identical, but are compatible,
+ /// unless compiled with -fsanitize=cfi, in which case the type mismatch
+ /// may trip an indirect call runtime check.
+ IncompatibleFunctionPointerStrict,
+
/// IncompatiblePointerSign - The assignment is between two pointers types
/// which point to integers which have a different sign, but are otherwise
/// identical. This is a subset of the above, but broken out because it's by
@@ -11680,7 +12968,8 @@ public:
// For simple assignment, pass both expressions and a null converted type.
// For compound assignment, pass both expressions and the converted type.
QualType CheckAssignmentOperands( // C99 6.5.16.[1,2]
- Expr *LHSExpr, ExprResult &RHS, SourceLocation Loc, QualType CompoundType);
+ Expr *LHSExpr, ExprResult &RHS, SourceLocation Loc, QualType CompoundType,
+ BinaryOperatorKind Opc);
ExprResult checkPseudoObjectIncDec(Scope *S, SourceLocation OpLoc,
UnaryOperatorKind Opcode, Expr *Op);
@@ -11699,6 +12988,10 @@ public:
QualType CheckVectorConditionalTypes(ExprResult &Cond, ExprResult &LHS,
ExprResult &RHS,
SourceLocation QuestionLoc);
+
+ QualType CheckSizelessVectorConditionalTypes(ExprResult &Cond,
+ ExprResult &LHS, ExprResult &RHS,
+ SourceLocation QuestionLoc);
QualType FindCompositePointerType(SourceLocation Loc, Expr *&E1, Expr *&E2,
bool ConvertArgs = true);
QualType FindCompositePointerType(SourceLocation Loc,
@@ -11715,7 +13008,7 @@ public:
QualType FindCompositeObjCPointerType(ExprResult &LHS, ExprResult &RHS,
SourceLocation QuestionLoc);
- bool DiagnoseConditionalForNull(Expr *LHSExpr, Expr *RHSExpr,
+ bool DiagnoseConditionalForNull(const Expr *LHSExpr, const Expr *RHSExpr,
SourceLocation QuestionLoc);
void DiagnoseAlwaysNonNullPointer(Expr *E,
@@ -11725,14 +13018,24 @@ public:
/// type checking for vector binary operators.
QualType CheckVectorOperands(ExprResult &LHS, ExprResult &RHS,
SourceLocation Loc, bool IsCompAssign,
- bool AllowBothBool, bool AllowBoolConversion);
+ bool AllowBothBool, bool AllowBoolConversion,
+ bool AllowBoolOperation, bool ReportInvalid);
QualType GetSignedVectorType(QualType V);
+ QualType GetSignedSizelessVectorType(QualType V);
QualType CheckVectorCompareOperands(ExprResult &LHS, ExprResult &RHS,
SourceLocation Loc,
BinaryOperatorKind Opc);
+ QualType CheckSizelessVectorCompareOperands(ExprResult &LHS, ExprResult &RHS,
+ SourceLocation Loc,
+ BinaryOperatorKind Opc);
QualType CheckVectorLogicalOperands(ExprResult &LHS, ExprResult &RHS,
SourceLocation Loc);
+ // type checking for sizeless vector binary operators.
+ QualType CheckSizelessVectorOperands(ExprResult &LHS, ExprResult &RHS,
+ SourceLocation Loc, bool IsCompAssign,
+ ArithConvKind OperationKind);
+
/// Type checking for matrix binary operators.
QualType CheckMatrixElementwiseOperands(ExprResult &LHS, ExprResult &RHS,
SourceLocation Loc,
@@ -11741,12 +13044,14 @@ public:
SourceLocation Loc, bool IsCompAssign);
bool isValidSveBitcast(QualType srcType, QualType destType);
+ bool isValidRVVBitcast(QualType srcType, QualType destType);
bool areMatrixTypesOfTheSameDimension(QualType srcTy, QualType destTy);
bool areVectorTypesSameSize(QualType srcType, QualType destType);
bool areLaxCompatibleVectorTypes(QualType srcType, QualType destType);
bool isLaxVectorConversion(QualType srcType, QualType destType);
+ bool anyAltivecTypes(QualType srcType, QualType destType);
/// type checking declaration initializers (C99 6.7.8)
bool CheckForConstantInitializer(Expr *e, QualType t);
@@ -11898,20 +13203,22 @@ public:
Decl *ConditionVar;
FullExprArg Condition;
bool Invalid;
- bool HasKnownValue;
- bool KnownValue;
+ std::optional<bool> KnownValue;
friend class Sema;
ConditionResult(Sema &S, Decl *ConditionVar, FullExprArg Condition,
bool IsConstexpr)
- : ConditionVar(ConditionVar), Condition(Condition), Invalid(false),
- HasKnownValue(IsConstexpr && Condition.get() &&
- !Condition.get()->isValueDependent()),
- KnownValue(HasKnownValue &&
- !!Condition.get()->EvaluateKnownConstInt(S.Context)) {}
+ : ConditionVar(ConditionVar), Condition(Condition), Invalid(false) {
+ if (IsConstexpr && Condition.get()) {
+ if (std::optional<llvm::APSInt> Val =
+ Condition.get()->getIntegerConstantExpr(S.Context)) {
+ KnownValue = !!(*Val);
+ }
+ }
+ }
explicit ConditionResult(bool Invalid)
: ConditionVar(nullptr), Condition(nullptr), Invalid(Invalid),
- HasKnownValue(false), KnownValue(false) {}
+ KnownValue(std::nullopt) {}
public:
ConditionResult() : ConditionResult(false) {}
@@ -11920,11 +13227,7 @@ public:
return std::make_pair(cast_or_null<VarDecl>(ConditionVar),
Condition.get());
}
- llvm::Optional<bool> getKnownValue() const {
- if (!HasKnownValue)
- return None;
- return KnownValue;
- }
+ std::optional<bool> getKnownValue() const { return KnownValue; }
};
static ConditionResult ConditionError() { return ConditionResult(true); }
@@ -11933,9 +13236,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,
@@ -11978,13 +13284,6 @@ public:
/// CheckCXXBooleanCondition - Returns true if conversion to bool is invalid.
ExprResult CheckCXXBooleanCondition(Expr *CondExpr, bool IsConstexpr = false);
- /// ConvertIntegerToTypeWarnOnOverflow - Convert the specified APInt to have
- /// the specified width and sign. If an overflow occurs, detect it and emit
- /// the specified diagnostic.
- void ConvertIntegerToTypeWarnOnOverflow(llvm::APSInt &OldVal,
- unsigned NewWidth, bool NewSign,
- SourceLocation Loc, unsigned DiagID);
-
/// Checks that the Objective-C declaration is declared in the global scope.
/// Emits an error and marks the declaration as invalid if it's not declared
/// in the global scope.
@@ -12031,10 +13330,8 @@ public:
/// VerifyBitField - verifies that a bit field expression is an ICE and has
/// the correct width, and that the field type is valid.
/// Returns false on success.
- /// Can optionally return whether the bit-field is of width 0
ExprResult VerifyBitField(SourceLocation FieldLoc, IdentifierInfo *FieldName,
- QualType FieldTy, bool IsMsStruct,
- Expr *BitWidth, bool *ZeroWidth = nullptr);
+ QualType FieldTy, bool IsMsStruct, Expr *BitWidth);
private:
unsigned ForceCUDAHostDeviceDepth = 0;
@@ -12053,14 +13350,14 @@ public:
/// Diagnostics that are emitted only if we discover that the given function
/// must be codegen'ed. Because handling these correctly adds overhead to
/// compilation, this is currently only enabled for CUDA compilations.
- llvm::DenseMap<CanonicalDeclPtr<FunctionDecl>,
+ llvm::DenseMap<CanonicalDeclPtr<const FunctionDecl>,
std::vector<PartialDiagnosticAt>>
DeviceDeferredDiags;
/// A pair of a canonical FunctionDecl and a SourceLocation. When used as the
/// key in a hashtable, both the FD and location are hashed.
struct FunctionDeclAndLoc {
- CanonicalDeclPtr<FunctionDecl> FD;
+ CanonicalDeclPtr<const FunctionDecl> FD;
SourceLocation Loc;
};
@@ -12074,7 +13371,7 @@ public:
///
/// Functions that we can tell a priori must be emitted aren't added to this
/// map.
- llvm::DenseMap</* Callee = */ CanonicalDeclPtr<FunctionDecl>,
+ llvm::DenseMap</* Callee = */ CanonicalDeclPtr<const FunctionDecl>,
/* Caller = */ FunctionDeclAndLoc>
DeviceKnownEmittedFns;
@@ -12119,8 +13416,9 @@ public:
/// if (diagIfOpenMPDeviceCode(Loc, diag::err_vla_unsupported))
/// return ExprError();
/// // Otherwise, continue parsing as normal.
- SemaDiagnosticBuilder
- diagIfOpenMPDeviceCode(SourceLocation Loc, unsigned DiagID, FunctionDecl *FD);
+ SemaDiagnosticBuilder diagIfOpenMPDeviceCode(SourceLocation Loc,
+ unsigned DiagID,
+ const FunctionDecl *FD);
/// Creates a SemaDiagnosticBuilder that emits the diagnostic if the current
/// context is "used as host code".
@@ -12136,27 +13434,20 @@ public:
/// return ExprError();
/// // Otherwise, continue parsing as normal.
SemaDiagnosticBuilder diagIfOpenMPHostCode(SourceLocation Loc,
- unsigned DiagID, FunctionDecl *FD);
+ unsigned DiagID,
+ const FunctionDecl *FD);
SemaDiagnosticBuilder targetDiag(SourceLocation Loc, unsigned DiagID,
- FunctionDecl *FD = nullptr);
+ const FunctionDecl *FD = nullptr);
SemaDiagnosticBuilder targetDiag(SourceLocation Loc,
const PartialDiagnostic &PD,
- FunctionDecl *FD = nullptr) {
+ const FunctionDecl *FD = nullptr) {
return targetDiag(Loc, PD.getDiagID(), FD) << PD;
}
- /// Check if the expression is allowed to be used in expressions for the
- /// offloading devices.
- void checkDeviceDecl(ValueDecl *D, SourceLocation Loc);
-
- enum CUDAFunctionTarget {
- CFT_Device,
- CFT_Global,
- CFT_Host,
- CFT_HostDevice,
- CFT_InvalidTarget
- };
+ /// Check if the type is allowed to be used for the current target.
+ void checkTypeSupport(QualType Ty, SourceLocation Loc,
+ ValueDecl *D = nullptr);
/// Determines whether the given function is a CUDA device/host/kernel/etc.
/// function.
@@ -12176,6 +13467,29 @@ public:
/// Determines whether the given variable is emitted on host or device side.
CUDAVariableTarget IdentifyCUDATarget(const VarDecl *D);
+ /// Defines kinds of CUDA global host/device context where a function may be
+ /// called.
+ enum CUDATargetContextKind {
+ CTCK_Unknown, /// Unknown context
+ CTCK_InitGlobalVar, /// Function called during global variable
+ /// initialization
+ };
+
+ /// Define the current global CUDA host/device context where a function may be
+ /// called. Only used when a function is called outside of any functions.
+ struct CUDATargetContext {
+ CUDAFunctionTarget Target = CFT_HostDevice;
+ CUDATargetContextKind Kind = CTCK_Unknown;
+ Decl *D = nullptr;
+ } CurCUDATargetCtx;
+
+ struct CUDATargetContextRAII {
+ Sema &S;
+ CUDATargetContext SavedCtx;
+ CUDATargetContextRAII(Sema &S_, CUDATargetContextKind K, Decl *D);
+ ~CUDATargetContextRAII() { S.CurCUDATargetCtx = SavedCtx; }
+ };
+
/// Gets the CUDA target for the current context.
CUDAFunctionTarget CurrentCUDATarget() {
return IdentifyCUDATarget(dyn_cast<FunctionDecl>(CurContext));
@@ -12251,6 +13565,10 @@ public:
/// host or device attribute.
void CUDASetLambdaAttrs(CXXMethodDecl *Method);
+ /// Record \p FD if it is a CUDA/HIP implicit host device function used on
+ /// device side in device compilation.
+ void CUDARecordImplicitHostDeviceFuncUsedByDevice(const FunctionDecl *FD);
+
/// Finds a function in \p Matches with highest calling priority
/// from \p Caller context and erases all functions with lower
/// calling priority.
@@ -12347,7 +13665,9 @@ public:
PCC_ParenthesizedExpression,
/// Code completion occurs within a sequence of declaration
/// specifiers within a function, method, or block.
- PCC_LocalDeclarationSpecifiers
+ PCC_LocalDeclarationSpecifiers,
+ /// Code completion occurs at top-level in a REPL session
+ PCC_TopLevelOrExpression,
};
void CodeCompleteModuleImport(SourceLocation ImportLoc, ModuleIdPath Path);
@@ -12374,6 +13694,15 @@ public:
const VirtSpecifiers *VS = nullptr);
void CodeCompleteBracketDeclarator(Scope *S);
void CodeCompleteCase(Scope *S);
+ enum class AttributeCompletion {
+ Attribute,
+ Scope,
+ None,
+ };
+ void CodeCompleteAttribute(
+ AttributeCommonInfo::Syntax Syntax,
+ AttributeCompletion Completion = AttributeCompletion::Attribute,
+ const IdentifierInfo *Scope = nullptr);
/// Determines the preferred type of the current function argument, by
/// examining the signatures of all possible overloads.
/// Returns null if unknown or ambiguous, or if code completion is off.
@@ -12382,18 +13711,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
@@ -12448,6 +13777,7 @@ public:
ArrayRef<IdentifierLocPair> Protocols);
void CodeCompleteObjCProtocolDecl(Scope *S);
void CodeCompleteObjCInterfaceDecl(Scope *S);
+ void CodeCompleteObjCClassForwardDecl(Scope *S);
void CodeCompleteObjCSuperclass(Scope *S,
IdentifierInfo *ClassName,
SourceLocation ClassNameLoc);
@@ -12461,7 +13791,8 @@ public:
void CodeCompleteObjCPropertyDefinition(Scope *S);
void CodeCompleteObjCPropertySynthesizeIvar(Scope *S,
IdentifierInfo *PropertyName);
- void CodeCompleteObjCMethodDecl(Scope *S, Optional<bool> IsInstanceMethod,
+ void CodeCompleteObjCMethodDecl(Scope *S,
+ std::optional<bool> IsInstanceMethod,
ParsedType ReturnType);
void CodeCompleteObjCMethodDeclSelector(Scope *S,
bool IsInstanceMethod,
@@ -12494,21 +13825,29 @@ public:
SourceLocation getLocationOfStringLiteralByte(const StringLiteral *SL,
unsigned ByteNo) const;
-private:
- void CheckArrayAccess(const Expr *BaseExpr, const Expr *IndexExpr,
- const ArraySubscriptExpr *ASE=nullptr,
- bool AllowOnePastEnd=true, bool IndexNegated=false);
- void CheckArrayAccess(const Expr *E);
+ enum FormatArgumentPassingKind {
+ FAPK_Fixed, // values to format are fixed (no C-style variadic arguments)
+ FAPK_Variadic, // values to format are passed as variadic arguments
+ FAPK_VAList, // values to format are passed in a va_list
+ };
+
// Used to grab the relevant information from a FormatAttr and a
// FunctionDeclaration.
struct FormatStringInfo {
unsigned FormatIdx;
unsigned FirstDataArg;
- bool HasVAListArg;
+ FormatArgumentPassingKind ArgPassingKind;
};
static bool getFormatStringInfo(const FormatAttr *Format, bool IsCXXMember,
- FormatStringInfo *FSI);
+ bool IsVariadic, FormatStringInfo *FSI);
+
+private:
+ void CheckArrayAccess(const Expr *BaseExpr, const Expr *IndexExpr,
+ const ArraySubscriptExpr *ASE = nullptr,
+ bool AllowOnePastEnd = true, bool IndexNegated = false);
+ void CheckArrayAccess(const Expr *E);
+
bool CheckFunctionCall(FunctionDecl *FDecl, CallExpr *TheCall,
const FunctionProtoType *Proto);
bool CheckObjCMethodCall(ObjCMethodDecl *Method, SourceLocation loc,
@@ -12520,6 +13859,8 @@ private:
ArrayRef<const Expr *> Args,
const FunctionProtoType *Proto, SourceLocation Loc);
+ void checkAIXMemberAlignment(SourceLocation Loc, const Expr *Arg);
+
void CheckArgAlignment(SourceLocation Loc, NamedDecl *FDecl,
StringRef ParamName, QualType ArgTy, QualType ParamTy);
@@ -12545,6 +13886,9 @@ private:
CallExpr *TheCall);
bool CheckMVEBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall);
bool CheckSVEBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall);
+ bool ParseSVEImmChecks(CallExpr *TheCall,
+ SmallVector<std::tuple<int, int, int>, 3> &ImmChecks);
+ bool CheckSMEBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall);
bool CheckCDEBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID,
CallExpr *TheCall);
bool CheckARMCoprocessorImmediate(const TargetInfo &TI, const Expr *CoprocArg,
@@ -12579,11 +13923,20 @@ private:
bool CheckRISCVLMUL(CallExpr *TheCall, unsigned ArgNum);
bool CheckRISCVBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID,
CallExpr *TheCall);
+ void checkRVVTypeSupport(QualType Ty, SourceLocation Loc, Decl *D);
+ bool CheckLoongArchBuiltinFunctionCall(const TargetInfo &TI,
+ unsigned BuiltinID, CallExpr *TheCall);
+ bool CheckWebAssemblyBuiltinFunctionCall(const TargetInfo &TI,
+ unsigned BuiltinID,
+ CallExpr *TheCall);
+ bool CheckNVPTXBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID,
+ CallExpr *TheCall);
bool SemaBuiltinVAStart(unsigned BuiltinID, CallExpr *TheCall);
bool SemaBuiltinVAStartARMMicrosoft(CallExpr *Call);
- bool SemaBuiltinUnorderedCompare(CallExpr *TheCall);
- bool SemaBuiltinFPClassification(CallExpr *TheCall, unsigned NumArgs);
+ bool SemaBuiltinUnorderedCompare(CallExpr *TheCall, unsigned BuiltinID);
+ bool SemaBuiltinFPClassification(CallExpr *TheCall, unsigned NumArgs,
+ unsigned BuiltinID);
bool SemaBuiltinComplex(CallExpr *TheCall);
bool SemaBuiltinVSX(CallExpr *TheCall);
bool SemaBuiltinOSLogFormat(CallExpr *TheCall);
@@ -12625,10 +13978,18 @@ private:
int ArgNum, unsigned ExpectedFieldNum,
bool AllowName);
bool SemaBuiltinARMMemoryTaggingCall(unsigned BuiltinID, CallExpr *TheCall);
- bool SemaBuiltinPPCMMACall(CallExpr *TheCall, const char *TypeDesc);
+ bool SemaBuiltinPPCMMACall(CallExpr *TheCall, unsigned BuiltinID,
+ const char *TypeDesc);
bool CheckPPCMMAType(QualType Type, SourceLocation TypeLoc);
+ bool SemaBuiltinElementwiseMath(CallExpr *TheCall);
+ bool SemaBuiltinElementwiseTernaryMath(CallExpr *TheCall);
+ bool PrepareBuiltinElementwiseMathOneArgCall(CallExpr *TheCall);
+ bool PrepareBuiltinReduceMathOneArgCall(CallExpr *TheCall);
+
+ bool SemaBuiltinNonDeterministicValue(CallExpr *TheCall);
+
// Matrix builtin handling.
ExprResult SemaBuiltinMatrixTranspose(CallExpr *TheCall,
ExprResult CallResult);
@@ -12637,6 +13998,16 @@ private:
ExprResult SemaBuiltinMatrixColumnMajorStore(CallExpr *TheCall,
ExprResult CallResult);
+ // WebAssembly builtin handling.
+ bool BuiltinWasmRefNullExtern(CallExpr *TheCall);
+ bool BuiltinWasmRefNullFunc(CallExpr *TheCall);
+ bool BuiltinWasmTableGet(CallExpr *TheCall);
+ bool BuiltinWasmTableSet(CallExpr *TheCall);
+ bool BuiltinWasmTableSize(CallExpr *TheCall);
+ bool BuiltinWasmTableGrow(CallExpr *TheCall);
+ bool BuiltinWasmTableFill(CallExpr *TheCall);
+ bool BuiltinWasmTableCopy(CallExpr *TheCall);
+
public:
enum FormatStringType {
FST_Scanf,
@@ -12658,18 +14029,19 @@ public:
private:
bool CheckFormatArguments(const FormatAttr *Format,
- ArrayRef<const Expr *> Args,
- bool IsCXXMember,
- VariadicCallType CallType,
- SourceLocation Loc, SourceRange Range,
+ ArrayRef<const Expr *> Args, bool IsCXXMember,
+ VariadicCallType CallType, SourceLocation Loc,
+ SourceRange Range,
llvm::SmallBitVector &CheckedVarArgs);
bool CheckFormatArguments(ArrayRef<const Expr *> Args,
- bool HasVAListArg, unsigned format_idx,
+ FormatArgumentPassingKind FAPK, unsigned format_idx,
unsigned firstDataArg, FormatStringType Type,
- VariadicCallType CallType,
- SourceLocation Loc, SourceRange range,
+ VariadicCallType CallType, SourceLocation Loc,
+ SourceRange range,
llvm::SmallBitVector &CheckedVarArgs);
+ void CheckInfNaNFunction(const CallExpr *Call, const FunctionDecl *FDecl);
+
void CheckAbsoluteValueFunction(const CallExpr *Call,
const FunctionDecl *FDecl);
@@ -12694,12 +14066,13 @@ private:
const FunctionDecl *FD = nullptr);
public:
- void CheckFloatComparison(SourceLocation Loc, Expr *LHS, Expr *RHS);
+ void CheckFloatComparison(SourceLocation Loc, Expr *LHS, Expr *RHS,
+ BinaryOperatorKind Opcode);
private:
void CheckImplicitConversions(Expr *E, SourceLocation CC = SourceLocation());
void CheckBoolLikeConversion(Expr *E, SourceLocation CC);
- void CheckForIntOverflow(Expr *E);
+ void CheckForIntOverflow(const Expr *E);
void CheckUnsequencedOperations(const Expr *E);
/// Perform semantic checks on a completed expression. This will either
@@ -12724,7 +14097,8 @@ private:
/// attempts to add itself into the container
void CheckObjCCircularContainer(ObjCMessageExpr *Message);
- void CheckTCBEnforcement(const CallExpr *TheCall, const FunctionDecl *Callee);
+ void CheckTCBEnforcement(const SourceLocation CallExprLoc,
+ const NamedDecl *Callee);
void AnalyzeDeleteExprMismatch(const CXXDeleteExpr *DE);
void AnalyzeDeleteExprMismatch(FieldDecl *Field, SourceLocation DeleteLoc,
@@ -12747,7 +14121,9 @@ public:
/// If true, \c Type should be compared with other expression's types for
/// layout-compatibility.
+ LLVM_PREFERRED_TYPE(bool)
unsigned LayoutCompatible : 1;
+ LLVM_PREFERRED_TYPE(bool)
unsigned MustBeNull : 1;
};
@@ -12776,7 +14152,6 @@ private:
Scope *CurScope;
mutable IdentifierInfo *Ident_super;
- mutable IdentifierInfo *Ident___float128;
/// Nullability type specifiers.
IdentifierInfo *Ident__Nonnull = nullptr;
@@ -12825,9 +14200,8 @@ public:
}
IdentifierInfo *getSuperIdentifier() const;
- IdentifierInfo *getFloat128Identifier() const;
- Decl *getObjCDeclContext() const;
+ ObjCContainerDecl *getObjCDeclContext() const;
DeclContext *getCurLexicalContext() const {
return OriginalLexicalContext ? OriginalLexicalContext : CurContext;
@@ -12901,7 +14275,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) {}
@@ -12968,69 +14342,9 @@ public:
SemaDiagnosticBuilder SYCLDiagIfDeviceCode(SourceLocation Loc,
unsigned DiagID);
- /// Check whether we're allowed to call Callee from the current context.
- ///
- /// - If the call is never allowed in a semantically-correct program
- /// emits an error and returns false.
- ///
- /// - If the call is allowed in semantically-correct programs, but only if
- /// it's never codegen'ed, creates a deferred diagnostic to be emitted if
- /// and when the caller is codegen'ed, and returns true.
- ///
- /// - Otherwise, returns true without emitting any diagnostics.
- ///
- /// Adds Callee to DeviceCallGraph if we don't know if its caller will be
- /// codegen'ed yet.
- bool checkSYCLDeviceFunction(SourceLocation Loc, FunctionDecl *Callee);
-};
-
-/// RAII object that enters a new expression evaluation context.
-class EnterExpressionEvaluationContext {
- Sema &Actions;
- bool Entered = true;
-
-public:
- EnterExpressionEvaluationContext(
- Sema &Actions, Sema::ExpressionEvaluationContext NewContext,
- Decl *LambdaContextDecl = nullptr,
- Sema::ExpressionEvaluationContextRecord::ExpressionKind ExprContext =
- Sema::ExpressionEvaluationContextRecord::EK_Other,
- bool ShouldEnter = true)
- : Actions(Actions), Entered(ShouldEnter) {
- if (Entered)
- Actions.PushExpressionEvaluationContext(NewContext, LambdaContextDecl,
- ExprContext);
- }
- EnterExpressionEvaluationContext(
- Sema &Actions, Sema::ExpressionEvaluationContext NewContext,
- Sema::ReuseLambdaContextDecl_t,
- Sema::ExpressionEvaluationContextRecord::ExpressionKind ExprContext =
- Sema::ExpressionEvaluationContextRecord::EK_Other)
- : Actions(Actions) {
- Actions.PushExpressionEvaluationContext(
- NewContext, Sema::ReuseLambdaContextDecl, ExprContext);
- }
-
- enum InitListTag { InitList };
- EnterExpressionEvaluationContext(Sema &Actions, InitListTag,
- bool ShouldEnter = true)
- : Actions(Actions), Entered(false) {
- // In C++11 onwards, narrowing checks are performed on the contents of
- // braced-init-lists, even when they occur within unevaluated operands.
- // Therefore we still need to instantiate constexpr functions used in such
- // a context.
- if (ShouldEnter && Actions.isUnevaluatedContext() &&
- Actions.getLangOpts().CPlusPlus11) {
- Actions.PushExpressionEvaluationContext(
- Sema::ExpressionEvaluationContext::UnevaluatedList);
- Entered = true;
- }
- }
-
- ~EnterExpressionEvaluationContext() {
- if (Entered)
- Actions.PopExpressionEvaluationContext();
- }
+ void deepTypeCheckForSYCLDevice(SourceLocation UsedAt,
+ llvm::DenseSet<QualType> Visited,
+ ValueDecl *DeclToCheck);
};
DeductionFailureInfo
@@ -13043,6 +14357,8 @@ struct LateParsedTemplate {
CachedTokens Toks;
/// The template function declaration to be late parsed.
Decl *D;
+ /// Floating-point options in the point of definition.
+ FPOptions FPO;
};
template <>
@@ -13051,6 +14367,8 @@ void Sema::PragmaStack<Sema::AlignPackInfo>::Act(SourceLocation PragmaLocation,
llvm::StringRef StackSlotLabel,
AlignPackInfo Value);
+std::unique_ptr<sema::RISCVIntrinsicManager>
+CreateRISCVIntrinsicManager(Sema &S);
} // end namespace clang
namespace llvm {
@@ -13058,7 +14376,8 @@ namespace llvm {
// SourceLocation.
template <> struct DenseMapInfo<clang::Sema::FunctionDeclAndLoc> {
using FunctionDeclAndLoc = clang::Sema::FunctionDeclAndLoc;
- using FDBaseInfo = DenseMapInfo<clang::CanonicalDeclPtr<clang::FunctionDecl>>;
+ using FDBaseInfo =
+ DenseMapInfo<clang::CanonicalDeclPtr<const clang::FunctionDecl>>;
static FunctionDeclAndLoc getEmptyKey() {
return {FDBaseInfo::getEmptyKey(), clang::SourceLocation()};
diff --git a/contrib/llvm-project/clang/include/clang/Sema/SemaConcept.h b/contrib/llvm-project/clang/include/clang/Sema/SemaConcept.h
index c5f9fc45612a..711443505174 100644
--- a/contrib/llvm-project/clang/include/clang/Sema/SemaConcept.h
+++ b/contrib/llvm-project/clang/include/clang/Sema/SemaConcept.h
@@ -1,9 +1,8 @@
//===-- SemaConcept.h - Semantic Analysis for Constraints and Concepts ----===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// 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
//
//===----------------------------------------------------------------------===//
///
@@ -19,8 +18,8 @@
#include "clang/AST/DeclTemplate.h"
#include "clang/Basic/SourceLocation.h"
#include "llvm/ADT/PointerUnion.h"
-#include "llvm/ADT/Optional.h"
#include "llvm/ADT/SmallVector.h"
+#include <optional>
#include <string>
#include <utility>
@@ -29,7 +28,7 @@ class Sema;
struct AtomicConstraint {
const Expr *ConstraintExpr;
- Optional<MutableArrayRef<TemplateArgumentLoc>> ParameterMapping;
+ std::optional<ArrayRef<TemplateArgumentLoc>> ParameterMapping;
AtomicConstraint(Sema &S, const Expr *ConstraintExpr) :
ConstraintExpr(ConstraintExpr) { };
@@ -145,12 +144,12 @@ struct NormalizedConstraint {
}
private:
- static Optional<NormalizedConstraint>
+ static std::optional<NormalizedConstraint>
fromConstraintExprs(Sema &S, NamedDecl *D, ArrayRef<const Expr *> E);
- static Optional<NormalizedConstraint>
+ static std::optional<NormalizedConstraint>
fromConstraintExpr(Sema &S, NamedDecl *D, const Expr *E);
};
} // clang
-#endif //LLVM_CLANG_SEMA_SEMACONCEPT_H
+#endif // LLVM_CLANG_SEMA_SEMACONCEPT_H
diff --git a/contrib/llvm-project/clang/include/clang/Sema/SemaLambda.h b/contrib/llvm-project/clang/include/clang/Sema/SemaLambda.h
index e8eaa46b88a2..3c9d22df70c0 100644
--- a/contrib/llvm-project/clang/include/clang/Sema/SemaLambda.h
+++ b/contrib/llvm-project/clang/include/clang/Sema/SemaLambda.h
@@ -16,6 +16,7 @@
#define LLVM_CLANG_SEMA_SEMALAMBDA_H
#include "clang/AST/ASTLambda.h"
+#include <optional>
namespace clang {
namespace sema {
@@ -30,9 +31,9 @@ class Sema;
/// of the capture-capable lambda's LambdaScopeInfo.
/// See Implementation for more detailed comments.
-Optional<unsigned> getStackIndexOfNearestEnclosingCaptureCapableLambda(
+std::optional<unsigned> getStackIndexOfNearestEnclosingCaptureCapableLambda(
ArrayRef<const sema::FunctionScopeInfo *> FunctionScopes,
- VarDecl *VarToCapture, Sema &S);
+ ValueDecl *VarToCapture, Sema &S);
} // clang
diff --git a/contrib/llvm-project/clang/include/clang/Sema/Template.h b/contrib/llvm-project/clang/include/clang/Sema/Template.h
index 540d2c9aa87e..ce44aca797b0 100644
--- a/contrib/llvm-project/clang/include/clang/Sema/Template.h
+++ b/contrib/llvm-project/clang/include/clang/Sema/Template.h
@@ -23,6 +23,7 @@
#include "llvm/ADT/PointerUnion.h"
#include "llvm/ADT/SmallVector.h"
#include <cassert>
+#include <optional>
#include <utility>
namespace clang {
@@ -74,11 +75,20 @@ enum class TemplateSubstitutionKind : char {
/// template argument list (17) at depth 1.
class MultiLevelTemplateArgumentList {
/// The template argument list at a certain template depth
+
using ArgList = ArrayRef<TemplateArgument>;
+ struct ArgumentListLevel {
+ llvm::PointerIntPair<Decl *, 1, bool> AssociatedDeclAndFinal;
+ ArgList Args;
+ };
+ using ContainerType = SmallVector<ArgumentListLevel, 4>;
+
+ using ArgListsIterator = ContainerType::iterator;
+ using ConstArgListsIterator = ContainerType::const_iterator;
/// The template argument lists, stored from the innermost template
/// argument list (first) to the outermost template argument list (last).
- SmallVector<ArgList, 4> TemplateArgumentLists;
+ ContainerType TemplateArgumentLists;
/// The number of outer levels of template arguments that are not
/// being substituted.
@@ -92,9 +102,8 @@ enum class TemplateSubstitutionKind : char {
MultiLevelTemplateArgumentList() = default;
/// Construct a single-level template argument list.
- explicit
- MultiLevelTemplateArgumentList(const TemplateArgumentList &TemplateArgs) {
- addOuterTemplateArguments(&TemplateArgs);
+ MultiLevelTemplateArgumentList(Decl *D, ArgList Args, bool Final) {
+ addOuterTemplateArguments(D, Args, Final);
}
void setKind(TemplateSubstitutionKind K) { Kind = K; }
@@ -121,6 +130,12 @@ enum class TemplateSubstitutionKind : char {
return TemplateArgumentLists.size();
}
+ // Determine the number of substituted args at 'Depth'.
+ unsigned getNumSubsitutedArgs(unsigned Depth) const {
+ assert(NumRetainedOuterLevels <= Depth && Depth < getNumLevels());
+ return TemplateArgumentLists[getNumLevels() - Depth - 1].Args.size();
+ }
+
unsigned getNumRetainedOuterLevels() const {
return NumRetainedOuterLevels;
}
@@ -138,8 +153,19 @@ enum class TemplateSubstitutionKind : char {
/// Retrieve the template argument at a given depth and index.
const TemplateArgument &operator()(unsigned Depth, unsigned Index) const {
assert(NumRetainedOuterLevels <= Depth && Depth < getNumLevels());
- assert(Index < TemplateArgumentLists[getNumLevels() - Depth - 1].size());
- return TemplateArgumentLists[getNumLevels() - Depth - 1][Index];
+ assert(Index <
+ TemplateArgumentLists[getNumLevels() - Depth - 1].Args.size());
+ return TemplateArgumentLists[getNumLevels() - Depth - 1].Args[Index];
+ }
+
+ /// A template-like entity which owns the whole pattern being substituted.
+ /// This will usually own a set of template parameters, or in some
+ /// cases might even be a template parameter itself.
+ std::pair<Decl *, bool> getAssociatedDecl(unsigned Depth) const {
+ assert(NumRetainedOuterLevels <= Depth && Depth < getNumLevels());
+ auto AD = TemplateArgumentLists[getNumLevels() - Depth - 1]
+ .AssociatedDeclAndFinal;
+ return {AD.getPointer(), AD.getInt()};
}
/// Determine whether there is a non-NULL template argument at the
@@ -152,35 +178,77 @@ enum class TemplateSubstitutionKind : char {
if (Depth < NumRetainedOuterLevels)
return false;
- if (Index >= TemplateArgumentLists[getNumLevels() - Depth - 1].size())
+ if (Index >=
+ TemplateArgumentLists[getNumLevels() - Depth - 1].Args.size())
return false;
return !(*this)(Depth, Index).isNull();
}
+ bool isAnyArgInstantiationDependent() const {
+ for (ArgumentListLevel ListLevel : TemplateArgumentLists)
+ for (const TemplateArgument &TA : ListLevel.Args)
+ if (TA.isInstantiationDependent())
+ return true;
+ return false;
+ }
+
/// Clear out a specific template argument.
void setArgument(unsigned Depth, unsigned Index,
TemplateArgument Arg) {
assert(NumRetainedOuterLevels <= Depth && Depth < getNumLevels());
- assert(Index < TemplateArgumentLists[getNumLevels() - Depth - 1].size());
- const_cast<TemplateArgument&>(
- TemplateArgumentLists[getNumLevels() - Depth - 1][Index])
- = Arg;
+ assert(Index <
+ TemplateArgumentLists[getNumLevels() - Depth - 1].Args.size());
+ const_cast<TemplateArgument &>(
+ TemplateArgumentLists[getNumLevels() - Depth - 1].Args[Index]) = Arg;
}
- /// Add a new outermost level to the multi-level template argument
+ /// Add a new outmost level to the multi-level template argument
/// list.
- void addOuterTemplateArguments(const TemplateArgumentList *TemplateArgs) {
- addOuterTemplateArguments(ArgList(TemplateArgs->data(),
- TemplateArgs->size()));
+ /// A 'Final' substitution means that Subst* nodes won't be built
+ /// for the replacements.
+ void addOuterTemplateArguments(Decl *AssociatedDecl, ArgList Args,
+ bool Final) {
+ assert(!NumRetainedOuterLevels &&
+ "substituted args outside retained args?");
+ assert(getKind() == TemplateSubstitutionKind::Specialization);
+ TemplateArgumentLists.push_back(
+ {{AssociatedDecl ? AssociatedDecl->getCanonicalDecl() : nullptr,
+ Final},
+ Args});
}
- /// Add a new outmost level to the multi-level template argument
- /// list.
void addOuterTemplateArguments(ArgList Args) {
assert(!NumRetainedOuterLevels &&
"substituted args outside retained args?");
- TemplateArgumentLists.push_back(Args);
+ assert(getKind() == TemplateSubstitutionKind::Rewrite);
+ TemplateArgumentLists.push_back({{}, Args});
+ }
+
+ void addOuterTemplateArguments(std::nullopt_t) {
+ assert(!NumRetainedOuterLevels &&
+ "substituted args outside retained args?");
+ TemplateArgumentLists.push_back({});
+ }
+
+ /// Replaces the current 'innermost' level with the provided argument list.
+ /// This is useful for type deduction cases where we need to get the entire
+ /// list from the AST, but then add the deduced innermost list.
+ void replaceInnermostTemplateArguments(Decl *AssociatedDecl, ArgList Args) {
+ assert((!TemplateArgumentLists.empty() || NumRetainedOuterLevels) &&
+ "Replacing in an empty list?");
+
+ if (!TemplateArgumentLists.empty()) {
+ assert((TemplateArgumentLists[0].AssociatedDeclAndFinal.getPointer() ||
+ TemplateArgumentLists[0].AssociatedDeclAndFinal.getPointer() ==
+ AssociatedDecl) &&
+ "Trying to change incorrect declaration?");
+ TemplateArgumentLists[0].Args = Args;
+ } else {
+ --NumRetainedOuterLevels;
+ TemplateArgumentLists.push_back(
+ {{AssociatedDecl, /*Final=*/false}, Args});
+ }
}
/// Add an outermost level that we are not substituting. We have no
@@ -195,7 +263,34 @@ enum class TemplateSubstitutionKind : char {
/// Retrieve the innermost template argument list.
const ArgList &getInnermost() const {
- return TemplateArgumentLists.front();
+ return TemplateArgumentLists.front().Args;
+ }
+ /// Retrieve the outermost template argument list.
+ const ArgList &getOutermost() const {
+ return TemplateArgumentLists.back().Args;
+ }
+ ArgListsIterator begin() { return TemplateArgumentLists.begin(); }
+ ConstArgListsIterator begin() const {
+ return TemplateArgumentLists.begin();
+ }
+ ArgListsIterator end() { return TemplateArgumentLists.end(); }
+ ConstArgListsIterator end() const { return TemplateArgumentLists.end(); }
+
+ LLVM_DUMP_METHOD void dump() const {
+ LangOptions LO;
+ LO.CPlusPlus = true;
+ LO.Bool = true;
+ PrintingPolicy PP(LO);
+ llvm::errs() << "NumRetainedOuterLevels: " << NumRetainedOuterLevels
+ << "\n";
+ for (unsigned Depth = NumRetainedOuterLevels; Depth < getNumLevels();
+ ++Depth) {
+ llvm::errs() << Depth << ": ";
+ printTemplateArgumentList(
+ llvm::errs(),
+ TemplateArgumentLists[getNumLevels() - Depth - 1].Args, PP);
+ llvm::errs() << "\n";
+ }
}
};
@@ -398,7 +493,7 @@ enum class TemplateSubstitutionKind : char {
return newScope;
}
- /// deletes the given scope, and all otuer scopes, down to the
+ /// deletes the given scope, and all outer scopes, down to the
/// given outermost scope.
static void deleteScopes(LocalInstantiationScope *Scope,
LocalInstantiationScope *Outermost) {
@@ -469,6 +564,8 @@ enum class TemplateSubstitutionKind : char {
const MultiLevelTemplateArgumentList &TemplateArgs;
Sema::LateInstantiatedAttrVec* LateAttrs = nullptr;
LocalInstantiationScope *StartingScope = nullptr;
+ // Whether to evaluate the C++20 constraints or simply substitute into them.
+ bool EvaluateConstraints = true;
/// A list of out-of-line class template partial
/// specializations that will need to be instantiated after the
@@ -492,6 +589,13 @@ enum class TemplateSubstitutionKind : char {
SubstIndex(SemaRef, SemaRef.ArgumentPackSubstitutionIndex),
Owner(Owner), TemplateArgs(TemplateArgs) {}
+ void setEvaluateConstraints(bool B) {
+ EvaluateConstraints = B;
+ }
+ bool getEvaluateConstraints() {
+ return EvaluateConstraints;
+ }
+
// Define all the decl visitors using DeclNodes.inc
#define DECL(DERIVED, BASE) \
Decl *Visit ## DERIVED ## Decl(DERIVED ## Decl *D);
@@ -500,6 +604,7 @@ enum class TemplateSubstitutionKind : char {
// Decls which never appear inside a class or function.
#define OBJCCONTAINER(DERIVED, BASE)
#define FILESCOPEASM(DERIVED, BASE)
+#define TOPLEVELSTMT(DERIVED, BASE)
#define IMPORT(DERIVED, BASE)
#define EXPORT(DERIVED, BASE)
#define LINKAGESPEC(DERIVED, BASE)
@@ -528,8 +633,6 @@ enum class TemplateSubstitutionKind : char {
// A few supplemental visitor functions.
Decl *VisitCXXMethodDecl(CXXMethodDecl *D,
TemplateParameterList *TemplateParams,
- Optional<const ASTTemplateArgumentListInfo *>
- ClassScopeSpecializationArgs = llvm::None,
RewriteKind RK = RewriteKind::None);
Decl *VisitFunctionDecl(FunctionDecl *D,
TemplateParameterList *TemplateParams,
diff --git a/contrib/llvm-project/clang/include/clang/Sema/TemplateDeduction.h b/contrib/llvm-project/clang/include/clang/Sema/TemplateDeduction.h
index c0af9f3260b6..85691c66a044 100644
--- a/contrib/llvm-project/clang/include/clang/Sema/TemplateDeduction.h
+++ b/contrib/llvm-project/clang/include/clang/Sema/TemplateDeduction.h
@@ -22,10 +22,10 @@
#include "clang/AST/TemplateBase.h"
#include "clang/Basic/PartialDiagnostic.h"
#include "clang/Basic/SourceLocation.h"
-#include "llvm/ADT/Optional.h"
#include "llvm/ADT/SmallVector.h"
#include <cassert>
#include <cstddef>
+#include <optional>
#include <utility>
namespace clang {
@@ -41,7 +41,7 @@ namespace sema {
/// TemplateDeductionResult value.
class TemplateDeductionInfo {
/// The deduced template argument list.
- TemplateArgumentList *Deduced = nullptr;
+ TemplateArgumentList *DeducedSugared = nullptr, *DeducedCanonical = nullptr;
/// The source location at which template argument
/// deduction is occurring.
@@ -71,8 +71,8 @@ public:
/// Create temporary template deduction info for speculatively deducing
/// against a base class of an argument's type.
TemplateDeductionInfo(ForBaseTag, const TemplateDeductionInfo &Info)
- : Deduced(Info.Deduced), Loc(Info.Loc), DeducedDepth(Info.DeducedDepth),
- ExplicitArgs(Info.ExplicitArgs) {}
+ : DeducedSugared(Info.DeducedSugared), Loc(Info.Loc),
+ DeducedDepth(Info.DeducedDepth), ExplicitArgs(Info.ExplicitArgs) {}
/// Returns the location at which template argument is
/// occurring.
@@ -91,10 +91,15 @@ public:
return ExplicitArgs;
}
- /// Take ownership of the deduced template argument list.
- TemplateArgumentList *take() {
- TemplateArgumentList *Result = Deduced;
- Deduced = nullptr;
+ /// Take ownership of the deduced template argument lists.
+ TemplateArgumentList *takeSugared() {
+ TemplateArgumentList *Result = DeducedSugared;
+ DeducedSugared = nullptr;
+ return Result;
+ }
+ TemplateArgumentList *takeCanonical() {
+ TemplateArgumentList *Result = DeducedCanonical;
+ DeducedCanonical = nullptr;
return Result;
}
@@ -120,15 +125,20 @@ public:
/// Provide an initial template argument list that contains the
/// explicitly-specified arguments.
- void setExplicitArgs(TemplateArgumentList *NewDeduced) {
- Deduced = NewDeduced;
- ExplicitArgs = Deduced->size();
+ void setExplicitArgs(TemplateArgumentList *NewDeducedSugared,
+ TemplateArgumentList *NewDeducedCanonical) {
+ assert(NewDeducedSugared->size() == NewDeducedCanonical->size());
+ DeducedSugared = NewDeducedSugared;
+ DeducedCanonical = NewDeducedCanonical;
+ ExplicitArgs = DeducedSugared->size();
}
/// Provide a new template argument list that contains the
/// results of template argument deduction.
- void reset(TemplateArgumentList *NewDeduced) {
- Deduced = NewDeduced;
+ void reset(TemplateArgumentList *NewDeducedSugared,
+ TemplateArgumentList *NewDeducedCanonical) {
+ DeducedSugared = NewDeducedSugared;
+ DeducedCanonical = NewDeducedCanonical;
}
/// Is a SFINAE diagnostic available?
@@ -224,6 +234,13 @@ public:
/// different argument type from its substituted parameter type.
unsigned CallArgIndex = 0;
+ // C++20 [over.match.class.deduct]p5.2:
+ // During template argument deduction for the aggregate deduction
+ // candidate, the number of elements in a trailing parameter pack is only
+ // deduced from the number of remaining function arguments if it is not
+ // otherwise deduced.
+ bool AggregateDeductionCandidateHasMismatchedArity = false;
+
/// Information on packs that we're currently expanding.
///
/// FIXME: This should be kept internal to SemaTemplateDeduction.
@@ -274,7 +291,7 @@ struct DeductionFailureInfo {
/// Return the index of the call argument that this deduction
/// failure refers to, if any.
- llvm::Optional<unsigned> getCallArgIndex();
+ std::optional<unsigned> getCallArgIndex();
/// Free any memory associated with this deduction failure.
void Destroy();
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/Sema/TypoCorrection.h b/contrib/llvm-project/clang/include/clang/Sema/TypoCorrection.h
index e0f8d152dbe5..09de164297e7 100644
--- a/contrib/llvm-project/clang/include/clang/Sema/TypoCorrection.h
+++ b/contrib/llvm-project/clang/include/clang/Sema/TypoCorrection.h
@@ -282,7 +282,7 @@ class CorrectionCandidateCallback {
public:
static const unsigned InvalidDistance = TypoCorrection::InvalidDistance;
- explicit CorrectionCandidateCallback(IdentifierInfo *Typo = nullptr,
+ explicit CorrectionCandidateCallback(const IdentifierInfo *Typo = nullptr,
NestedNameSpecifier *TypoNNS = nullptr)
: Typo(Typo), TypoNNS(TypoNNS) {}
@@ -319,7 +319,7 @@ public:
/// this method.
virtual std::unique_ptr<CorrectionCandidateCallback> clone() = 0;
- void setTypoName(IdentifierInfo *II) { Typo = II; }
+ void setTypoName(const IdentifierInfo *II) { Typo = II; }
void setTypoNNS(NestedNameSpecifier *NNS) { TypoNNS = NNS; }
// Flags for context-dependent keywords. WantFunctionLikeCasts is only
@@ -345,13 +345,13 @@ protected:
candidate.getCorrectionSpecifier() == TypoNNS;
}
- IdentifierInfo *Typo;
+ const IdentifierInfo *Typo;
NestedNameSpecifier *TypoNNS;
};
class DefaultFilterCCC final : public CorrectionCandidateCallback {
public:
- explicit DefaultFilterCCC(IdentifierInfo *Typo = nullptr,
+ explicit DefaultFilterCCC(const IdentifierInfo *Typo = nullptr,
NestedNameSpecifier *TypoNNS = nullptr)
: CorrectionCandidateCallback(Typo, TypoNNS) {}
@@ -365,6 +365,10 @@ public:
template <class C>
class DeclFilterCCC final : public CorrectionCandidateCallback {
public:
+ explicit DeclFilterCCC(const IdentifierInfo *Typo = nullptr,
+ NestedNameSpecifier *TypoNNS = nullptr)
+ : CorrectionCandidateCallback(Typo, TypoNNS) {}
+
bool ValidateCandidate(const TypoCorrection &candidate) override {
return candidate.getCorrectionDeclAs<C>();
}
diff --git a/contrib/llvm-project/clang/include/clang/Sema/Weak.h b/contrib/llvm-project/clang/include/clang/Sema/Weak.h
index 434393677d42..877b47d2474e 100644
--- a/contrib/llvm-project/clang/include/clang/Sema/Weak.h
+++ b/contrib/llvm-project/clang/include/clang/Sema/Weak.h
@@ -15,6 +15,7 @@
#define LLVM_CLANG_SEMA_WEAK_H
#include "clang/Basic/SourceLocation.h"
+#include "llvm/ADT/DenseMapInfo.h"
namespace clang {
@@ -22,22 +23,32 @@ class IdentifierInfo;
/// Captures information about a \#pragma weak directive.
class WeakInfo {
- IdentifierInfo *alias; // alias (optional)
- SourceLocation loc; // for diagnostics
- bool used; // identifier later declared?
+ const IdentifierInfo *alias = nullptr; // alias (optional)
+ SourceLocation loc; // for diagnostics
public:
- WeakInfo()
- : alias(nullptr), loc(SourceLocation()), used(false) {}
- WeakInfo(IdentifierInfo *Alias, SourceLocation Loc)
- : alias(Alias), loc(Loc), used(false) {}
- inline IdentifierInfo * getAlias() const { return alias; }
+ WeakInfo() = default;
+ WeakInfo(const IdentifierInfo *Alias, SourceLocation Loc)
+ : alias(Alias), loc(Loc) {}
+ inline const IdentifierInfo *getAlias() const { return alias; }
inline SourceLocation getLocation() const { return loc; }
- void setUsed(bool Used=true) { used = Used; }
- inline bool getUsed() { return used; }
- bool operator==(WeakInfo RHS) const {
- return alias == RHS.getAlias() && loc == RHS.getLocation();
- }
- bool operator!=(WeakInfo RHS) const { return !(*this == RHS); }
+ bool operator==(WeakInfo RHS) const = delete;
+ bool operator!=(WeakInfo RHS) const = delete;
+
+ struct DenseMapInfoByAliasOnly
+ : private llvm::DenseMapInfo<const IdentifierInfo *> {
+ static inline WeakInfo getEmptyKey() {
+ return WeakInfo(DenseMapInfo::getEmptyKey(), SourceLocation());
+ }
+ static inline WeakInfo getTombstoneKey() {
+ return WeakInfo(DenseMapInfo::getTombstoneKey(), SourceLocation());
+ }
+ static unsigned getHashValue(const WeakInfo &W) {
+ return DenseMapInfo::getHashValue(W.getAlias());
+ }
+ static bool isEqual(const WeakInfo &LHS, const WeakInfo &RHS) {
+ return DenseMapInfo::isEqual(LHS.getAlias(), RHS.getAlias());
+ }
+ };
};
} // end namespace clang
diff --git a/contrib/llvm-project/clang/include/clang/Serialization/ASTBitCodes.h b/contrib/llvm-project/clang/include/clang/Serialization/ASTBitCodes.h
index 027a981df22c..fdd64f2abbe9 100644
--- a/contrib/llvm-project/clang/include/clang/Serialization/ASTBitCodes.h
+++ b/contrib/llvm-project/clang/include/clang/Serialization/ASTBitCodes.h
@@ -41,7 +41,7 @@ namespace serialization {
/// Version 4 of AST files also requires that the version control branch and
/// revision match exactly, since there is no backward compatibility of
/// AST files at this time.
-const unsigned VERSION_MAJOR = 15;
+const unsigned VERSION_MAJOR = 29;
/// AST file minor version number supported by this version of
/// Clang.
@@ -51,7 +51,7 @@ const unsigned VERSION_MAJOR = 15;
/// for the previous version could still support reading the new
/// version by ignoring new kinds of subblocks), this number
/// should be increased.
-const unsigned VERSION_MINOR = 0;
+const unsigned VERSION_MINOR = 1;
/// An ID number that refers to an identifier in an AST file.
///
@@ -343,9 +343,6 @@ enum ControlRecordTypes {
/// name.
ORIGINAL_FILE,
- /// The directory that the PCH was originally created in.
- ORIGINAL_PCH_DIR,
-
/// Record code for file ID of the file or buffer that was used to
/// generate the AST file.
ORIGINAL_FILE_ID,
@@ -400,8 +397,14 @@ enum UnhashedControlBlockRecordTypes {
/// Record code for the diagnostic options table.
DIAGNOSTIC_OPTIONS,
+ /// Record code for the headers search paths.
+ HEADER_SEARCH_PATHS,
+
/// Record code for \#pragma diagnostic mappings.
DIAG_PRAGMA_MAPPINGS,
+
+ /// Record code for the indices of used header search entries.
+ HEADER_SEARCH_ENTRY_USAGE,
};
/// Record code for extension blocks.
@@ -521,13 +524,7 @@ enum ASTRecordTypes {
/// of source-location information.
SOURCE_LOCATION_OFFSETS = 14,
- /// Record code for the set of source location entries
- /// that need to be preloaded by the AST reader.
- ///
- /// This set contains the source location entry for the
- /// predefines buffer and for any file entries that need to be
- /// preloaded.
- SOURCE_LOCATION_PRELOADS = 15,
+ // ID 15 used to be for source location entry preloads.
/// Record code for the set of ext_vector type names.
EXT_VECTOR_DECLS = 16,
@@ -692,6 +689,12 @@ enum ASTRecordTypes {
/// Record code for \#pragma float_control options.
FLOAT_CONTROL_PRAGMA_OPTIONS = 65,
+
+ /// ID 66 used to be the list of included files.
+
+ /// Record code for an unterminated \#pragma clang assume_nonnull begin
+ /// recorded in a preamble.
+ PP_ASSUME_NONNULL_LOC = 67,
};
/// Record types used within a source manager block.
@@ -822,6 +825,9 @@ enum SubmoduleRecordTypes {
/// Specifies the name of the module that will eventually
/// re-export the entities in this module.
SUBMODULE_EXPORT_AS = 17,
+
+ /// Specifies affecting modules that were not imported.
+ SUBMODULE_AFFECTING_MODULES = 18,
};
/// Record types used within a comments block.
@@ -1064,6 +1070,9 @@ enum PredefinedTypeIDs {
/// \brief The '__bf16' type
PREDEF_TYPE_BFLOAT16_ID = 73,
+ /// \brief The '__ibm128' type
+ PREDEF_TYPE_IBM128_ID = 74,
+
/// OpenCL image types with auto numeration
#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
PREDEF_TYPE_##Id##_ID,
@@ -1080,6 +1089,11 @@ enum PredefinedTypeIDs {
// \brief RISC-V V types with auto numeration
#define RVV_TYPE(Name, Id, SingletonId) PREDEF_TYPE_##Id##_ID,
#include "clang/Basic/RISCVVTypes.def"
+// \brief WebAssembly reference types with auto numeration
+#define WASM_TYPE(Name, Id, SingletonId) PREDEF_TYPE_##Id##_ID,
+#include "clang/Basic/WebAssemblyReferenceTypes.def"
+ // Sentinel value. Considered a predefined type but not useable as one.
+ PREDEF_TYPE_LAST_ID
};
/// The number of predefined type IDs that are reserved for
@@ -1087,7 +1101,13 @@ enum PredefinedTypeIDs {
///
/// Type IDs for non-predefined types will start at
/// NUM_PREDEF_TYPE_IDs.
-const unsigned NUM_PREDEF_TYPE_IDS = 300;
+const unsigned NUM_PREDEF_TYPE_IDS = 502;
+
+// Ensure we do not overrun the predefined types we reserved
+// in the enum PredefinedTypeIDs above.
+static_assert(PREDEF_TYPE_LAST_ID < NUM_PREDEF_TYPE_IDS,
+ "Too many enumerators in PredefinedTypeIDs. Review the value of "
+ "NUM_PREDEF_TYPE_IDS");
/// Record codes for each kind of type.
///
@@ -1302,6 +1322,9 @@ enum DeclCode {
/// A FileScopeAsmDecl record.
DECL_FILE_SCOPE_ASM,
+ /// A TopLevelStmtDecl record.
+ DECL_TOP_LEVEL_STMT_DECL,
+
/// A BlockDecl record.
DECL_BLOCK,
@@ -1452,10 +1475,6 @@ enum DeclCode {
/// template template parameter pack.
DECL_EXPANDED_TEMPLATE_TEMPLATE_PARM_PACK,
- /// A ClassScopeFunctionSpecializationDecl record a class scope
- /// function specialization. (Microsoft extension).
- DECL_CLASS_SCOPE_FUNCTION_SPECIALIZATION,
-
/// An ImportDecl recording a module import.
DECL_IMPORT,
@@ -1495,7 +1514,16 @@ enum DeclCode {
/// An OMPDeclareReductionDecl record.
DECL_OMP_DECLARE_REDUCTION,
- DECL_LAST = DECL_OMP_DECLARE_REDUCTION
+ /// A UnnamedGlobalConstantDecl record.
+ DECL_UNNAMED_GLOBAL_CONSTANT,
+
+ /// A HLSLBufferDecl record.
+ DECL_HLSL_BUFFER,
+
+ /// An ImplicitConceptSpecializationDecl record.
+ DECL_IMPLICIT_CONCEPT_SPECIALIZATION,
+
+ DECL_LAST = DECL_IMPLICIT_CONCEPT_SPECIALIZATION
};
/// Record codes for each kind of statement or expression.
@@ -1833,6 +1861,9 @@ enum StmtCode {
/// A CXXBoolLiteralExpr record.
EXPR_CXX_BOOL_LITERAL,
+ /// A CXXParenListInitExpr record.
+ EXPR_CXX_PAREN_LIST_INIT,
+
EXPR_CXX_NULL_PTR_LITERAL, // CXXNullPtrLiteralExpr
EXPR_CXX_TYPEID_EXPR, // CXXTypeidExpr (of expr).
EXPR_CXX_TYPEID_TYPE, // CXXTypeidExpr (of type).
@@ -1890,6 +1921,7 @@ enum StmtCode {
STMT_SEH_TRY, // SEHTryStmt
// OpenMP directives
+ STMT_OMP_META_DIRECTIVE,
STMT_OMP_CANONICAL_LOOP,
STMT_OMP_PARALLEL_DIRECTIVE,
STMT_OMP_SIMD_DIRECTIVE,
@@ -1905,9 +1937,11 @@ enum StmtCode {
STMT_OMP_PARALLEL_FOR_DIRECTIVE,
STMT_OMP_PARALLEL_FOR_SIMD_DIRECTIVE,
STMT_OMP_PARALLEL_MASTER_DIRECTIVE,
+ STMT_OMP_PARALLEL_MASKED_DIRECTIVE,
STMT_OMP_PARALLEL_SECTIONS_DIRECTIVE,
STMT_OMP_TASK_DIRECTIVE,
STMT_OMP_TASKYIELD_DIRECTIVE,
+ STMT_OMP_ERROR_DIRECTIVE,
STMT_OMP_BARRIER_DIRECTIVE,
STMT_OMP_TASKWAIT_DIRECTIVE,
STMT_OMP_FLUSH_DIRECTIVE,
@@ -1931,6 +1965,10 @@ enum StmtCode {
STMT_OMP_MASTER_TASKLOOP_SIMD_DIRECTIVE,
STMT_OMP_PARALLEL_MASTER_TASKLOOP_DIRECTIVE,
STMT_OMP_PARALLEL_MASTER_TASKLOOP_SIMD_DIRECTIVE,
+ STMT_OMP_MASKED_TASKLOOP_DIRECTIVE,
+ STMT_OMP_MASKED_TASKLOOP_SIMD_DIRECTIVE,
+ STMT_OMP_PARALLEL_MASKED_TASKLOOP_DIRECTIVE,
+ STMT_OMP_PARALLEL_MASKED_TASKLOOP_SIMD_DIRECTIVE,
STMT_OMP_DISTRIBUTE_DIRECTIVE,
STMT_OMP_TARGET_UPDATE_DIRECTIVE,
STMT_OMP_DISTRIBUTE_PARALLEL_FOR_DIRECTIVE,
@@ -1947,9 +1985,15 @@ enum StmtCode {
STMT_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_DIRECTIVE,
STMT_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_DIRECTIVE,
STMT_OMP_TARGET_TEAMS_DISTRIBUTE_SIMD_DIRECTIVE,
+ STMT_OMP_SCOPE_DIRECTIVE,
STMT_OMP_INTEROP_DIRECTIVE,
STMT_OMP_DISPATCH_DIRECTIVE,
STMT_OMP_MASKED_DIRECTIVE,
+ STMT_OMP_GENERIC_LOOP_DIRECTIVE,
+ STMT_OMP_TEAMS_GENERIC_LOOP_DIRECTIVE,
+ STMT_OMP_TARGET_TEAMS_GENERIC_LOOP_DIRECTIVE,
+ STMT_OMP_PARALLEL_GENERIC_LOOP_DIRECTIVE,
+ STMT_OMP_TARGET_PARALLEL_GENERIC_LOOP_DIRECTIVE,
EXPR_OMP_ARRAY_SECTION,
EXPR_OMP_ARRAY_SHAPING,
EXPR_OMP_ITERATOR,
diff --git a/contrib/llvm-project/clang/include/clang/Serialization/ASTReader.h b/contrib/llvm-project/clang/include/clang/Serialization/ASTReader.h
index 242b75baca6c..62c25f5b7a0d 100644
--- a/contrib/llvm-project/clang/include/clang/Serialization/ASTReader.h
+++ b/contrib/llvm-project/clang/include/clang/Serialization/ASTReader.h
@@ -32,12 +32,13 @@
#include "clang/Serialization/ModuleFile.h"
#include "clang/Serialization/ModuleFileExtension.h"
#include "clang/Serialization/ModuleManager.h"
+#include "clang/Serialization/SourceLocationEncoding.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/IntrusiveRefCntPtr.h"
#include "llvm/ADT/MapVector.h"
-#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/PagedVector.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/SmallPtrSet.h"
@@ -56,6 +57,7 @@
#include <ctime>
#include <deque>
#include <memory>
+#include <optional>
#include <set>
#include <string>
#include <utility>
@@ -84,7 +86,6 @@ class GlobalModuleIndex;
struct HeaderFileInfo;
class HeaderSearchOptions;
class LangOptions;
-class LazyASTUnresolvedSet;
class MacroInfo;
class InMemoryModuleCache;
class NamedDecl;
@@ -94,7 +95,6 @@ class ObjCInterfaceDecl;
class PCHContainerReader;
class Preprocessor;
class PreprocessorOptions;
-struct QualifierInfo;
class Sema;
class SourceManager;
class Stmt;
@@ -165,6 +165,10 @@ public:
/// Receives the header search options.
///
+ /// \param HSOpts The read header search options. The following fields are
+ /// missing and are reported in ReadHeaderSearchPaths():
+ /// UserEntries, SystemHeaderPrefixes, VFSOverlayFiles.
+ ///
/// \returns true to indicate the header search options are invalid, or false
/// otherwise.
virtual bool ReadHeaderSearchOptions(const HeaderSearchOptions &HSOpts,
@@ -173,6 +177,20 @@ public:
return false;
}
+ /// Receives the header search paths.
+ ///
+ /// \param HSOpts The read header search paths. Only the following fields are
+ /// initialized: UserEntries, SystemHeaderPrefixes,
+ /// VFSOverlayFiles. The rest is reported in
+ /// ReadHeaderSearchOptions().
+ ///
+ /// \returns true to indicate the header search paths are invalid, or false
+ /// otherwise.
+ virtual bool ReadHeaderSearchPaths(const HeaderSearchOptions &HSOpts,
+ bool Complain) {
+ return false;
+ }
+
/// Receives the preprocessor options.
///
/// \param SuggestedPredefines Can be filled in with the set of predefines
@@ -182,7 +200,7 @@ public:
/// \returns true to indicate the preprocessor options are invalid, or false
/// otherwise.
virtual bool ReadPreprocessorOptions(const PreprocessorOptions &PPOpts,
- bool Complain,
+ bool ReadMacros, bool Complain,
std::string &SuggestedPredefines) {
return false;
}
@@ -257,7 +275,7 @@ public:
StringRef SpecificModuleCachePath,
bool Complain) override;
bool ReadPreprocessorOptions(const PreprocessorOptions &PPOpts,
- bool Complain,
+ bool ReadMacros, bool Complain,
std::string &SuggestedPredefines) override;
void ReadCounter(const serialization::ModuleFile &M, unsigned Value) override;
@@ -287,15 +305,13 @@ public:
bool AllowCompatibleDifferences) override;
bool ReadDiagnosticOptions(IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts,
bool Complain) override;
- bool ReadPreprocessorOptions(const PreprocessorOptions &PPOpts, bool Complain,
+ bool ReadPreprocessorOptions(const PreprocessorOptions &PPOpts,
+ bool ReadMacros, bool Complain,
std::string &SuggestedPredefines) override;
bool ReadHeaderSearchOptions(const HeaderSearchOptions &HSOpts,
StringRef SpecificModuleCachePath,
bool Complain) override;
void ReadCounter(const serialization::ModuleFile &M, unsigned Value) override;
-
-private:
- void Error(const char *Msg);
};
/// ASTReaderListenter implementation to set SuggestedPredefines of
@@ -308,7 +324,8 @@ class SimpleASTReaderListener : public ASTReaderListener {
public:
SimpleASTReaderListener(Preprocessor &PP) : PP(PP) {}
- bool ReadPreprocessorOptions(const PreprocessorOptions &PPOpts, bool Complain,
+ bool ReadPreprocessorOptions(const PreprocessorOptions &PPOpts,
+ bool ReadMacros, bool Complain,
std::string &SuggestedPredefines) override;
};
@@ -382,7 +399,7 @@ public:
/// The AST file was written by a different version of Clang.
VersionMismatch,
- /// The AST file was writtten with a different language/target
+ /// The AST file was written with a different language/target
/// configuration.
ConfigurationMismatch,
@@ -398,6 +415,8 @@ public:
using ModuleReverseIterator = ModuleManager::ModuleReverseIterator;
private:
+ using LocSeq = SourceLocationSequence;
+
/// The receiver of some callbacks invoked by ASTReader.
std::unique_ptr<ASTReaderListener> Listener;
@@ -443,7 +462,7 @@ private:
SourceLocation CurrentImportLoc;
/// The module kind that is currently deserializing.
- Optional<ModuleKind> CurrentDeserializingModuleKind;
+ std::optional<ModuleKind> CurrentDeserializingModuleKind;
/// The global module index, if loaded.
std::unique_ptr<GlobalModuleIndex> GlobalIndex;
@@ -466,7 +485,7 @@ private:
///
/// When the pointer at index I is non-NULL, the type with
/// ID = (I + 1) << FastQual::Width has already been loaded
- std::vector<QualType> TypesLoaded;
+ llvm::PagedVector<QualType> TypesLoaded;
using GlobalTypeMapType =
ContinuousRangeMap<serialization::TypeID, ModuleFile *, 4>;
@@ -480,7 +499,7 @@ private:
///
/// When the pointer at index I is non-NULL, the declaration with ID
/// = I + 1 has already been loaded.
- std::vector<Decl *> DeclsLoaded;
+ llvm::PagedVector<Decl *> DeclsLoaded;
using GlobalDeclMapType =
ContinuousRangeMap<serialization::DeclID, ModuleFile *, 4>;
@@ -531,6 +550,10 @@ private:
/// declaration and the value is the deduced return type.
llvm::SmallMapVector<FunctionDecl *, QualType, 4> PendingDeducedTypeUpdates;
+ /// Functions has undededuced return type and we wish we can find the deduced
+ /// return type by iterating the redecls in other modules.
+ llvm::SmallVector<FunctionDecl *, 4> PendingUndeducedFunctionDecls;
+
/// Declarations that have been imported and have typedef names for
/// linkage purposes.
llvm::DenseMap<std::pair<DeclContext *, IdentifierInfo *>, NamedDecl *>
@@ -541,6 +564,10 @@ private:
llvm::DenseMap<Decl*, llvm::SmallVector<NamedDecl*, 2>>
AnonymousDeclarationsForMerging;
+ /// Map from numbering information for lambdas to the corresponding lambdas.
+ llvm::DenseMap<std::pair<const Decl *, unsigned>, NamedDecl *>
+ LambdaDeclarationsForMerging;
+
/// Key used to identify LifetimeExtendedTemporaryDecl for merging,
/// containing the lifetime-extending declaration and the mangling number.
using LETemporaryKey = std::pair<Decl *, unsigned>;
@@ -688,7 +715,7 @@ private:
Module *Mod;
/// The kind of module reference.
- enum { Import, Export, Conflict } Kind;
+ enum { Import, Export, Conflict, Affecting } Kind;
/// The local ID of the module that is being exported.
unsigned ID;
@@ -863,7 +890,7 @@ private:
SourceLocation PointersToMembersPragmaLocation;
/// The pragma float_control state.
- Optional<FPOptionsOverride> FpPragmaCurrentValue;
+ std::optional<FPOptionsOverride> FpPragmaCurrentValue;
SourceLocation FpPragmaCurrentLocation;
struct FpPragmaStackEntry {
FPOptionsOverride Value;
@@ -875,7 +902,7 @@ private:
llvm::SmallVector<std::string, 2> FpPragmaStrings;
/// The pragma align/pack state.
- Optional<Sema::AlignPackInfo> PragmaAlignPackCurrentValue;
+ std::optional<Sema::AlignPackInfo> PragmaAlignPackCurrentValue;
SourceLocation PragmaAlignPackCurrentLocation;
struct PragmaAlignPackStackEntry {
Sema::AlignPackInfo Value;
@@ -914,7 +941,7 @@ private:
/// Sema tracks these to emit deferred diags.
llvm::SmallSetVector<serialization::DeclID, 4> DeclsToCheckForDeferredDiags;
-public:
+private:
struct ImportedSubmodule {
serialization::SubmoduleID ID;
SourceLocation ImportLoc;
@@ -923,10 +950,15 @@ public:
: ID(ID), ImportLoc(ImportLoc) {}
};
-private:
/// A list of modules that were imported by precompiled headers or
- /// any other non-module AST file.
- SmallVector<ImportedSubmodule, 2> ImportedModules;
+ /// any other non-module AST file and have not yet been made visible. If a
+ /// module is made visible in the ASTReader, it will be transfered to
+ /// \c PendingImportedModulesSema.
+ SmallVector<ImportedSubmodule, 2> PendingImportedModules;
+
+ /// A list of modules that were imported by precompiled headers or
+ /// any other non-module AST file and have not yet been made visible for Sema.
+ SmallVector<ImportedSubmodule, 2> PendingImportedModulesSema;
//@}
/// The system include root to be used when loading the
@@ -1082,7 +1114,13 @@ private:
/// they might contain a deduced return type that refers to a local type
/// declared within the function.
SmallVector<std::pair<FunctionDecl *, serialization::TypeID>, 16>
- PendingFunctionTypes;
+ PendingDeducedFunctionTypes;
+
+ /// The list of deduced variable types that we have not yet read, because
+ /// they might contain a deduced type that refers to a local type declared
+ /// within the variable.
+ SmallVector<std::pair<VarDecl *, serialization::TypeID>, 16>
+ PendingDeducedVarTypes;
/// The list of redeclaration chains that still need to be
/// reconstructed, and the local offset to the corresponding list
@@ -1108,6 +1146,23 @@ private:
/// been completed.
std::deque<PendingDeclContextInfo> PendingDeclContextInfos;
+ template <typename DeclTy>
+ using DuplicateObjCDecls = std::pair<DeclTy *, DeclTy *>;
+
+ /// When resolving duplicate ivars from Objective-C extensions we don't error
+ /// out immediately but check if can merge identical extensions. Not checking
+ /// extensions for equality immediately because ivar deserialization isn't
+ /// over yet at that point.
+ llvm::SmallMapVector<DuplicateObjCDecls<ObjCCategoryDecl>,
+ llvm::SmallVector<DuplicateObjCDecls<ObjCIvarDecl>, 4>,
+ 2>
+ PendingObjCExtensionIvarRedeclarations;
+
+ /// Members that have been added to classes, for which the class has not yet
+ /// been notified. CXXRecordDecl::addedMember will be called for each of
+ /// these once recursive deserialization is complete.
+ SmallVector<std::pair<CXXRecordDecl*, Decl*>, 4> PendingAddedClassMembers;
+
/// The set of NamedDecls that have been loaded, but are members of a
/// context that has been merged into another context where the corresponding
/// declaration is either missing or has not yet been loaded.
@@ -1118,11 +1173,20 @@ private:
using DataPointers =
std::pair<CXXRecordDecl *, struct CXXRecordDecl::DefinitionData *>;
+ using ObjCInterfaceDataPointers =
+ std::pair<ObjCInterfaceDecl *,
+ struct ObjCInterfaceDecl::DefinitionData *>;
+ using ObjCProtocolDataPointers =
+ std::pair<ObjCProtocolDecl *, struct ObjCProtocolDecl::DefinitionData *>;
/// Record definitions in which we found an ODR violation.
llvm::SmallDenseMap<CXXRecordDecl *, llvm::SmallVector<DataPointers, 2>, 2>
PendingOdrMergeFailures;
+ /// C/ObjC record definitions in which we found an ODR violation.
+ llvm::SmallDenseMap<RecordDecl *, llvm::SmallVector<RecordDecl *, 2>, 2>
+ PendingRecordOdrMergeFailures;
+
/// Function definitions in which we found an ODR violation.
llvm::SmallDenseMap<FunctionDecl *, llvm::SmallVector<FunctionDecl *, 2>, 2>
PendingFunctionOdrMergeFailures;
@@ -1131,6 +1195,16 @@ private:
llvm::SmallDenseMap<EnumDecl *, llvm::SmallVector<EnumDecl *, 2>, 2>
PendingEnumOdrMergeFailures;
+ /// ObjCInterfaceDecl in which we found an ODR violation.
+ llvm::SmallDenseMap<ObjCInterfaceDecl *,
+ llvm::SmallVector<ObjCInterfaceDataPointers, 2>, 2>
+ PendingObjCInterfaceOdrMergeFailures;
+
+ /// ObjCProtocolDecl in which we found an ODR violation.
+ llvm::SmallDenseMap<ObjCProtocolDecl *,
+ llvm::SmallVector<ObjCProtocolDataPointers, 2>, 2>
+ PendingObjCProtocolOdrMergeFailures;
+
/// DeclContexts in which we have diagnosed an ODR violation.
llvm::SmallPtrSet<DeclContext*, 2> DiagnosedOdrMergeFailures;
@@ -1162,6 +1236,10 @@ private:
/// definitions. Only populated when using modules in C++.
llvm::DenseMap<EnumDecl *, EnumDecl *> EnumDefinitions;
+ /// A mapping from canonical declarations of records to their canonical
+ /// definitions. Doesn't cover CXXRecordDecl.
+ llvm::DenseMap<RecordDecl *, RecordDecl *> RecordDefinitions;
+
/// When reading a Stmt tree, Stmt operands are placed in this stack.
SmallVector<Stmt *, 16> StmtStack;
@@ -1223,18 +1301,8 @@ private:
/// Reads a statement from the specified cursor.
Stmt *ReadStmtFromStream(ModuleFile &F);
- struct InputFileInfo {
- std::string Filename;
- uint64_t ContentHash;
- off_t StoredSize;
- time_t StoredTime;
- bool Overridden;
- bool Transient;
- bool TopLevelModuleMap;
- };
-
- /// Reads the stored information about an input file.
- InputFileInfo readInputFileInfo(ModuleFile &F, unsigned ID);
+ /// Retrieve the stored information about an input file.
+ serialization::InputFileInfo getInputFileInfo(ModuleFile &F, unsigned ID);
/// Retrieve the file entry and 'overridden' bit for an input
/// file in the given module file.
@@ -1320,18 +1388,17 @@ private:
ASTReaderListener *Listener,
bool ValidateDiagnosticOptions);
- ASTReadResult ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities);
- ASTReadResult ReadExtensionBlock(ModuleFile &F);
+ llvm::Error ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities);
+ llvm::Error ReadExtensionBlock(ModuleFile &F);
void ReadModuleOffsetMap(ModuleFile &F) const;
- bool ParseLineTable(ModuleFile &F, const RecordData &Record);
- bool ReadSourceManagerBlock(ModuleFile &F);
- llvm::BitstreamCursor &SLocCursorForID(int ID);
+ void ParseLineTable(ModuleFile &F, const RecordData &Record);
+ llvm::Error ReadSourceManagerBlock(ModuleFile &F);
SourceLocation getImportLocation(ModuleFile *F);
ASTReadResult ReadModuleMapFileBlock(RecordData &Record, ModuleFile &F,
const ModuleFile *ImportedBy,
unsigned ClientLoadCapabilities);
- ASTReadResult ReadSubmoduleBlock(ModuleFile &F,
- unsigned ClientLoadCapabilities);
+ llvm::Error ReadSubmoduleBlock(ModuleFile &F,
+ unsigned ClientLoadCapabilities);
static bool ParseLanguageOptions(const RecordData &Record, bool Complain,
ASTReaderListener &Listener,
bool AllowCompatibleDifferences);
@@ -1344,6 +1411,8 @@ private:
ASTReaderListener &Listener);
static bool ParseHeaderSearchOptions(const RecordData &Record, bool Complain,
ASTReaderListener &Listener);
+ static bool ParseHeaderSearchPaths(const RecordData &Record, bool Complain,
+ ASTReaderListener &Listener);
static bool ParsePreprocessorOptions(const RecordData &Record, bool Complain,
ASTReaderListener &Listener,
std::string &SuggestedPredefines);
@@ -1359,7 +1428,7 @@ private:
RecordLocation TypeCursorForIndex(unsigned Index);
void LoadedDecl(unsigned Index, Decl *D);
Decl *ReadDeclRecord(serialization::DeclID ID);
- void markIncompleteDeclChain(Decl *Canon);
+ void markIncompleteDeclChain(Decl *D);
/// Returns the most recent declaration of a declaration (which must be
/// of a redeclarable kind) that is either local or has already been loaded
@@ -1566,12 +1635,17 @@ public:
/// capabilities, represented as a bitset of the enumerators of
/// LoadFailureCapabilities.
///
- /// \param Imported optional out-parameter to append the list of modules
- /// that were imported by precompiled headers or any other non-module AST file
+ /// \param LoadedModuleFile The optional out-parameter refers to the new
+ /// loaded modules. In case the module specified by FileName is already
+ /// loaded, the module file pointer referred by NewLoadedModuleFile wouldn't
+ /// change. Otherwise if the AST file get loaded successfully,
+ /// NewLoadedModuleFile would refer to the address of the new loaded top level
+ /// module. The state of NewLoadedModuleFile is unspecified if the AST file
+ /// isn't loaded successfully.
ASTReadResult ReadAST(StringRef FileName, ModuleKind Type,
SourceLocation ImportLoc,
unsigned ClientLoadCapabilities,
- SmallVectorImpl<ImportedSubmodule> *Imported = nullptr);
+ ModuleFile **NewLoadedModuleFile = nullptr);
/// Make the entities in the given module and any of its (non-explicit)
/// submodules visible to name lookup.
@@ -1706,21 +1780,23 @@ public:
/// Read the control block for the named AST file.
///
/// \returns true if an error occurred, false otherwise.
- static bool
- readASTFileControlBlock(StringRef Filename, FileManager &FileMgr,
- const PCHContainerReader &PCHContainerRdr,
- bool FindModuleFileExtensions,
- ASTReaderListener &Listener,
- bool ValidateDiagnosticOptions);
+ static bool readASTFileControlBlock(StringRef Filename, FileManager &FileMgr,
+ const InMemoryModuleCache &ModuleCache,
+ const PCHContainerReader &PCHContainerRdr,
+ bool FindModuleFileExtensions,
+ ASTReaderListener &Listener,
+ bool ValidateDiagnosticOptions);
/// Determine whether the given AST file is acceptable to load into a
/// translation unit with the given language and target options.
static bool isAcceptableASTFile(StringRef Filename, FileManager &FileMgr,
+ const InMemoryModuleCache &ModuleCache,
const PCHContainerReader &PCHContainerRdr,
const LangOptions &LangOpts,
const TargetOptions &TargetOpts,
const PreprocessorOptions &PPOpts,
- StringRef ExistingModuleCachePath);
+ StringRef ExistingModuleCachePath,
+ bool RequireStrictOptionMatches = false);
/// Returns the suggested contents of the predefines buffer,
/// which contains a (typically-empty) subset of the predefines
@@ -1740,14 +1816,14 @@ public:
/// Optionally returns true or false if the preallocated preprocessed
/// entity with index \p Index came from file \p FID.
- Optional<bool> isPreprocessedEntityInFileID(unsigned Index,
- FileID FID) override;
+ std::optional<bool> isPreprocessedEntityInFileID(unsigned Index,
+ FileID FID) override;
/// Read a preallocated skipped range from the external source.
SourceRange ReadSkippedRange(unsigned Index) override;
/// Read the header file information for the given file entry.
- HeaderFileInfo GetHeaderFileInfo(const FileEntry *FE) override;
+ HeaderFileInfo GetHeaderFileInfo(FileEntryRef FE) override;
void ReadPragmaDiagnosticMappings(DiagnosticsEngine &Diag);
@@ -1826,10 +1902,6 @@ public:
/// if the declaration is not from a module file.
ModuleFile *getOwningModuleFile(const Decl *D);
- /// Get the best name we know for the module that owns the given
- /// declaration, or an empty string if the declaration is not from a module.
- std::string getOwningModuleNameForDiagnostic(const Decl *D);
-
/// Returns the source location for the decl \p ID.
SourceLocation getSourceLocationForDeclID(serialization::GlobalDeclID ID);
@@ -1904,8 +1976,9 @@ public:
/// ReadBlockAbbrevs - Enter a subblock of the specified BlockID with the
/// specified cursor. Read the abbreviations that are at the top of the block
/// and then leave the cursor pointing into the block.
- static bool ReadBlockAbbrevs(llvm::BitstreamCursor &Cursor, unsigned BlockID,
- uint64_t *StartOfBlockOffset = nullptr);
+ static llvm::Error ReadBlockAbbrevs(llvm::BitstreamCursor &Cursor,
+ unsigned BlockID,
+ uint64_t *StartOfBlockOffset = nullptr);
/// Finds all the visible declarations with a given name.
/// The current implementation of this method just loads the entire
@@ -2024,7 +2097,7 @@ public:
SmallVectorImpl<std::pair<Selector, SourceLocation>> &Sels) override;
void ReadWeakUndeclaredIdentifiers(
- SmallVectorImpl<std::pair<IdentifierInfo *, WeakInfo>> &WI) override;
+ SmallVectorImpl<std::pair<IdentifierInfo *, WeakInfo>> &WeakIDs) override;
void ReadUsedVTables(SmallVectorImpl<ExternalVTableUse> &VTables) override;
@@ -2036,6 +2109,8 @@ public:
llvm::MapVector<const FunctionDecl *, std::unique_ptr<LateParsedTemplate>>
&LPTMap) override;
+ void AssignedLambdaNumbering(const CXXRecordDecl *Lambda) override;
+
/// Load a selector from disk, registering its ID if it exists.
void LoadSelector(Selector Sel);
@@ -2080,6 +2155,12 @@ public:
/// Read the source location entry with index ID.
bool ReadSLocEntry(int ID) override;
+ /// Get the index ID for the loaded SourceLocation offset.
+ int getSLocEntryID(SourceLocation::UIntTy SLocOffset) override;
+ /// Try to read the offset of the SLocEntry at the given index in the given
+ /// module file.
+ llvm::Expected<SourceLocation::UIntTy> readSLocOffset(ModuleFile *F,
+ unsigned Index);
/// Retrieve the module import location and module name for the
/// given source manager entry ID.
@@ -2107,7 +2188,7 @@ public:
unsigned getModuleFileID(ModuleFile *M);
/// Return a descriptor for the corresponding module.
- llvm::Optional<ASTSourceDescriptor> getSourceDescriptor(unsigned ID) override;
+ std::optional<ASTSourceDescriptor> getSourceDescriptor(unsigned ID) override;
ExtKind hasExternalDefinitions(const Decl *D) override;
@@ -2126,7 +2207,7 @@ public:
/// Retrieve the global selector ID that corresponds to this
/// the local selector ID in a given module.
- serialization::SelectorID getGlobalSelectorID(ModuleFile &F,
+ serialization::SelectorID getGlobalSelectorID(ModuleFile &M,
unsigned LocalID) const;
/// Read the contents of a CXXCtorInitializer array.
@@ -2139,16 +2220,16 @@ public:
/// Read a source location from raw form and return it in its
/// originating module file's source location space.
- SourceLocation
- ReadUntranslatedSourceLocation(SourceLocation::UIntTy Raw) const {
- return SourceLocation::getFromRawEncoding((Raw >> 1) |
- (Raw << (8 * sizeof(Raw) - 1)));
+ SourceLocation ReadUntranslatedSourceLocation(SourceLocation::UIntTy Raw,
+ LocSeq *Seq = nullptr) const {
+ return SourceLocationEncoding::decode(Raw, Seq);
}
/// Read a source location from raw form.
SourceLocation ReadSourceLocation(ModuleFile &ModuleFile,
- SourceLocation::UIntTy Raw) const {
- SourceLocation Loc = ReadUntranslatedSourceLocation(Raw);
+ SourceLocation::UIntTy Raw,
+ LocSeq *Seq = nullptr) const {
+ SourceLocation Loc = ReadUntranslatedSourceLocation(Raw, Seq);
return TranslateSourceLocation(ModuleFile, Loc);
}
@@ -2168,17 +2249,29 @@ public:
/// Read a source location.
SourceLocation ReadSourceLocation(ModuleFile &ModuleFile,
- const RecordDataImpl &Record,
- unsigned &Idx) {
- return ReadSourceLocation(ModuleFile, Record[Idx++]);
+ const RecordDataImpl &Record, unsigned &Idx,
+ LocSeq *Seq = nullptr) {
+ return ReadSourceLocation(ModuleFile, Record[Idx++], Seq);
+ }
+
+ /// Read a FileID.
+ FileID ReadFileID(ModuleFile &F, const RecordDataImpl &Record,
+ unsigned &Idx) const {
+ return TranslateFileID(F, FileID::get(Record[Idx++]));
+ }
+
+ /// Translate a FileID from another module file's FileID space into ours.
+ FileID TranslateFileID(ModuleFile &F, FileID FID) const {
+ assert(FID.ID >= 0 && "Reading non-local FileID.");
+ return FileID::get(F.SLocEntryBaseID + FID.ID - 1);
}
/// Read a source range.
- SourceRange ReadSourceRange(ModuleFile &F,
- const RecordData &Record, unsigned &Idx);
+ SourceRange ReadSourceRange(ModuleFile &F, const RecordData &Record,
+ unsigned &Idx, LocSeq *Seq = nullptr);
// Read a string
- static std::string ReadString(const RecordData &Record, unsigned &Idx);
+ static std::string ReadString(const RecordDataImpl &Record, unsigned &Idx);
// Skip a string
static void SkipString(const RecordData &Record, unsigned &Idx) {
@@ -2294,6 +2387,13 @@ public:
/// Loads comments ranges.
void ReadComments() override;
+ /// Visit all the input file infos of the given module file.
+ void visitInputFileInfos(
+ serialization::ModuleFile &MF, bool IncludeSystem,
+ llvm::function_ref<void(const serialization::InputFileInfo &IFI,
+ bool IsSystem)>
+ Visitor);
+
/// Visit all the input files of the given module file.
void visitInputFiles(serialization::ModuleFile &MF,
bool IncludeSystem, bool Complain,
@@ -2303,12 +2403,54 @@ public:
/// Visit all the top-level module maps loaded when building the given module
/// file.
void visitTopLevelModuleMaps(serialization::ModuleFile &MF,
- llvm::function_ref<
- void(const FileEntry *)> Visitor);
+ llvm::function_ref<void(FileEntryRef)> Visitor);
bool isProcessingUpdateRecords() { return ProcessingUpdateRecords; }
};
+/// A simple helper class to unpack an integer to bits and consuming
+/// the bits in order.
+class BitsUnpacker {
+ constexpr static uint32_t BitsIndexUpbound = 32;
+
+public:
+ BitsUnpacker(uint32_t V) { updateValue(V); }
+ BitsUnpacker(const BitsUnpacker &) = delete;
+ BitsUnpacker(BitsUnpacker &&) = delete;
+ BitsUnpacker operator=(const BitsUnpacker &) = delete;
+ BitsUnpacker operator=(BitsUnpacker &&) = delete;
+ ~BitsUnpacker() = default;
+
+ void updateValue(uint32_t V) {
+ Value = V;
+ CurrentBitsIndex = 0;
+ }
+
+ void advance(uint32_t BitsWidth) { CurrentBitsIndex += BitsWidth; }
+
+ bool getNextBit() {
+ assert(isValid());
+ return Value & (1 << CurrentBitsIndex++);
+ }
+
+ uint32_t getNextBits(uint32_t Width) {
+ assert(isValid());
+ assert(Width < BitsIndexUpbound);
+ uint32_t Ret = (Value >> CurrentBitsIndex) & ((1 << Width) - 1);
+ CurrentBitsIndex += Width;
+ return Ret;
+ }
+
+ bool canGetNextNBits(uint32_t Width) const {
+ return CurrentBitsIndex + Width < BitsIndexUpbound;
+ }
+
+private:
+ bool isValid() const { return CurrentBitsIndex < BitsIndexUpbound; }
+
+ uint32_t Value;
+ uint32_t CurrentBitsIndex = ~0;
+};
} // namespace clang
#endif // LLVM_CLANG_SERIALIZATION_ASTREADER_H
diff --git a/contrib/llvm-project/clang/include/clang/Serialization/ASTRecordReader.h b/contrib/llvm-project/clang/include/clang/Serialization/ASTRecordReader.h
index b85609bf4e05..80a1359fd16a 100644
--- a/contrib/llvm-project/clang/include/clang/Serialization/ASTRecordReader.h
+++ b/contrib/llvm-project/clang/include/clang/Serialization/ASTRecordReader.h
@@ -18,6 +18,7 @@
#include "clang/AST/AbstractBasicReader.h"
#include "clang/Lex/Token.h"
#include "clang/Serialization/ASTReader.h"
+#include "clang/Serialization/SourceLocationEncoding.h"
#include "llvm/ADT/APFloat.h"
#include "llvm/ADT/APInt.h"
#include "llvm/ADT/APSInt.h"
@@ -30,6 +31,7 @@ class OMPChildren;
class ASTRecordReader
: public serialization::DataStreamBasicReader<ASTRecordReader> {
using ModuleFile = serialization::ModuleFile;
+ using LocSeq = SourceLocationSequence;
ASTReader *Reader;
ModuleFile *F;
@@ -72,7 +74,7 @@ public:
uint64_t readInt() { return Record[Idx++]; }
ArrayRef<uint64_t> readIntArray(unsigned Len) {
- auto Array = llvm::makeArrayRef(Record).slice(Idx, Len);
+ auto Array = llvm::ArrayRef(Record).slice(Idx, Len);
Idx += Len;
return Array;
}
@@ -153,15 +155,19 @@ public:
/// Reads a TemplateArgumentLoc, advancing Idx.
TemplateArgumentLoc readTemplateArgumentLoc();
+ void readTemplateArgumentListInfo(TemplateArgumentListInfo &Result);
+
const ASTTemplateArgumentListInfo*
readASTTemplateArgumentListInfo();
+ // Reads a concept reference from the given record.
+ ConceptReference *readConceptReference();
+
/// Reads a declarator info from the given record, advancing Idx.
TypeSourceInfo *readTypeSourceInfo();
/// Reads the location information for a type.
- void readTypeLoc(TypeLoc TL);
-
+ void readTypeLoc(TypeLoc TL, LocSeq *Seq = nullptr);
/// Map a local type ID within a given AST file to a global type ID.
serialization::TypeID getGlobalTypeID(unsigned LocalID) const {
@@ -271,13 +277,13 @@ public:
void readOMPChildren(OMPChildren *Data);
/// Read a source location, advancing Idx.
- SourceLocation readSourceLocation() {
- return Reader->ReadSourceLocation(*F, Record, Idx);
+ SourceLocation readSourceLocation(LocSeq *Seq = nullptr) {
+ return Reader->ReadSourceLocation(*F, Record, Idx, Seq);
}
/// Read a source range, advancing Idx.
- SourceRange readSourceRange() {
- return Reader->ReadSourceRange(*F, Record, Idx);
+ SourceRange readSourceRange(LocSeq *Seq = nullptr) {
+ return Reader->ReadSourceRange(*F, Record, Idx, Seq);
}
/// Read an arbitrary constant value, advancing Idx.
@@ -326,6 +332,11 @@ public:
/// Reads attributes from the current stream position, advancing Idx.
void readAttributes(AttrVec &Attrs);
+ /// Read an BTFTypeTagAttr object.
+ BTFTypeTagAttr *readBTFTypeTagAttr() {
+ return cast<BTFTypeTagAttr>(readAttr());
+ }
+
/// Reads a token out of a record, advancing Idx.
Token readToken() {
return Reader->ReadToken(*F, Record, Idx);
@@ -350,7 +361,7 @@ struct SavedStreamPosition {
~SavedStreamPosition() {
if (llvm::Error Err = Cursor.JumpToBit(Offset))
llvm::report_fatal_error(
- "Cursor should always be able to go back, failed: " +
+ llvm::Twine("Cursor should always be able to go back, failed: ") +
toString(std::move(Err)));
}
@@ -359,10 +370,6 @@ private:
uint64_t Offset;
};
-inline void PCHValidator::Error(const char *Msg) {
- Reader.Error(Msg);
-}
-
} // namespace clang
#endif
diff --git a/contrib/llvm-project/clang/include/clang/Serialization/ASTRecordWriter.h b/contrib/llvm-project/clang/include/clang/Serialization/ASTRecordWriter.h
index 0dc69bd3f3bd..9a64735c9fa5 100644
--- a/contrib/llvm-project/clang/include/clang/Serialization/ASTRecordWriter.h
+++ b/contrib/llvm-project/clang/include/clang/Serialization/ASTRecordWriter.h
@@ -17,6 +17,7 @@
#include "clang/AST/AbstractBasicWriter.h"
#include "clang/AST/OpenMPClause.h"
#include "clang/Serialization/ASTWriter.h"
+#include "clang/Serialization/SourceLocationEncoding.h"
namespace clang {
@@ -25,6 +26,8 @@ class TypeLoc;
/// An object for streaming information to a record.
class ASTRecordWriter
: public serialization::DataStreamBasicWriter<ASTRecordWriter> {
+ using LocSeq = SourceLocationSequence;
+
ASTWriter *Writer;
ASTWriter::RecordDataImpl *Record;
@@ -123,21 +126,24 @@ public:
AddStmt(const_cast<Stmt*>(S));
}
+ /// Write an BTFTypeTagAttr object.
+ void writeBTFTypeTagAttr(const BTFTypeTagAttr *A) { AddAttr(A); }
+
/// Add a definition for the given function to the queue of statements
/// to emit.
void AddFunctionDefinition(const FunctionDecl *FD);
/// Emit a source location.
- void AddSourceLocation(SourceLocation Loc) {
- return Writer->AddSourceLocation(Loc, *Record);
+ void AddSourceLocation(SourceLocation Loc, LocSeq *Seq = nullptr) {
+ return Writer->AddSourceLocation(Loc, *Record, Seq);
}
void writeSourceLocation(SourceLocation Loc) {
AddSourceLocation(Loc);
}
/// Emit a source range.
- void AddSourceRange(SourceRange Range) {
- return Writer->AddSourceRange(Range, *Record);
+ void AddSourceRange(SourceRange Range, LocSeq *Seq = nullptr) {
+ return Writer->AddSourceRange(Range, *Record, Seq);
}
void writeBool(bool Value) {
@@ -203,7 +209,7 @@ public:
void AddTypeSourceInfo(TypeSourceInfo *TInfo);
/// Emits source location information for a type. Does not emit the type.
- void AddTypeLoc(TypeLoc TL);
+ void AddTypeLoc(TypeLoc TL, LocSeq *Seq = nullptr);
/// Emits a template argument location info.
void AddTemplateArgumentLocInfo(TemplateArgument::ArgKind Kind,
@@ -216,6 +222,9 @@ public:
void AddASTTemplateArgumentListInfo(
const ASTTemplateArgumentListInfo *ASTTemplArgList);
+ // Emits a concept reference.
+ void AddConceptReference(const ConceptReference *CR);
+
/// Emit a reference to a declaration.
void AddDeclRef(const Decl *D) {
return Writer->AddDeclRef(D, *Record);
diff --git a/contrib/llvm-project/clang/include/clang/Serialization/ASTWriter.h b/contrib/llvm-project/clang/include/clang/Serialization/ASTWriter.h
index ac88cb0a3177..de69f99003d8 100644
--- a/contrib/llvm-project/clang/include/clang/Serialization/ASTWriter.h
+++ b/contrib/llvm-project/clang/include/clang/Serialization/ASTWriter.h
@@ -18,12 +18,14 @@
#include "clang/AST/Decl.h"
#include "clang/AST/Type.h"
#include "clang/Basic/LLVM.h"
+#include "clang/Basic/Module.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Sema/Sema.h"
#include "clang/Sema/SemaConsumer.h"
#include "clang/Serialization/ASTBitCodes.h"
#include "clang/Serialization/ASTDeserializationListener.h"
#include "clang/Serialization/PCHContainerOperations.h"
+#include "clang/Serialization/SourceLocationEncoding.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/DenseSet.h"
@@ -43,26 +45,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 +68,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.
///
@@ -119,6 +105,8 @@ private:
using TypeIdxMap = llvm::DenseMap<QualType, serialization::TypeIdx,
serialization::UnsafeQualTypeDenseMapInfo>;
+ using LocSeq = SourceLocationSequence;
+
/// The bitstream writer used to emit this precompiled header.
llvm::BitstreamWriter &Stream;
@@ -140,10 +128,17 @@ private:
/// The module we're currently writing, if any.
Module *WritingModule = nullptr;
- /// The offset of the first bit inside the AST_BLOCK.
+ /// The byte range representing all the UNHASHED_CONTROL_BLOCK.
+ std::pair<uint64_t, uint64_t> UnhashedControlBlockRange;
+ /// The bit offset of the AST block hash blob.
+ uint64_t ASTBlockHashOffset = 0;
+ /// The bit offset of the signature blob.
+ uint64_t SignatureOffset = 0;
+
+ /// The bit offset of the first bit inside the AST_BLOCK.
uint64_t ASTBlockStartOffset = 0;
- /// The range representing all the AST_BLOCK.
+ /// The byte range representing all the AST_BLOCK.
std::pair<uint64_t, uint64_t> ASTBlockRange;
/// The base directory for any relative paths we emit.
@@ -155,6 +150,11 @@ private:
/// file is up to date, but not otherwise.
bool IncludeTimestamps;
+ /// Indicates whether the AST file being written is an implicit module.
+ /// If that's the case, we may be able to skip writing some information that
+ /// are guaranteed to be the same in the importer by the context hash.
+ bool BuildingImplicitModule = false;
+
/// Indicates when the AST writing is actively performing
/// serialization, rather than just queueing updates.
bool WritingAST = false;
@@ -456,6 +456,41 @@ private:
std::vector<std::unique_ptr<ModuleFileExtensionWriter>>
ModuleFileExtensionWriters;
+ /// Mapping from a source location entry to whether it is affecting or not.
+ llvm::BitVector IsSLocAffecting;
+
+ /// Mapping from \c FileID to an index into the FileID adjustment table.
+ std::vector<FileID> NonAffectingFileIDs;
+ std::vector<unsigned> NonAffectingFileIDAdjustments;
+
+ /// Mapping from an offset to an index into the offset adjustment table.
+ std::vector<SourceRange> NonAffectingRanges;
+ std::vector<SourceLocation::UIntTy> NonAffectingOffsetAdjustments;
+
+ /// Collects input files that didn't affect compilation of the current module,
+ /// and initializes data structures necessary for leaving those files out
+ /// during \c SourceManager serialization.
+ void collectNonAffectingInputFiles();
+
+ /// Returns an adjusted \c FileID, accounting for any non-affecting input
+ /// files.
+ FileID getAdjustedFileID(FileID FID) const;
+ /// Returns an adjusted number of \c FileIDs created within the specified \c
+ /// FileID, accounting for any non-affecting input files.
+ unsigned getAdjustedNumCreatedFIDs(FileID FID) const;
+ /// Returns an adjusted \c SourceLocation, accounting for any non-affecting
+ /// input files.
+ SourceLocation getAdjustedLocation(SourceLocation Loc) const;
+ /// Returns an adjusted \c SourceRange, accounting for any non-affecting input
+ /// files.
+ SourceRange getAdjustedRange(SourceRange Range) const;
+ /// Returns an adjusted \c SourceLocation offset, accounting for any
+ /// non-affecting input files.
+ SourceLocation::UIntTy getAdjustedOffset(SourceLocation::UIntTy Offset) const;
+ /// Returns an adjustment for offset into SourceManager, accounting for any
+ /// non-affecting input files.
+ SourceLocation::UIntTy getAdjustment(SourceLocation::UIntTy Offset) const;
+
/// Retrieve or create a submodule ID for this module.
unsigned getSubmoduleID(Module *Mod);
@@ -464,18 +499,16 @@ private:
void WriteBlockInfoBlock();
void WriteControlBlock(Preprocessor &PP, ASTContext &Context,
- StringRef isysroot, const std::string &OutputFile);
+ StringRef isysroot);
/// Write out the signature and diagnostic options, and return the signature.
- ASTFileSignature writeUnhashedControlBlock(Preprocessor &PP,
- ASTContext &Context);
+ void writeUnhashedControlBlock(Preprocessor &PP, ASTContext &Context);
+ ASTFileSignature backpatchSignature();
/// Calculate hash of the pcm content.
- static std::pair<ASTFileSignature, ASTFileSignature>
- createSignature(StringRef AllBytes, StringRef ASTBlockBytes);
+ std::pair<ASTFileSignature, ASTFileSignature> createSignature() const;
- void WriteInputFiles(SourceManager &SourceMgr, HeaderSearchOptions &HSOpts,
- bool Modules);
+ void WriteInputFiles(SourceManager &SourceMgr, HeaderSearchOptions &HSOpts);
void WriteSourceManagerBlock(SourceManager &SourceMgr,
const Preprocessor &PP);
void WritePreprocessor(const Preprocessor &PP, bool IsModule);
@@ -488,7 +521,6 @@ private:
bool isModule);
unsigned TypeExtQualAbbrev = 0;
- unsigned TypeFunctionProtoAbbrev = 0;
void WriteTypeAbbrevs();
void WriteType(QualType T);
@@ -532,17 +564,30 @@ private:
unsigned DeclEnumAbbrev = 0;
unsigned DeclObjCIvarAbbrev = 0;
unsigned DeclCXXMethodAbbrev = 0;
+ unsigned DeclDependentNonTemplateCXXMethodAbbrev = 0;
+ unsigned DeclTemplateCXXMethodAbbrev = 0;
+ unsigned DeclMemberSpecializedCXXMethodAbbrev = 0;
+ unsigned DeclTemplateSpecializedCXXMethodAbbrev = 0;
+ unsigned DeclDependentSpecializationCXXMethodAbbrev = 0;
+ unsigned DeclTemplateTypeParmAbbrev = 0;
+ unsigned DeclUsingShadowAbbrev = 0;
unsigned DeclRefExprAbbrev = 0;
unsigned CharacterLiteralAbbrev = 0;
unsigned IntegerLiteralAbbrev = 0;
unsigned ExprImplicitCastAbbrev = 0;
+ unsigned BinaryOperatorAbbrev = 0;
+ unsigned CompoundAssignOperatorAbbrev = 0;
+ unsigned CallExprAbbrev = 0;
+ unsigned CXXOperatorCallExprAbbrev = 0;
+ unsigned CXXMemberCallExprAbbrev = 0;
+
+ unsigned CompoundStmtAbbrev = 0;
void WriteDeclAbbrevs();
void WriteDecl(ASTContext &Context, Decl *D);
ASTFileSignature WriteASTCore(Sema &SemaRef, StringRef isysroot,
- const std::string &OutputFile,
Module *WritingModule);
public:
@@ -551,7 +596,7 @@ public:
ASTWriter(llvm::BitstreamWriter &Stream, SmallVectorImpl<char> &Buffer,
InMemoryModuleCache &ModuleCache,
ArrayRef<std::shared_ptr<ModuleFileExtension>> Extensions,
- bool IncludeTimestamps = true);
+ bool IncludeTimestamps = true, bool BuildingImplicitModule = false);
~ASTWriter() override;
ASTContext &getASTContext() const {
@@ -580,9 +625,8 @@ public:
///
/// \return the module signature, which eventually will be a hash of
/// the module but currently is merely a random 32-bit number.
- ASTFileSignature WriteAST(Sema &SemaRef, const std::string &OutputFile,
+ ASTFileSignature WriteAST(Sema &SemaRef, StringRef OutputFile,
Module *WritingModule, StringRef isysroot,
- bool hasErrors = false,
bool ShouldCacheASTInMemory = false);
/// Emit a token.
@@ -592,11 +636,16 @@ public:
void AddAlignPackInfo(const Sema::AlignPackInfo &Info,
RecordDataImpl &Record);
+ /// Emit a FileID.
+ void AddFileID(FileID FID, RecordDataImpl &Record);
+
/// Emit a source location.
- void AddSourceLocation(SourceLocation Loc, RecordDataImpl &Record);
+ void AddSourceLocation(SourceLocation Loc, RecordDataImpl &Record,
+ LocSeq *Seq = nullptr);
/// Emit a source range.
- void AddSourceRange(SourceRange Range, RecordDataImpl &Record);
+ void AddSourceRange(SourceRange Range, RecordDataImpl &Record,
+ LocSeq *Seq = nullptr);
/// Emit a reference to an identifier.
void AddIdentifierRef(const IdentifierInfo *II, RecordDataImpl &Record);
@@ -693,10 +742,6 @@ public:
return TypeExtQualAbbrev;
}
- unsigned getTypeFunctionProtoAbbrev() const {
- return TypeFunctionProtoAbbrev;
- }
-
unsigned getDeclParmVarAbbrev() const { return DeclParmVarAbbrev; }
unsigned getDeclRecordAbbrev() const { return DeclRecordAbbrev; }
unsigned getDeclTypedefAbbrev() const { return DeclTypedefAbbrev; }
@@ -704,16 +749,49 @@ public:
unsigned getDeclFieldAbbrev() const { return DeclFieldAbbrev; }
unsigned getDeclEnumAbbrev() const { return DeclEnumAbbrev; }
unsigned getDeclObjCIvarAbbrev() const { return DeclObjCIvarAbbrev; }
- unsigned getDeclCXXMethodAbbrev() const { return DeclCXXMethodAbbrev; }
+ unsigned getDeclCXXMethodAbbrev(FunctionDecl::TemplatedKind Kind) const {
+ switch (Kind) {
+ case FunctionDecl::TK_NonTemplate:
+ return DeclCXXMethodAbbrev;
+ case FunctionDecl::TK_FunctionTemplate:
+ return DeclTemplateCXXMethodAbbrev;
+ case FunctionDecl::TK_MemberSpecialization:
+ return DeclMemberSpecializedCXXMethodAbbrev;
+ case FunctionDecl::TK_FunctionTemplateSpecialization:
+ return DeclTemplateSpecializedCXXMethodAbbrev;
+ case FunctionDecl::TK_DependentNonTemplate:
+ return DeclDependentNonTemplateCXXMethodAbbrev;
+ case FunctionDecl::TK_DependentFunctionTemplateSpecialization:
+ return DeclDependentSpecializationCXXMethodAbbrev;
+ }
+ llvm_unreachable("Unknwon Template Kind!");
+ }
+ unsigned getDeclTemplateTypeParmAbbrev() const {
+ return DeclTemplateTypeParmAbbrev;
+ }
+ unsigned getDeclUsingShadowAbbrev() const { return DeclUsingShadowAbbrev; }
unsigned getDeclRefExprAbbrev() const { return DeclRefExprAbbrev; }
unsigned getCharacterLiteralAbbrev() const { return CharacterLiteralAbbrev; }
unsigned getIntegerLiteralAbbrev() const { return IntegerLiteralAbbrev; }
unsigned getExprImplicitCastAbbrev() const { return ExprImplicitCastAbbrev; }
+ unsigned getBinaryOperatorAbbrev() const { return BinaryOperatorAbbrev; }
+ unsigned getCompoundAssignOperatorAbbrev() const {
+ return CompoundAssignOperatorAbbrev;
+ }
+ unsigned getCallExprAbbrev() const { return CallExprAbbrev; }
+ unsigned getCXXOperatorCallExprAbbrev() { return CXXOperatorCallExprAbbrev; }
+ unsigned getCXXMemberCallExprAbbrev() { return CXXMemberCallExprAbbrev; }
+
+ unsigned getCompoundStmtAbbrev() const { return CompoundStmtAbbrev; }
bool hasChain() const { return Chain; }
ASTReader *getChain() const { return Chain; }
+ bool isWritingStdCXXNamedModules() const {
+ return WritingModule && WritingModule->isNamedModule();
+ }
+
private:
// ASTDeserializationListener implementation
void ReaderInitialized(ASTReader *Reader) override;
@@ -784,6 +862,7 @@ public:
std::shared_ptr<PCHBuffer> Buffer,
ArrayRef<std::shared_ptr<ModuleFileExtension>> Extensions,
bool AllowASTWithErrors = false, bool IncludeTimestamps = true,
+ bool BuildingImplicitModule = false,
bool ShouldCacheASTInMemory = false);
~PCHGenerator() override;
@@ -794,6 +873,46 @@ public:
bool hasEmittedPCH() const { return Buffer->IsComplete; }
};
+/// A simple helper class to pack several bits in order into (a) 32 bit
+/// integer(s).
+class BitsPacker {
+ constexpr static uint32_t BitIndexUpbound = 32u;
+
+public:
+ BitsPacker() = default;
+ BitsPacker(const BitsPacker &) = delete;
+ BitsPacker(BitsPacker &&) = delete;
+ BitsPacker operator=(const BitsPacker &) = delete;
+ BitsPacker operator=(BitsPacker &&) = delete;
+ ~BitsPacker() = default;
+
+ bool canWriteNextNBits(uint32_t BitsWidth) const {
+ return CurrentBitIndex + BitsWidth < BitIndexUpbound;
+ }
+
+ void reset(uint32_t Value) {
+ UnderlyingValue = Value;
+ CurrentBitIndex = 0;
+ }
+
+ void addBit(bool Value) { addBits(Value, 1); }
+ void addBits(uint32_t Value, uint32_t BitsWidth) {
+ assert(BitsWidth < BitIndexUpbound);
+ assert((Value < (1u << BitsWidth)) && "Passing narrower bit width!");
+ assert(canWriteNextNBits(BitsWidth) &&
+ "Inserting too much bits into a value!");
+
+ UnderlyingValue |= Value << CurrentBitIndex;
+ CurrentBitIndex += BitsWidth;
+ }
+
+ operator uint32_t() { return UnderlyingValue; }
+
+private:
+ uint32_t UnderlyingValue = 0;
+ uint32_t CurrentBitIndex = 0;
+};
+
} // namespace clang
#endif // LLVM_CLANG_SERIALIZATION_ASTWRITER_H
diff --git a/contrib/llvm-project/clang/include/clang/Serialization/GlobalModuleIndex.h b/contrib/llvm-project/clang/include/clang/Serialization/GlobalModuleIndex.h
index 5f4812626224..93d674e44003 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;
@@ -69,20 +67,20 @@ class GlobalModuleIndex {
/// Information about a given module file.
struct ModuleInfo {
- ModuleInfo() : File(), Size(), ModTime() { }
+ ModuleInfo() = default;
/// The module file, once it has been resolved.
- ModuleFile *File;
+ ModuleFile *File = nullptr;
/// The module file name.
std::string FileName;
/// Size of the module file at the time the global index was built.
- off_t Size;
+ off_t Size = 0;
/// Modification time of the module file at the time the global
/// index was built.
- time_t ModTime;
+ time_t ModTime = 0;
/// The module IDs on which this module directly depends.
/// FIXME: We don't really need a vector here.
@@ -138,12 +136,6 @@ public:
/// The caller accepts ownership of the returned object.
IdentifierIterator *createIdentifierIterator() const;
- /// Retrieve the set of modules that have up-to-date indexes.
- ///
- /// \param ModuleFiles Will be populated with the set of module files that
- /// have been indexed.
- void getKnownModules(llvm::SmallVectorImpl<ModuleFile *> &ModuleFiles);
-
/// Retrieve the set of module files on which the given module file
/// directly depends.
void getModuleDependencies(ModuleFile *File,
diff --git a/contrib/llvm-project/clang/include/clang/Serialization/InMemoryModuleCache.h b/contrib/llvm-project/clang/include/clang/Serialization/InMemoryModuleCache.h
index 7b5b5c1cf1be..fc3ba334fc64 100644
--- a/contrib/llvm-project/clang/include/clang/Serialization/InMemoryModuleCache.h
+++ b/contrib/llvm-project/clang/include/clang/Serialization/InMemoryModuleCache.h
@@ -10,7 +10,6 @@
#define LLVM_CLANG_SERIALIZATION_INMEMORYMODULECACHE_H
#include "llvm/ADT/IntrusiveRefCntPtr.h"
-#include "llvm/ADT/Optional.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/Support/MemoryBuffer.h"
#include <memory>
diff --git a/contrib/llvm-project/clang/include/clang/Serialization/ModuleFile.h b/contrib/llvm-project/clang/include/clang/Serialization/ModuleFile.h
index b1c8a8c8e72b..9a14129d72ff 100644
--- a/contrib/llvm-project/clang/include/clang/Serialization/ModuleFile.h
+++ b/contrib/llvm-project/clang/include/clang/Serialization/ModuleFile.h
@@ -20,6 +20,7 @@
#include "clang/Serialization/ASTBitCodes.h"
#include "clang/Serialization/ContinuousRangeMap.h"
#include "clang/Serialization/ModuleFileExtension.h"
+#include "llvm/ADT/BitVector.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/PointerIntPair.h"
#include "llvm/ADT/SetVector.h"
@@ -58,6 +59,19 @@ enum ModuleKind {
MK_PrebuiltModule
};
+/// The input file info that has been loaded from an AST file.
+struct InputFileInfo {
+ std::string FilenameAsRequested;
+ std::string Filename;
+ uint64_t ContentHash;
+ off_t StoredSize;
+ time_t StoredTime;
+ bool Overridden;
+ bool Transient;
+ bool TopLevel;
+ bool ModuleMap;
+};
+
/// The input file that has been loaded from this AST file, along with
/// bools indicating whether this was an overridden buffer or if it was
/// out-of-date or not-found.
@@ -90,10 +104,10 @@ public:
return File;
}
- OptionalFileEntryRefDegradesToFileEntryPtr getFile() const {
+ OptionalFileEntryRef getFile() const {
if (auto *P = Val.getPointer())
return FileEntryRef(*P);
- return None;
+ return std::nullopt;
}
bool isOverridden() const { return Val.getInt() == Overridden; }
bool isOutOfDate() const { return Val.getInt() == OutOfDate; }
@@ -109,8 +123,8 @@ public:
/// other modules.
class ModuleFile {
public:
- ModuleFile(ModuleKind Kind, unsigned Generation)
- : Kind(Kind), Generation(Generation) {}
+ ModuleFile(ModuleKind Kind, FileEntryRef File, unsigned Generation)
+ : Kind(Kind), File(File), Generation(Generation) {}
~ModuleFile();
// === General information ===
@@ -147,15 +161,14 @@ public:
/// build this AST file.
FileID OriginalSourceFileID;
- /// The directory that the PCH was originally created in. Used to
- /// allow resolving headers even after headers+PCH was moved to a new path.
- std::string OriginalDir;
-
std::string ModuleMapPath;
/// Whether this precompiled header is a relocatable PCH file.
bool RelocatablePCH = false;
+ /// Whether this module file is a standard C++ module.
+ bool StandardCXXModule = false;
+
/// Whether timestamps are included in this module file.
bool HasTimestamps = false;
@@ -163,7 +176,7 @@ public:
bool DidReadTopLevelSubmodule = false;
/// The file entry for the module file.
- OptionalFileEntryRefDegradesToFileEntryPtr File;
+ FileEntryRef File;
/// The signature of the module file, which may be used instead of the size
/// and modification time to identify this particular file.
@@ -173,6 +186,9 @@ public:
/// unique module files based on AST contents.
ASTFileSignature ASTBlockHash;
+ /// The bit vector denoting usage of each header search entry (true = used).
+ llvm::BitVector SearchPathUsage;
+
/// Whether this module has been directly imported by the
/// user.
bool DirectlyImported = false;
@@ -182,7 +198,7 @@ public:
/// The memory buffer that stores the data associated with
/// this AST file, owned by the InMemoryModuleCache.
- llvm::MemoryBuffer *Buffer;
+ llvm::MemoryBuffer *Buffer = nullptr;
/// The size of this file, in bits.
uint64_t SizeInBits = 0;
@@ -229,12 +245,18 @@ public:
/// The cursor to the start of the input-files block.
llvm::BitstreamCursor InputFilesCursor;
- /// Offsets for all of the input file entries in the AST file.
+ /// Absolute offset of the start of the input-files block.
+ uint64_t InputFilesOffsetBase = 0;
+
+ /// Relative offsets for all of the input file entries in the AST file.
const llvm::support::unaligned_uint64_t *InputFileOffsets = nullptr;
/// The input files that have been loaded from this AST file.
std::vector<InputFile> InputFilesLoaded;
+ /// The input file infos that have been loaded from this AST file.
+ std::vector<InputFileInfo> InputFileInfosLoaded;
+
// All user input files reside at the index range [0, NumUserInputFiles), and
// system input files reside at [NumUserInputFiles, InputFilesLoaded.size()).
unsigned NumUserInputFiles = 0;
@@ -270,9 +292,6 @@ public:
/// AST file.
const uint32_t *SLocEntryOffsets = nullptr;
- /// SLocEntries that we're going to preload.
- SmallVector<uint64_t, 4> PreloadSLocEntries;
-
/// Remapping table for source locations in this module.
ContinuousRangeMap<SourceLocation::UIntTy, SourceLocation::IntTy, 2>
SLocRemap;
diff --git a/contrib/llvm-project/clang/include/clang/Serialization/ModuleFileExtension.h b/contrib/llvm-project/clang/include/clang/Serialization/ModuleFileExtension.h
index 34ea870724a4..d7d456c8b5db 100644
--- a/contrib/llvm-project/clang/include/clang/Serialization/ModuleFileExtension.h
+++ b/contrib/llvm-project/clang/include/clang/Serialization/ModuleFileExtension.h
@@ -11,13 +11,14 @@
#include "llvm/ADT/IntrusiveRefCntPtr.h"
#include "llvm/Support/ExtensibleRTTI.h"
+#include "llvm/Support/HashBuilder.h"
+#include "llvm/Support/MD5.h"
#include <memory>
#include <string>
namespace llvm {
class BitstreamCursor;
class BitstreamWriter;
-class hash_code;
class raw_ostream;
}
@@ -74,19 +75,19 @@ public:
virtual ModuleFileExtensionMetadata getExtensionMetadata() const = 0;
/// Hash information about the presence of this extension into the
- /// module hash code.
+ /// module hash.
///
- /// The module hash code is used to distinguish different variants
- /// of a module that are incompatible. If the presence, absence, or
- /// version of the module file extension should force the creation
- /// of a separate set of module files, override this method to
- /// combine that distinguishing information into the module hash
- /// code.
+ /// The module hash is used to distinguish different variants of a module that
+ /// are incompatible. If the presence, absence, or version of the module file
+ /// extension should force the creation of a separate set of module files,
+ /// override this method to combine that distinguishing information into the
+ /// module hash.
///
- /// The default implementation of this function simply returns the
- /// hash code as given, so the presence/absence of this extension
- /// does not distinguish module files.
- virtual llvm::hash_code hashExtension(llvm::hash_code c) const;
+ /// The default implementation of this function simply does nothing, so the
+ /// presence/absence of this extension does not distinguish module files.
+ using ExtensionHashBuilder =
+ llvm::HashBuilder<llvm::MD5, llvm::endianness::native>;
+ virtual void hashExtension(ExtensionHashBuilder &HBuilder) const;
/// Create a new module file extension writer, which will be
/// responsible for writing the extension contents into a particular
@@ -152,4 +153,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..3bd379acf7ed 100644
--- a/contrib/llvm-project/clang/include/clang/Serialization/ModuleManager.h
+++ b/contrib/llvm-project/clang/include/clang/Serialization/ModuleManager.h
@@ -39,7 +39,6 @@ class FileManager;
class GlobalModuleIndex;
class HeaderSearch;
class InMemoryModuleCache;
-class ModuleMap;
class PCHContainerReader;
namespace serialization {
@@ -105,10 +104,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 +116,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 +137,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(); }
@@ -255,7 +249,7 @@ public:
std::string &ErrorStr);
/// Remove the modules starting from First (to the end).
- void removeModules(ModuleIterator First, ModuleMap *modMap);
+ void removeModules(ModuleIterator First);
/// Add an in-memory buffer the list of known buffers
void addInMemoryBuffer(StringRef FileName,
@@ -308,7 +302,7 @@ public:
/// modification time criteria, false if the file is either available and
/// suitable, or is missing.
bool lookupModuleFile(StringRef FileName, off_t ExpectedSize,
- time_t ExpectedModTime, Optional<FileEntryRef> &File);
+ time_t ExpectedModTime, OptionalFileEntryRef &File);
/// View the graphviz representation of the module graph.
void viewGraph();
diff --git a/contrib/llvm-project/clang/include/clang/Serialization/PCHContainerOperations.h b/contrib/llvm-project/clang/include/clang/Serialization/PCHContainerOperations.h
index 33fc4a0a24e0..be10feb5e351 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 {
@@ -58,7 +56,7 @@ class PCHContainerReader {
public:
virtual ~PCHContainerReader() = 0;
/// Equivalent to the format passed to -fmodule-format=
- virtual llvm::StringRef getFormat() const = 0;
+ virtual llvm::ArrayRef<llvm::StringRef> getFormats() const = 0;
/// Returns the serialized AST inside the PCH container Buffer.
virtual llvm::StringRef ExtractPCH(llvm::MemoryBufferRef Buffer) const = 0;
@@ -80,8 +78,7 @@ class RawPCHContainerWriter : public PCHContainerWriter {
/// Implements read operations for a raw pass-through PCH container.
class RawPCHContainerReader : public PCHContainerReader {
- llvm::StringRef getFormat() const override { return "raw"; }
-
+ llvm::ArrayRef<llvm::StringRef> getFormats() const override;
/// Simply returns the buffer contained in Buffer.
llvm::StringRef ExtractPCH(llvm::MemoryBufferRef Buffer) const override;
};
@@ -89,7 +86,9 @@ class RawPCHContainerReader : public PCHContainerReader {
/// A registry of PCHContainerWriter and -Reader objects for different formats.
class PCHContainerOperations {
llvm::StringMap<std::unique_ptr<PCHContainerWriter>> Writers;
- llvm::StringMap<std::unique_ptr<PCHContainerReader>> Readers;
+ llvm::StringMap<PCHContainerReader *> Readers;
+ llvm::SmallVector<std::unique_ptr<PCHContainerReader>> OwnedReaders;
+
public:
/// Automatically registers a RawPCHContainerWriter and
/// RawPCHContainerReader.
@@ -98,13 +97,17 @@ public:
Writers[Writer->getFormat()] = std::move(Writer);
}
void registerReader(std::unique_ptr<PCHContainerReader> Reader) {
- Readers[Reader->getFormat()] = std::move(Reader);
+ assert(!Reader->getFormats().empty() &&
+ "PCHContainerReader must handle >=1 format");
+ for (llvm::StringRef Fmt : Reader->getFormats())
+ Readers[Fmt] = Reader.get();
+ OwnedReaders.push_back(std::move(Reader));
}
const PCHContainerWriter *getWriterOrNull(llvm::StringRef Format) {
return Writers[Format].get();
}
const PCHContainerReader *getReaderOrNull(llvm::StringRef Format) {
- return Readers[Format].get();
+ return Readers[Format];
}
const PCHContainerReader &getRawReader() {
return *getReaderOrNull("raw");
diff --git a/contrib/llvm-project/clang/include/clang/Serialization/SourceLocationEncoding.h b/contrib/llvm-project/clang/include/clang/Serialization/SourceLocationEncoding.h
new file mode 100644
index 000000000000..9bb0dbe2e4d6
--- /dev/null
+++ b/contrib/llvm-project/clang/include/clang/Serialization/SourceLocationEncoding.h
@@ -0,0 +1,163 @@
+//===--- SourceLocationEncoding.h - Small serialized locations --*- 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
+//
+//===----------------------------------------------------------------------===//
+//
+// Source locations are stored pervasively in the AST, making up a third of
+// the size of typical serialized files. Storing them efficiently is important.
+//
+// We use integers optimized by VBR-encoding, because:
+// - when abbreviations cannot be used, VBR6 encoding is our only choice
+// - in the worst case a SourceLocation can be ~any 32-bit number, but in
+// practice they are highly predictable
+//
+// We encode the integer so that likely values encode as small numbers that
+// turn into few VBR chunks:
+// - the invalid sentinel location is a very common value: it encodes as 0
+// - the "macro or not" bit is stored at the bottom of the integer
+// (rather than at the top, as in memory), so macro locations can have
+// small representations.
+// - related locations (e.g. of a left and right paren pair) are usually
+// similar, so when encoding a sequence of locations we store only
+// differences between successive elements.
+//
+//===----------------------------------------------------------------------===//
+
+#include <climits>
+#include "clang/Basic/SourceLocation.h"
+
+#ifndef LLVM_CLANG_SERIALIZATION_SOURCELOCATIONENCODING_H
+#define LLVM_CLANG_SERIALIZATION_SOURCELOCATIONENCODING_H
+
+namespace clang {
+class SourceLocationSequence;
+
+/// Serialized encoding of SourceLocations without context.
+/// Optimized to have small unsigned values (=> small after VBR encoding).
+///
+// Macro locations have the top bit set, we rotate by one so it is the low bit.
+class SourceLocationEncoding {
+ using UIntTy = SourceLocation::UIntTy;
+ constexpr static unsigned UIntBits = CHAR_BIT * sizeof(UIntTy);
+
+ static UIntTy encodeRaw(UIntTy Raw) {
+ return (Raw << 1) | (Raw >> (UIntBits - 1));
+ }
+ static UIntTy decodeRaw(UIntTy Raw) {
+ return (Raw >> 1) | (Raw << (UIntBits - 1));
+ }
+ friend SourceLocationSequence;
+
+public:
+ static uint64_t encode(SourceLocation Loc,
+ SourceLocationSequence * = nullptr);
+ static SourceLocation decode(uint64_t, SourceLocationSequence * = nullptr);
+};
+
+/// Serialized encoding of a sequence of SourceLocations.
+///
+/// Optimized to produce small values when locations with the sequence are
+/// similar. Each element can be delta-encoded against the last nonzero element.
+///
+/// Sequences should be started by creating a SourceLocationSequence::State,
+/// and then passed around as SourceLocationSequence*. Example:
+///
+/// // establishes a sequence
+/// void EmitTopLevelThing() {
+/// SourceLocationSequence::State Seq;
+/// EmitContainedThing(Seq);
+/// EmitRecursiveThing(Seq);
+/// }
+///
+/// // optionally part of a sequence
+/// void EmitContainedThing(SourceLocationSequence *Seq = nullptr) {
+/// Record.push_back(SourceLocationEncoding::encode(SomeLoc, Seq));
+/// }
+///
+/// // establishes a sequence if there isn't one already
+/// void EmitRecursiveThing(SourceLocationSequence *ParentSeq = nullptr) {
+/// SourceLocationSequence::State Seq(ParentSeq);
+/// Record.push_back(SourceLocationEncoding::encode(SomeLoc, Seq));
+/// EmitRecursiveThing(Seq);
+/// }
+///
+class SourceLocationSequence {
+ using UIntTy = SourceLocation::UIntTy;
+ using EncodedTy = uint64_t;
+ constexpr static auto UIntBits = SourceLocationEncoding::UIntBits;
+ static_assert(sizeof(EncodedTy) > sizeof(UIntTy), "Need one extra bit!");
+
+ // Prev stores the rotated last nonzero location.
+ UIntTy &Prev;
+
+ // Zig-zag encoding turns small signed integers into small unsigned integers.
+ // 0 => 0, -1 => 1, 1 => 2, -2 => 3, ...
+ static UIntTy zigZag(UIntTy V) {
+ UIntTy Sign = (V & (1 << (UIntBits - 1))) ? UIntTy(-1) : UIntTy(0);
+ return Sign ^ (V << 1);
+ }
+ static UIntTy zagZig(UIntTy V) { return (V >> 1) ^ -(V & 1); }
+
+ SourceLocationSequence(UIntTy &Prev) : Prev(Prev) {}
+
+ EncodedTy encodeRaw(UIntTy Raw) {
+ if (Raw == 0)
+ return 0;
+ UIntTy Rotated = SourceLocationEncoding::encodeRaw(Raw);
+ if (Prev == 0)
+ return Prev = Rotated;
+ UIntTy Delta = Rotated - Prev;
+ Prev = Rotated;
+ // Exactly one 33 bit value is possible! (1 << 32).
+ // This is because we have two representations of zero: trivial & relative.
+ return 1 + EncodedTy{zigZag(Delta)};
+ }
+ UIntTy decodeRaw(EncodedTy Encoded) {
+ if (Encoded == 0)
+ return 0;
+ if (Prev == 0)
+ return SourceLocationEncoding::decodeRaw(Prev = Encoded);
+ return SourceLocationEncoding::decodeRaw(Prev += zagZig(Encoded - 1));
+ }
+
+public:
+ SourceLocation decode(EncodedTy Encoded) {
+ return SourceLocation::getFromRawEncoding(decodeRaw(Encoded));
+ }
+ EncodedTy encode(SourceLocation Loc) {
+ return encodeRaw(Loc.getRawEncoding());
+ }
+
+ class State;
+};
+
+/// This object establishes a SourceLocationSequence.
+class SourceLocationSequence::State {
+ UIntTy Prev = 0;
+ SourceLocationSequence Seq;
+
+public:
+ // If Parent is provided and non-null, then this root becomes part of that
+ // enclosing sequence instead of establishing a new one.
+ State(SourceLocationSequence *Parent = nullptr)
+ : Seq(Parent ? Parent->Prev : Prev) {}
+
+ // Implicit conversion for uniform use of roots vs propagated sequences.
+ operator SourceLocationSequence *() { return &Seq; }
+};
+
+inline uint64_t SourceLocationEncoding::encode(SourceLocation Loc,
+ SourceLocationSequence *Seq) {
+ return Seq ? Seq->encode(Loc) : encodeRaw(Loc.getRawEncoding());
+}
+inline SourceLocation
+SourceLocationEncoding::decode(uint64_t Encoded, SourceLocationSequence *Seq) {
+ return Seq ? Seq->decode(Encoded)
+ : SourceLocation::getFromRawEncoding(decodeRaw(Encoded));
+}
+
+} // namespace clang
+#endif
diff --git a/contrib/llvm-project/clang/include/clang/Serialization/TypeBitCodes.def b/contrib/llvm-project/clang/include/clang/Serialization/TypeBitCodes.def
index e92e05810648..89ae1a2fa395 100644
--- a/contrib/llvm-project/clang/include/clang/Serialization/TypeBitCodes.def
+++ b/contrib/llvm-project/clang/include/clang/Serialization/TypeBitCodes.def
@@ -58,9 +58,11 @@ TYPE_BIT_CODE(DependentSizedExtVector, DEPENDENT_SIZED_EXT_VECTOR, 46)
TYPE_BIT_CODE(DependentAddressSpace, DEPENDENT_ADDRESS_SPACE, 47)
TYPE_BIT_CODE(DependentVector, DEPENDENT_SIZED_VECTOR, 48)
TYPE_BIT_CODE(MacroQualified, MACRO_QUALIFIED, 49)
-TYPE_BIT_CODE(ExtInt, EXT_INT, 50)
-TYPE_BIT_CODE(DependentExtInt, DEPENDENT_EXT_INT, 51)
+TYPE_BIT_CODE(BitInt, BIT_INT, 50)
+TYPE_BIT_CODE(DependentBitInt, DEPENDENT_BIT_INT, 51)
TYPE_BIT_CODE(ConstantMatrix, CONSTANT_MATRIX, 52)
TYPE_BIT_CODE(DependentSizedMatrix, DEPENDENT_SIZE_MATRIX, 53)
+TYPE_BIT_CODE(Using, USING, 54)
+TYPE_BIT_CODE(BTFTagAttributed, BTFTAG_ATTRIBUTED, 55)
#undef TYPE_BIT_CODE
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/CheckerBase.td b/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Checkers/CheckerBase.td
index 98d26aaa637d..bc1da9bb3f90 100644
--- a/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Checkers/CheckerBase.td
+++ b/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Checkers/CheckerBase.td
@@ -86,15 +86,14 @@ class ParentPackage<Package P> { Package ParentPackage = P; }
class HelpText<string text> { string HelpText = text; }
/// Describes what kind of documentation exists for the checker.
-class DocumentationEnum<bits<2> val> {
- bits<2> Documentation = val;
+class DocumentationEnum<bits<1> val> {
+ bits<1> Documentation = val;
}
def NotDocumented : DocumentationEnum<0>;
def HasDocumentation : DocumentationEnum<1>;
-def HasAlphaDocumentation : DocumentationEnum<2>;
class Documentation<DocumentationEnum val> {
- bits<2> Documentation = val.Documentation;
+ bits<1> Documentation = val.Documentation;
}
/// Describes a checker. Every builtin checker has to be registered with the use
@@ -114,7 +113,7 @@ class Checker<string name = ""> {
list<Checker> Dependencies;
// This field is optional.
list<Checker> WeakDependencies;
- bits<2> Documentation;
+ bits<1> Documentation;
Package ParentPackage;
bit Hidden = 0;
}
diff --git a/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td b/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td
index 444b00d73f0b..e7774e5a9392 100644
--- a/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td
+++ b/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td
@@ -36,6 +36,7 @@ def CoreAlpha : Package<"core">, ParentPackage<Alpha>;
// Note: OptIn is *not* intended for checkers that are too noisy to be on by
// default. Such checkers belong in the alpha package.
def OptIn : Package<"optin">;
+def CoreOptIn : Package<"core">, ParentPackage<OptIn>;
// In the Portability package reside checkers for finding code that relies on
// implementation-defined behavior. Such checks are wanted for cross-platform
@@ -71,8 +72,11 @@ def InsecureAPI : Package<"insecureAPI">, ParentPackage<Security>;
def SecurityAlpha : Package<"security">, ParentPackage<Alpha>;
def Taint : Package<"taint">, ParentPackage<SecurityAlpha>;
-def CERT : Package<"cert">, ParentPackage<SecurityAlpha>;
-def POS : Package<"pos">, ParentPackage<CERT>;
+def CERT : Package<"cert">, ParentPackage<Security>;
+def ENV : Package<"env">, ParentPackage<CERT>;
+
+def CERTAlpha : Package<"cert">, ParentPackage<SecurityAlpha>;
+def POSAlpha : Package<"pos">, ParentPackage<CERTAlpha>;
def Unix : Package<"unix">;
def UnixAlpha : Package<"unix">, ParentPackage<Alpha>;
@@ -125,6 +129,19 @@ def WebKitAlpha : Package<"webkit">, ParentPackage<Alpha>;
let ParentPackage = Core in {
+def BitwiseShiftChecker : Checker<"BitwiseShift">,
+ HelpText<"Finds cases where bitwise shift operation causes undefined behaviour.">,
+ CheckerOptions<[
+ CmdLineOption<Boolean,
+ "Pedantic",
+ "If set to true, the checker reports undefined behavior even "
+ "if it is supported by most compilers. (This flag has no "
+ "effect in C++20 where these constructs are legal.)",
+ "false",
+ Released>,
+ ]>,
+ Documentation<HasDocumentation>;
+
def CallAndMessageModeling : Checker<"CallAndMessageModeling">,
HelpText<"Responsible for essential modeling and assumptions after a "
"function/method call. For instance, if we can't reason about the "
@@ -190,6 +207,13 @@ def CallAndMessageChecker : Checker<"CallAndMessage">,
def DereferenceChecker : Checker<"NullDereference">,
HelpText<"Check for dereferences of null pointers">,
+ CheckerOptions<[
+ CmdLineOption<Boolean,
+ "SuppressAddressSpaces",
+ "Suppresses warning when pointer dereferences an address space",
+ "true",
+ Released>
+ ]>,
Documentation<HasDocumentation>;
def NonNullParamChecker : Checker<"NonNullParamChecker">,
@@ -235,57 +259,57 @@ let ParentPackage = CoreAlpha in {
def BoolAssignmentChecker : Checker<"BoolAssignment">,
HelpText<"Warn about assigning non-{0,1} values to Boolean variables">,
- Documentation<HasAlphaDocumentation>;
+ Documentation<HasDocumentation>;
def CastSizeChecker : Checker<"CastSize">,
HelpText<"Check when casting a malloc'ed type T, whether the size is a "
"multiple of the size of T">,
- Documentation<HasAlphaDocumentation>;
+ Documentation<HasDocumentation>;
def CastToStructChecker : Checker<"CastToStruct">,
HelpText<"Check for cast from non-struct pointer to struct pointer">,
- Documentation<HasAlphaDocumentation>;
+ Documentation<HasDocumentation>;
def ConversionChecker : Checker<"Conversion">,
HelpText<"Loss of sign/precision in implicit conversions">,
- Documentation<HasAlphaDocumentation>;
+ Documentation<HasDocumentation>;
def IdenticalExprChecker : Checker<"IdenticalExpr">,
HelpText<"Warn about unintended use of identical expressions in operators">,
- Documentation<HasAlphaDocumentation>;
+ Documentation<HasDocumentation>;
def FixedAddressChecker : Checker<"FixedAddr">,
HelpText<"Check for assignment of a fixed address to a pointer">,
- Documentation<HasAlphaDocumentation>;
+ Documentation<HasDocumentation>;
def PointerArithChecker : Checker<"PointerArithm">,
HelpText<"Check for pointer arithmetic on locations other than array "
"elements">,
- Documentation<HasAlphaDocumentation>;
+ Documentation<HasDocumentation>;
def PointerSubChecker : Checker<"PointerSub">,
HelpText<"Check for pointer subtractions on two pointers pointing to "
"different memory chunks">,
- Documentation<HasAlphaDocumentation>;
+ Documentation<HasDocumentation>;
def SizeofPointerChecker : Checker<"SizeofPtr">,
HelpText<"Warn about unintended use of sizeof() on pointer expressions">,
- Documentation<HasAlphaDocumentation>;
+ Documentation<HasDocumentation>;
def TestAfterDivZeroChecker : Checker<"TestAfterDivZero">,
HelpText<"Check for division by variable that is later compared against 0. "
"Either the comparison is useless or there is division by zero.">,
- Documentation<HasAlphaDocumentation>;
+ Documentation<HasDocumentation>;
def DynamicTypeChecker : Checker<"DynamicTypeChecker">,
HelpText<"Check for cases where the dynamic and the static type of an object "
"are unrelated.">,
- Documentation<HasAlphaDocumentation>;
+ Documentation<HasDocumentation>;
def StackAddrAsyncEscapeChecker : Checker<"StackAddressAsyncEscape">,
HelpText<"Check that addresses to stack memory do not escape the function">,
Dependencies<[StackAddrEscapeBase]>,
- Documentation<HasAlphaDocumentation>;
+ Documentation<HasDocumentation>;
def PthreadLockBase : Checker<"PthreadLockBase">,
HelpText<"Helper registering multiple checks.">,
@@ -295,7 +319,11 @@ def PthreadLockBase : Checker<"PthreadLockBase">,
def C11LockChecker : Checker<"C11Lock">,
HelpText<"Simple lock -> unlock checker">,
Dependencies<[PthreadLockBase]>,
- Documentation<HasAlphaDocumentation>;
+ Documentation<HasDocumentation>;
+
+def StdVariantChecker : Checker<"StdVariant">,
+ HelpText<"Check for bad type access for std::variant.">,
+ Documentation<HasDocumentation>;
} // end "alpha.core"
@@ -347,34 +375,20 @@ def NullableReturnedFromNonnullChecker : Checker<"NullableReturnedFromNonnull">,
let ParentPackage = APIModeling in {
-def StdCLibraryFunctionsChecker : Checker<"StdCLibraryFunctions">,
- HelpText<"Improve modeling of the C standard library functions">,
- // Uninitialized value check is a mandatory dependency. This Checker asserts
- // that arguments are always initialized.
- Dependencies<[CallAndMessageModeling]>,
- CheckerOptions<[
- CmdLineOption<Boolean,
- "DisplayLoadedSummaries",
- "If set to true, the checker displays the found summaries "
- "for the given translation unit.",
- "false",
- Released,
- Hide>,
- CmdLineOption<Boolean,
- "ModelPOSIX",
- "If set to true, the checker models functions from the "
- "POSIX standard.",
- "false",
- InAlpha>
- ]>,
- Documentation<NotDocumented>,
- Hidden;
+def ErrnoModeling : Checker<"Errno">,
+ HelpText<"Make the special value 'errno' available to other checkers.">,
+ Documentation<NotDocumented>;
def TrustNonnullChecker : Checker<"TrustNonnull">,
HelpText<"Trust that returns from framework methods annotated with _Nonnull "
"are not null">,
Documentation<NotDocumented>;
+def TrustReturnsNonnullChecker : Checker<"TrustReturnsNonnull">,
+ HelpText<"Trust that returns from methods annotated with returns_nonnull "
+ "are not null">,
+ Documentation<NotDocumented>;
+
} // end "apiModeling"
//===----------------------------------------------------------------------===//
@@ -420,9 +434,25 @@ def ReturnUndefChecker : Checker<"UndefReturn">,
HelpText<"Check for uninitialized values being returned to the caller">,
Documentation<HasDocumentation>;
+def UndefinedNewArraySizeChecker : Checker<"NewArraySize">,
+ HelpText<"Check if the size of the array in a new[] expression is undefined">,
+ Documentation<HasDocumentation>;
+
} // end "core.uninitialized"
//===----------------------------------------------------------------------===//
+// Optin checkers for core language features
+//===----------------------------------------------------------------------===//
+
+let ParentPackage = CoreOptIn in {
+
+def EnumCastOutOfRangeChecker : Checker<"EnumCastOutOfRange">,
+ HelpText<"Check integer to enumeration casts for out of range values">,
+ Documentation<HasDocumentation>;
+
+} // end "optin.core"
+
+//===----------------------------------------------------------------------===//
// Unix API checkers.
//===----------------------------------------------------------------------===//
@@ -454,17 +484,22 @@ let ParentPackage = CStringAlpha in {
def CStringOutOfBounds : Checker<"OutOfBounds">,
HelpText<"Check for out-of-bounds access in string functions">,
Dependencies<[CStringModeling]>,
- Documentation<HasAlphaDocumentation>;
+ Documentation<HasDocumentation>;
def CStringBufferOverlap : Checker<"BufferOverlap">,
HelpText<"Checks for overlap in two buffer arguments">,
Dependencies<[CStringModeling]>,
- Documentation<HasAlphaDocumentation>;
+ Documentation<HasDocumentation>;
def CStringNotNullTerm : Checker<"NotNullTerminated">,
HelpText<"Check for arguments which are not null-terminating strings">,
Dependencies<[CStringModeling]>,
- Documentation<HasAlphaDocumentation>;
+ Documentation<HasDocumentation>;
+
+def CStringUninitializedRead : Checker<"UninitializedRead">,
+ HelpText<"Checks if the string manipulation function would read uninitialized bytes">,
+ Dependencies<[CStringModeling]>,
+ Documentation<HasDocumentation>;
} // end "alpha.unix.cstring"
@@ -485,12 +520,34 @@ def DynamicMemoryModeling: Checker<"DynamicMemoryModeling">,
"allocating and deallocating functions are annotated with "
"ownership_holds, ownership_takes and ownership_returns.",
"false",
- InAlpha>
+ InAlpha>,
+ CmdLineOption<Boolean,
+ "AddNoOwnershipChangeNotes",
+ "Add an additional note to the bug report for leak-like "
+ "bugs. Dynamically allocated objects passed to functions "
+ "that neither deallocated it, or have taken responsibility "
+ "of the ownership are noted, similarly to "
+ "NoStoreFuncVisitor.",
+ "true",
+ Released,
+ Hide>
]>,
Dependencies<[CStringModeling]>,
Documentation<NotDocumented>,
Hidden;
+def ErrnoChecker : Checker<"Errno">,
+ HelpText<"Check for improper use of 'errno'">,
+ Dependencies<[ErrnoModeling]>,
+ CheckerOptions<[
+ CmdLineOption<Boolean,
+ "AllowErrnoReadOutsideConditionExpressions",
+ "Allow read of undefined value from errno outside of conditions",
+ "true",
+ InAlpha>,
+ ]>,
+ Documentation<HasDocumentation>;
+
def MallocChecker: Checker<"Malloc">,
HelpText<"Check for memory leaks, double free, and use-after-free problems. "
"Traces memory managed by malloc()/free().">,
@@ -506,6 +563,27 @@ def MismatchedDeallocatorChecker : Checker<"MismatchedDeallocator">,
Dependencies<[DynamicMemoryModeling]>,
Documentation<HasDocumentation>;
+def StdCLibraryFunctionsChecker : Checker<"StdCLibraryFunctions">,
+ HelpText<"Check for invalid arguments of C standard library functions, "
+ "and apply relations between arguments and return value">,
+ CheckerOptions<[
+ CmdLineOption<Boolean,
+ "DisplayLoadedSummaries",
+ "If set to true, the checker displays the found summaries "
+ "for the given translation unit.",
+ "false",
+ Released,
+ Hide>,
+ CmdLineOption<Boolean,
+ "ModelPOSIX",
+ "If set to true, the checker models additional functions "
+ "from the POSIX standard.",
+ "false",
+ InAlpha>
+ ]>,
+ WeakDependencies<[CallAndMessageChecker, NonNullParamChecker]>,
+ Documentation<HasDocumentation>;
+
def VforkChecker : Checker<"Vfork">,
HelpText<"Check for proper usage of vfork">,
Documentation<HasDocumentation>;
@@ -516,32 +594,25 @@ let ParentPackage = UnixAlpha in {
def ChrootChecker : Checker<"Chroot">,
HelpText<"Check improper use of chroot">,
- Documentation<HasAlphaDocumentation>;
+ Documentation<HasDocumentation>;
def PthreadLockChecker : Checker<"PthreadLock">,
HelpText<"Simple lock -> unlock checker">,
Dependencies<[PthreadLockBase]>,
- Documentation<HasAlphaDocumentation>;
+ Documentation<HasDocumentation>;
def StreamChecker : Checker<"Stream">,
HelpText<"Check stream handling functions">,
- Documentation<HasAlphaDocumentation>;
+ WeakDependencies<[NonNullParamChecker]>,
+ Documentation<HasDocumentation>;
def SimpleStreamChecker : Checker<"SimpleStream">,
HelpText<"Check for misuses of stream APIs">,
- Documentation<HasAlphaDocumentation>;
+ Documentation<HasDocumentation>;
def BlockInCriticalSectionChecker : Checker<"BlockInCriticalSection">,
HelpText<"Check for calls to blocking functions inside a critical section">,
- Documentation<HasAlphaDocumentation>;
-
-def StdCLibraryFunctionArgsChecker : Checker<"StdCLibraryFunctionArgs">,
- HelpText<"Check constraints of arguments of C standard library functions, "
- "such as whether the parameter of isalpha is in the range [0, 255] "
- "or is EOF.">,
- Dependencies<[StdCLibraryFunctionsChecker]>,
- WeakDependencies<[CallAndMessageChecker, NonNullParamChecker, StreamChecker]>,
- Documentation<NotDocumented>;
+ Documentation<HasDocumentation>;
} // end "alpha.unix"
@@ -592,6 +663,10 @@ def SmartPtrModeling: Checker<"SmartPtrModeling">,
]>,
Hidden;
+def StringChecker: Checker<"StringChecker">,
+ HelpText<"Checks C++ std::string bugs">,
+ Documentation<HasDocumentation>;
+
def MoveChecker: Checker<"Move">,
HelpText<"Find use-after-move bugs in C++">,
CheckerOptions<[
@@ -672,7 +747,7 @@ def UninitializedObjectChecker: Checker<"UninitializedObject">,
"false",
InAlpha>
]>,
- Documentation<HasAlphaDocumentation>;
+ Documentation<HasDocumentation>;
def VirtualCallChecker : Checker<"VirtualCall">,
HelpText<"Check virtual function calls during construction/destruction">,
@@ -702,14 +777,15 @@ def ContainerModeling : Checker<"ContainerModeling">,
Documentation<NotDocumented>,
Hidden;
+def CXXArrayDeleteChecker : Checker<"ArrayDelete">,
+ HelpText<"Reports destructions of arrays of polymorphic objects that are "
+ "destructed as their base class.">,
+ Documentation<HasDocumentation>;
+
def DeleteWithNonVirtualDtorChecker : Checker<"DeleteWithNonVirtualDtor">,
HelpText<"Reports destructions of polymorphic objects with a non-virtual "
"destructor in their base class">,
- Documentation<HasAlphaDocumentation>;
-
-def EnumCastOutOfRangeChecker : Checker<"EnumCastOutOfRange">,
- HelpText<"Check integer to enumeration casts for out of range values">,
- Documentation<HasAlphaDocumentation>;
+ Documentation<HasDocumentation>;
def IteratorModeling : Checker<"IteratorModeling">,
HelpText<"Models iterators of C++ containers">,
@@ -733,23 +809,23 @@ def STLAlgorithmModeling : Checker<"STLAlgorithmModeling">,
def InvalidatedIteratorChecker : Checker<"InvalidatedIterator">,
HelpText<"Check for use of invalidated iterators">,
Dependencies<[IteratorModeling]>,
- Documentation<HasAlphaDocumentation>;
+ Documentation<HasDocumentation>;
def IteratorRangeChecker : Checker<"IteratorRange">,
HelpText<"Check for iterators used outside their valid ranges">,
Dependencies<[IteratorModeling]>,
- Documentation<HasAlphaDocumentation>;
+ Documentation<HasDocumentation>;
def MismatchedIteratorChecker : Checker<"MismatchedIterator">,
HelpText<"Check for use of iterators of different containers where iterators "
"of the same container are expected">,
Dependencies<[IteratorModeling]>,
- Documentation<HasAlphaDocumentation>;
+ Documentation<HasDocumentation>;
def SmartPtrChecker: Checker<"SmartPtr">,
HelpText<"Find the dereference of null SmrtPtr">,
Dependencies<[SmartPtrModeling]>,
- Documentation<HasAlphaDocumentation>;
+ Documentation<HasDocumentation>;
} // end: "alpha.cplusplus"
@@ -812,7 +888,7 @@ let ParentPackage = DeadCodeAlpha in {
def UnreachableCodeChecker : Checker<"UnreachableCode">,
HelpText<"Check unreachable code">,
- Documentation<HasAlphaDocumentation>;
+ Documentation<HasDocumentation>;
} // end "alpha.deadcode"
@@ -928,7 +1004,24 @@ def FloatLoopCounter : Checker<"FloatLoopCounter">,
} // end "security"
-let ParentPackage = POS in {
+let ParentPackage = ENV in {
+
+ def InvalidPtrChecker : Checker<"InvalidPtr">,
+ HelpText<"Finds usages of possibly invalidated pointers">,
+ CheckerOptions<[
+ CmdLineOption<Boolean,
+ "InvalidatingGetEnv",
+ "Regard getenv as an invalidating call (as per POSIX "
+ "standard), which can lead to false positives depending on "
+ "implementation.",
+ "false",
+ Released>,
+ ]>,
+ Documentation<HasDocumentation>;
+
+} // end "security.cert.env"
+
+let ParentPackage = POSAlpha in {
def PutenvWithAuto : Checker<"34c">,
HelpText<"Finds calls to the 'putenv' function which pass a pointer to "
@@ -941,19 +1034,19 @@ let ParentPackage = SecurityAlpha in {
def ArrayBoundChecker : Checker<"ArrayBound">,
HelpText<"Warn about buffer overflows (older checker)">,
- Documentation<HasAlphaDocumentation>;
+ Documentation<HasDocumentation>;
def ArrayBoundCheckerV2 : Checker<"ArrayBoundV2">,
HelpText<"Warn about buffer overflows (newer checker)">,
- Documentation<HasAlphaDocumentation>;
+ Documentation<HasDocumentation>;
def ReturnPointerRangeChecker : Checker<"ReturnPtrRange">,
HelpText<"Check for an out-of-bound pointer being returned to callers">,
- Documentation<HasAlphaDocumentation>;
+ Documentation<HasDocumentation>;
def MallocOverflowSecurityChecker : Checker<"MallocOverflow">,
HelpText<"Check for overflows in the arguments to malloc()">,
- Documentation<HasAlphaDocumentation>;
+ Documentation<HasDocumentation>;
def MmapWriteExecChecker : Checker<"MmapWriteExec">,
HelpText<"Warn on mmap() calls that are both writable and executable">,
@@ -969,7 +1062,7 @@ def MmapWriteExecChecker : Checker<"MmapWriteExec">,
"0x01",
Released>
]>,
- Documentation<HasAlphaDocumentation>;
+ Documentation<HasDocumentation>;
} // end "alpha.security"
@@ -988,7 +1081,7 @@ def GenericTaintChecker : Checker<"TaintPropagation">,
"",
InAlpha>,
]>,
- Documentation<HasAlphaDocumentation>;
+ Documentation<HasDocumentation>;
} // end "alpha.security.taint"
@@ -1179,13 +1272,13 @@ def InstanceVariableInvalidation : Checker<"InstanceVariableInvalidation">,
HelpText<"Check that the invalidatable instance variables are invalidated in "
"the methods annotated with objc_instance_variable_invalidator">,
Dependencies<[IvarInvalidationModeling]>,
- Documentation<HasAlphaDocumentation>;
+ Documentation<HasDocumentation>;
def MissingInvalidationMethod : Checker<"MissingInvalidationMethod">,
HelpText<"Check that the invalidation methods are present in classes that "
"contain invalidatable instance variables">,
Dependencies<[IvarInvalidationModeling]>,
- Documentation<HasAlphaDocumentation>;
+ Documentation<HasDocumentation>;
def DirectIvarAssignment : Checker<"DirectIvarAssignment">,
HelpText<"Check for direct assignments to instance variables">,
@@ -1198,7 +1291,7 @@ def DirectIvarAssignment : Checker<"DirectIvarAssignment">,
"false",
InAlpha>
]>,
- Documentation<HasAlphaDocumentation>;
+ Documentation<HasDocumentation>;
} // end "alpha.osx.cocoa"
@@ -1264,7 +1357,7 @@ let ParentPackage = LocalizabilityAlpha in {
def PluralMisuseChecker : Checker<"PluralMisuseChecker">,
HelpText<"Warns against using one vs. many plural pattern in code when "
"generating localized strings.">,
- Documentation<HasAlphaDocumentation>;
+ Documentation<HasDocumentation>;
} // end "alpha.osx.cocoa.localizability"
@@ -1284,7 +1377,7 @@ let ParentPackage = LLVMAlpha in {
def LLVMConventionsChecker : Checker<"Conventions">,
HelpText<"Check code for LLVM codebase conventions">,
- Documentation<HasAlphaDocumentation>;
+ Documentation<HasDocumentation>;
} // end "llvm"
@@ -1528,6 +1621,11 @@ def StreamTesterChecker : Checker<"StreamTester">,
"purposes.">,
Documentation<NotDocumented>;
+def ErrnoTesterChecker : Checker<"ErrnoTest">,
+ HelpText<"Check modeling aspects of 'errno'.">,
+ Dependencies<[ErrnoModeling]>,
+ Documentation<NotDocumented>;
+
def ExprInspectionChecker : Checker<"ExprInspection">,
HelpText<"Check the analyzer's understanding of expressions">,
Documentation<NotDocumented>;
@@ -1553,7 +1651,7 @@ def DebugIteratorModeling : Checker<"DebugIteratorModeling">,
def StdCLibraryFunctionsTesterChecker : Checker<"StdCLibraryFunctionsTester">,
HelpText<"Add test functions to the summary map, so testing of individual "
"summary constituents becomes possible.">,
- Dependencies<[StdCLibraryFunctionsChecker]>,
+ WeakDependencies<[StdCLibraryFunctionsChecker]>,
Documentation<NotDocumented>;
} // end "debug"
@@ -1589,7 +1687,7 @@ def CloneChecker : Checker<"CloneChecker">,
"\"\"",
Released>
]>,
- Documentation<HasAlphaDocumentation>;
+ Documentation<HasDocumentation>;
} // end "clone"
diff --git a/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Checkers/LocalCheckers.h b/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Checkers/LocalCheckers.h
deleted file mode 100644
index 8f7148fde19a..000000000000
--- a/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Checkers/LocalCheckers.h
+++ /dev/null
@@ -1,27 +0,0 @@
-//==- LocalCheckers.h - Intra-Procedural+Flow-Sensitive Checkers -*- 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 the interface to call a set of intra-procedural (local)
-// checkers that use flow/path-sensitive analyses to find bugs.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_STATICANALYZER_CHECKERS_LOCALCHECKERS_H
-#define LLVM_CLANG_STATICANALYZER_CHECKERS_LOCALCHECKERS_H
-
-namespace clang {
-namespace ento {
-
-class ExprEngine;
-
-void RegisterCallInliner(ExprEngine &Eng);
-
-} // end namespace ento
-} // end namespace clang
-
-#endif
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/Checkers/SValExplainer.h b/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Checkers/SValExplainer.h
index 31a4ed50a723..43a70f596a4d 100644
--- a/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Checkers/SValExplainer.h
+++ b/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Checkers/SValExplainer.h
@@ -32,7 +32,7 @@ private:
std::string Str;
llvm::raw_string_ostream OS(Str);
S->printPretty(OS, nullptr, PrintingPolicy(ACtx.getLangOpts()));
- return OS.str();
+ return Str;
}
bool isThisObject(const SymbolicRegion *R) {
@@ -42,6 +42,18 @@ private:
return false;
}
+ bool isThisObject(const ElementRegion *R) {
+ if (const auto *Idx = R->getIndex().getAsInteger()) {
+ if (const auto *SR = R->getSuperRegion()->getAs<SymbolicRegion>()) {
+ QualType Ty = SR->getPointeeStaticType();
+ bool IsNotReinterpretCast = R->getValueType() == Ty;
+ if (Idx->isZero() && IsNotReinterpretCast)
+ return isThisObject(SR);
+ }
+ }
+ return false;
+ }
+
public:
SValExplainer(ASTContext &Ctx) : ACtx(Ctx) {}
@@ -53,7 +65,7 @@ public:
return "undefined value";
}
- std::string VisitLocMemRegionVal(loc::MemRegionVal V) {
+ std::string VisitMemRegionVal(loc::MemRegionVal V) {
const MemRegion *R = V.getRegion();
// Avoid the weird "pointer to pointee of ...".
if (auto SR = dyn_cast<SymbolicRegion>(R)) {
@@ -64,28 +76,28 @@ public:
return "pointer to " + Visit(R);
}
- std::string VisitLocConcreteInt(loc::ConcreteInt V) {
+ std::string VisitConcreteInt(loc::ConcreteInt V) {
const llvm::APSInt &I = V.getValue();
std::string Str;
llvm::raw_string_ostream OS(Str);
OS << "concrete memory address '" << I << "'";
- return OS.str();
+ return Str;
}
- std::string VisitNonLocSymbolVal(nonloc::SymbolVal V) {
+ std::string VisitSymbolVal(nonloc::SymbolVal V) {
return Visit(V.getSymbol());
}
- std::string VisitNonLocConcreteInt(nonloc::ConcreteInt V) {
+ std::string VisitConcreteInt(nonloc::ConcreteInt V) {
const llvm::APSInt &I = V.getValue();
std::string Str;
llvm::raw_string_ostream OS(Str);
OS << (I.isSigned() ? "signed " : "unsigned ") << I.getBitWidth()
<< "-bit integer '" << I << "'";
- return OS.str();
+ return Str;
}
- std::string VisitNonLocLazyCompoundVal(nonloc::LazyCompoundVal V) {
+ std::string VisitLazyCompoundVal(nonloc::LazyCompoundVal V) {
return "lazily frozen compound value of " + Visit(V.getRegion());
}
@@ -123,7 +135,7 @@ public:
OS << "(" << Visit(S->getLHS()) << ") "
<< std::string(BinaryOperator::getOpcodeStr(S->getOpcode())) << " "
<< S->getRHS();
- return OS.str();
+ return Str;
}
// TODO: IntSymExpr doesn't appear in practice.
@@ -135,11 +147,16 @@ public:
" (" + Visit(S->getRHS()) + ")";
}
+ std::string VisitUnarySymExpr(const UnarySymExpr *S) {
+ return std::string(UnaryOperator::getOpcodeStr(S->getOpcode())) + " (" +
+ Visit(S->getOperand()) + ")";
+ }
+
// TODO: SymbolCast doesn't appear in practice.
// Add the relevant code once it does.
std::string VisitSymbolicRegion(const SymbolicRegion *R) {
- // Explain 'this' object here.
+ // Explain 'this' object here - if it's not wrapped by an ElementRegion.
// TODO: Explain CXXThisRegion itself, find a way to test it.
if (isThisObject(R))
return "'this' object";
@@ -169,15 +186,21 @@ public:
std::string VisitElementRegion(const ElementRegion *R) {
std::string Str;
llvm::raw_string_ostream OS(Str);
- OS << "element of type '" << R->getElementType().getAsString()
- << "' with index ";
+
+ // Explain 'this' object here.
+ // They are represented by a SymRegion wrapped by an ElementRegion; so
+ // match and handle it here.
+ if (isThisObject(R))
+ return "'this' object";
+
+ OS << "element of type '" << R->getElementType() << "' with index ";
// For concrete index: omit type of the index integer.
if (auto I = R->getIndex().getAs<nonloc::ConcreteInt>())
OS << I->getValue();
else
OS << "'" << Visit(R->getIndex()) << "'";
OS << " of " + Visit(R->getSuperRegion());
- return OS.str();
+ return Str;
}
std::string VisitNonParamVarRegion(const NonParamVarRegion *R) {
diff --git a/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Checkers/Taint.h b/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Checkers/Taint.h
new file mode 100644
index 000000000000..3ec8dbfb09ee
--- /dev/null
+++ b/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Checkers/Taint.h
@@ -0,0 +1,128 @@
+//=== Taint.h - Taint tracking and basic propagation rules. --------*- 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
+//
+//===----------------------------------------------------------------------===//
+//
+// Defines basic, non-domain-specific mechanisms for tracking tainted values.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_LIB_STATICANALYZER_CHECKERS_TAINT_H
+#define LLVM_CLANG_LIB_STATICANALYZER_CHECKERS_TAINT_H
+
+#include "clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitors.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"
+
+namespace clang {
+namespace ento {
+namespace taint {
+
+/// The type of taint, which helps to differentiate between different types of
+/// taint.
+using TaintTagType = unsigned;
+
+static constexpr TaintTagType TaintTagGeneric = 0;
+
+/// Create a new state in which the value of the statement is marked as tainted.
+[[nodiscard]] ProgramStateRef addTaint(ProgramStateRef State, const Stmt *S,
+ const LocationContext *LCtx,
+ TaintTagType Kind = TaintTagGeneric);
+
+/// Create a new state in which the value is marked as tainted.
+[[nodiscard]] ProgramStateRef addTaint(ProgramStateRef State, SVal V,
+ TaintTagType Kind = TaintTagGeneric);
+
+/// Create a new state in which the symbol is marked as tainted.
+[[nodiscard]] ProgramStateRef addTaint(ProgramStateRef State, SymbolRef Sym,
+ TaintTagType Kind = TaintTagGeneric);
+
+/// Create a new state in which the pointer represented by the region
+/// is marked as tainted.
+[[nodiscard]] ProgramStateRef addTaint(ProgramStateRef State,
+ const MemRegion *R,
+ TaintTagType Kind = TaintTagGeneric);
+
+[[nodiscard]] ProgramStateRef removeTaint(ProgramStateRef State, SVal V);
+
+[[nodiscard]] ProgramStateRef removeTaint(ProgramStateRef State,
+ const MemRegion *R);
+
+[[nodiscard]] ProgramStateRef removeTaint(ProgramStateRef State, SymbolRef Sym);
+
+/// Create a new state in a which a sub-region of a given symbol is tainted.
+/// This might be necessary when referring to regions that can not have an
+/// individual symbol, e.g. if they are represented by the default binding of
+/// a LazyCompoundVal.
+[[nodiscard]] ProgramStateRef
+addPartialTaint(ProgramStateRef State, SymbolRef ParentSym,
+ const SubRegion *SubRegion,
+ TaintTagType Kind = TaintTagGeneric);
+
+/// Check if the statement has a tainted value in the given state.
+bool isTainted(ProgramStateRef State, const Stmt *S,
+ const LocationContext *LCtx,
+ TaintTagType Kind = TaintTagGeneric);
+
+/// Check if the value is tainted in the given state.
+bool isTainted(ProgramStateRef State, SVal V,
+ TaintTagType Kind = TaintTagGeneric);
+
+/// Check if the symbol is tainted in the given state.
+bool isTainted(ProgramStateRef State, SymbolRef Sym,
+ TaintTagType Kind = TaintTagGeneric);
+
+/// Check if the pointer represented by the region is tainted in the given
+/// state.
+bool isTainted(ProgramStateRef State, const MemRegion *Reg,
+ TaintTagType Kind = TaintTagGeneric);
+
+/// Returns the tainted Symbols for a given Statement and state.
+std::vector<SymbolRef> getTaintedSymbols(ProgramStateRef State, const Stmt *S,
+ const LocationContext *LCtx,
+ TaintTagType Kind = TaintTagGeneric);
+
+/// Returns the tainted Symbols for a given SVal and state.
+std::vector<SymbolRef> getTaintedSymbols(ProgramStateRef State, SVal V,
+ TaintTagType Kind = TaintTagGeneric);
+
+/// Returns the tainted Symbols for a SymbolRef and state.
+std::vector<SymbolRef> getTaintedSymbols(ProgramStateRef State, SymbolRef Sym,
+ TaintTagType Kind = TaintTagGeneric);
+
+/// Returns the tainted (index, super/sub region, symbolic region) symbols
+/// for a given memory region.
+std::vector<SymbolRef> getTaintedSymbols(ProgramStateRef State,
+ const MemRegion *Reg,
+ TaintTagType Kind = TaintTagGeneric);
+
+std::vector<SymbolRef> getTaintedSymbolsImpl(ProgramStateRef State,
+ const Stmt *S,
+ const LocationContext *LCtx,
+ TaintTagType Kind,
+ bool returnFirstOnly);
+
+std::vector<SymbolRef> getTaintedSymbolsImpl(ProgramStateRef State, SVal V,
+ TaintTagType Kind,
+ bool returnFirstOnly);
+
+std::vector<SymbolRef> getTaintedSymbolsImpl(ProgramStateRef State,
+ SymbolRef Sym, TaintTagType Kind,
+ bool returnFirstOnly);
+
+std::vector<SymbolRef> getTaintedSymbolsImpl(ProgramStateRef State,
+ const MemRegion *Reg,
+ TaintTagType Kind,
+ bool returnFirstOnly);
+
+void printTaint(ProgramStateRef State, raw_ostream &Out, const char *nl = "\n",
+ const char *sep = "");
+
+LLVM_DUMP_METHOD void dumpTaint(ProgramStateRef State);
+} // namespace taint
+} // namespace ento
+} // namespace clang
+
+#endif
diff --git a/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/Analyses.def b/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/Analyses.def
index 88c375ce0925..51803e7c1f0d 100644
--- a/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/Analyses.def
+++ b/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/Analyses.def
@@ -10,13 +10,6 @@
//
//===----------------------------------------------------------------------===//
-#ifndef ANALYSIS_STORE
-#define ANALYSIS_STORE(NAME, CMDFLAG, DESC, CREATFN)
-#endif
-
-ANALYSIS_STORE(RegionStore, "region", "Use region-based analyzer store",
- CreateRegionStoreManager)
-
#ifndef ANALYSIS_CONSTRAINTS
#define ANALYSIS_CONSTRAINTS(NAME, CMDFLAG, DESC, CREATFN)
#endif
@@ -94,7 +87,6 @@ ANALYSIS_INLINING_MODE(
NoRedundancy, "noredundancy",
"Do not analyze a function which has been previously inlined")
-#undef ANALYSIS_STORE
#undef ANALYSIS_CONSTRAINTS
#undef ANALYSIS_DIAGNOSTICS
#undef ANALYSIS_PURGE
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 f0359d2dbb3c..2fc825c2af9c 100644
--- a/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/AnalyzerOptions.def
+++ b/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/AnalyzerOptions.def
@@ -128,7 +128,8 @@ ANALYZER_OPTION(bool, MayInlineCXXStandardLibrary, "c++-stdlib-inlining",
true)
ANALYZER_OPTION(bool, MayInlineCXXAllocator, "c++-allocator-inlining",
- "Whether or not allocator call may be considered for inlining.",
+ "Whether or not allocator and deallocator calls may be "
+ "considered for inlining.",
true)
ANALYZER_OPTION(
@@ -190,7 +191,13 @@ ANALYZER_OPTION(bool, ShouldReportIssuesInMainSourceFile,
false)
ANALYZER_OPTION(bool, ShouldWriteStableReportFilename, "stable-report-filename",
- "Whether or not the report filename should be random or not.",
+ "Deprecated: report filenames are now always stable. "
+ "See also 'verbose-report-filename'.",
+ false)
+
+ANALYZER_OPTION(bool, ShouldWriteVerboseReportFilename, "verbose-report-filename",
+ "Whether or not the report filename should contain extra "
+ "information about the issue.",
false)
ANALYZER_OPTION(
@@ -314,6 +321,31 @@ 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, ShouldAssumeControlledEnvironment, "assume-controlled-environment",
+ "Whether the analyzed application runs in a controlled environment. "
+ "We will assume that environment variables exist in queries and they hold "
+ "no malicious data. For instance, if this option is enabled, 'getenv()' "
+ "might be modeled by the analyzer to never return NULL.",
+ false)
+
+ANALYZER_OPTION(
+ bool, ShouldIgnoreBisonGeneratedFiles, "ignore-bison-generated-files",
+ "If enabled, any files containing the \"/* A Bison parser, made by\" "
+ "won't be analyzed.",
+ true)
+
+ANALYZER_OPTION(
+ bool, ShouldIgnoreFlexGeneratedFiles, "ignore-flex-generated-files",
+ "If enabled, any files containing the \"/* A lexical scanner generated by "
+ "flex\" won't be analyzed.",
+ true)
+
//===----------------------------------------------------------------------===//
// Unsigned analyzer options.
//===----------------------------------------------------------------------===//
@@ -370,13 +402,49 @@ ANALYZER_OPTION_DEPENDS_ON_USER_MODE(
/* SHALLOW_VAL */ 75000, /* DEEP_VAL */ 225000)
ANALYZER_OPTION(
+ unsigned, CTUMaxNodesPercentage, "ctu-max-nodes-pct",
+ "The percentage of single-TU analysed nodes that the CTU analysis is "
+ "allowed to visit.", 50)
+
+ANALYZER_OPTION(
+ unsigned, CTUMaxNodesMin, "ctu-max-nodes-min",
+ "The maximum number of nodes in CTU mode is determinded by "
+ "'ctu-max-nodes-pct'. However, if the number of nodes in single-TU "
+ "analysis is too low, it is meaningful to provide a minimum value that "
+ "serves as an upper bound instead.", 10000)
+
+ANALYZER_OPTION(
+ StringRef, CTUPhase1InliningMode, "ctu-phase1-inlining",
+ "Controls which functions will be inlined during the first phase of the ctu "
+ "analysis. "
+ "If the value is set to 'all' then all foreign functions are inlinied "
+ "immediately during the first phase, thus rendering the second phase a noop. "
+ "The 'ctu-max-nodes-*' budge has no effect in this case. "
+ "If the value is 'small' then only functions with a linear CFG and with a "
+ "limited number of statements would be inlined during the first phase. The "
+ "long and/or nontrivial functions are handled in the second phase and are "
+ "controlled by the 'ctu-max-nodes-*' budge. "
+ "The value 'none' means that all foreign functions are inlined only in the "
+ "second phase, 'ctu-max-nodes-*' budge limits the second phase. "
+ "Value: \"none\", \"small\", \"all\".",
+ "small")
+
+ANALYZER_OPTION(
unsigned, RegionStoreSmallStructLimit, "region-store-small-struct-limit",
"The largest number of fields a struct can have and still be considered "
- "small This is currently used to decide whether or not it is worth forcing "
+ "small. This is currently used to decide whether or not it is worth forcing "
"a LazyCompoundVal on bind. To disable all small-struct-dependent "
"behavior, set the option to 0.",
2)
+ANALYZER_OPTION(
+ unsigned, RegionStoreSmallArrayLimit, "region-store-small-array-limit",
+ "The largest number of elements an array can have and still be considered "
+ "small. This is currently used to decide whether or not it is worth forcing "
+ "a LazyCompoundVal on bind. To disable all small-array-dependent "
+ "behavior, set the option to 0.",
+ 5)
+
//===----------------------------------------------------------------------===//
// String analyzer options.
//===----------------------------------------------------------------------===//
diff --git a/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h b/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h
index ccf35e0a81ec..276d11e80a5b 100644
--- a/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h
+++ b/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h
@@ -17,10 +17,8 @@
#include "clang/Analysis/PathDiagnostic.h"
#include "clang/Basic/LLVM.h"
#include "llvm/ADT/IntrusiveRefCntPtr.h"
-#include "llvm/ADT/Optional.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
-#include "llvm/ADT/StringSwitch.h"
#include <string>
#include <utility>
#include <vector>
@@ -33,20 +31,6 @@ class CheckerBase;
} // namespace ento
-/// Analysis - Set of available source code analyses.
-enum Analyses {
-#define ANALYSIS(NAME, CMDFLAG, DESC, SCOPE) NAME,
-#include "clang/StaticAnalyzer/Core/Analyses.def"
-NumAnalyses
-};
-
-/// AnalysisStores - Set of available analysis store models.
-enum AnalysisStores {
-#define ANALYSIS_STORE(NAME, CMDFLAG, DESC, CREATFN) NAME##Model,
-#include "clang/StaticAnalyzer/Core/Analyses.def"
-NumStores
-};
-
/// AnalysisConstraints - Set of available constraint models.
enum AnalysisConstraints {
#define ANALYSIS_CONSTRAINTS(NAME, CMDFLAG, DESC, CREATFN) NAME##Model,
@@ -138,6 +122,8 @@ enum UserModeKind {
UMK_Deep = 2
};
+enum class CTUPhase1InliningKind { None, Small, All };
+
/// Stores options for the analyzer from the command line.
///
/// Some options are frontend flags (e.g.: -analyzer-output), but some are
@@ -205,7 +191,6 @@ public:
/// A key-value table of use-specified configuration values.
// TODO: This shouldn't be public.
ConfigTable Config;
- AnalysisStores AnalysisStoreOpt = RegionStoreModel;
AnalysisConstraints AnalysisConstraintsOpt = RangeConstraintsModel;
AnalysisDiagClients AnalysisDiagOpt = PD_HTML;
AnalysisPurgeMode AnalysisPurgeOpt = PurgeStmt;
@@ -242,7 +227,6 @@ public:
unsigned ShouldEmitErrorsOnInvalidConfigValue : 1;
unsigned AnalyzeAll : 1;
unsigned AnalyzerDisplayProgress : 1;
- unsigned AnalyzeNestedBlocks : 1;
unsigned eagerlyAssumeBinOpBifurcation : 1;
@@ -276,9 +260,10 @@ public:
#undef ANALYZER_OPTION
#undef ANALYZER_OPTION_DEPENDS_ON_USER_MODE
- // Create an array of all -analyzer-config command line options. Sort it in
- // the constructor.
- std::vector<llvm::StringLiteral> AnalyzerConfigCmdFlags = {
+ bool isUnknownAnalyzerConfig(llvm::StringRef Name) {
+ static std::vector<llvm::StringLiteral> AnalyzerConfigCmdFlags = []() {
+ // Create an array of all -analyzer-config command line options.
+ std::vector<llvm::StringLiteral> AnalyzerConfigCmdFlags = {
#define ANALYZER_OPTION_DEPENDS_ON_USER_MODE(TYPE, NAME, CMDFLAG, DESC, \
SHALLOW_VAL, DEEP_VAL) \
ANALYZER_OPTION(TYPE, NAME, CMDFLAG, DESC, SHALLOW_VAL)
@@ -289,10 +274,11 @@ public:
#include "clang/StaticAnalyzer/Core/AnalyzerOptions.def"
#undef ANALYZER_OPTION
#undef ANALYZER_OPTION_DEPENDS_ON_USER_MODE
- };
-
- bool isUnknownAnalyzerConfig(StringRef Name) const {
- assert(llvm::is_sorted(AnalyzerConfigCmdFlags));
+ };
+ // FIXME: Sort this at compile-time when we get constexpr sort (C++20).
+ llvm::sort(AnalyzerConfigCmdFlags);
+ return AnalyzerConfigCmdFlags;
+ }();
return !std::binary_search(AnalyzerConfigCmdFlags.begin(),
AnalyzerConfigCmdFlags.end(), Name);
@@ -303,13 +289,12 @@ public:
ShowCheckerHelpAlpha(false), ShowCheckerHelpDeveloper(false),
ShowCheckerOptionList(false), ShowCheckerOptionAlphaList(false),
ShowCheckerOptionDeveloperList(false), ShowEnabledCheckerList(false),
- ShowConfigOptionsList(false), AnalyzeAll(false),
- AnalyzerDisplayProgress(false), AnalyzeNestedBlocks(false),
- eagerlyAssumeBinOpBifurcation(false), TrimGraph(false),
- visualizeExplodedGraphWithGraphViz(false), UnoptimizedCFG(false),
- PrintStats(false), NoRetryExhausted(false), AnalyzerWerror(false) {
- llvm::sort(AnalyzerConfigCmdFlags);
- }
+ ShowConfigOptionsList(false),
+ ShouldEmitErrorsOnInvalidConfigValue(false), AnalyzeAll(false),
+ AnalyzerDisplayProgress(false), eagerlyAssumeBinOpBifurcation(false),
+ TrimGraph(false), visualizeExplodedGraphWithGraphViz(false),
+ UnoptimizedCFG(false), PrintStats(false), NoRetryExhausted(false),
+ AnalyzerWerror(false) {}
/// Interprets an option's string value as a boolean. The "true" string is
/// interpreted as true and the "false" string is interpreted as false.
@@ -373,12 +358,8 @@ public:
StringRef OptionName,
bool SearchInParents = false) const;
- /// Retrieves and sets the UserMode. This is a high-level option,
- /// which is used to set other low-level options. It is not accessible
- /// outside of AnalyzerOptions.
- UserModeKind getUserMode() const;
-
ExplorationStrategyKind getExplorationStrategy() const;
+ CTUPhase1InliningKind getCTUPhase1Inlining() const;
/// Returns the inter-procedural analysis mode.
IPAKind getIPAMode() const;
@@ -395,7 +376,11 @@ public:
return {FullCompilerInvocation,
ShouldDisplayMacroExpansions,
ShouldSerializeStats,
- ShouldWriteStableReportFilename,
+ // The stable report filename option is deprecated because
+ // file names are now always stable. Now the old option acts as
+ // an alias to the new verbose filename option because this
+ // closely mimics the behavior under the old option.
+ ShouldWriteStableReportFilename || ShouldWriteVerboseReportFilename,
AnalyzerWerror,
ShouldApplyFixIts,
ShouldDisplayCheckerNameForText};
@@ -412,15 +397,6 @@ using AnalyzerOptionsRef = IntrusiveRefCntPtr<AnalyzerOptions>;
// For this reason, implement some methods in this header file.
//===----------------------------------------------------------------------===//
-inline UserModeKind AnalyzerOptions::getUserMode() const {
- auto K = llvm::StringSwitch<llvm::Optional<UserModeKind>>(UserMode)
- .Case("shallow", UMK_Shallow)
- .Case("deep", UMK_Deep)
- .Default(None);
- assert(K.hasValue() && "User mode is invalid.");
- return K.getValue();
-}
-
inline std::vector<StringRef>
AnalyzerOptions::getRegisteredCheckers(bool IncludeExperimental) {
static constexpr llvm::StringLiteral StaticAnalyzerCheckerNames[] = {
@@ -433,8 +409,8 @@ AnalyzerOptions::getRegisteredCheckers(bool IncludeExperimental) {
};
std::vector<StringRef> Checkers;
for (StringRef CheckerName : StaticAnalyzerCheckerNames) {
- if (!CheckerName.startswith("debug.") &&
- (IncludeExperimental || !CheckerName.startswith("alpha.")))
+ if (!CheckerName.starts_with("debug.") &&
+ (IncludeExperimental || !CheckerName.starts_with("alpha.")))
Checkers.push_back(CheckerName);
}
return Checkers;
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..e762f7548e0b 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
@@ -19,6 +19,7 @@
#include "clang/Basic/SourceLocation.h"
#include "clang/Lex/Preprocessor.h"
#include "clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitors.h"
+#include "clang/StaticAnalyzer/Core/BugReporter/BugSuppression.h"
#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
#include "clang/StaticAnalyzer/Core/CheckerManager.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h"
@@ -26,10 +27,8 @@
#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/SymExpr.h"
#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/FoldingSet.h"
#include "llvm/ADT/ImmutableSet.h"
-#include "llvm/ADT/None.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringMap.h"
@@ -39,6 +38,7 @@
#include "llvm/ADT/iterator_range.h"
#include <cassert>
#include <memory>
+#include <optional>
#include <string>
#include <utility>
#include <vector>
@@ -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.
@@ -455,13 +453,13 @@ public:
bool isInteresting(SVal V) const;
bool isInteresting(const LocationContext *LC) const;
- Optional<bugreporter::TrackingKind>
+ std::optional<bugreporter::TrackingKind>
getInterestingnessKind(SymbolRef sym) const;
- Optional<bugreporter::TrackingKind>
+ std::optional<bugreporter::TrackingKind>
getInterestingnessKind(const MemRegion *R) const;
- Optional<bugreporter::TrackingKind> getInterestingnessKind(SVal V) const;
+ std::optional<bugreporter::TrackingKind> getInterestingnessKind(SVal V) const;
/// Returns whether or not this report should be considered valid.
///
@@ -597,6 +595,9 @@ private:
/// A vector of BugReports for tracking the allocated pointers and cleanup.
std::vector<BugReportEquivClass *> EQClassesVector;
+ /// User-provided in-code suppressions.
+ BugSuppression UserSuppressions;
+
public:
BugReporter(BugReporterData &d);
virtual ~BugReporter();
@@ -610,8 +611,9 @@ public:
/// Iterator over the set of BugReports tracked by the BugReporter.
using EQClasses_iterator = llvm::FoldingSet<BugReportEquivClass>::iterator;
- EQClasses_iterator EQClasses_begin() { return EQClasses.begin(); }
- EQClasses_iterator EQClasses_end() { return EQClasses.end(); }
+ llvm::iterator_range<EQClasses_iterator> equivalenceClasses() {
+ return EQClasses;
+ }
ASTContext &getContext() { return D.getASTContext(); }
@@ -631,14 +633,14 @@ public:
void EmitBasicReport(const Decl *DeclWithIssue, const CheckerBase *Checker,
StringRef BugName, StringRef BugCategory,
StringRef BugStr, PathDiagnosticLocation Loc,
- ArrayRef<SourceRange> Ranges = None,
- ArrayRef<FixItHint> Fixits = None);
+ ArrayRef<SourceRange> Ranges = std::nullopt,
+ ArrayRef<FixItHint> Fixits = std::nullopt);
void EmitBasicReport(const Decl *DeclWithIssue, CheckerNameRef CheckerName,
StringRef BugName, StringRef BugCategory,
StringRef BugStr, PathDiagnosticLocation Loc,
- ArrayRef<SourceRange> Ranges = None,
- ArrayRef<FixItHint> Fixits = None);
+ ArrayRef<SourceRange> Ranges = std::nullopt,
+ ArrayRef<FixItHint> Fixits = std::nullopt);
private:
llvm::StringMap<std::unique_ptr<BugType>> StrBugTypes;
@@ -781,11 +783,11 @@ public:
return T->getTagKind() == &Kind;
}
- Optional<std::string> generateMessage(BugReporterContext &BRC,
- PathSensitiveBugReport &R) const {
+ std::optional<std::string> generateMessage(BugReporterContext &BRC,
+ PathSensitiveBugReport &R) const {
std::string Msg = Cb(BRC, R);
if (Msg.empty())
- return None;
+ return std::nullopt;
return std::move(Msg);
}
diff --git a/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitors.h b/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitors.h
index 24cae12af24a..d9b3d9352d32 100644
--- a/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitors.h
+++ b/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitors.h
@@ -21,9 +21,11 @@
#include "llvm/ADT/FoldingSet.h"
#include "llvm/ADT/IntrusiveRefCntPtr.h"
#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/StringRef.h"
#include <list>
#include <memory>
+#include <optional>
#include <utility>
namespace clang {
@@ -49,6 +51,12 @@ public:
BugReporterVisitor() = default;
BugReporterVisitor(const BugReporterVisitor &) = default;
BugReporterVisitor(BugReporterVisitor &&) {}
+
+ // The copy and move assignment operator is defined as deleted pending further
+ // motivation.
+ BugReporterVisitor &operator=(const BugReporterVisitor &) = delete;
+ BugReporterVisitor &operator=(BugReporterVisitor &&) = delete;
+
virtual ~BugReporterVisitor();
/// Return a diagnostic piece which should be associated with the
@@ -384,19 +392,19 @@ const Expr *getDerefExpr(const Stmt *S);
} // namespace bugreporter
class TrackConstraintBRVisitor final : public BugReporterVisitor {
- DefinedSVal Constraint;
- bool Assumption;
+ const SmallString<64> Message;
+ const DefinedSVal Constraint;
+ const bool Assumption;
bool IsSatisfied = false;
- bool IsZeroCheck;
/// We should start tracking from the last node along the path in which the
/// value is constrained.
bool IsTrackingTurnedOn = false;
public:
- TrackConstraintBRVisitor(DefinedSVal constraint, bool assumption)
- : Constraint(constraint), Assumption(assumption),
- IsZeroCheck(!Assumption && Constraint.getAs<Loc>()) {}
+ TrackConstraintBRVisitor(DefinedSVal constraint, bool assumption,
+ StringRef Message)
+ : Message(Message), Constraint(constraint), Assumption(assumption) {}
void Profile(llvm::FoldingSetNodeID &ID) const override;
@@ -409,6 +417,9 @@ public:
PathSensitiveBugReport &BR) override;
private:
+ /// Checks if the constraint refers to a null-location.
+ bool isZeroCheck() const;
+
/// Checks if the constraint is valid in the current state.
bool isUnderconstrained(const ExplodedNode *N) const;
};
@@ -501,13 +512,9 @@ public:
bool printValue(const Expr *CondVarExpr, raw_ostream &Out,
const ExplodedNode *N, bool TookTrue, bool IsAssuming);
- bool patternMatch(const Expr *Ex,
- const Expr *ParentEx,
- raw_ostream &Out,
- BugReporterContext &BRC,
- PathSensitiveBugReport &R,
- const ExplodedNode *N,
- Optional<bool> &prunable,
+ bool patternMatch(const Expr *Ex, const Expr *ParentEx, raw_ostream &Out,
+ BugReporterContext &BRC, PathSensitiveBugReport &R,
+ const ExplodedNode *N, std::optional<bool> &prunable,
bool IsSameFieldName);
static bool isPieceMessageGeneric(const PathDiagnosticPiece *Piece);
@@ -622,8 +629,118 @@ public:
PathSensitiveBugReport &R) override;
};
-} // namespace ento
+class ObjCMethodCall;
+class CXXConstructorCall;
+
+/// Put a diagnostic on return statement (or on } in its absence) of all inlined
+/// functions for which some property remained unchanged.
+/// Resulting diagnostics may read such as "Returning without writing to X".
+///
+/// Descendants can define what a "state change is", like a change of value
+/// to a memory region, liveness, etc. For function calls where the state did
+/// not change as defined, a custom note may be constructed.
+///
+/// For a minimal example, check out
+/// clang/unittests/StaticAnalyzer/NoStateChangeFuncVisitorTest.cpp.
+class NoStateChangeFuncVisitor : public BugReporterVisitor {
+private:
+ /// Frames modifying the state as defined in \c wasModifiedBeforeCallExit.
+ /// This visitor generates a note only if a function does *not* change the
+ /// state that way. This information is not immediately available
+ /// by looking at the node associated with the exit from the function
+ /// (usually the return statement). To avoid recomputing the same information
+ /// many times (going up the path for each node and checking whether the
+ /// region was written into) we instead lazily compute the stack frames
+ /// along the path.
+ // TODO: Can't we just use a map instead? This is likely not as cheap as it
+ // makes the code difficult to read.
+ llvm::SmallPtrSet<const StackFrameContext *, 32> FramesModifying;
+ llvm::SmallPtrSet<const StackFrameContext *, 32> FramesModifyingCalculated;
+
+ /// Check and lazily calculate whether the state is modified in the stack
+ /// frame to which \p CallExitBeginN belongs.
+ /// The calculation is cached in FramesModifying.
+ bool isModifiedInFrame(const ExplodedNode *CallExitBeginN);
+
+ void markFrameAsModifying(const StackFrameContext *SCtx);
+
+ /// Write to \c FramesModifying all stack frames along the path in the current
+ /// stack frame which modifies the state.
+ void findModifyingFrames(const ExplodedNode *const CallExitBeginN);
+
+protected:
+ bugreporter::TrackingKind TKind;
+
+ /// \return Whether the state was modified from the current node, \p CurrN, to
+ /// the end of the stack frame, at \p CallExitBeginN. \p CurrN and
+ /// \p CallExitBeginN are always in the same stack frame.
+ /// Clients should override this callback when a state change is important
+ /// not only on the entire function call, but inside of it as well.
+ /// Example: we may want to leave a note about the lack of locking/unlocking
+ /// on a particular mutex, but not if inside the function its state was
+ /// changed, but also restored. wasModifiedInFunction() wouldn't know of this
+ /// change.
+ virtual bool wasModifiedBeforeCallExit(const ExplodedNode *CurrN,
+ const ExplodedNode *CallExitBeginN) {
+ return false;
+ }
+
+ /// \return Whether the state was modified in the inlined function call in
+ /// between \p CallEnterN and \p CallExitEndN. Mind that the stack frame
+ /// retrieved from a CallEnterN and CallExitEndN is the *caller's* stack
+ /// frame! The inlined function's stack should be retrieved from either the
+ /// immediate successor to \p CallEnterN or immediate predecessor to
+ /// \p CallExitEndN.
+ /// Clients should override this function if a state changes local to the
+ /// inlined function are not interesting, only the change occuring as a
+ /// result of it.
+ /// Example: we want to leave a not about a leaked resource object not being
+ /// deallocated / its ownership changed inside a function, and we don't care
+ /// if it was assigned to a local variable (its change in ownership is
+ /// inconsequential).
+ virtual bool wasModifiedInFunction(const ExplodedNode *CallEnterN,
+ const ExplodedNode *CallExitEndN) {
+ return false;
+ }
+
+ /// Consume the information on the non-modifying stack frame in order to
+ /// either emit a note or not. May suppress the report entirely.
+ /// \return Diagnostics piece for the unmodified state in the current
+ /// function, if it decides to emit one. A good description might start with
+ /// "Returning without...".
+ virtual PathDiagnosticPieceRef
+ maybeEmitNoteForObjCSelf(PathSensitiveBugReport &R,
+ const ObjCMethodCall &Call,
+ const ExplodedNode *N) = 0;
+
+ /// Consume the information on the non-modifying stack frame in order to
+ /// either emit a note or not. May suppress the report entirely.
+ /// \return Diagnostics piece for the unmodified state in the current
+ /// function, if it decides to emit one. A good description might start with
+ /// "Returning without...".
+ virtual PathDiagnosticPieceRef
+ maybeEmitNoteForCXXThis(PathSensitiveBugReport &R,
+ const CXXConstructorCall &Call,
+ const ExplodedNode *N) = 0;
+
+ /// Consume the information on the non-modifying stack frame in order to
+ /// either emit a note or not. May suppress the report entirely.
+ /// \return Diagnostics piece for the unmodified state in the current
+ /// function, if it decides to emit one. A good description might start with
+ /// "Returning without...".
+ virtual PathDiagnosticPieceRef
+ maybeEmitNoteForParameters(PathSensitiveBugReport &R, const CallEvent &Call,
+ const ExplodedNode *N) = 0;
+
+public:
+ NoStateChangeFuncVisitor(bugreporter::TrackingKind TKind) : TKind(TKind) {}
+ PathDiagnosticPieceRef VisitNode(const ExplodedNode *N,
+ BugReporterContext &BR,
+ PathSensitiveBugReport &R) final;
+};
+
+} // namespace ento
} // namespace clang
#endif // LLVM_CLANG_STATICANALYZER_CORE_BUGREPORTER_BUGREPORTERVISITORS_H
diff --git a/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/BugReporter/BugSuppression.h b/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/BugReporter/BugSuppression.h
new file mode 100644
index 000000000000..4fd81b627519
--- /dev/null
+++ b/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/BugReporter/BugSuppression.h
@@ -0,0 +1,53 @@
+//===- BugSuppression.h - Suppression interface -----------------*- 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 BugSuppression, a simple interface class encapsulating
+// all user provided in-code suppressions.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_STATICANALYZER_CORE_BUGREPORTER_SUPPRESSION_H
+#define LLVM_CLANG_STATICANALYZER_CORE_BUGREPORTER_SUPPRESSION_H
+
+#include "clang/Basic/SourceLocation.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/SmallVector.h"
+
+namespace clang {
+class Decl;
+
+namespace ento {
+class BugReport;
+class PathDiagnosticLocation;
+
+class BugSuppression {
+public:
+ using DiagnosticIdentifierList = llvm::ArrayRef<llvm::StringRef>;
+
+ /// Return true if the given bug report was explicitly suppressed by the user.
+ bool isSuppressed(const BugReport &);
+
+ /// Return true if the bug reported at the given location was explicitly
+ /// suppressed by the user.
+ bool isSuppressed(const PathDiagnosticLocation &Location,
+ const Decl *DeclWithIssue,
+ DiagnosticIdentifierList DiagnosticIdentification);
+
+private:
+ // Overly pessimistic number, to be honest.
+ static constexpr unsigned EXPECTED_NUMBER_OF_SUPPRESSIONS = 8;
+ using CachedRanges =
+ llvm::SmallVector<SourceRange, EXPECTED_NUMBER_OF_SUPPRESSIONS>;
+
+ llvm::DenseMap<const Decl *, CachedRanges> CachedSuppressionLocations;
+};
+
+} // end namespace ento
+} // end namespace clang
+
+#endif // LLVM_CLANG_STATICANALYZER_CORE_BUGREPORTER_SUPPRESSION_H
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..e50afd6d0da7 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:
@@ -37,13 +35,13 @@ private:
virtual void anchor();
public:
- BugType(CheckerNameRef CheckerName, StringRef Name, StringRef Cat,
- bool SuppressOnSink = false)
- : CheckerName(CheckerName), Description(Name), Category(Cat),
+ BugType(CheckerNameRef CheckerName, StringRef Desc,
+ StringRef Cat = categories::LogicError, bool SuppressOnSink = false)
+ : CheckerName(CheckerName), Description(Desc), Category(Cat),
Checker(nullptr), SuppressOnSink(SuppressOnSink) {}
- BugType(const CheckerBase *Checker, StringRef Name, StringRef Cat,
- bool SuppressOnSink = false)
- : CheckerName(Checker->getCheckerName()), Description(Name),
+ BugType(const CheckerBase *Checker, StringRef Desc,
+ StringRef Cat = categories::LogicError, bool SuppressOnSink = false)
+ : CheckerName(Checker->getCheckerName()), Description(Desc),
Category(Cat), Checker(Checker), SuppressOnSink(SuppressOnSink) {}
virtual ~BugType() = default;
@@ -66,27 +64,6 @@ public:
bool isSuppressOnSink() const { return SuppressOnSink; }
};
-class BuiltinBug : public BugType {
- const std::string desc;
- void anchor() override;
-public:
- BuiltinBug(class CheckerNameRef checker, const char *name,
- const char *description)
- : BugType(checker, name, categories::LogicError), desc(description) {}
-
- BuiltinBug(const CheckerBase *checker, const char *name,
- const char *description)
- : BugType(checker, name, categories::LogicError), desc(description) {}
-
- BuiltinBug(class CheckerNameRef checker, const char *name)
- : BugType(checker, name, categories::LogicError), desc(name) {}
-
- BuiltinBug(const CheckerBase *checker, const char *name)
- : BugType(checker, name, categories::LogicError), desc(name) {}
-
- StringRef getDescription() const { return desc; }
-};
-
} // namespace ento
} // end clang namespace
diff --git a/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/BugReporter/CommonBugCategories.h b/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/BugReporter/CommonBugCategories.h
index 392bc484bf62..45187433c069 100644
--- a/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/BugReporter/CommonBugCategories.h
+++ b/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/BugReporter/CommonBugCategories.h
@@ -13,6 +13,7 @@
namespace clang {
namespace ento {
namespace categories {
+extern const char *const AppleAPIMisuse;
extern const char *const CoreFoundationObjectiveC;
extern const char *const LogicError;
extern const char *const MemoryRefCount;
@@ -22,6 +23,7 @@ extern const char *const CXXObjectLifecycle;
extern const char *const CXXMoveSemantics;
extern const char *const SecurityError;
extern const char *const UnusedCode;
+extern const char *const TaintedData;
} // namespace categories
} // namespace ento
} // namespace clang
diff --git a/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/Checker.h b/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/Checker.h
index fdba49664615..2ec54a837c42 100644
--- a/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/Checker.h
+++ b/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/Checker.h
@@ -193,9 +193,8 @@ public:
class Location {
template <typename CHECKER>
- static void _checkLocation(void *checker,
- const SVal &location, bool isLoad, const Stmt *S,
- CheckerContext &C) {
+ static void _checkLocation(void *checker, SVal location, bool isLoad,
+ const Stmt *S, CheckerContext &C) {
((const CHECKER *)checker)->checkLocation(location, isLoad, S, C);
}
@@ -209,8 +208,7 @@ public:
class Bind {
template <typename CHECKER>
- static void _checkBind(void *checker,
- const SVal &location, const SVal &val, const Stmt *S,
+ static void _checkBind(void *checker, SVal location, SVal val, const Stmt *S,
CheckerContext &C) {
((const CHECKER *)checker)->checkBind(location, val, S, C);
}
@@ -370,13 +368,12 @@ class PointerEscape {
Kind);
InvalidatedSymbols RegularEscape;
- for (InvalidatedSymbols::const_iterator I = Escaped.begin(),
- E = Escaped.end(); I != E; ++I)
- if (!ETraits->hasTrait(*I,
- RegionAndSymbolInvalidationTraits::TK_PreserveContents) &&
- !ETraits->hasTrait(*I,
- RegionAndSymbolInvalidationTraits::TK_SuppressEscape))
- RegularEscape.insert(*I);
+ for (SymbolRef Sym : Escaped)
+ if (!ETraits->hasTrait(
+ Sym, RegionAndSymbolInvalidationTraits::TK_PreserveContents) &&
+ !ETraits->hasTrait(
+ Sym, RegionAndSymbolInvalidationTraits::TK_SuppressEscape))
+ RegularEscape.insert(Sym);
if (RegularEscape.empty())
return State;
@@ -410,13 +407,13 @@ class ConstPointerEscape {
return State;
InvalidatedSymbols ConstEscape;
- for (InvalidatedSymbols::const_iterator I = Escaped.begin(),
- E = Escaped.end(); I != E; ++I)
- if (ETraits->hasTrait(*I,
- RegionAndSymbolInvalidationTraits::TK_PreserveContents) &&
- !ETraits->hasTrait(*I,
- RegionAndSymbolInvalidationTraits::TK_SuppressEscape))
- ConstEscape.insert(*I);
+ for (SymbolRef Sym : Escaped) {
+ if (ETraits->hasTrait(
+ Sym, RegionAndSymbolInvalidationTraits::TK_PreserveContents) &&
+ !ETraits->hasTrait(
+ Sym, RegionAndSymbolInvalidationTraits::TK_SuppressEscape))
+ ConstEscape.insert(Sym);
+ }
if (ConstEscape.empty())
return State;
@@ -457,10 +454,8 @@ namespace eval {
class Assume {
template <typename CHECKER>
- static ProgramStateRef _evalAssume(void *checker,
- ProgramStateRef state,
- const SVal &cond,
- bool assumption) {
+ static ProgramStateRef _evalAssume(void *checker, ProgramStateRef state,
+ SVal cond, bool assumption) {
return ((const CHECKER *)checker)->evalAssume(state, cond, assumption);
}
@@ -534,9 +529,9 @@ public:
template <typename EVENT>
class EventDispatcher {
- CheckerManager *Mgr;
+ CheckerManager *Mgr = nullptr;
public:
- EventDispatcher() : Mgr(nullptr) { }
+ EventDispatcher() = default;
template <typename CHECKER>
static void _register(CHECKER *checker, CheckerManager &mgr) {
@@ -563,18 +558,6 @@ struct ImplicitNullDerefEvent {
static int Tag;
};
-/// A helper class which wraps a boolean value set to false by default.
-///
-/// This class should behave exactly like 'bool' except that it doesn't need to
-/// be explicitly initialized.
-struct DefaultBool {
- bool val;
- DefaultBool() : val(false) {}
- /*implicit*/ operator bool&() { return val; }
- /*implicit*/ operator const bool&() const { return val; }
- DefaultBool &operator=(bool b) { val = b; return *this; }
-};
-
} // end ento namespace
} // end clang namespace
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..a45ba1bc573e 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;
@@ -154,7 +153,7 @@ public:
/// Constructs a CheckerManager without requiring an AST. No checker
/// registration will take place. Only useful when one needs to print the
- /// help flags through CheckerRegistryData, and the AST is unavalaible.
+ /// help flags through CheckerRegistryData, and the AST is unavailable.
CheckerManager(AnalyzerOptions &AOptions, const LangOptions &LangOpts,
DiagnosticsEngine &Diags, ArrayRef<std::string> plugins);
@@ -489,13 +488,11 @@ public:
using CheckCallFunc =
CheckerFn<void (const CallEvent &, CheckerContext &)>;
- using CheckLocationFunc =
- CheckerFn<void (const SVal &location, bool isLoad, const Stmt *S,
- CheckerContext &)>;
+ using CheckLocationFunc = CheckerFn<void(SVal location, bool isLoad,
+ const Stmt *S, CheckerContext &)>;
using CheckBindFunc =
- CheckerFn<void (const SVal &location, const SVal &val, const Stmt *S,
- CheckerContext &)>;
+ CheckerFn<void(SVal location, SVal val, const Stmt *S, CheckerContext &)>;
using CheckEndAnalysisFunc =
CheckerFn<void (ExplodedGraph &, BugReporter &, ExprEngine &)>;
@@ -531,8 +528,7 @@ public:
RegionAndSymbolInvalidationTraits *ITraits)>;
using EvalAssumeFunc =
- CheckerFn<ProgramStateRef (ProgramStateRef, const SVal &cond,
- bool assumption)>;
+ CheckerFn<ProgramStateRef(ProgramStateRef, SVal cond, bool assumption)>;
using EvalCallFunc = CheckerFn<bool (const CallEvent &, CheckerContext &)>;
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/APSIntType.h b/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/APSIntType.h
index 4b7d6054cd87..f1c50e721937 100644
--- a/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/APSIntType.h
+++ b/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/APSIntType.h
@@ -21,8 +21,8 @@ class APSIntType {
bool IsUnsigned;
public:
- APSIntType(uint32_t Width, bool Unsigned)
- : BitWidth(Width), IsUnsigned(Unsigned) {}
+ constexpr APSIntType(uint32_t Width, bool Unsigned)
+ : BitWidth(Width), IsUnsigned(Unsigned) {}
/* implicit */ APSIntType(const llvm::APSInt &Value)
: BitWidth(Value.getBitWidth()), IsUnsigned(Value.isUnsigned()) {}
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..ec503b41b381 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 {
@@ -67,10 +66,14 @@ class LazyCompoundValData : public llvm::FoldingSetNode {
public:
LazyCompoundValData(const StoreRef &st, const TypedValueRegion *r)
: store(st), region(r) {
+ assert(r);
assert(NonLoc::isCompoundType(r->getValueType()));
}
+ /// It might return null.
const void *getStore() const { return store.getStore(); }
+
+ LLVM_ATTRIBUTE_RETURNS_NONNULL
const TypedValueRegion *getRegion() const { return region; }
static void Profile(llvm::FoldingSetNodeID& ID,
@@ -98,6 +101,8 @@ public:
llvm::ImmutableList<const CXXBaseSpecifier *> L);
void Profile(llvm::FoldingSetNodeID &ID) { Profile(ID, D, L); }
+
+ /// It might return null.
const NamedDecl *getDeclaratorDecl() const { return D; }
llvm::ImmutableList<const CXXBaseSpecifier *> getCXXBaseList() const {
@@ -147,9 +152,15 @@ public:
T = AT->getValueType();
}
- assert(T->isIntegralOrEnumerationType() || Loc::isLocType(T));
- return APSIntType(Ctx.getIntWidth(T),
- !T->isSignedIntegerOrEnumerationType());
+ if (T->isIntegralOrEnumerationType() || Loc::isLocType(T)) {
+ return APSIntType(Ctx.getIntWidth(T),
+ !T->isSignedIntegerOrEnumerationType());
+ } else {
+ // implicitly handle case of T->isFixedPointType()
+ return APSIntType(Ctx.getIntWidth(T), T->isUnsignedFixedPointType());
+ }
+
+ llvm_unreachable("Unsupported type in getAPSIntType!");
}
/// Convert - Create a new persistent APSInt with the same value as 'From'
@@ -221,14 +232,6 @@ public:
return getValue(0, Ctx.getTypeSize(T), true);
}
- const llvm::APSInt &getZeroWithPtrWidth(bool isUnsigned = true) {
- return getValue(0, Ctx.getTypeSize(Ctx.VoidPtrTy), isUnsigned);
- }
-
- const llvm::APSInt &getIntWithPtrWidth(uint64_t X, bool isUnsigned) {
- return getValue(X, Ctx.getTypeSize(Ctx.VoidPtrTy), isUnsigned);
- }
-
const llvm::APSInt &getTruthValue(bool b, QualType T) {
return getValue(b ? 1 : 0, Ctx.getIntWidth(T),
T->isUnsignedIntegerOrEnumerationType());
diff --git a/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CallDescription.h b/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CallDescription.h
new file mode 100644
index 000000000000..965838a4408c
--- /dev/null
+++ b/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CallDescription.h
@@ -0,0 +1,257 @@
+//===- CallDescription.h - function/method call matching --*- 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 defines a generic mechanism for matching for function and
+/// method calls of C, C++, and Objective-C languages. Instances of these
+/// classes are frequently used together with the CallEvent classes.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_CALLDESCRIPTION_H
+#define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_CALLDESCRIPTION_H
+
+#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/Support/Compiler.h"
+#include <optional>
+#include <vector>
+
+namespace clang {
+class IdentifierInfo;
+} // namespace clang
+
+namespace clang {
+namespace ento {
+
+enum CallDescriptionFlags : unsigned {
+ CDF_None = 0,
+
+ /// Describes a C standard function that is sometimes implemented as a macro
+ /// that expands to a compiler builtin with some __builtin prefix.
+ /// The builtin may as well have a few extra arguments on top of the requested
+ /// number of arguments.
+ CDF_MaybeBuiltin = 1 << 0,
+};
+
+/// This class represents a description of a function call using the number of
+/// arguments and the name of the function.
+class CallDescription {
+ friend class CallEvent;
+ using MaybeCount = std::optional<unsigned>;
+
+ mutable std::optional<const IdentifierInfo *> II;
+ // The list of the qualified names used to identify the specified CallEvent,
+ // e.g. "{a, b}" represent the qualified names, like "a::b".
+ std::vector<std::string> QualifiedName;
+ MaybeCount RequiredArgs;
+ MaybeCount RequiredParams;
+ int Flags;
+
+public:
+ /// Constructs a CallDescription object.
+ ///
+ /// @param QualifiedName The list of the name qualifiers of the function that
+ /// will be matched. The user is allowed to skip any of the qualifiers.
+ /// For example, {"std", "basic_string", "c_str"} would match both
+ /// std::basic_string<...>::c_str() and std::__1::basic_string<...>::c_str().
+ ///
+ /// @param RequiredArgs The number of arguments that is expected to match a
+ /// call. Omit this parameter to match every occurrence of call with a given
+ /// name regardless the number of arguments.
+ CallDescription(CallDescriptionFlags Flags, ArrayRef<StringRef> QualifiedName,
+ MaybeCount RequiredArgs = std::nullopt,
+ MaybeCount RequiredParams = std::nullopt);
+
+ /// Construct a CallDescription with default flags.
+ CallDescription(ArrayRef<StringRef> QualifiedName,
+ MaybeCount RequiredArgs = std::nullopt,
+ MaybeCount RequiredParams = std::nullopt);
+
+ CallDescription(std::nullptr_t) = delete;
+
+ /// Get the name of the function that this object matches.
+ StringRef getFunctionName() const { return QualifiedName.back(); }
+
+ /// Get the qualified name parts in reversed order.
+ /// E.g. { "std", "vector", "data" } -> "vector", "std"
+ auto begin_qualified_name_parts() const {
+ return std::next(QualifiedName.rbegin());
+ }
+ auto end_qualified_name_parts() const { return QualifiedName.rend(); }
+
+ /// It's false, if and only if we expect a single identifier, such as
+ /// `getenv`. It's true for `std::swap`, or `my::detail::container::data`.
+ bool hasQualifiedNameParts() const { return QualifiedName.size() > 1; }
+
+ /// @name Matching CallDescriptions against a CallEvent
+ /// @{
+
+ /// Returns true if the CallEvent is a call to a function that matches
+ /// the CallDescription.
+ ///
+ /// \note This function is not intended to be used to match Obj-C method
+ /// calls.
+ bool matches(const CallEvent &Call) const;
+
+ /// Returns true whether the CallEvent matches on any of the CallDescriptions
+ /// supplied.
+ ///
+ /// \note This function is not intended to be used to match Obj-C method
+ /// calls.
+ friend bool matchesAny(const CallEvent &Call, const CallDescription &CD1) {
+ return CD1.matches(Call);
+ }
+
+ /// \copydoc clang::ento::CallDescription::matchesAny(const CallEvent &, const CallDescription &)
+ template <typename... Ts>
+ friend bool matchesAny(const CallEvent &Call, const CallDescription &CD1,
+ const Ts &...CDs) {
+ return CD1.matches(Call) || matchesAny(Call, CDs...);
+ }
+ /// @}
+
+ /// @name Matching CallDescriptions against a CallExpr
+ /// @{
+
+ /// Returns true if the CallExpr is a call to a function that matches the
+ /// CallDescription.
+ ///
+ /// When available, always prefer matching with a CallEvent! This function
+ /// exists only when that is not available, for example, when _only_
+ /// syntactic check is done on a piece of code.
+ ///
+ /// Also, StdLibraryFunctionsChecker::Signature is likely a better candicade
+ /// for syntactic only matching if you are writing a new checker. This is
+ /// handy if a CallDescriptionMap is already there.
+ ///
+ /// The function is imprecise because CallEvent may know path sensitive
+ /// information, such as the precise argument count (see comments for
+ /// CallEvent::getNumArgs), the called function if it was called through a
+ /// function pointer, and other information not available syntactically.
+ bool matchesAsWritten(const CallExpr &CE) const;
+
+ /// Returns true whether the CallExpr matches on any of the CallDescriptions
+ /// supplied.
+ ///
+ /// \note This function is not intended to be used to match Obj-C method
+ /// calls.
+ friend bool matchesAnyAsWritten(const CallExpr &CE,
+ const CallDescription &CD1) {
+ return CD1.matchesAsWritten(CE);
+ }
+
+ /// \copydoc clang::ento::CallDescription::matchesAnyAsWritten(const CallExpr &, const CallDescription &)
+ template <typename... Ts>
+ friend bool matchesAnyAsWritten(const CallExpr &CE,
+ const CallDescription &CD1,
+ const Ts &...CDs) {
+ return CD1.matchesAsWritten(CE) || matchesAnyAsWritten(CE, CDs...);
+ }
+ /// @}
+
+private:
+ bool matchesImpl(const FunctionDecl *Callee, size_t ArgCount,
+ size_t ParamCount) const;
+};
+
+/// An immutable map from CallDescriptions to arbitrary data. Provides a unified
+/// way for checkers to react on function calls.
+template <typename T> class CallDescriptionMap {
+ friend class CallDescriptionSet;
+
+ // Some call descriptions aren't easily hashable (eg., the ones with qualified
+ // names in which some sections are omitted), so let's put them
+ // in a simple vector and use linear lookup.
+ // TODO: Implement an actual map for fast lookup for "hashable" call
+ // descriptions (eg., the ones for C functions that just match the name).
+ std::vector<std::pair<CallDescription, T>> LinearMap;
+
+public:
+ CallDescriptionMap(
+ std::initializer_list<std::pair<CallDescription, T>> &&List)
+ : LinearMap(List) {}
+
+ template <typename InputIt>
+ CallDescriptionMap(InputIt First, InputIt Last) : LinearMap(First, Last) {}
+
+ ~CallDescriptionMap() = default;
+
+ // These maps are usually stored once per checker, so let's make sure
+ // we don't do redundant copies.
+ CallDescriptionMap(const CallDescriptionMap &) = delete;
+ CallDescriptionMap &operator=(const CallDescription &) = delete;
+
+ CallDescriptionMap(CallDescriptionMap &&) = default;
+ CallDescriptionMap &operator=(CallDescriptionMap &&) = default;
+
+ [[nodiscard]] const T *lookup(const CallEvent &Call) const {
+ // Slow path: linear lookup.
+ // TODO: Implement some sort of fast path.
+ for (const std::pair<CallDescription, T> &I : LinearMap)
+ if (I.first.matches(Call))
+ return &I.second;
+
+ return nullptr;
+ }
+
+ /// When available, always prefer lookup with a CallEvent! This function
+ /// exists only when that is not available, for example, when _only_
+ /// syntactic check is done on a piece of code.
+ ///
+ /// Also, StdLibraryFunctionsChecker::Signature is likely a better candicade
+ /// for syntactic only matching if you are writing a new checker. This is
+ /// handy if a CallDescriptionMap is already there.
+ ///
+ /// The function is imprecise because CallEvent may know path sensitive
+ /// information, such as the precise argument count (see comments for
+ /// CallEvent::getNumArgs), the called function if it was called through a
+ /// function pointer, and other information not available syntactically.
+ [[nodiscard]] const T *lookupAsWritten(const CallExpr &Call) const {
+ // Slow path: linear lookup.
+ // TODO: Implement some sort of fast path.
+ for (const std::pair<CallDescription, T> &I : LinearMap)
+ if (I.first.matchesAsWritten(Call))
+ return &I.second;
+
+ return nullptr;
+ }
+};
+
+/// An immutable set of CallDescriptions.
+/// Checkers can efficiently decide if a given CallEvent matches any
+/// CallDescription in the set.
+class CallDescriptionSet {
+ CallDescriptionMap<bool /*unused*/> Impl = {};
+
+public:
+ CallDescriptionSet(std::initializer_list<CallDescription> &&List);
+
+ CallDescriptionSet(const CallDescriptionSet &) = delete;
+ CallDescriptionSet &operator=(const CallDescription &) = delete;
+
+ [[nodiscard]] bool contains(const CallEvent &Call) const;
+
+ /// When available, always prefer lookup with a CallEvent! This function
+ /// exists only when that is not available, for example, when _only_
+ /// syntactic check is done on a piece of code.
+ ///
+ /// Also, StdLibraryFunctionsChecker::Signature is likely a better candicade
+ /// for syntactic only matching if you are writing a new checker. This is
+ /// handy if a CallDescriptionMap is already there.
+ ///
+ /// The function is imprecise because CallEvent may know path sensitive
+ /// information, such as the precise argument count (see comments for
+ /// CallEvent::getNumArgs), the called function if it was called through a
+ /// function pointer, and other information not available syntactically.
+ [[nodiscard]] bool containsAsWritten(const CallExpr &CE) const;
+};
+
+} // namespace ento
+} // namespace clang
+
+#endif // LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_CALLDESCRIPTION_H
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 060fff1a7407..0d36587484bf 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
@@ -45,6 +45,7 @@
#include "llvm/Support/ErrorHandling.h"
#include <cassert>
#include <limits>
+#include <optional>
#include <utility>
namespace clang {
@@ -76,22 +77,24 @@ enum CallEventKind {
};
class CallEvent;
-class CallDescription;
-template<typename T = CallEvent>
+template <typename T = CallEvent>
class CallEventRef : public IntrusiveRefCntPtr<const T> {
public:
CallEventRef(const T *Call) : IntrusiveRefCntPtr<const T>(Call) {}
CallEventRef(const CallEventRef &Orig) : IntrusiveRefCntPtr<const T>(Orig) {}
+ // The copy assignment operator is defined as deleted pending further
+ // motivation.
+ CallEventRef &operator=(const CallEventRef &) = delete;
+
CallEventRef<T> cloneWithState(ProgramStateRef State) const {
return this->get()->template cloneWithState<T>(State);
}
// Allow implicit conversions to a superclass type, since CallEventRef
// behaves like a pointer-to-const.
- template <typename SuperT>
- operator CallEventRef<SuperT> () const {
+ template <typename SuperT> operator CallEventRef<SuperT>() const {
return this->get();
}
};
@@ -114,12 +117,18 @@ class RuntimeDefinition {
/// precise.
const MemRegion *R = nullptr;
+ /// A definition is foreign if it has been imported and newly created by the
+ /// ASTImporter. This can be true only if CTU is enabled.
+ const bool Foreign = false;
+
public:
RuntimeDefinition() = default;
- RuntimeDefinition(const Decl *InD): D(InD) {}
- RuntimeDefinition(const Decl *InD, const MemRegion *InR): D(InD), R(InR) {}
+ RuntimeDefinition(const Decl *InD) : D(InD) {}
+ RuntimeDefinition(const Decl *InD, bool Foreign) : D(InD), Foreign(Foreign) {}
+ RuntimeDefinition(const Decl *InD, const MemRegion *InR) : D(InD), R(InR) {}
const Decl *getDecl() { return D; }
+ bool isForeign() const { return Foreign; }
/// Check if the definition we have is precise.
/// If not, it is possible that the call dispatches to another definition at
@@ -148,6 +157,8 @@ private:
ProgramStateRef State;
const LocationContext *LCtx;
llvm::PointerUnion<const Expr *, const Decl *> Origin;
+ CFGBlock::ConstCFGElementRef ElemRef = {nullptr, 0};
+ mutable std::optional<bool> Foreign; // Set by CTU analysis.
protected:
// This is user data for subclasses.
@@ -169,16 +180,19 @@ private:
protected:
friend class CallEventManager;
- CallEvent(const Expr *E, ProgramStateRef state, const LocationContext *lctx)
- : State(std::move(state)), LCtx(lctx), Origin(E) {}
+ CallEvent(const Expr *E, ProgramStateRef state, const LocationContext *lctx,
+ CFGBlock::ConstCFGElementRef ElemRef)
+ : State(std::move(state)), LCtx(lctx), Origin(E), ElemRef(ElemRef) {}
- CallEvent(const Decl *D, ProgramStateRef state, const LocationContext *lctx)
- : State(std::move(state)), LCtx(lctx), Origin(D) {}
+ CallEvent(const Decl *D, ProgramStateRef state, const LocationContext *lctx,
+ CFGBlock::ConstCFGElementRef ElemRef)
+ : State(std::move(state)), LCtx(lctx), Origin(D), ElemRef(ElemRef) {}
// DO NOT MAKE PUBLIC
CallEvent(const CallEvent &Original)
: State(Original.State), LCtx(Original.LCtx), Origin(Original.Origin),
- Data(Original.Data), Location(Original.Location) {}
+ ElemRef(Original.ElemRef), Data(Original.Data),
+ Location(Original.Location) {}
/// Copies this CallEvent, with vtable intact, into a new block of memory.
virtual void cloneTo(void *Dest) const = 0;
@@ -192,8 +206,9 @@ protected:
/// Used to specify non-argument regions that will be invalidated as a
/// result of this call.
- virtual void getExtraInvalidatedValues(ValueList &Values,
- RegionAndSymbolInvalidationTraits *ETraits) const {}
+ virtual void
+ getExtraInvalidatedValues(ValueList &Values,
+ RegionAndSymbolInvalidationTraits *ETraits) const {}
public:
CallEvent &operator=(const CallEvent &) = delete;
@@ -209,14 +224,20 @@ public:
return Origin.dyn_cast<const Decl *>();
}
- /// The state in which the call is being evaluated.
- const ProgramStateRef &getState() const {
- return State;
+ bool isForeign() const {
+ assert(Foreign && "Foreign must be set before querying");
+ return *Foreign;
}
+ void setForeign(bool B) const { Foreign = B; }
+
+ /// The state in which the call is being evaluated.
+ const ProgramStateRef &getState() const { return State; }
/// The context in which the call is being evaluated.
- const LocationContext *getLocationContext() const {
- return LCtx;
+ const LocationContext *getLocationContext() const { return LCtx; }
+
+ const CFGBlock::ConstCFGElementRef &getCFGElementRef() const {
+ return ElemRef;
}
/// Returns the definition of the function or method that will be
@@ -245,7 +266,7 @@ public:
SourceLocation Loc = D->getLocation();
if (Loc.isValid()) {
const SourceManager &SM =
- getState()->getStateManager().getContext().getSourceManager();
+ getState()->getStateManager().getContext().getSourceManager();
return SM.isInSystemHeader(D->getLocation());
}
@@ -257,20 +278,6 @@ public:
return false;
}
- /// Returns true if the CallEvent is a call to a function that matches
- /// the CallDescription.
- ///
- /// Note that this function is not intended to be used to match Obj-C method
- /// calls.
- bool isCalled(const CallDescription &CD) const;
-
- /// Returns true whether the CallEvent is any of the CallDescriptions supplied
- /// as a parameter.
- template <typename FirstCallDesc, typename... CallDescs>
- bool isCalled(const FirstCallDesc &First, const CallDescs &... Rest) const {
- return isCalled(First) || isCalled(Rest...);
- }
-
/// Returns a source range for the entire call, suitable for
/// outputting in diagnostics.
virtual SourceRange getSourceRange() const {
@@ -313,9 +320,7 @@ public:
// NOTE: The exact semantics of this are still being defined!
// We don't really want a list of hardcoded exceptions in the long run,
// but we don't want duplicated lists of known APIs in the short term either.
- virtual bool argumentsMayEscape() const {
- return hasNonZeroCallbackArg();
- }
+ virtual bool argumentsMayEscape() const { return hasNonZeroCallbackArg(); }
/// Returns true if the callee is an externally-visible function in the
/// top-level namespace, such as \c malloc.
@@ -416,14 +421,15 @@ public:
bool isArgumentConstructedDirectly(unsigned Index) const {
// This assumes that the object was not yet removed from the state.
return ExprEngine::getObjectUnderConstruction(
- getState(), {getOriginExpr(), Index}, getLocationContext()).hasValue();
+ getState(), {getOriginExpr(), Index}, getLocationContext())
+ .has_value();
}
/// Some calls have parameter numbering mismatched from argument numbering.
/// This function converts an argument index to the corresponding
- /// parameter index. Returns None is the argument doesn't correspond
+ /// parameter index. Returns std::nullopt is the argument doesn't correspond
/// to any parameter variable.
- virtual Optional<unsigned>
+ virtual std::optional<unsigned>
getAdjustedParameterIndex(unsigned ASTArgumentIndex) const {
return ASTArgumentIndex;
}
@@ -442,7 +448,15 @@ public:
/// If the call returns a C++ record type then the region of its return value
/// can be retrieved from its construction context.
- Optional<SVal> getReturnValueUnderConstruction() const;
+ std::optional<SVal> getReturnValueUnderConstruction() const;
+
+ // Returns the CallEvent representing the caller of this function
+ const CallEventRef<> getCaller() const;
+
+ // Returns true if the function was called from a standard library function.
+ // If not or could not get the caller (it may be a top level function)
+ // returns false.
+ bool isCalledFromSystemHeader() const;
// Iterator access to formal parameters and their types.
private:
@@ -484,11 +498,13 @@ public:
class AnyFunctionCall : public CallEvent {
protected:
AnyFunctionCall(const Expr *E, ProgramStateRef St,
- const LocationContext *LCtx)
- : CallEvent(E, St, LCtx) {}
+ const LocationContext *LCtx,
+ CFGBlock::ConstCFGElementRef ElemRef)
+ : CallEvent(E, St, LCtx, ElemRef) {}
AnyFunctionCall(const Decl *D, ProgramStateRef St,
- const LocationContext *LCtx)
- : CallEvent(D, St, LCtx) {}
+ const LocationContext *LCtx,
+ CFGBlock::ConstCFGElementRef ElemRef)
+ : CallEvent(D, St, LCtx, ElemRef) {}
AnyFunctionCall(const AnyFunctionCall &Other) = default;
public:
@@ -521,8 +537,9 @@ class SimpleFunctionCall : public AnyFunctionCall {
protected:
SimpleFunctionCall(const CallExpr *CE, ProgramStateRef St,
- const LocationContext *LCtx)
- : AnyFunctionCall(CE, St, LCtx) {}
+ const LocationContext *LCtx,
+ CFGBlock::ConstCFGElementRef ElemRef)
+ : AnyFunctionCall(CE, St, LCtx, ElemRef) {}
SimpleFunctionCall(const SimpleFunctionCall &Other) = default;
void cloneTo(void *Dest) const override {
@@ -557,15 +574,16 @@ class BlockCall : public CallEvent {
friend class CallEventManager;
protected:
- BlockCall(const CallExpr *CE, ProgramStateRef St,
- const LocationContext *LCtx)
- : CallEvent(CE, St, LCtx) {}
+ BlockCall(const CallExpr *CE, ProgramStateRef St, const LocationContext *LCtx,
+ CFGBlock::ConstCFGElementRef ElemRef)
+ : CallEvent(CE, St, LCtx, ElemRef) {}
BlockCall(const BlockCall &Other) = default;
void cloneTo(void *Dest) const override { new (Dest) BlockCall(*this); }
- void getExtraInvalidatedValues(ValueList &Values,
- RegionAndSymbolInvalidationTraits *ETraits) const override;
+ void getExtraInvalidatedValues(
+ ValueList &Values,
+ RegionAndSymbolInvalidationTraits *ETraits) const override;
public:
const CallExpr *getOriginExpr() const override {
@@ -605,10 +623,9 @@ public:
const BlockDataRegion *BR = getBlockRegion();
assert(BR && "Block converted from lambda must have a block region");
- auto I = BR->referenced_vars_begin();
- assert(I != BR->referenced_vars_end());
-
- return I.getCapturedRegion();
+ auto ReferencedVars = BR->referenced_vars();
+ assert(!ReferencedVars.empty());
+ return ReferencedVars.begin().getCapturedRegion();
}
RuntimeDefinition getRuntimeDefinition() const override {
@@ -636,14 +653,12 @@ public:
// the block body and analyze the operator() method on the captured lambda.
const VarDecl *LambdaVD = getRegionStoringCapturedLambda()->getDecl();
const CXXRecordDecl *LambdaDecl = LambdaVD->getType()->getAsCXXRecordDecl();
- CXXMethodDecl* LambdaCallOperator = LambdaDecl->getLambdaCallOperator();
+ CXXMethodDecl *LambdaCallOperator = LambdaDecl->getLambdaCallOperator();
return RuntimeDefinition(LambdaCallOperator);
}
- bool argumentsMayEscape() const override {
- return true;
- }
+ bool argumentsMayEscape() const override { return true; }
void getInitialStackFrameContents(const StackFrameContext *CalleeCtx,
BindingsTy &Bindings) const override;
@@ -661,15 +676,18 @@ public:
class CXXInstanceCall : public AnyFunctionCall {
protected:
CXXInstanceCall(const CallExpr *CE, ProgramStateRef St,
- const LocationContext *LCtx)
- : AnyFunctionCall(CE, St, LCtx) {}
+ const LocationContext *LCtx,
+ CFGBlock::ConstCFGElementRef ElemRef)
+ : AnyFunctionCall(CE, St, LCtx, ElemRef) {}
CXXInstanceCall(const FunctionDecl *D, ProgramStateRef St,
- const LocationContext *LCtx)
- : AnyFunctionCall(D, St, LCtx) {}
+ const LocationContext *LCtx,
+ CFGBlock::ConstCFGElementRef ElemRef)
+ : AnyFunctionCall(D, St, LCtx, ElemRef) {}
CXXInstanceCall(const CXXInstanceCall &Other) = default;
- void getExtraInvalidatedValues(ValueList &Values,
- RegionAndSymbolInvalidationTraits *ETraits) const override;
+ void getExtraInvalidatedValues(
+ ValueList &Values,
+ RegionAndSymbolInvalidationTraits *ETraits) const override;
public:
/// Returns the expression representing the implicit 'this' object.
@@ -699,8 +717,9 @@ class CXXMemberCall : public CXXInstanceCall {
protected:
CXXMemberCall(const CXXMemberCallExpr *CE, ProgramStateRef St,
- const LocationContext *LCtx)
- : CXXInstanceCall(CE, St, LCtx) {}
+ const LocationContext *LCtx,
+ CFGBlock::ConstCFGElementRef ElemRef)
+ : CXXInstanceCall(CE, St, LCtx, ElemRef) {}
CXXMemberCall(const CXXMemberCall &Other) = default;
void cloneTo(void *Dest) const override { new (Dest) CXXMemberCall(*this); }
@@ -741,8 +760,9 @@ class CXXMemberOperatorCall : public CXXInstanceCall {
protected:
CXXMemberOperatorCall(const CXXOperatorCallExpr *CE, ProgramStateRef St,
- const LocationContext *LCtx)
- : CXXInstanceCall(CE, St, LCtx) {}
+ const LocationContext *LCtx,
+ CFGBlock::ConstCFGElementRef ElemRef)
+ : CXXInstanceCall(CE, St, LCtx, ElemRef) {}
CXXMemberOperatorCall(const CXXMemberOperatorCall &Other) = default;
void cloneTo(void *Dest) const override {
@@ -771,12 +791,13 @@ public:
return CA->getKind() == CE_CXXMemberOperator;
}
- Optional<unsigned>
+ std::optional<unsigned>
getAdjustedParameterIndex(unsigned ASTArgumentIndex) const override {
// For member operator calls argument 0 on the expression corresponds
// to implicit this-parameter on the declaration.
- return (ASTArgumentIndex > 0) ? Optional<unsigned>(ASTArgumentIndex - 1)
- : None;
+ return (ASTArgumentIndex > 0)
+ ? std::optional<unsigned>(ASTArgumentIndex - 1)
+ : std::nullopt;
}
unsigned getASTArgumentIndex(unsigned CallArgumentIndex) const override {
@@ -807,17 +828,26 @@ protected:
/// \param Target The object region to be destructed.
/// \param St The path-sensitive state at this point in the program.
/// \param LCtx The location context at this point in the program.
+ /// \param ElemRef The reference to this destructor in the CFG.
+ ///
+ /// FIXME: Eventually we want to drop \param Target and deduce it from
+ /// \param ElemRef. To do that we need to migrate the logic for target
+ /// region lookup from ExprEngine::ProcessImplicitDtor() and make it
+ /// independent from ExprEngine.
CXXDestructorCall(const CXXDestructorDecl *DD, const Stmt *Trigger,
const MemRegion *Target, bool IsBaseDestructor,
- ProgramStateRef St, const LocationContext *LCtx)
- : CXXInstanceCall(DD, St, LCtx) {
+ ProgramStateRef St, const LocationContext *LCtx,
+ CFGBlock::ConstCFGElementRef ElemRef)
+ : CXXInstanceCall(DD, St, LCtx, ElemRef) {
Data = DtorDataTy(Target, IsBaseDestructor).getOpaqueValue();
Location = Trigger->getEndLoc();
}
CXXDestructorCall(const CXXDestructorCall &Other) = default;
- void cloneTo(void *Dest) const override {new (Dest) CXXDestructorCall(*this);}
+ void cloneTo(void *Dest) const override {
+ new (Dest) CXXDestructorCall(*this);
+ }
public:
SourceRange getSourceRange() const override { return Location; }
@@ -846,15 +876,17 @@ public:
class AnyCXXConstructorCall : public AnyFunctionCall {
protected:
AnyCXXConstructorCall(const Expr *E, const MemRegion *Target,
- ProgramStateRef St, const LocationContext *LCtx)
- : AnyFunctionCall(E, St, LCtx) {
+ ProgramStateRef St, const LocationContext *LCtx,
+ CFGBlock::ConstCFGElementRef ElemRef)
+ : AnyFunctionCall(E, St, LCtx, ElemRef) {
assert(E && (isa<CXXConstructExpr>(E) || isa<CXXInheritedCtorInitExpr>(E)));
// Target may be null when the region is unknown.
Data = Target;
}
- void getExtraInvalidatedValues(ValueList &Values,
- RegionAndSymbolInvalidationTraits *ETraits) const override;
+ void getExtraInvalidatedValues(
+ ValueList &Values,
+ RegionAndSymbolInvalidationTraits *ETraits) const override;
void getInitialStackFrameContents(const StackFrameContext *CalleeCtx,
BindingsTy &Bindings) const override;
@@ -883,13 +915,20 @@ protected:
/// a new symbolic region will be used.
/// \param St The path-sensitive state at this point in the program.
/// \param LCtx The location context at this point in the program.
+ /// \param ElemRef The reference to this constructor in the CFG.
+ ///
+ /// FIXME: Eventually we want to drop \param Target and deduce it from
+ /// \param ElemRef.
CXXConstructorCall(const CXXConstructExpr *CE, const MemRegion *Target,
- ProgramStateRef St, const LocationContext *LCtx)
- : AnyCXXConstructorCall(CE, Target, St, LCtx) {}
+ ProgramStateRef St, const LocationContext *LCtx,
+ CFGBlock::ConstCFGElementRef ElemRef)
+ : AnyCXXConstructorCall(CE, Target, St, LCtx, ElemRef) {}
CXXConstructorCall(const CXXConstructorCall &Other) = default;
- void cloneTo(void *Dest) const override { new (Dest) CXXConstructorCall(*this); }
+ void cloneTo(void *Dest) const override {
+ new (Dest) CXXConstructorCall(*this);
+ }
public:
const CXXConstructExpr *getOriginExpr() const override {
@@ -940,8 +979,9 @@ class CXXInheritedConstructorCall : public AnyCXXConstructorCall {
protected:
CXXInheritedConstructorCall(const CXXInheritedCtorInitExpr *CE,
const MemRegion *Target, ProgramStateRef St,
- const LocationContext *LCtx)
- : AnyCXXConstructorCall(CE, Target, St, LCtx) {}
+ const LocationContext *LCtx,
+ CFGBlock::ConstCFGElementRef ElemRef)
+ : AnyCXXConstructorCall(CE, Target, St, LCtx, ElemRef) {}
CXXInheritedConstructorCall(const CXXInheritedConstructorCall &Other) =
default;
@@ -1002,11 +1042,14 @@ class CXXAllocatorCall : public AnyFunctionCall {
protected:
CXXAllocatorCall(const CXXNewExpr *E, ProgramStateRef St,
- const LocationContext *LCtx)
- : AnyFunctionCall(E, St, LCtx) {}
+ const LocationContext *LCtx,
+ CFGBlock::ConstCFGElementRef ElemRef)
+ : AnyFunctionCall(E, St, LCtx, ElemRef) {}
CXXAllocatorCall(const CXXAllocatorCall &Other) = default;
- void cloneTo(void *Dest) const override { new (Dest) CXXAllocatorCall(*this); }
+ void cloneTo(void *Dest) const override {
+ new (Dest) CXXAllocatorCall(*this);
+ }
public:
const CXXNewExpr *getOriginExpr() const override {
@@ -1018,9 +1061,8 @@ public:
}
SVal getObjectUnderConstruction() const {
- return ExprEngine::getObjectUnderConstruction(getState(), getOriginExpr(),
- getLocationContext())
- .getValue();
+ return *ExprEngine::getObjectUnderConstruction(getState(), getOriginExpr(),
+ getLocationContext());
}
/// Number of non-placement arguments to the call. It is equal to 2 for
@@ -1034,6 +1076,18 @@ public:
return getOriginExpr()->getNumPlacementArgs() + getNumImplicitArgs();
}
+ bool isArray() const { return getOriginExpr()->isArray(); }
+
+ std::optional<const clang::Expr *> getArraySizeExpr() const {
+ return getOriginExpr()->getArraySize();
+ }
+
+ SVal getArraySizeVal() const {
+ assert(isArray() && "The allocator call doesn't allocate and array!");
+
+ return getState()->getSVal(*getArraySizeExpr(), getLocationContext());
+ }
+
const Expr *getArgExpr(unsigned Index) const override {
// The first argument of an allocator call is the size of the allocation.
if (Index < getNumImplicitArgs())
@@ -1072,8 +1126,9 @@ class CXXDeallocatorCall : public AnyFunctionCall {
protected:
CXXDeallocatorCall(const CXXDeleteExpr *E, ProgramStateRef St,
- const LocationContext *LCtx)
- : AnyFunctionCall(E, St, LCtx) {}
+ const LocationContext *LCtx,
+ CFGBlock::ConstCFGElementRef ElemRef)
+ : AnyFunctionCall(E, St, LCtx, ElemRef) {}
CXXDeallocatorCall(const CXXDeallocatorCall &Other) = default;
void cloneTo(void *Dest) const override {
@@ -1108,11 +1163,7 @@ public:
//
// Note to maintainers: OCM_Message should always be last, since it does not
// need to fit in the Data field's low bits.
-enum ObjCMessageKind {
- OCM_PropertyAccess,
- OCM_Subscript,
- OCM_Message
-};
+enum ObjCMessageKind { OCM_PropertyAccess, OCM_Subscript, OCM_Message };
/// Represents any expression that calls an Objective-C method.
///
@@ -1124,8 +1175,9 @@ class ObjCMethodCall : public CallEvent {
protected:
ObjCMethodCall(const ObjCMessageExpr *Msg, ProgramStateRef St,
- const LocationContext *LCtx)
- : CallEvent(Msg, St, LCtx) {
+ const LocationContext *LCtx,
+ CFGBlock::ConstCFGElementRef ElemRef)
+ : CallEvent(Msg, St, LCtx, ElemRef) {
Data = nullptr;
}
@@ -1133,8 +1185,9 @@ protected:
void cloneTo(void *Dest) const override { new (Dest) ObjCMethodCall(*this); }
- void getExtraInvalidatedValues(ValueList &Values,
- RegionAndSymbolInvalidationTraits *ETraits) const override;
+ void getExtraInvalidatedValues(
+ ValueList &Values,
+ RegionAndSymbolInvalidationTraits *ETraits) const override;
/// Check if the selector may have multiple definitions (may have overrides).
virtual bool canBeOverridenInSubclass(ObjCInterfaceDecl *IDecl,
@@ -1149,9 +1202,7 @@ public:
return getOriginExpr()->getMethodDecl();
}
- unsigned getNumArgs() const override {
- return getOriginExpr()->getNumArgs();
- }
+ unsigned getNumArgs() const override { return getOriginExpr()->getNumArgs(); }
const Expr *getArgExpr(unsigned Index) const override {
return getOriginExpr()->getArg(Index);
@@ -1165,9 +1216,7 @@ public:
return getOriginExpr()->getMethodFamily();
}
- Selector getSelector() const {
- return getOriginExpr()->getSelector();
- }
+ Selector getSelector() const { return getOriginExpr()->getSelector(); }
SourceRange getSourceRange() const override;
@@ -1215,7 +1264,7 @@ public:
void getInitialStackFrameContents(const StackFrameContext *CalleeCtx,
BindingsTy &Bindings) const override;
- ArrayRef<ParmVarDecl*> parameters() const override;
+ ArrayRef<ParmVarDecl *> parameters() const override;
Kind getKind() const override { return CE_ObjCMessage; }
StringRef getKindAsString() const override { return "ObjCMethodCall"; }
@@ -1225,99 +1274,6 @@ public:
}
};
-enum CallDescriptionFlags : int {
- /// Describes a C standard function that is sometimes implemented as a macro
- /// that expands to a compiler builtin with some __builtin prefix.
- /// The builtin may as well have a few extra arguments on top of the requested
- /// number of arguments.
- CDF_MaybeBuiltin = 1 << 0,
-};
-
-/// This class represents a description of a function call using the number of
-/// arguments and the name of the function.
-class CallDescription {
- friend CallEvent;
-
- mutable IdentifierInfo *II = nullptr;
- mutable bool IsLookupDone = false;
- // The list of the qualified names used to identify the specified CallEvent,
- // e.g. "{a, b}" represent the qualified names, like "a::b".
- std::vector<const char *> QualifiedName;
- Optional<unsigned> RequiredArgs;
- Optional<size_t> RequiredParams;
- int Flags;
-
- // A constructor helper.
- static Optional<size_t> readRequiredParams(Optional<unsigned> RequiredArgs,
- Optional<size_t> RequiredParams) {
- if (RequiredParams)
- return RequiredParams;
- if (RequiredArgs)
- return static_cast<size_t>(*RequiredArgs);
- return None;
- }
-
-public:
- /// Constructs a CallDescription object.
- ///
- /// @param QualifiedName The list of the name qualifiers of the function that
- /// will be matched. The user is allowed to skip any of the qualifiers.
- /// For example, {"std", "basic_string", "c_str"} would match both
- /// std::basic_string<...>::c_str() and std::__1::basic_string<...>::c_str().
- ///
- /// @param RequiredArgs The number of arguments that is expected to match a
- /// call. Omit this parameter to match every occurrence of call with a given
- /// name regardless the number of arguments.
- CallDescription(int Flags, ArrayRef<const char *> QualifiedName,
- Optional<unsigned> RequiredArgs = None,
- Optional<size_t> RequiredParams = None)
- : QualifiedName(QualifiedName), RequiredArgs(RequiredArgs),
- RequiredParams(readRequiredParams(RequiredArgs, RequiredParams)),
- Flags(Flags) {}
-
- /// Construct a CallDescription with default flags.
- CallDescription(ArrayRef<const char *> QualifiedName,
- Optional<unsigned> RequiredArgs = None,
- Optional<size_t> RequiredParams = None)
- : CallDescription(0, QualifiedName, RequiredArgs, RequiredParams) {}
-
- /// Get the name of the function that this object matches.
- StringRef getFunctionName() const { return QualifiedName.back(); }
-};
-
-/// An immutable map from CallDescriptions to arbitrary data. Provides a unified
-/// way for checkers to react on function calls.
-template <typename T> class CallDescriptionMap {
- // Some call descriptions aren't easily hashable (eg., the ones with qualified
- // names in which some sections are omitted), so let's put them
- // in a simple vector and use linear lookup.
- // TODO: Implement an actual map for fast lookup for "hashable" call
- // descriptions (eg., the ones for C functions that just match the name).
- std::vector<std::pair<CallDescription, T>> LinearMap;
-
-public:
- CallDescriptionMap(
- std::initializer_list<std::pair<CallDescription, T>> &&List)
- : LinearMap(List) {}
-
- ~CallDescriptionMap() = default;
-
- // These maps are usually stored once per checker, so let's make sure
- // we don't do redundant copies.
- CallDescriptionMap(const CallDescriptionMap &) = delete;
- CallDescriptionMap &operator=(const CallDescription &) = delete;
-
- const T *lookup(const CallEvent &Call) const {
- // Slow path: linear lookup.
- // TODO: Implement some sort of fast path.
- for (const std::pair<CallDescription, T> &I : LinearMap)
- if (Call.isCalled(I.first))
- return &I.second;
-
- return nullptr;
- }
-};
-
/// Manages the lifetime of CallEvent objects.
///
/// CallEventManager provides a way to create arbitrary CallEvents "on the
@@ -1346,89 +1302,98 @@ class CallEventManager {
}
template <typename T, typename Arg>
- T *create(Arg A, ProgramStateRef St, const LocationContext *LCtx) {
+ T *create(Arg A, ProgramStateRef St, const LocationContext *LCtx,
+ CFGBlock::ConstCFGElementRef ElemRef) {
static_assert(sizeof(T) == sizeof(CallEventTemplateTy),
"CallEvent subclasses are not all the same size");
- return new (allocate()) T(A, St, LCtx);
+ return new (allocate()) T(A, St, LCtx, ElemRef);
}
template <typename T, typename Arg1, typename Arg2>
- T *create(Arg1 A1, Arg2 A2, ProgramStateRef St, const LocationContext *LCtx) {
+ T *create(Arg1 A1, Arg2 A2, ProgramStateRef St, const LocationContext *LCtx,
+ CFGBlock::ConstCFGElementRef ElemRef) {
static_assert(sizeof(T) == sizeof(CallEventTemplateTy),
"CallEvent subclasses are not all the same size");
- return new (allocate()) T(A1, A2, St, LCtx);
+ return new (allocate()) T(A1, A2, St, LCtx, ElemRef);
}
template <typename T, typename Arg1, typename Arg2, typename Arg3>
T *create(Arg1 A1, Arg2 A2, Arg3 A3, ProgramStateRef St,
- const LocationContext *LCtx) {
+ const LocationContext *LCtx, CFGBlock::ConstCFGElementRef ElemRef) {
static_assert(sizeof(T) == sizeof(CallEventTemplateTy),
"CallEvent subclasses are not all the same size");
- return new (allocate()) T(A1, A2, A3, St, LCtx);
+ return new (allocate()) T(A1, A2, A3, St, LCtx, ElemRef);
}
template <typename T, typename Arg1, typename Arg2, typename Arg3,
typename Arg4>
T *create(Arg1 A1, Arg2 A2, Arg3 A3, Arg4 A4, ProgramStateRef St,
- const LocationContext *LCtx) {
+ const LocationContext *LCtx, CFGBlock::ConstCFGElementRef ElemRef) {
static_assert(sizeof(T) == sizeof(CallEventTemplateTy),
"CallEvent subclasses are not all the same size");
- return new (allocate()) T(A1, A2, A3, A4, St, LCtx);
+ return new (allocate()) T(A1, A2, A3, A4, St, LCtx, ElemRef);
}
public:
CallEventManager(llvm::BumpPtrAllocator &alloc) : Alloc(alloc) {}
/// Gets an outside caller given a callee context.
- CallEventRef<>
- getCaller(const StackFrameContext *CalleeCtx, ProgramStateRef State);
+ CallEventRef<> getCaller(const StackFrameContext *CalleeCtx,
+ ProgramStateRef State);
/// Gets a call event for a function call, Objective-C method call,
- /// or a 'new' call.
- CallEventRef<>
- getCall(const Stmt *S, ProgramStateRef State,
- const LocationContext *LC);
+ /// a 'new', or a 'delete' call.
+ CallEventRef<> getCall(const Stmt *S, ProgramStateRef State,
+ const LocationContext *LC,
+ CFGBlock::ConstCFGElementRef ElemRef);
- CallEventRef<>
- getSimpleCall(const CallExpr *E, ProgramStateRef State,
- const LocationContext *LCtx);
+ CallEventRef<> getSimpleCall(const CallExpr *E, ProgramStateRef State,
+ const LocationContext *LCtx,
+ CFGBlock::ConstCFGElementRef ElemRef);
CallEventRef<ObjCMethodCall>
getObjCMethodCall(const ObjCMessageExpr *E, ProgramStateRef State,
- const LocationContext *LCtx) {
- return create<ObjCMethodCall>(E, State, LCtx);
+ const LocationContext *LCtx,
+ CFGBlock::ConstCFGElementRef ElemRef) {
+ return create<ObjCMethodCall>(E, State, LCtx, ElemRef);
}
CallEventRef<CXXConstructorCall>
getCXXConstructorCall(const CXXConstructExpr *E, const MemRegion *Target,
- ProgramStateRef State, const LocationContext *LCtx) {
- return create<CXXConstructorCall>(E, Target, State, LCtx);
+ ProgramStateRef State, const LocationContext *LCtx,
+ CFGBlock::ConstCFGElementRef ElemRef) {
+ return create<CXXConstructorCall>(E, Target, State, LCtx, ElemRef);
}
CallEventRef<CXXInheritedConstructorCall>
getCXXInheritedConstructorCall(const CXXInheritedCtorInitExpr *E,
const MemRegion *Target, ProgramStateRef State,
- const LocationContext *LCtx) {
- return create<CXXInheritedConstructorCall>(E, Target, State, LCtx);
+ const LocationContext *LCtx,
+ CFGBlock::ConstCFGElementRef ElemRef) {
+ return create<CXXInheritedConstructorCall>(E, Target, State, LCtx, ElemRef);
}
CallEventRef<CXXDestructorCall>
getCXXDestructorCall(const CXXDestructorDecl *DD, const Stmt *Trigger,
const MemRegion *Target, bool IsBase,
- ProgramStateRef State, const LocationContext *LCtx) {
- return create<CXXDestructorCall>(DD, Trigger, Target, IsBase, State, LCtx);
+ ProgramStateRef State, const LocationContext *LCtx,
+ CFGBlock::ConstCFGElementRef ElemRef) {
+ return create<CXXDestructorCall>(DD, Trigger, Target, IsBase, State, LCtx,
+ ElemRef);
}
CallEventRef<CXXAllocatorCall>
getCXXAllocatorCall(const CXXNewExpr *E, ProgramStateRef State,
- const LocationContext *LCtx) {
- return create<CXXAllocatorCall>(E, State, LCtx);
+ const LocationContext *LCtx,
+ CFGBlock::ConstCFGElementRef ElemRef) {
+ return create<CXXAllocatorCall>(E, State, LCtx, ElemRef);
}
CallEventRef<CXXDeallocatorCall>
getCXXDeallocatorCall(const CXXDeleteExpr *E, ProgramStateRef State,
- const LocationContext *LCtx) {
- return create<CXXDeallocatorCall>(E, State, LCtx);
+ const LocationContext *LCtx,
+ CFGBlock::ConstCFGElementRef ElemRef) {
+ return create<CXXDeallocatorCall>(E, State, LCtx, ElemRef);
}
};
@@ -1470,11 +1435,10 @@ inline void CallEvent::Release() const {
namespace llvm {
// Support isa<>, cast<>, and dyn_cast<> for CallEventRef.
-template<class T> struct simplify_type< clang::ento::CallEventRef<T>> {
+template <class T> struct simplify_type<clang::ento::CallEventRef<T>> {
using SimpleType = const T *;
- static SimpleType
- getSimplifiedValue(clang::ento::CallEventRef<T> Val) {
+ static SimpleType getSimplifiedValue(clang::ento::CallEventRef<T> Val) {
return Val.get();
}
};
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..9923c41e6ad2 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
@@ -16,6 +16,7 @@
#include "clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h"
+#include <optional>
namespace clang {
namespace ento {
@@ -84,6 +85,8 @@ public:
return Eng.getContext();
}
+ const ASTContext &getASTContext() const { return Eng.getContext(); }
+
const LangOptions &getLangOpts() const {
return Eng.getContext().getLangOpts();
}
@@ -137,7 +140,7 @@ public:
/// example, for finding variables that the given symbol was assigned to.
static const MemRegion *getLocationRegionIfPostStore(const ExplodedNode *N) {
ProgramPoint L = N->getLocation();
- if (Optional<PostStore> PSL = L.getAs<PostStore>())
+ if (std::optional<PostStore> PSL = L.getAs<PostStore>())
return reinterpret_cast<const MemRegion*>(PSL->getLocationValue());
return nullptr;
}
@@ -210,6 +213,22 @@ public:
}
/// Generate a transition to a node that will be used to report
+ /// an error. This node will be a sink. That is, it will stop exploration of
+ /// the given path.
+ ///
+ /// @param State The state of the generated node.
+ /// @param Pred The transition will be generated from the specified Pred node
+ /// to the newly generated node.
+ /// @param Tag The tag to uniquely identify the creation site. If null,
+ /// the default tag for the checker will be used.
+ ExplodedNode *generateErrorNode(ProgramStateRef State,
+ ExplodedNode *Pred,
+ const ProgramPointTag *Tag = nullptr) {
+ return generateSink(State, Pred,
+ (Tag ? Tag : Location.getTag()));
+ }
+
+ /// Generate a transition to a node that will be used to report
/// an error. This node will not be a sink. That is, exploration will
/// continue along this path.
///
@@ -254,6 +273,7 @@ public:
/// @param IsPrunable Whether the note is prunable. It allows BugReporter
/// to omit the note from the report if it would make the displayed
/// bug path significantly shorter.
+ LLVM_ATTRIBUTE_RETURNS_NONNULL
const NoteTag *getNoteTag(NoteTag::Callback &&Cb, bool IsPrunable = false) {
return Eng.getDataTags().make<NoteTag>(std::move(Cb), IsPrunable);
}
@@ -296,8 +316,8 @@ public:
/// bug path significantly shorter.
const NoteTag *getNoteTag(StringRef Note, bool IsPrunable = false) {
return getNoteTag(
- [Note](BugReporterContext &,
- PathSensitiveBugReport &) { return std::string(Note); },
+ [Note = std::string(Note)](BugReporterContext &,
+ PathSensitiveBugReport &) { return Note; },
IsPrunable);
}
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..65982457ad83 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
@@ -16,7 +16,7 @@
#include "clang/AST/OperationKinds.h"
#include "clang/AST/Stmt.h"
#include "clang/Basic/OperatorKinds.h"
-#include "llvm/ADT/Optional.h"
+#include <optional>
#include <tuple>
namespace clang {
@@ -24,7 +24,6 @@ namespace clang {
class Expr;
class VarDecl;
class QualType;
-class AttributedType;
class Preprocessor;
namespace ento {
@@ -68,8 +67,9 @@ Nullability getNullabilityAnnotation(QualType Type);
/// Try to parse the value of a defined preprocessor macro. We can only parse
/// simple expressions that consist of an optional minus sign token and then a
-/// token for an integer. If we cannot parse the value then None is returned.
-llvm::Optional<int> tryExpandAsInteger(StringRef Macro, const Preprocessor &PP);
+/// token for an integer. If we cannot parse the value then std::nullopt is
+/// returned.
+std::optional<int> tryExpandAsInteger(StringRef Macro, const Preprocessor &PP);
class OperatorKind {
union {
@@ -88,7 +88,7 @@ public:
return Op.Bin;
}
- Optional<BinaryOperatorKind> GetBinaryOp() const {
+ std::optional<BinaryOperatorKind> GetBinaryOp() const {
if (IsBinary)
return Op.Bin;
return {};
@@ -100,7 +100,7 @@ public:
return Op.Un;
}
- Optional<UnaryOperatorKind> GetUnaryOp() const {
+ std::optional<UnaryOperatorKind> GetUnaryOp() const {
if (!IsBinary)
return Op.Un;
return {};
diff --git a/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ConstraintManager.h b/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ConstraintManager.h
index 335536b6a310..4de04bc4d397 100644
--- a/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ConstraintManager.h
+++ b/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ConstraintManager.h
@@ -17,9 +17,9 @@
#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState_Fwd.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/SymExpr.h"
-#include "llvm/ADT/Optional.h"
#include "llvm/Support/SaveAndRestore.h"
#include <memory>
+#include <optional>
#include <utility>
namespace llvm {
@@ -36,7 +36,7 @@ class ExprEngine;
class SymbolReaper;
class ConditionTruthVal {
- Optional<bool> Val;
+ std::optional<bool> Val;
public:
/// Construct a ConditionTruthVal indicating the constraint is constrained
@@ -53,25 +53,17 @@ public:
}
/// Return true if the constraint is perfectly constrained to 'true'.
- bool isConstrainedTrue() const {
- return Val.hasValue() && Val.getValue();
- }
+ bool isConstrainedTrue() const { return Val && *Val; }
/// Return true if the constraint is perfectly constrained to 'false'.
- bool isConstrainedFalse() const {
- return Val.hasValue() && !Val.getValue();
- }
+ bool isConstrainedFalse() const { return Val && !*Val; }
/// Return true if the constrained is perfectly constrained.
- bool isConstrained() const {
- return Val.hasValue();
- }
+ bool isConstrained() const { return Val.has_value(); }
/// Return true if the constrained is underconstrained and we do not know
/// if the constraint is true of value.
- bool isUnderconstrained() const {
- return !Val.hasValue();
- }
+ bool isUnderconstrained() const { return !Val.has_value(); }
};
class ConstraintManager {
@@ -82,77 +74,58 @@ public:
virtual bool haveEqualConstraints(ProgramStateRef S1,
ProgramStateRef S2) const = 0;
- virtual ProgramStateRef assume(ProgramStateRef state,
- DefinedSVal Cond,
- bool Assumption) = 0;
+ ProgramStateRef assume(ProgramStateRef state, DefinedSVal Cond,
+ bool Assumption);
using ProgramStatePair = std::pair<ProgramStateRef, ProgramStateRef>;
/// Returns a pair of states (StTrue, StFalse) where the given condition is
/// assumed to be true or false, respectively.
- ProgramStatePair assumeDual(ProgramStateRef State, DefinedSVal Cond) {
- ProgramStateRef StTrue = assume(State, Cond, true);
-
- // If StTrue is infeasible, asserting the falseness of Cond is unnecessary
- // because the existing constraints already establish this.
- if (!StTrue) {
-#ifdef EXPENSIVE_CHECKS
- assert(assume(State, Cond, false) && "System is over constrained.");
-#endif
- return ProgramStatePair((ProgramStateRef)nullptr, State);
- }
-
- ProgramStateRef StFalse = assume(State, Cond, false);
- if (!StFalse) {
- // We are careful to return the original state, /not/ StTrue,
- // because we want to avoid having callers generate a new node
- // in the ExplodedGraph.
- return ProgramStatePair(State, (ProgramStateRef)nullptr);
- }
-
- return ProgramStatePair(StTrue, StFalse);
- }
-
- virtual ProgramStateRef assumeInclusiveRange(ProgramStateRef State,
- NonLoc Value,
- const llvm::APSInt &From,
- const llvm::APSInt &To,
- bool InBound) = 0;
-
- virtual ProgramStatePair assumeInclusiveRangeDual(ProgramStateRef State,
- NonLoc Value,
- const llvm::APSInt &From,
- const llvm::APSInt &To) {
- ProgramStateRef StInRange =
- assumeInclusiveRange(State, Value, From, To, true);
-
- // If StTrue is infeasible, asserting the falseness of Cond is unnecessary
- // because the existing constraints already establish this.
- if (!StInRange)
- return ProgramStatePair((ProgramStateRef)nullptr, State);
-
- ProgramStateRef StOutOfRange =
- assumeInclusiveRange(State, Value, From, To, false);
- if (!StOutOfRange) {
- // We are careful to return the original state, /not/ StTrue,
- // because we want to avoid having callers generate a new node
- // in the ExplodedGraph.
- return ProgramStatePair(State, (ProgramStateRef)nullptr);
- }
-
- return ProgramStatePair(StInRange, StOutOfRange);
- }
+ /// (Note that these two states might be equal if the parent state turns out
+ /// to be infeasible. This may happen if the underlying constraint solver is
+ /// not perfectly precise and this may happen very rarely.)
+ ProgramStatePair assumeDual(ProgramStateRef State, DefinedSVal Cond);
+
+ ProgramStateRef assumeInclusiveRange(ProgramStateRef State, NonLoc Value,
+ const llvm::APSInt &From,
+ const llvm::APSInt &To, bool InBound);
+
+ /// Returns a pair of states (StInRange, StOutOfRange) where the given value
+ /// is assumed to be in the range or out of the range, respectively.
+ /// (Note that these two states might be equal if the parent state turns out
+ /// to be infeasible. This may happen if the underlying constraint solver is
+ /// not perfectly precise and this may happen very rarely.)
+ ProgramStatePair assumeInclusiveRangeDual(ProgramStateRef State, NonLoc Value,
+ const llvm::APSInt &From,
+ const llvm::APSInt &To);
/// If a symbol is perfectly constrained to a constant, attempt
/// to return the concrete value.
///
/// Note that a ConstraintManager is not obligated to return a concretized
/// value for a symbol, even if it is perfectly constrained.
+ /// It might return null.
virtual const llvm::APSInt* getSymVal(ProgramStateRef state,
SymbolRef sym) const {
return nullptr;
}
+ /// Attempt to return the minimal possible value for a given symbol. Note
+ /// that a ConstraintManager is not obligated to return a lower bound, it may
+ /// also return nullptr.
+ virtual const llvm::APSInt *getSymMinVal(ProgramStateRef state,
+ SymbolRef sym) const {
+ return nullptr;
+ }
+
+ /// Attempt to return the minimal possible value for a given symbol. Note
+ /// that a ConstraintManager is not obligated to return a lower bound, it may
+ /// also return nullptr.
+ virtual const llvm::APSInt *getSymMaxVal(ProgramStateRef state,
+ SymbolRef sym) const {
+ return nullptr;
+ }
+
/// Scan all symbols referenced by the constraints. If the symbol is not
/// alive, remove it.
virtual ProgramStateRef removeDeadBindings(ProgramStateRef state,
@@ -162,22 +135,38 @@ public:
const char *NL, unsigned int Space,
bool IsDot) const = 0;
+ virtual void printValue(raw_ostream &Out, ProgramStateRef State,
+ SymbolRef Sym) {}
+
/// Convenience method to query the state to see if a symbol is null or
/// not null, or if neither assumption can be made.
ConditionTruthVal isNull(ProgramStateRef State, SymbolRef Sym) {
- SaveAndRestore<bool> DisableNotify(NotifyAssumeClients, false);
-
return checkNull(State, Sym);
}
protected:
- /// A flag to indicate that clients should be notified of assumptions.
- /// By default this is the case, but sometimes this needs to be restricted
- /// to avoid infinite recursions within the ConstraintManager.
- ///
- /// Note that this flag allows the ConstraintManager to be re-entrant,
- /// but not thread-safe.
- bool NotifyAssumeClients = true;
+ /// A helper class to simulate the call stack of nested assume calls.
+ class AssumeStackTy {
+ public:
+ void push(const ProgramState *S) { Aux.push_back(S); }
+ void pop() { Aux.pop_back(); }
+ bool contains(const ProgramState *S) const {
+ return llvm::is_contained(Aux, S);
+ }
+
+ private:
+ llvm::SmallVector<const ProgramState *, 4> Aux;
+ };
+ AssumeStackTy AssumeStack;
+
+ virtual ProgramStateRef assumeInternal(ProgramStateRef state,
+ DefinedSVal Cond, bool Assumption) = 0;
+
+ virtual ProgramStateRef assumeInclusiveRangeInternal(ProgramStateRef State,
+ NonLoc Value,
+ const llvm::APSInt &From,
+ const llvm::APSInt &To,
+ bool InBound) = 0;
/// canReasonAbout - Not all ConstraintManagers can accurately reason about
/// all SVal values. This method returns true if the ConstraintManager can
@@ -189,6 +178,10 @@ protected:
/// Returns whether or not a symbol is known to be null ("true"), known to be
/// non-null ("false"), or may be either ("underconstrained").
virtual ConditionTruthVal checkNull(ProgramStateRef State, SymbolRef Sym);
+
+ template <typename AssumeFunction>
+ ProgramStatePair assumeDualImpl(ProgramStateRef &State,
+ AssumeFunction &Assume);
};
std::unique_ptr<ConstraintManager>
diff --git a/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h b/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h
index 9898b9b42f4b..8dbe767cef9d 100644
--- a/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h
+++ b/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h
@@ -25,6 +25,7 @@
#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState_Fwd.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/WorkList.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/iterator_range.h"
#include "llvm/Support/Casting.h"
#include <cassert>
#include <memory>
@@ -78,6 +79,7 @@ private:
/// worklist algorithm. It is up to the implementation of WList to decide
/// the order that nodes are processed.
std::unique_ptr<WorkList> WList;
+ std::unique_ptr<WorkList> CTUWList;
/// BCounterFactory - A factory object for created BlockCounter objects.
/// These are used to record for key nodes in the ExplodedGraph the
@@ -101,6 +103,8 @@ private:
/// tags.
DataTag::Factory DataTags;
+ void setBlockCounter(BlockCounter C);
+
void generateNode(const ProgramPoint &Loc,
ProgramStateRef State,
ExplodedNode *Pred);
@@ -170,22 +174,13 @@ public:
}
WorkList *getWorkList() const { return WList.get(); }
+ WorkList *getCTUWorkList() const { return CTUWList.get(); }
- BlocksExhausted::const_iterator blocks_exhausted_begin() const {
- return blocksExhausted.begin();
+ auto exhausted_blocks() const {
+ return llvm::iterator_range(blocksExhausted);
}
- BlocksExhausted::const_iterator blocks_exhausted_end() const {
- return blocksExhausted.end();
- }
-
- BlocksAborted::const_iterator blocks_aborted_begin() const {
- return blocksAborted.begin();
- }
-
- BlocksAborted::const_iterator blocks_aborted_end() const {
- return blocksAborted.end();
- }
+ auto aborted_blocks() const { return llvm::iterator_range(blocksAborted); }
/// Enqueue the given set of nodes onto the work list.
void enqueue(ExplodedNodeSet &Set);
@@ -210,8 +205,14 @@ struct NodeBuilderContext {
const CFGBlock *Block;
const LocationContext *LC;
+ NodeBuilderContext(const CoreEngine &E, const CFGBlock *B,
+ const LocationContext *L)
+ : Eng(E), Block(B), LC(L) {
+ assert(B);
+ }
+
NodeBuilderContext(const CoreEngine &E, const CFGBlock *B, ExplodedNode *N)
- : Eng(E), Block(B), LC(N->getLocationContext()) { assert(B); }
+ : NodeBuilderContext(E, B, N->getLocationContext()) {}
/// Return the CFGBlock associated with this builder.
const CFGBlock *getBlock() const { return Block; }
@@ -290,7 +291,9 @@ public:
ExplodedNode *generateNode(const ProgramPoint &PP,
ProgramStateRef State,
ExplodedNode *Pred) {
- return generateNodeImpl(PP, State, Pred, false);
+ return generateNodeImpl(
+ PP, State, Pred,
+ /*MarkAsSink=*/State->isPosteriorlyOverconstrained());
}
/// Generates a sink in the ExplodedGraph.
@@ -495,6 +498,11 @@ public:
iterator(CFGBlock::const_succ_iterator i) : I(i) {}
public:
+ // This isn't really a conventional iterator.
+ // We just implement the deref as a no-op for now to make range-based for
+ // loops work.
+ const iterator &operator*() const { return *this; }
+
iterator &operator++() { ++I; return *this; }
bool operator!=(const iterator &X) const { return I != X.I; }
diff --git a/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/DynamicExtent.h b/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/DynamicExtent.h
index cfd7aa9664b6..50d5d254415a 100644
--- a/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/DynamicExtent.h
+++ b/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/DynamicExtent.h
@@ -53,6 +53,11 @@ ProgramStateRef setDynamicExtent(ProgramStateRef State, const MemRegion *MR,
/// (bufptr) // extent is unknown
SVal getDynamicExtentWithOffset(ProgramStateRef State, SVal BufV);
+/// \returns The stored element count of the region represented by a symbolic
+/// value \p BufV.
+DefinedOrUnknownSVal getDynamicElementCountWithOffset(ProgramStateRef State,
+ SVal BufV, QualType Ty);
+
} // namespace ento
} // namespace clang
diff --git a/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/DynamicType.h b/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/DynamicType.h
index ffe1fe846be1..52d1526b1acf 100644
--- a/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/DynamicType.h
+++ b/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/DynamicType.h
@@ -22,8 +22,6 @@
#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState_Fwd.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h"
-#include "llvm/ADT/ImmutableMap.h"
-#include "llvm/ADT/Optional.h"
namespace clang {
namespace ento {
@@ -32,6 +30,7 @@ namespace ento {
DynamicTypeInfo getDynamicTypeInfo(ProgramStateRef State, const MemRegion *MR);
/// Get raw dynamic type information for the region \p MR.
+/// It might return null.
const DynamicTypeInfo *getRawDynamicTypeInfo(ProgramStateRef State,
const MemRegion *MR);
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/ExplodedGraph.h b/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h
index e87772c04b9b..2fb05ac46e8f 100644
--- a/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h
+++ b/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h
@@ -30,14 +30,15 @@
#include "llvm/ADT/DepthFirstIterator.h"
#include "llvm/ADT/FoldingSet.h"
#include "llvm/ADT/GraphTraits.h"
-#include "llvm/ADT/Optional.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SetVector.h"
+#include "llvm/ADT/iterator_range.h"
#include "llvm/Support/Allocator.h"
#include "llvm/Support/Compiler.h"
#include <cassert>
#include <cstdint>
#include <memory>
+#include <optional>
#include <utility>
#include <vector>
@@ -161,15 +162,13 @@ public:
return getLocationContext()->getParentMap();
}
- template <typename T>
- T &getAnalysis() const {
+ template <typename T> T &getAnalysis() const {
return *getLocationContext()->getAnalysis<T>();
}
const ProgramStateRef &getState() const { return State; }
- template <typename T>
- Optional<T> getLocationAs() const LLVM_LVALUE_FUNCTION {
+ template <typename T> std::optional<T> getLocationAs() const & {
return Location.getAs<T>();
}
@@ -397,13 +396,9 @@ public:
using node_iterator = AllNodesTy::iterator;
using const_node_iterator = AllNodesTy::const_iterator;
- node_iterator nodes_begin() { return Nodes.begin(); }
+ llvm::iterator_range<node_iterator> nodes() { return Nodes; }
- node_iterator nodes_end() { return Nodes.end(); }
-
- const_node_iterator nodes_begin() const { return Nodes.begin(); }
-
- const_node_iterator nodes_end() const { return Nodes.end(); }
+ llvm::iterator_range<const_node_iterator> nodes() const { return Nodes; }
roots_iterator roots_begin() { return Roots.begin(); }
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..ed5c4adb5e3d 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
@@ -36,6 +36,7 @@
#include "clang/StaticAnalyzer/Core/PathSensitive/WorkList.h"
#include "llvm/ADT/ArrayRef.h"
#include <cassert>
+#include <optional>
#include <utility>
namespace clang {
@@ -77,13 +78,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;
@@ -139,6 +136,7 @@ public:
private:
cross_tu::CrossTranslationUnitContext &CTU;
+ bool IsCTUEnabled;
AnalysisManager &AMgr;
@@ -231,10 +229,15 @@ public:
const Stmt *getStmt() const;
- void GenerateAutoTransition(ExplodedNode *N);
- void enqueueEndOfPath(ExplodedNodeSet &S);
- void GenerateCallExitNode(ExplodedNode *N);
+ const LocationContext *getRootLocationContext() const {
+ assert(G.roots_begin() != G.roots_end());
+ return (*G.roots_begin())->getLocation().getLocationContext();
+ }
+ CFGBlock::ConstCFGElementRef getCFGElementRef() const {
+ const CFGBlock *blockPtr = currBldrCtx ? currBldrCtx->getBlock() : nullptr;
+ return {blockPtr, currStmtIdx};
+ }
/// Dump graph to the specified filename.
/// If filename is empty, generate a temporary one.
@@ -358,13 +361,13 @@ public:
void processSwitch(SwitchNodeBuilder& builder);
/// Called by CoreEngine. Used to notify checkers that processing a
- /// function has begun. Called for both inlined and and top-level functions.
+ /// function has begun. Called for both inlined and top-level functions.
void processBeginOfFunction(NodeBuilderContext &BC,
ExplodedNode *Pred, ExplodedNodeSet &Dst,
const BlockEdge &L);
/// Called by CoreEngine. Used to notify checkers that processing a
- /// function has ended. Called for both inlined and and top-level functions.
+ /// function has ended. Called for both inlined and top-level functions.
void processEndOfFunction(NodeBuilderContext& BC,
ExplodedNode *Pred,
const ReturnStmt *RS = nullptr);
@@ -442,6 +445,10 @@ public:
/// other functions that handle specific kinds of statements.
void Visit(const Stmt *S, ExplodedNode *Pred, ExplodedNodeSet &Dst);
+ /// VisitArrayInitLoopExpr - Transfer function for array init loop.
+ void VisitArrayInitLoopExpr(const ArrayInitLoopExpr *Ex, ExplodedNode *Pred,
+ ExplodedNodeSet &Dst);
+
/// VisitArraySubscriptExpr - Transfer function for array accesses.
void VisitArraySubscriptExpr(const ArraySubscriptExpr *Ex,
ExplodedNode *Pred,
@@ -589,51 +596,40 @@ public:
static std::pair<const ProgramPointTag *, const ProgramPointTag *>
geteagerlyAssumeBinOpBifurcationTags();
- SVal evalMinus(SVal X) {
- return X.isValid() ? svalBuilder.evalMinus(X.castAs<NonLoc>()) : X;
- }
-
- SVal evalComplement(SVal X) {
- return X.isValid() ? svalBuilder.evalComplement(X.castAs<NonLoc>()) : X;
- }
-
ProgramStateRef handleLValueBitCast(ProgramStateRef state, const Expr *Ex,
const LocationContext *LCtx, QualType T,
QualType ExTy, const CastExpr *CastE,
StmtNodeBuilder &Bldr,
ExplodedNode *Pred);
- ProgramStateRef handleLVectorSplat(ProgramStateRef state,
- const LocationContext *LCtx,
- const CastExpr *CastE,
- StmtNodeBuilder &Bldr,
- ExplodedNode *Pred);
-
- void handleUOExtension(ExplodedNodeSet::iterator I,
- const UnaryOperator* U,
+ void handleUOExtension(ExplodedNode *N, const UnaryOperator *U,
StmtNodeBuilder &Bldr);
public:
- SVal evalBinOp(ProgramStateRef state, BinaryOperator::Opcode op,
- NonLoc L, NonLoc R, QualType T) {
- return svalBuilder.evalBinOpNN(state, op, L, R, T);
- }
-
- SVal evalBinOp(ProgramStateRef state, BinaryOperator::Opcode op,
- NonLoc L, SVal R, QualType T) {
- return R.isValid() ? svalBuilder.evalBinOpNN(state, op, L,
- R.castAs<NonLoc>(), T) : R;
- }
-
SVal evalBinOp(ProgramStateRef ST, BinaryOperator::Opcode Op,
SVal LHS, SVal RHS, QualType T) {
return svalBuilder.evalBinOp(ST, Op, LHS, RHS, T);
}
+ /// Retreives which element is being constructed in a non-POD type array.
+ static std::optional<unsigned>
+ getIndexOfElementToConstruct(ProgramStateRef State, const CXXConstructExpr *E,
+ const LocationContext *LCtx);
+
+ /// Retreives which element is being destructed in a non-POD type array.
+ static std::optional<unsigned>
+ getPendingArrayDestruction(ProgramStateRef State,
+ const LocationContext *LCtx);
+
+ /// Retreives the size of the array in the pending ArrayInitLoopExpr.
+ static std::optional<unsigned>
+ getPendingInitLoop(ProgramStateRef State, const CXXConstructExpr *E,
+ const LocationContext *LCtx);
+
/// By looking at a certain item that may be potentially part of an object's
/// ConstructionContext, retrieve such object's location. A particular
/// statement can be transparently passed as \p Item in most cases.
- static Optional<SVal>
+ static std::optional<SVal>
getObjectUnderConstruction(ProgramStateRef State,
const ConstructionContextItem &Item,
const LocationContext *LC);
@@ -721,10 +717,20 @@ public:
/// fully implemented it sometimes indicates that it failed via its
/// out-parameter CallOpts; in such cases a fake temporary region is
/// returned, which is better than nothing but does not represent
- /// the actual behavior of the program.
- SVal computeObjectUnderConstruction(
- const Expr *E, ProgramStateRef State, const LocationContext *LCtx,
- const ConstructionContext *CC, EvalCallOptions &CallOpts);
+ /// the actual behavior of the program. The Idx parameter is used if we
+ /// construct an array of objects. In that case it points to the index
+ /// of the continuous memory region.
+ /// E.g.:
+ /// For `int arr[4]` this index can be 0,1,2,3.
+ /// For `int arr2[3][3]` this index can be 0,1,...,7,8.
+ /// A multi-dimensional array is also a continuous memory location in a
+ /// row major order, so for arr[0][0] Idx is 0 and for arr[2][2] Idx is 8.
+ SVal computeObjectUnderConstruction(const Expr *E, ProgramStateRef State,
+ const NodeBuilderContext *BldrCtx,
+ const LocationContext *LCtx,
+ const ConstructionContext *CC,
+ EvalCallOptions &CallOpts,
+ unsigned Idx = 0);
/// Update the program state with all the path-sensitive information
/// that's necessary to perform construction of an object with a given
@@ -738,11 +744,15 @@ public:
/// A convenient wrapper around computeObjectUnderConstruction
/// and updateObjectsUnderConstruction.
std::pair<ProgramStateRef, SVal> handleConstructionContext(
- const Expr *E, ProgramStateRef State, const LocationContext *LCtx,
- const ConstructionContext *CC, EvalCallOptions &CallOpts) {
- SVal V = computeObjectUnderConstruction(E, State, LCtx, CC, CallOpts);
- return std::make_pair(
- updateObjectsUnderConstruction(V, E, State, LCtx, CC, CallOpts), V);
+ const Expr *E, ProgramStateRef State, const NodeBuilderContext *BldrCtx,
+ const LocationContext *LCtx, const ConstructionContext *CC,
+ EvalCallOptions &CallOpts, unsigned Idx = 0) {
+
+ SVal V = computeObjectUnderConstruction(E, State, BldrCtx, LCtx, CC,
+ CallOpts, Idx);
+ State = updateObjectsUnderConstruction(V, E, State, LCtx, CC, CallOpts);
+
+ return std::make_pair(State, V);
}
private:
@@ -751,15 +761,6 @@ private:
void finishArgumentConstruction(ExplodedNodeSet &Dst, ExplodedNode *Pred,
const CallEvent &Call);
- void evalLoadCommon(ExplodedNodeSet &Dst,
- const Expr *NodeEx, /* Eventually will be a CFGStmt */
- const Expr *BoundEx,
- ExplodedNode *Pred,
- ProgramStateRef St,
- SVal location,
- const ProgramPointTag *tag,
- QualType LoadTy);
-
void evalLocation(ExplodedNodeSet &Dst,
const Stmt *NodeEx, /* This will eventually be a CFGStmt */
const Stmt *BoundEx,
@@ -809,8 +810,46 @@ private:
const ExplodedNode *Pred,
const EvalCallOptions &CallOpts = {});
- bool inlineCall(const CallEvent &Call, const Decl *D, NodeBuilder &Bldr,
- ExplodedNode *Pred, ProgramStateRef State);
+ /// Checks whether our policies allow us to inline a non-POD type array
+ /// construction.
+ bool shouldInlineArrayConstruction(const ProgramStateRef State,
+ const CXXConstructExpr *CE,
+ const LocationContext *LCtx);
+
+ /// Checks whether our policies allow us to inline a non-POD type array
+ /// destruction.
+ /// \param Size The size of the array.
+ bool shouldInlineArrayDestruction(uint64_t Size);
+
+ /// Prepares the program state for array destruction. If no error happens
+ /// the function binds a 'PendingArrayDestruction' entry to the state, which
+ /// it returns along with the index. If any error happens (we fail to read
+ /// the size, the index would be -1, etc.) the function will return the
+ /// original state along with an index of 0. The actual element count of the
+ /// array can be accessed by the optional 'ElementCountVal' parameter. \param
+ /// State The program state. \param Region The memory region where the array
+ /// is stored. \param ElementTy The type an element in the array. \param LCty
+ /// The location context. \param ElementCountVal A pointer to an optional
+ /// SVal. If specified, the size of the array will be returned in it. It can
+ /// be Unknown.
+ std::pair<ProgramStateRef, uint64_t> prepareStateForArrayDestruction(
+ const ProgramStateRef State, const MemRegion *Region,
+ const QualType &ElementTy, const LocationContext *LCtx,
+ SVal *ElementCountVal = nullptr);
+
+ /// Checks whether we construct an array of non-POD type, and decides if the
+ /// constructor should be inkoved once again.
+ bool shouldRepeatCtorCall(ProgramStateRef State, const CXXConstructExpr *E,
+ const LocationContext *LCtx);
+
+ void inlineCall(WorkList *WList, const CallEvent &Call, const Decl *D,
+ NodeBuilder &Bldr, ExplodedNode *Pred, ProgramStateRef State);
+
+ void ctuBifurcate(const CallEvent &Call, const Decl *D, NodeBuilder &Bldr,
+ ExplodedNode *Pred, ProgramStateRef State);
+
+ /// Returns true if the CTU analysis is running its second phase.
+ bool isSecondPhaseCTU() { return IsCTUEnabled && !Engine.getCTUWorkList(); }
/// Conservatively evaluate call by invalidating regions and binding
/// a conjured return value.
@@ -845,7 +884,7 @@ private:
const Expr *InitWithAdjustments, const Expr *Result = nullptr,
const SubRegion **OutRegionWithAdjustments = nullptr);
- /// Returns a region representing the first element of a (possibly
+ /// Returns a region representing the `Idx`th element of a (possibly
/// multi-dimensional) array, for the purposes of element construction or
/// destruction.
///
@@ -853,15 +892,8 @@ private:
///
/// If the type is not an array type at all, the original value is returned.
/// Otherwise the "IsArray" flag is set.
- static SVal makeZeroElementRegion(ProgramStateRef State, SVal LValue,
- QualType &Ty, bool &IsArray);
-
- /// For a DeclStmt or CXXInitCtorInitializer, walk backward in the current CFG
- /// block to find the constructor expression that directly constructed into
- /// the storage for this statement. Returns null if the constructor for this
- /// statement created a temporary object region rather than directly
- /// constructing into an existing region.
- const CXXConstructExpr *findDirectConstructorForCurrentCFGElement();
+ static SVal makeElementRegion(ProgramStateRef State, SVal LValue,
+ QualType &Ty, bool &IsArray, unsigned Idx = 0);
/// Common code that handles either a CXXConstructExpr or a
/// CXXInheritedCtorInitExpr.
@@ -872,19 +904,56 @@ public:
/// Note whether this loop has any more iteratios to model. These methods are
/// essentially an interface for a GDM trait. Further reading in
/// ExprEngine::VisitObjCForCollectionStmt().
- LLVM_NODISCARD static ProgramStateRef
+ [[nodiscard]] static ProgramStateRef
setWhetherHasMoreIteration(ProgramStateRef State,
const ObjCForCollectionStmt *O,
const LocationContext *LC, bool HasMoreIteraton);
- LLVM_NODISCARD static ProgramStateRef
+ [[nodiscard]] static ProgramStateRef
removeIterationState(ProgramStateRef State, const ObjCForCollectionStmt *O,
const LocationContext *LC);
- LLVM_NODISCARD static bool hasMoreIteration(ProgramStateRef State,
- const ObjCForCollectionStmt *O,
- const LocationContext *LC);
+ [[nodiscard]] static bool hasMoreIteration(ProgramStateRef State,
+ const ObjCForCollectionStmt *O,
+ const LocationContext *LC);
+
private:
+ /// Assuming we construct an array of non-POD types, this method allows us
+ /// to store which element is to be constructed next.
+ static ProgramStateRef
+ setIndexOfElementToConstruct(ProgramStateRef State, const CXXConstructExpr *E,
+ const LocationContext *LCtx, unsigned Idx);
+
+ static ProgramStateRef
+ removeIndexOfElementToConstruct(ProgramStateRef State,
+ const CXXConstructExpr *E,
+ const LocationContext *LCtx);
+
+ /// Assuming we destruct an array of non-POD types, this method allows us
+ /// to store which element is to be destructed next.
+ static ProgramStateRef setPendingArrayDestruction(ProgramStateRef State,
+ const LocationContext *LCtx,
+ unsigned Idx);
+
+ static ProgramStateRef
+ removePendingArrayDestruction(ProgramStateRef State,
+ const LocationContext *LCtx);
+
+ /// Sets the size of the array in a pending ArrayInitLoopExpr.
+ static ProgramStateRef setPendingInitLoop(ProgramStateRef State,
+ const CXXConstructExpr *E,
+ const LocationContext *LCtx,
+ unsigned Idx);
+
+ static ProgramStateRef removePendingInitLoop(ProgramStateRef State,
+ const CXXConstructExpr *E,
+ const LocationContext *LCtx);
+
+ static ProgramStateRef
+ removeStateTraitsUsedForArrayEvaluation(ProgramStateRef State,
+ const CXXConstructExpr *E,
+ const LocationContext *LCtx);
+
/// Store the location of a C++ object corresponding to a statement
/// until the statement is actually encountered. For example, if a DeclStmt
/// has CXXConstructExpr as its initializer, the object would be considered
diff --git a/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/FunctionSummary.h b/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/FunctionSummary.h
index 53b4bf605871..3ee0d229cfc2 100644
--- a/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/FunctionSummary.h
+++ b/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/FunctionSummary.h
@@ -17,11 +17,10 @@
#include "clang/Basic/LLVM.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/DenseSet.h"
-#include "llvm/ADT/None.h"
-#include "llvm/ADT/Optional.h"
#include "llvm/ADT/SmallBitVector.h"
#include <cassert>
#include <deque>
+#include <optional>
#include <utility>
namespace clang {
@@ -86,11 +85,11 @@ public:
markShouldNotInline(D);
}
- Optional<bool> mayInline(const Decl *D) {
+ std::optional<bool> mayInline(const Decl *D) {
MapTy::const_iterator I = Map.find(D);
if (I != Map.end() && I->second.InlineChecked)
return I->second.MayInline;
- return None;
+ return std::nullopt;
}
void markVisitedBasicBlock(unsigned ID, const Decl* D, unsigned TotalIDs) {
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/MemRegion.h b/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h
index 9f85347db5df..151d3e57c1cb 100644
--- a/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h
+++ b/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h
@@ -30,13 +30,14 @@
#include "clang/StaticAnalyzer/Core/PathSensitive/SymExpr.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/FoldingSet.h"
-#include "llvm/ADT/Optional.h"
#include "llvm/ADT/PointerIntPair.h"
+#include "llvm/ADT/iterator_range.h"
#include "llvm/Support/Allocator.h"
#include "llvm/Support/Casting.h"
#include <cassert>
#include <cstdint>
#include <limits>
+#include <optional>
#include <string>
#include <utility>
@@ -74,6 +75,7 @@ public:
RegionOffset() = default;
RegionOffset(const MemRegion *r, int64_t off) : R(r), Offset(off) {}
+ /// It might return null.
const MemRegion *getRegion() const { return R; }
bool hasSymbolicOffset() const { return Offset == Symbolic; }
@@ -101,7 +103,7 @@ public:
private:
const Kind kind;
- mutable Optional<RegionOffset> cachedOffset;
+ mutable std::optional<RegionOffset> cachedOffset;
protected:
MemRegion(Kind k) : kind(k) {}
@@ -114,26 +116,27 @@ public:
virtual MemRegionManager &getMemRegionManager() const = 0;
- const MemSpaceRegion *getMemorySpace() const;
+ LLVM_ATTRIBUTE_RETURNS_NONNULL const MemSpaceRegion *getMemorySpace() const;
- const MemRegion *getBaseRegion() const;
+ LLVM_ATTRIBUTE_RETURNS_NONNULL const MemRegion *getBaseRegion() const;
/// Recursively retrieve the region of the most derived class instance of
/// regions of C++ base class instances.
+ LLVM_ATTRIBUTE_RETURNS_NONNULL
const MemRegion *getMostDerivedObjectRegion() const;
/// Check if the region is a subregion of the given region.
/// Each region is a subregion of itself.
virtual bool isSubRegionOf(const MemRegion *R) const;
+ LLVM_ATTRIBUTE_RETURNS_NONNULL
const MemRegion *StripCasts(bool StripBaseAndDerivedCasts = true) const;
/// If this is a symbolic region, returns the region. Otherwise,
/// goes up the base chain looking for the first symbolic base region.
+ /// It might return null.
const SymbolicRegion *getSymbolicBase() const;
- bool hasGlobalsOrParametersStorage() const;
-
bool hasStackStorage() const;
bool hasStackNonParametersStorage() const;
@@ -169,7 +172,8 @@ public:
Kind getKind() const { return kind; }
template<typename RegionTy> const RegionTy* getAs() const;
- template<typename RegionTy> const RegionTy* castAs() const;
+ template <typename RegionTy>
+ LLVM_ATTRIBUTE_RETURNS_NONNULL const RegionTy *castAs() const;
virtual bool isBoundable() const { return false; }
@@ -268,6 +272,7 @@ public:
void dumpToStream(raw_ostream &os) const override;
+ LLVM_ATTRIBUTE_RETURNS_NONNULL
const CodeTextRegion *getCodeRegion() const { return CR; }
static bool classof(const MemRegion *R) {
@@ -391,6 +396,7 @@ protected:
}
public:
+ LLVM_ATTRIBUTE_RETURNS_NONNULL
const StackFrameContext *getStackFrame() const { return SFC; }
void Profile(llvm::FoldingSetNodeID &ID) const override;
@@ -444,6 +450,7 @@ protected:
}
public:
+ LLVM_ATTRIBUTE_RETURNS_NONNULL
const MemRegion* getSuperRegion() const {
return superRegion;
}
@@ -481,6 +488,7 @@ class AllocaRegion : public SubRegion {
unsigned Cnt, const MemRegion *superRegion);
public:
+ LLVM_ATTRIBUTE_RETURNS_NONNULL
const Expr *getExpr() const { return Ex; }
bool isBoundable() const override { return true; }
@@ -639,10 +647,12 @@ public:
return locTy;
}
+ LLVM_ATTRIBUTE_RETURNS_NONNULL
const BlockDecl *getDecl() const {
return BD;
}
+ LLVM_ATTRIBUTE_RETURNS_NONNULL
AnalysisDeclContext *getAnalysisDeclContext() const { return AC; }
void dumpToStream(raw_ostream &os) const override;
@@ -674,6 +684,7 @@ class BlockDataRegion : public TypedRegion {
: TypedRegion(sreg, BlockDataRegionKind), BC(bc), LC(lc),
BlockCount(count) {
assert(bc);
+ assert(bc->getDecl());
assert(lc);
assert(isa<GlobalImmutableSpaceRegion>(sreg) ||
isa<StackLocalsSpaceRegion>(sreg) ||
@@ -685,8 +696,10 @@ class BlockDataRegion : public TypedRegion {
const MemRegion *);
public:
+ LLVM_ATTRIBUTE_RETURNS_NONNULL
const BlockCodeRegion *getCodeRegion() const { return BC; }
+ LLVM_ATTRIBUTE_RETURNS_NONNULL
const BlockDecl *getDecl() const { return BC->getDecl(); }
QualType getLocationType() const override { return BC->getLocationType(); }
@@ -700,10 +713,12 @@ public:
const MemRegion * const *originalR)
: R(r), OriginalR(originalR) {}
+ LLVM_ATTRIBUTE_RETURNS_NONNULL
const VarRegion *getCapturedRegion() const {
return cast<VarRegion>(*R);
}
+ LLVM_ATTRIBUTE_RETURNS_NONNULL
const VarRegion *getOriginalRegion() const {
return cast<VarRegion>(*OriginalR);
}
@@ -723,14 +738,20 @@ public:
++OriginalR;
return *this;
}
+
+ // This isn't really a conventional iterator.
+ // We just implement the deref as a no-op for now to make range-based for
+ // loops work.
+ const referenced_vars_iterator &operator*() const { return *this; }
};
/// Return the original region for a captured region, if
- /// one exists.
+ /// one exists. It might return null.
const VarRegion *getOriginalRegion(const VarRegion *VR) const;
referenced_vars_iterator referenced_vars_begin() const;
referenced_vars_iterator referenced_vars_end() const;
+ llvm::iterator_range<referenced_vars_iterator> referenced_vars() const;
void dumpToStream(raw_ostream &os) const override;
@@ -764,12 +785,26 @@ class SymbolicRegion : public SubRegion {
assert(s->getType()->isAnyPointerType() ||
s->getType()->isReferenceType() ||
s->getType()->isBlockPointerType());
- assert(isa<UnknownSpaceRegion>(sreg) || isa<HeapSpaceRegion>(sreg));
+ assert(isa<UnknownSpaceRegion>(sreg) || isa<HeapSpaceRegion>(sreg) ||
+ isa<GlobalSystemSpaceRegion>(sreg));
}
public:
+ /// It might return null.
SymbolRef getSymbol() const { return sym; }
+ /// Gets the type of the wrapped symbol.
+ /// This type might not be accurate at all times - it's just our best guess.
+ /// Consider these cases:
+ /// void foo(void *data, char *str, base *obj) {...}
+ /// The type of the pointee of `data` is of course not `void`, yet that's our
+ /// best guess. `str` might point to any object and `obj` might point to some
+ /// derived instance. `TypedRegions` other hand are representing the cases
+ /// when we actually know their types.
+ QualType getPointeeStaticType() const {
+ return sym->getType()->getPointeeType();
+ }
+
bool isBoundable() const override { return true; }
void Profile(llvm::FoldingSetNodeID& ID) const override;
@@ -801,6 +836,7 @@ class StringRegion : public TypedValueRegion {
const MemRegion *superRegion);
public:
+ LLVM_ATTRIBUTE_RETURNS_NONNULL
const StringLiteral *getStringLiteral() const { return Str; }
QualType getValueType() const override { return Str->getType(); }
@@ -835,6 +871,7 @@ class ObjCStringRegion : public TypedValueRegion {
const MemRegion *superRegion);
public:
+ LLVM_ATTRIBUTE_RETURNS_NONNULL
const ObjCStringLiteral *getObjCStringLiteral() const { return Str; }
QualType getValueType() const override { return Str->getType(); }
@@ -881,6 +918,7 @@ public:
void dumpToStream(raw_ostream &os) const override;
+ LLVM_ATTRIBUTE_RETURNS_NONNULL
const CompoundLiteralExpr *getLiteralExpr() const { return CL; }
static bool classof(const MemRegion* R) {
@@ -895,6 +933,7 @@ protected:
}
public:
+ // TODO what does this return?
virtual const ValueDecl *getDecl() const = 0;
static bool classof(const MemRegion* R) {
@@ -918,8 +957,10 @@ protected:
}
public:
+ // TODO what does this return?
const VarDecl *getDecl() const override = 0;
+ /// It might return null.
const StackFrameContext *getStackFrame() const;
QualType getValueType() const override {
@@ -947,6 +988,7 @@ class NonParamVarRegion : public VarRegion {
// which, unlike everything else on this list, are not memory spaces.
assert(isa<GlobalsSpaceRegion>(sReg) || isa<StackSpaceRegion>(sReg) ||
isa<BlockDataRegion>(sReg) || isa<UnknownSpaceRegion>(sReg));
+ assert(vd);
}
static void ProfileRegion(llvm::FoldingSetNodeID &ID, const VarDecl *VD,
@@ -955,6 +997,7 @@ class NonParamVarRegion : public VarRegion {
public:
void Profile(llvm::FoldingSetNodeID &ID) const override;
+ LLVM_ATTRIBUTE_RETURNS_NONNULL
const VarDecl *getDecl() const override { return VD; }
QualType getValueType() const override {
@@ -992,12 +1035,14 @@ class ParamVarRegion : public VarRegion {
ParamVarRegion(const Expr *OE, unsigned Idx, const MemRegion *SReg)
: VarRegion(SReg, ParamVarRegionKind), OriginExpr(OE), Index(Idx) {
assert(!cast<StackSpaceRegion>(SReg)->getStackFrame()->inTopFrame());
+ assert(OriginExpr);
}
static void ProfileRegion(llvm::FoldingSetNodeID &ID, const Expr *OE,
unsigned Idx, const MemRegion *SReg);
public:
+ LLVM_ATTRIBUTE_RETURNS_NONNULL
const Expr *getOriginExpr() const { return OriginExpr; }
unsigned getIndex() const { return Index; }
@@ -1006,6 +1051,8 @@ public:
void dumpToStream(raw_ostream &os) const override;
QualType getValueType() const override;
+
+ /// TODO: What does this return?
const ParmVarDecl *getDecl() const override;
bool canPrintPrettyAsExpr() const override;
@@ -1057,7 +1104,9 @@ class FieldRegion : public DeclRegion {
const FieldDecl *FD;
FieldRegion(const FieldDecl *fd, const SubRegion *sReg)
- : DeclRegion(sReg, FieldRegionKind), FD(fd) {}
+ : DeclRegion(sReg, FieldRegionKind), FD(fd) {
+ assert(FD);
+ }
static void ProfileRegion(llvm::FoldingSetNodeID &ID, const FieldDecl *FD,
const MemRegion* superRegion) {
@@ -1067,6 +1116,7 @@ class FieldRegion : public DeclRegion {
}
public:
+ LLVM_ATTRIBUTE_RETURNS_NONNULL
const FieldDecl *getDecl() const override { return FD; }
void Profile(llvm::FoldingSetNodeID &ID) const override;
@@ -1099,6 +1149,7 @@ class ObjCIvarRegion : public DeclRegion {
const MemRegion* superRegion);
public:
+ LLVM_ATTRIBUTE_RETURNS_NONNULL
const ObjCIvarDecl *getDecl() const override;
void Profile(llvm::FoldingSetNodeID& ID) const override;
@@ -1131,6 +1182,8 @@ class RegionRawOffset {
public:
// FIXME: Eventually support symbolic offsets.
CharUnits getOffset() const { return Offset; }
+
+ // It might return null.
const MemRegion *getRegion() const { return Region; }
void dumpToStream(raw_ostream &os) const;
@@ -1147,7 +1200,7 @@ class ElementRegion : public TypedValueRegion {
ElementRegion(QualType elementType, NonLoc Idx, const SubRegion *sReg)
: TypedValueRegion(sReg, ElementRegionKind), ElementType(elementType),
Index(Idx) {
- assert((!Idx.getAs<nonloc::ConcreteInt>() ||
+ assert((!isa<nonloc::ConcreteInt>(Idx) ||
Idx.castAs<nonloc::ConcreteInt>().getValue().isSigned()) &&
"The index must be signed");
assert(!elementType.isNull() && !elementType->isVoidType() &&
@@ -1185,16 +1238,19 @@ class CXXTempObjectRegion : public TypedValueRegion {
CXXTempObjectRegion(Expr const *E, MemSpaceRegion const *sReg)
: TypedValueRegion(sReg, CXXTempObjectRegionKind), Ex(E) {
assert(E);
- assert(isa<StackLocalsSpaceRegion>(sReg) ||
- isa<GlobalInternalSpaceRegion>(sReg));
+ assert(isa<StackLocalsSpaceRegion>(sReg));
}
static void ProfileRegion(llvm::FoldingSetNodeID &ID,
Expr const *E, const MemRegion *sReg);
public:
+ LLVM_ATTRIBUTE_RETURNS_NONNULL
const Expr *getExpr() const { return Ex; }
+ LLVM_ATTRIBUTE_RETURNS_NONNULL
+ const StackFrameContext *getStackFrame() const;
+
QualType getValueType() const override { return Ex->getType(); }
void dumpToStream(raw_ostream &os) const override;
@@ -1206,6 +1262,45 @@ public:
}
};
+// C++ temporary object that have lifetime extended to lifetime of the
+// variable. Usually they represent temporary bounds to reference variables.
+class CXXLifetimeExtendedObjectRegion : public TypedValueRegion {
+ friend class MemRegionManager;
+
+ Expr const *Ex;
+ ValueDecl const *ExD;
+
+ CXXLifetimeExtendedObjectRegion(Expr const *E, ValueDecl const *D,
+ MemSpaceRegion const *sReg)
+ : TypedValueRegion(sReg, CXXLifetimeExtendedObjectRegionKind), Ex(E),
+ ExD(D) {
+ assert(E);
+ assert(D);
+ assert((isa<StackLocalsSpaceRegion, GlobalInternalSpaceRegion>(sReg)));
+ }
+
+ static void ProfileRegion(llvm::FoldingSetNodeID &ID, Expr const *E,
+ ValueDecl const *D, const MemRegion *sReg);
+
+public:
+ LLVM_ATTRIBUTE_RETURNS_NONNULL
+ const Expr *getExpr() const { return Ex; }
+ LLVM_ATTRIBUTE_RETURNS_NONNULL
+ const ValueDecl *getExtendingDecl() const { return ExD; }
+ /// It might return null.
+ const StackFrameContext *getStackFrame() const;
+
+ QualType getValueType() const override { return Ex->getType(); }
+
+ void dumpToStream(raw_ostream &os) const override;
+
+ void Profile(llvm::FoldingSetNodeID &ID) const override;
+
+ static bool classof(const MemRegion *R) {
+ return R->getKind() == CXXLifetimeExtendedObjectRegionKind;
+ }
+};
+
// CXXBaseObjectRegion represents a base object within a C++ object. It is
// identified by the base class declaration and the region of its parent object.
class CXXBaseObjectRegion : public TypedValueRegion {
@@ -1223,6 +1318,7 @@ class CXXBaseObjectRegion : public TypedValueRegion {
bool IsVirtual, const MemRegion *SReg);
public:
+ LLVM_ATTRIBUTE_RETURNS_NONNULL
const CXXRecordDecl *getDecl() const { return Data.getPointer(); }
bool isVirtual() const { return Data.getInt(); }
@@ -1265,6 +1361,7 @@ class CXXDerivedObjectRegion : public TypedValueRegion {
const MemRegion *SReg);
public:
+ LLVM_ATTRIBUTE_RETURNS_NONNULL
const CXXRecordDecl *getDecl() const { return DerivedD; }
QualType getValueType() const override;
@@ -1290,8 +1387,8 @@ const RegionTy* MemRegion::getAs() const {
return nullptr;
}
-template<typename RegionTy>
-const RegionTy* MemRegion::castAs() const {
+template <typename RegionTy>
+LLVM_ATTRIBUTE_RETURNS_NONNULL const RegionTy *MemRegion::castAs() const {
return cast<RegionTy>(this);
}
@@ -1325,6 +1422,7 @@ public:
~MemRegionManager();
ASTContext &getContext() { return Ctx; }
+ const ASTContext &getContext() const { return Ctx; }
llvm::BumpPtrAllocator &getAllocator() { return A; }
@@ -1375,7 +1473,9 @@ public:
const LocationContext *LC);
/// Retrieve or create a "symbolic" memory region.
- const SymbolicRegion* getSymbolicRegion(SymbolRef Sym);
+ /// If no memory space is specified, `UnknownSpaceRegion` will be used.
+ const SymbolicRegion *
+ getSymbolicRegion(SymbolRef Sym, const MemSpaceRegion *MemSpace = nullptr);
/// Return a unique symbolic region belonging to heap memory space.
const SymbolicRegion *getSymbolicHeapRegion(SymbolRef sym);
@@ -1433,6 +1533,19 @@ public:
const CXXTempObjectRegion *getCXXTempObjectRegion(Expr const *Ex,
LocationContext const *LC);
+ /// Create a CXXLifetimeExtendedObjectRegion for temporaries which are
+ /// lifetime-extended by local references.
+ const CXXLifetimeExtendedObjectRegion *
+ getCXXLifetimeExtendedObjectRegion(Expr const *Ex, ValueDecl const *VD,
+ LocationContext const *LC);
+
+ /// Create a CXXLifetimeExtendedObjectRegion for temporaries which are
+ /// lifetime-extended by *static* references.
+ /// This differs from \ref getCXXLifetimeExtendedObjectRegion(Expr const *,
+ /// ValueDecl const *, LocationContext const *) in the super-region used.
+ const CXXLifetimeExtendedObjectRegion *
+ getCXXStaticLifetimeExtendedObjectRegion(const Expr *Ex, ValueDecl const *VD);
+
/// Create a CXXBaseObjectRegion with the given base class for region
/// \p Super.
///
@@ -1471,11 +1584,6 @@ public:
const LocationContext *lc,
unsigned blockCount);
- /// Create a CXXTempObjectRegion for temporaries which are lifetime-extended
- /// by static references. This differs from getCXXTempObjectRegion in the
- /// super-region used.
- const CXXTempObjectRegion *getCXXStaticTempObjectRegion(const Expr *Ex);
-
private:
template <typename RegionTy, typename SuperTy,
typename Arg1Ty>
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..ca75c2a756a4 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
@@ -23,6 +23,7 @@
#include "llvm/ADT/FoldingSet.h"
#include "llvm/ADT/ImmutableMap.h"
#include "llvm/Support/Allocator.h"
+#include <optional>
#include <utility>
namespace llvm {
@@ -47,8 +48,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; }
@@ -80,11 +79,49 @@ private:
friend class ProgramStateManager;
friend class ExplodedGraph;
friend class ExplodedNode;
+ friend class NodeBuilder;
ProgramStateManager *stateMgr;
Environment Env; // Maps a Stmt to its current SVal.
Store store; // Maps a location to its current value.
GenericDataMap GDM; // Custom data stored by a client of this class.
+
+ // A state is infeasible if there is a contradiction among the constraints.
+ // An infeasible state is represented by a `nullptr`.
+ // In the sense of `assumeDual`, a state can have two children by adding a
+ // new constraint and the negation of that new constraint. A parent state is
+ // over-constrained if both of its children are infeasible. In the
+ // mathematical sense, it means that the parent is infeasible and we should
+ // have realized that at the moment when we have created it. However, we
+ // could not recognize that because of the imperfection of the underlying
+ // constraint solver. We say it is posteriorly over-constrained because we
+ // recognize that a parent is infeasible only *after* a new and more specific
+ // constraint and its negation are evaluated.
+ //
+ // Example:
+ //
+ // x * x = 4 and x is in the range [0, 1]
+ // This is an already infeasible state, but the constraint solver is not
+ // capable of handling sqrt, thus we don't know it yet.
+ //
+ // Then a new constraint `x = 0` is added. At this moment the constraint
+ // solver re-evaluates the existing constraints and realizes the
+ // contradiction `0 * 0 = 4`.
+ // We also evaluate the negated constraint `x != 0`; the constraint solver
+ // deduces `x = 1` and then realizes the contradiction `1 * 1 = 4`.
+ // Both children are infeasible, thus the parent state is marked as
+ // posteriorly over-constrained. These parents are handled with special care:
+ // we do not allow transitions to exploded nodes with such states.
+ bool PosteriorlyOverconstrained = false;
+ // Make internal constraint solver entities friends so they can access the
+ // overconstrained-related functions. We want to keep this API inaccessible
+ // for Checkers.
+ friend class ConstraintManager;
+ bool isPosteriorlyOverconstrained() const {
+ return PosteriorlyOverconstrained;
+ }
+ ProgramStateRef cloneAsPosteriorlyOverconstrained() const;
+
unsigned refCount;
/// makeWithStore - Return a ProgramState with the same values as the current
@@ -137,6 +174,7 @@ public:
V->Env.Profile(ID);
ID.AddPointer(V->store);
V->GDM.Profile(ID);
+ ID.AddBoolean(V->PosteriorlyOverconstrained);
}
/// Profile - Used to profile the contents of this object for inclusion
@@ -179,18 +217,22 @@ public:
///
/// This returns a new state with the added constraint on \p cond.
/// If no new state is feasible, NULL is returned.
- LLVM_NODISCARD ProgramStateRef assume(DefinedOrUnknownSVal cond,
- bool assumption) const;
+ [[nodiscard]] ProgramStateRef assume(DefinedOrUnknownSVal cond,
+ bool assumption) const;
/// Assumes both "true" and "false" for \p cond, and returns both
/// corresponding states (respectively).
///
/// This is more efficient than calling assume() twice. Note that one (but not
/// both) of the returned states may be NULL.
- LLVM_NODISCARD std::pair<ProgramStateRef, ProgramStateRef>
+ [[nodiscard]] std::pair<ProgramStateRef, ProgramStateRef>
assume(DefinedOrUnknownSVal cond) const;
- LLVM_NODISCARD ProgramStateRef
+ [[nodiscard]] std::pair<ProgramStateRef, ProgramStateRef>
+ assumeInBoundDual(DefinedOrUnknownSVal idx, DefinedOrUnknownSVal upperBound,
+ QualType IndexType = QualType()) const;
+
+ [[nodiscard]] ProgramStateRef
assumeInBound(DefinedOrUnknownSVal idx, DefinedOrUnknownSVal upperBound,
bool assumption, QualType IndexType = QualType()) const;
@@ -200,17 +242,17 @@ public:
///
/// This returns a new state with the added constraint on \p cond.
/// If no new state is feasible, NULL is returned.
- LLVM_NODISCARD ProgramStateRef assumeInclusiveRange(DefinedOrUnknownSVal Val,
- const llvm::APSInt &From,
- const llvm::APSInt &To,
- bool assumption) const;
+ [[nodiscard]] ProgramStateRef assumeInclusiveRange(DefinedOrUnknownSVal Val,
+ const llvm::APSInt &From,
+ const llvm::APSInt &To,
+ bool assumption) const;
/// Assumes given range both "true" and "false" for \p Val, and returns both
/// corresponding states (respectively).
///
/// This is more efficient than calling assume() twice. Note that one (but not
/// both) of the returned states may be NULL.
- LLVM_NODISCARD std::pair<ProgramStateRef, ProgramStateRef>
+ [[nodiscard]] std::pair<ProgramStateRef, ProgramStateRef>
assumeInclusiveRange(DefinedOrUnknownSVal Val, const llvm::APSInt &From,
const llvm::APSInt &To) const;
@@ -226,6 +268,7 @@ public:
ConditionTruthVal areEqual(SVal Lhs, SVal Rhs) const;
/// Utility method for getting regions.
+ LLVM_ATTRIBUTE_RETURNS_NONNULL
const VarRegion* getRegion(const VarDecl *D, const LocationContext *LC) const;
//==---------------------------------------------------------------------==//
@@ -234,16 +277,16 @@ public:
/// Create a new state by binding the value 'V' to the statement 'S' in the
/// state's environment.
- LLVM_NODISCARD ProgramStateRef BindExpr(const Stmt *S,
- const LocationContext *LCtx, SVal V,
- bool Invalidate = true) const;
+ [[nodiscard]] ProgramStateRef BindExpr(const Stmt *S,
+ const LocationContext *LCtx, SVal V,
+ bool Invalidate = true) const;
- LLVM_NODISCARD ProgramStateRef bindLoc(Loc location, SVal V,
- const LocationContext *LCtx,
- bool notifyChanges = true) const;
+ [[nodiscard]] ProgramStateRef bindLoc(Loc location, SVal V,
+ const LocationContext *LCtx,
+ bool notifyChanges = true) const;
- LLVM_NODISCARD ProgramStateRef bindLoc(SVal location, SVal V,
- const LocationContext *LCtx) const;
+ [[nodiscard]] ProgramStateRef bindLoc(SVal location, SVal V,
+ const LocationContext *LCtx) const;
/// Initializes the region of memory represented by \p loc with an initial
/// value. Once initialized, all values loaded from any sub-regions of that
@@ -251,15 +294,15 @@ public:
/// This method should not be used on regions that are already initialized.
/// If you need to indicate that memory contents have suddenly become unknown
/// within a certain region of memory, consider invalidateRegions().
- LLVM_NODISCARD ProgramStateRef
+ [[nodiscard]] ProgramStateRef
bindDefaultInitial(SVal loc, SVal V, const LocationContext *LCtx) const;
/// Performs C++ zero-initialization procedure on the region of memory
/// represented by \p loc.
- LLVM_NODISCARD ProgramStateRef
+ [[nodiscard]] ProgramStateRef
bindDefaultZero(SVal loc, const LocationContext *LCtx) const;
- LLVM_NODISCARD ProgramStateRef killBinding(Loc LV) const;
+ [[nodiscard]] ProgramStateRef killBinding(Loc LV) const;
/// Returns the state with bindings for the given regions
/// cleared from the store.
@@ -279,24 +322,25 @@ public:
/// the call and should be considered directly invalidated.
/// \param ITraits information about special handling for a particular
/// region/symbol.
- LLVM_NODISCARD ProgramStateRef
+ [[nodiscard]] ProgramStateRef
invalidateRegions(ArrayRef<const MemRegion *> Regions, const Expr *E,
unsigned BlockCount, const LocationContext *LCtx,
bool CausesPointerEscape, InvalidatedSymbols *IS = nullptr,
const CallEvent *Call = nullptr,
RegionAndSymbolInvalidationTraits *ITraits = nullptr) const;
- LLVM_NODISCARD ProgramStateRef
- invalidateRegions(ArrayRef<SVal> Regions, const Expr *E,
- unsigned BlockCount, const LocationContext *LCtx,
- bool CausesPointerEscape, InvalidatedSymbols *IS = nullptr,
+ [[nodiscard]] ProgramStateRef
+ invalidateRegions(ArrayRef<SVal> Regions, const Expr *E, unsigned BlockCount,
+ const LocationContext *LCtx, bool CausesPointerEscape,
+ InvalidatedSymbols *IS = nullptr,
const CallEvent *Call = nullptr,
RegionAndSymbolInvalidationTraits *ITraits = nullptr) const;
/// enterStackFrame - Returns the state for entry to the given stack frame,
/// preserving the current state.
- LLVM_NODISCARD ProgramStateRef enterStackFrame(
- const CallEvent &Call, const StackFrameContext *CalleeCtx) const;
+ [[nodiscard]] ProgramStateRef
+ enterStackFrame(const CallEvent &Call,
+ const StackFrameContext *CalleeCtx) const;
/// Return the value of 'self' if available in the given context.
SVal getSelfSVal(const LocationContext *LC) const;
@@ -308,10 +352,6 @@ public:
Loc getLValue(const CXXRecordDecl *BaseClass, const SubRegion *Super,
bool IsVirtual) const;
- /// Get the lvalue for a parameter.
- Loc getLValue(const Expr *Call, unsigned Index,
- const LocationContext *LC) const;
-
/// Get the lvalue for a variable reference.
Loc getLValue(const VarDecl *D, const LocationContext *LC) const;
@@ -379,7 +419,7 @@ public:
void *const* FindGDM(void *K) const;
template <typename T>
- LLVM_NODISCARD ProgramStateRef
+ [[nodiscard]] ProgramStateRef
add(typename ProgramStateTrait<T>::key_type K) const;
template <typename T>
@@ -399,27 +439,27 @@ public:
typename ProgramStateTrait<T>::context_type get_context() const;
template <typename T>
- LLVM_NODISCARD ProgramStateRef
+ [[nodiscard]] ProgramStateRef
remove(typename ProgramStateTrait<T>::key_type K) const;
template <typename T>
- LLVM_NODISCARD ProgramStateRef
+ [[nodiscard]] ProgramStateRef
remove(typename ProgramStateTrait<T>::key_type K,
typename ProgramStateTrait<T>::context_type C) const;
- template <typename T> LLVM_NODISCARD ProgramStateRef remove() const;
+ template <typename T> [[nodiscard]] ProgramStateRef remove() const;
template <typename T>
- LLVM_NODISCARD ProgramStateRef
+ [[nodiscard]] ProgramStateRef
set(typename ProgramStateTrait<T>::data_type D) const;
template <typename T>
- LLVM_NODISCARD ProgramStateRef
+ [[nodiscard]] ProgramStateRef
set(typename ProgramStateTrait<T>::key_type K,
typename ProgramStateTrait<T>::value_type E) const;
template <typename T>
- LLVM_NODISCARD ProgramStateRef
+ [[nodiscard]] ProgramStateRef
set(typename ProgramStateTrait<T>::key_type K,
typename ProgramStateTrait<T>::value_type E,
typename ProgramStateTrait<T>::context_type C) const;
@@ -687,7 +727,7 @@ inline ProgramStateRef ProgramState::assumeInclusiveRange(
if (Val.isUnknown())
return this;
- assert(Val.getAs<NonLoc>() && "Only NonLocs are supported!");
+ assert(isa<NonLoc>(Val) && "Only NonLocs are supported!");
return getStateManager().ConstraintMgr->assumeInclusiveRange(
this, Val.castAs<NonLoc>(), From, To, Assumption);
@@ -700,14 +740,14 @@ ProgramState::assumeInclusiveRange(DefinedOrUnknownSVal Val,
if (Val.isUnknown())
return std::make_pair(this, this);
- assert(Val.getAs<NonLoc>() && "Only NonLocs are supported!");
+ assert(isa<NonLoc>(Val) && "Only NonLocs are supported!");
return getStateManager().ConstraintMgr->assumeInclusiveRangeDual(
this, Val.castAs<NonLoc>(), From, To);
}
inline ProgramStateRef ProgramState::bindLoc(SVal LV, SVal V, const LocationContext *LCtx) const {
- if (Optional<Loc> L = LV.getAs<Loc>())
+ if (std::optional<Loc> L = LV.getAs<Loc>())
return bindLoc(*L, V, LCtx);
return this;
}
@@ -757,7 +797,7 @@ inline SVal ProgramState::getLValue(const IndirectFieldDecl *D,
}
inline SVal ProgramState::getLValue(QualType ElementType, SVal Idx, SVal Base) const{
- if (Optional<NonLoc> N = Idx.getAs<NonLoc>())
+ if (std::optional<NonLoc> N = Idx.getAs<NonLoc>())
return getStateManager().StoreMgr->getLValueElement(ElementType, *N, Base);
return UnknownVal();
}
diff --git a/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h b/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h
index da82a55e3625..15bec97c5be8 100644
--- a/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h
+++ b/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h
@@ -21,29 +21,32 @@
#include "llvm/ADT/ImmutableSet.h"
#include "llvm/Support/Allocator.h"
#include <cstdint>
+#include <type_traits>
namespace clang {
namespace ento {
- template <typename T> struct ProgramStatePartialTrait;
-
- /// Declares a program state trait for type \p Type called \p Name, and
- /// introduce a type named \c NameTy.
- /// The macro should not be used inside namespaces.
- #define REGISTER_TRAIT_WITH_PROGRAMSTATE(Name, Type) \
- namespace { \
- class Name {}; \
- using Name ## Ty = Type; \
- } \
- namespace clang { \
- namespace ento { \
- template <> \
- struct ProgramStateTrait<Name> \
- : public ProgramStatePartialTrait<Name ## Ty> { \
- static void *GDMIndex() { static int Index; return &Index; } \
- }; \
- } \
- }
+template <typename T, typename Enable = void> struct ProgramStatePartialTrait;
+
+/// Declares a program state trait for type \p Type called \p Name, and
+/// introduce a type named \c NameTy.
+/// The macro should not be used inside namespaces.
+#define REGISTER_TRAIT_WITH_PROGRAMSTATE(Name, Type) \
+ namespace { \
+ class Name {}; \
+ using Name##Ty = Type; \
+ } \
+ namespace clang { \
+ namespace ento { \
+ template <> \
+ struct ProgramStateTrait<Name> : public ProgramStatePartialTrait<Name##Ty> { \
+ static void *GDMIndex() { \
+ static int Index; \
+ return &Index; \
+ } \
+ }; \
+ } \
+ }
/// Declares a factory for objects of type \p Type in the program state
/// manager. The type must provide a ::Factory sub-class. Commonly used for
@@ -267,60 +270,27 @@ namespace ento {
}
};
- // Partial specialization for bool.
- template <> struct ProgramStatePartialTrait<bool> {
- using data_type = bool;
-
- static data_type MakeData(void *const *p) {
- return p ? (data_type) (uintptr_t) *p
- : data_type();
- }
-
- static void *MakeVoidPtr(data_type d) {
- return (void *) (uintptr_t) d;
- }
+ template <typename T> struct DefaultProgramStatePartialTraitImpl {
+ using data_type = T;
+ static T MakeData(void *const *P) { return P ? (T)(uintptr_t)*P : T{}; }
+ static void *MakeVoidPtr(T D) { return (void *)(uintptr_t)D; }
};
- // Partial specialization for unsigned.
- template <> struct ProgramStatePartialTrait<unsigned> {
- using data_type = unsigned;
-
- static data_type MakeData(void *const *p) {
- return p ? (data_type) (uintptr_t) *p
- : data_type();
- }
-
- static void *MakeVoidPtr(data_type d) {
- return (void *) (uintptr_t) d;
- }
- };
-
- // Partial specialization for void*.
- template <> struct ProgramStatePartialTrait<void *> {
- using data_type = void *;
-
- static data_type MakeData(void *const *p) {
- return p ? *p
- : data_type();
- }
-
- static void *MakeVoidPtr(data_type d) {
- return d;
- }
- };
-
- // Partial specialization for const void *.
- template <> struct ProgramStatePartialTrait<const void *> {
- using data_type = const void *;
+ // Partial specialization for integral types.
+ template <typename T>
+ struct ProgramStatePartialTrait<T,
+ std::enable_if_t<std::is_integral<T>::value>>
+ : DefaultProgramStatePartialTraitImpl<T> {};
- static data_type MakeData(void *const *p) {
- return p ? *p : data_type();
- }
+ // Partial specialization for enums.
+ template <typename T>
+ struct ProgramStatePartialTrait<T, std::enable_if_t<std::is_enum<T>::value>>
+ : DefaultProgramStatePartialTraitImpl<T> {};
- static void *MakeVoidPtr(data_type d) {
- return const_cast<void *>(d);
- }
- };
+ // Partial specialization for pointers.
+ template <typename T>
+ struct ProgramStatePartialTrait<T *, void>
+ : DefaultProgramStatePartialTraitImpl<T *> {};
} // namespace ento
} // namespace clang
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 c67df1e51b4f..49ea006e27aa 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"
@@ -48,6 +48,7 @@ public:
ID.AddPointer(&To());
}
void dump(raw_ostream &OS) const;
+ void dump() const;
// In order to keep non-overlapping ranges sorted, we can compare only From
// points.
@@ -139,6 +140,30 @@ public:
/// Complexity: O(N)
/// where N = size(Original)
RangeSet add(RangeSet Original, const llvm::APSInt &Point);
+ /// Create a new set which is a union of two given ranges.
+ /// Possible intersections are not checked here.
+ ///
+ /// Complexity: O(N + M)
+ /// where N = size(LHS), M = size(RHS)
+ RangeSet unite(RangeSet LHS, RangeSet RHS);
+ /// Create a new set by uniting given range set with the given range.
+ /// All intersections and adjacent ranges are handled here.
+ ///
+ /// Complexity: O(N)
+ /// where N = size(Original)
+ RangeSet unite(RangeSet Original, Range Element);
+ /// Create a new set by uniting given range set with the given point.
+ /// All intersections and adjacent ranges are handled here.
+ ///
+ /// Complexity: O(N)
+ /// where N = size(Original)
+ RangeSet unite(RangeSet Original, llvm::APSInt Point);
+ /// Create a new set by uniting given range set with the given range
+ /// between points. All intersections and adjacent ranges are handled here.
+ ///
+ /// Complexity: O(N)
+ /// where N = size(Original)
+ RangeSet unite(RangeSet Original, llvm::APSInt From, llvm::APSInt To);
RangeSet getEmptySet() { return &EmptySet; }
@@ -212,6 +237,29 @@ public:
/// Complexity: O(N)
/// where N = size(What)
RangeSet negate(RangeSet What);
+ /// Performs promotions, truncations and conversions of the given set.
+ ///
+ /// This function is optimized for each of the six cast cases:
+ /// - noop
+ /// - conversion
+ /// - truncation
+ /// - truncation-conversion
+ /// - promotion
+ /// - promotion-conversion
+ ///
+ /// NOTE: This function is NOT self-inverse for truncations, because of
+ /// the higher bits loss:
+ /// - castTo(castTo(OrigRangeOfInt, char), int) != OrigRangeOfInt.
+ /// - castTo(castTo(OrigRangeOfChar, int), char) == OrigRangeOfChar.
+ /// But it is self-inverse for all the rest casts.
+ ///
+ /// Complexity:
+ /// - Noop O(1);
+ /// - Truncation O(N^2);
+ /// - Another case O(N);
+ /// where N = size(What)
+ RangeSet castTo(RangeSet What, APSIntType Ty);
+ RangeSet castTo(RangeSet What, QualType T);
/// Return associated value factory.
BasicValueFactory &getValueFactory() const { return ValueFactory; }
@@ -223,6 +271,25 @@ public:
ContainerType *construct(ContainerType &&From);
RangeSet intersect(const ContainerType &LHS, const ContainerType &RHS);
+ /// NOTE: This function relies on the fact that all values in the
+ /// containers are persistent (created via BasicValueFactory::getValue).
+ ContainerType unite(const ContainerType &LHS, const ContainerType &RHS);
+
+ /// This is a helper function for `castTo` method. Implies not to be used
+ /// separately.
+ /// Performs a truncation case of a cast operation.
+ ContainerType truncateTo(RangeSet What, APSIntType Ty);
+
+ /// This is a helper function for `castTo` method. Implies not to be used
+ /// separately.
+ /// Performs a conversion case and a promotion-conversion case for signeds
+ /// of a cast operation.
+ ContainerType convertTo(RangeSet What, APSIntType Ty);
+
+ /// This is a helper function for `castTo` method. Implies not to be used
+ /// separately.
+ /// Performs a promotion for unsigneds only.
+ ContainerType promoteTo(RangeSet What, APSIntType Ty);
// Many operations include producing new APSInt values and that's why
// we need this factory.
@@ -275,13 +342,37 @@ public:
/// Complexity: O(1)
const llvm::APSInt &getMaxValue() const;
+ bool isUnsigned() const;
+ uint32_t getBitWidth() const;
+ APSIntType getAPSIntType() const;
+
/// Test whether the given point is contained by any of the ranges.
///
/// Complexity: O(logN)
/// where N = size(this)
bool contains(llvm::APSInt Point) const { return containsImpl(Point); }
+ bool containsZero() const {
+ APSIntType T{getMinValue()};
+ return contains(T.getZeroValue());
+ }
+
+ /// Test if the range is the [0,0] range.
+ ///
+ /// Complexity: O(1)
+ bool encodesFalseRange() const {
+ const llvm::APSInt *Constant = getConcreteValue();
+ return Constant && Constant->isZero();
+ }
+
+ /// Test if the range doesn't contain zero.
+ ///
+ /// Complexity: O(logN)
+ /// where N = size(this)
+ bool encodesTrueRange() const { return !containsZero(); }
+
void dump(raw_ostream &OS) const;
+ void dump() const;
bool operator==(const RangeSet &Other) const { return *Impl == *Other.Impl; }
bool operator!=(const RangeSet &Other) const { return !(*this == Other); }
@@ -387,11 +478,22 @@ private:
static void computeAdjustment(SymbolRef &Sym, llvm::APSInt &Adjustment);
};
-/// Try to simplify a given symbolic expression's associated value based on the
-/// constraints in State. This is needed because the Environment bindings are
-/// not getting updated when a new constraint is added to the State.
+/// Try to simplify a given symbolic expression based on the constraints in
+/// State. This is needed because the Environment bindings are not getting
+/// updated when a new constraint is added to the State. If the symbol is
+/// simplified to a non-symbol (e.g. to a constant) then the original symbol
+/// is returned. We use this function in the family of assumeSymNE/EQ/LT/../GE
+/// functions where we can work only with symbols. Use the other function
+/// (simplifyToSVal) if you are interested in a simplification that may yield
+/// a concrete constant value.
SymbolRef simplify(ProgramStateRef State, SymbolRef Sym);
+/// Try to simplify a given symbolic expression's associated `SVal` based on the
+/// constraints in State. This is very similar to `simplify`, but this function
+/// always returns the simplified SVal. The simplified SVal might be a single
+/// constant (i.e. `ConcreteInt`).
+SVal simplifyToSVal(ProgramStateRef State, SymbolRef Sym);
+
} // namespace ento
} // namespace clang
diff --git a/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/Regions.def b/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/Regions.def
index 44ab31fc9f2e..245828a2fcc0 100644
--- a/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/Regions.def
+++ b/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/Regions.def
@@ -69,6 +69,7 @@ ABSTRACT_REGION(SubRegion, MemRegion)
REGION(CXXBaseObjectRegion, TypedValueRegion)
REGION(CXXDerivedObjectRegion, TypedValueRegion)
REGION(CXXTempObjectRegion, TypedValueRegion)
+ REGION(CXXLifetimeExtendedObjectRegion, TypedValueRegion)
REGION(CXXThisRegion, TypedValueRegion)
ABSTRACT_REGION(DeclRegion, TypedValueRegion)
REGION(FieldRegion, DeclRegion)
diff --git a/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SMTConstraintManager.h b/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SMTConstraintManager.h
index e4878d4e0156..5116a4c06850 100644
--- a/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SMTConstraintManager.h
+++ b/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SMTConstraintManager.h
@@ -18,6 +18,7 @@
#include "clang/Basic/TargetInfo.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/RangedConstraintManager.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/SMTConv.h"
+#include <optional>
typedef llvm::ImmutableSet<
std::pair<clang::ento::SymbolRef, const llvm::SMTExpr *>>
@@ -128,8 +129,8 @@ public:
addStateConstraints(State);
// Constraints are unsatisfiable
- Optional<bool> isSat = Solver->check();
- if (!isSat.hasValue() || !isSat.getValue())
+ std::optional<bool> isSat = Solver->check();
+ if (!isSat || !*isSat)
return nullptr;
// Model does not assign interpretation
@@ -145,8 +146,8 @@ public:
Solver->addConstraint(NotExp);
- Optional<bool> isNotSat = Solver->check();
- if (!isNotSat.hasValue() || isNotSat.getValue())
+ std::optional<bool> isNotSat = Solver->check();
+ if (!isNotSat || *isNotSat)
return nullptr;
// This is the only solution, store it
@@ -202,9 +203,9 @@ public:
auto CZ = State->get<ConstraintSMT>();
auto &CZFactory = State->get_context<ConstraintSMT>();
- for (auto I = CZ.begin(), E = CZ.end(); I != E; ++I) {
- if (SymReaper.isDead(I->first))
- CZ = CZFactory.remove(CZ, *I);
+ for (const auto &Entry : CZ) {
+ if (SymReaper.isDead(Entry.first))
+ CZ = CZFactory.remove(CZ, Entry);
}
return State->set<ConstraintSMT>(CZ);
@@ -246,7 +247,7 @@ public:
bool canReasonAbout(SVal X) const override {
const TargetInfo &TI = getBasicVals().getContext().getTargetInfo();
- Optional<nonloc::SymbolVal> SymVal = X.getAs<nonloc::SymbolVal>();
+ std::optional<nonloc::SymbolVal> SymVal = X.getAs<nonloc::SymbolVal>();
if (!SymVal)
return true;
@@ -340,11 +341,11 @@ protected:
Solver->reset();
addStateConstraints(NewState);
- Optional<bool> res = Solver->check();
- if (!res.hasValue())
+ std::optional<bool> res = Solver->check();
+ if (!res)
Cached[hash] = ConditionTruthVal();
else
- Cached[hash] = ConditionTruthVal(res.getValue());
+ Cached[hash] = ConditionTruthVal(*res);
return Cached[hash];
}
diff --git a/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SMTConv.h b/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SMTConv.h
index 2d0f169260a4..fcc9c02999b3 100644
--- a/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SMTConv.h
+++ b/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SMTConv.h
@@ -446,6 +446,30 @@ public:
return getCastExpr(Solver, Ctx, Exp, FromTy, Sym->getType());
}
+ if (const UnarySymExpr *USE = dyn_cast<UnarySymExpr>(Sym)) {
+ if (RetTy)
+ *RetTy = Sym->getType();
+
+ QualType OperandTy;
+ llvm::SMTExprRef OperandExp =
+ getSymExpr(Solver, Ctx, USE->getOperand(), &OperandTy, hasComparison);
+ llvm::SMTExprRef UnaryExp =
+ OperandTy->isRealFloatingType()
+ ? fromFloatUnOp(Solver, USE->getOpcode(), OperandExp)
+ : fromUnOp(Solver, USE->getOpcode(), OperandExp);
+
+ // Currently, without the `support-symbolic-integer-casts=true` option,
+ // we do not emit `SymbolCast`s for implicit casts.
+ // One such implicit cast is missing if the operand of the unary operator
+ // has a different type than the unary itself.
+ if (Ctx.getTypeSize(OperandTy) != Ctx.getTypeSize(Sym->getType())) {
+ if (hasComparison)
+ *hasComparison = false;
+ return getCastExpr(Solver, Ctx, UnaryExp, OperandTy, Sym->getType());
+ }
+ return UnaryExp;
+ }
+
if (const BinarySymExpr *BSE = dyn_cast<BinarySymExpr>(Sym)) {
llvm::SMTExprRef Exp =
getSymBinExpr(Solver, Ctx, BSE, hasComparison, RetTy);
@@ -654,14 +678,14 @@ public:
assert(!LTy.isNull() && !RTy.isNull() && "Input type is null!");
// Always perform integer promotion before checking type equality.
// Otherwise, e.g. (bool) a + (bool) b could trigger a backend assertion
- if (LTy->isPromotableIntegerType()) {
+ if (Ctx.isPromotableIntegerType(LTy)) {
QualType NewTy = Ctx.getPromotedIntegerType(LTy);
uint64_t NewBitWidth = Ctx.getTypeSize(NewTy);
LHS = (*doCast)(Solver, LHS, NewTy, NewBitWidth, LTy, LBitWidth);
LTy = NewTy;
LBitWidth = NewBitWidth;
}
- if (RTy->isPromotableIntegerType()) {
+ if (Ctx.isPromotableIntegerType(RTy)) {
QualType NewTy = Ctx.getPromotedIntegerType(RTy);
uint64_t NewBitWidth = Ctx.getTypeSize(NewTy);
RHS = (*doCast)(Solver, RHS, NewTy, NewBitWidth, RTy, RBitWidth);
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 87a49cf4ffe9..d7cff49036cb 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
@@ -28,11 +28,12 @@
#include "clang/StaticAnalyzer/Core/PathSensitive/SymExpr.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h"
#include "llvm/ADT/ImmutableList.h"
-#include "llvm/ADT/Optional.h"
#include <cstdint>
+#include <optional>
namespace clang {
+class AnalyzerOptions;
class BlockDecl;
class CXXBoolLiteralExpr;
class CXXMethodDecl;
@@ -66,65 +67,28 @@ protected:
ProgramStateManager &StateMgr;
+ const AnalyzerOptions &AnOpts;
+
/// The scalar type to use for array indices.
const QualType ArrayIndexTy;
/// The width of the scalar type used for array indices.
const unsigned ArrayIndexWidth;
- SVal evalCastKind(UndefinedVal V, QualType CastTy, QualType OriginalTy);
- SVal evalCastKind(UnknownVal V, QualType CastTy, QualType OriginalTy);
- SVal evalCastKind(Loc V, QualType CastTy, QualType OriginalTy);
- SVal evalCastKind(NonLoc V, QualType CastTy, QualType OriginalTy);
- SVal evalCastSubKind(loc::ConcreteInt V, QualType CastTy,
- QualType OriginalTy);
- SVal evalCastSubKind(loc::GotoLabel V, QualType CastTy, QualType OriginalTy);
- SVal evalCastSubKind(loc::MemRegionVal V, QualType CastTy,
- QualType OriginalTy);
- SVal evalCastSubKind(nonloc::CompoundVal V, QualType CastTy,
- QualType OriginalTy);
- SVal evalCastSubKind(nonloc::ConcreteInt V, QualType CastTy,
- QualType OriginalTy);
- SVal evalCastSubKind(nonloc::LazyCompoundVal V, QualType CastTy,
- QualType OriginalTy);
- SVal evalCastSubKind(nonloc::LocAsInteger V, QualType CastTy,
- QualType OriginalTy);
- SVal evalCastSubKind(nonloc::SymbolVal V, QualType CastTy,
- QualType OriginalTy);
- SVal evalCastSubKind(nonloc::PointerToMember V, QualType CastTy,
- QualType OriginalTy);
-
public:
SValBuilder(llvm::BumpPtrAllocator &alloc, ASTContext &context,
- ProgramStateManager &stateMgr)
- : Context(context), BasicVals(context, alloc),
- SymMgr(context, BasicVals, alloc), MemMgr(context, alloc),
- StateMgr(stateMgr), ArrayIndexTy(context.LongLongTy),
- ArrayIndexWidth(context.getTypeSize(ArrayIndexTy)) {}
+ ProgramStateManager &stateMgr);
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.
SVal evalIntegralCast(ProgramStateRef state, SVal val, QualType castTy,
QualType originalType);
- virtual SVal evalMinus(NonLoc val) = 0;
-
- virtual SVal evalComplement(NonLoc val) = 0;
+ SVal evalMinus(NonLoc val);
+ SVal evalComplement(NonLoc val);
/// Create a new value which represents a binary expression with two non-
/// location operands.
@@ -146,6 +110,14 @@ public:
/// that value is returned. Otherwise, returns NULL.
virtual const llvm::APSInt *getKnownValue(ProgramStateRef state, SVal val) = 0;
+ /// Tries to get the minimal possible (integer) value of a given SVal. If the
+ /// constraint manager cannot provide an useful answer, this returns NULL.
+ virtual const llvm::APSInt *getMinValue(ProgramStateRef state, SVal val) = 0;
+
+ /// Tries to get the maximal possible (integer) value of a given SVal. If the
+ /// constraint manager cannot provide an useful answer, this returns NULL.
+ virtual const llvm::APSInt *getMaxValue(ProgramStateRef state, SVal val) = 0;
+
/// Simplify symbolic expressions within a given SVal. Return an SVal
/// that represents the same value, but is hopefully easier to work with
/// than the original SVal.
@@ -155,6 +127,9 @@ public:
SVal makeSymExprValNN(BinaryOperator::Opcode op,
NonLoc lhs, NonLoc rhs, QualType resultTy);
+ SVal evalUnaryOp(ProgramStateRef state, UnaryOperator::Opcode opc,
+ SVal operand, QualType type);
+
SVal evalBinOp(ProgramStateRef state, BinaryOperator::Opcode op,
SVal lhs, SVal rhs, QualType type);
@@ -188,6 +163,8 @@ public:
MemRegionManager &getRegionManager() { return MemMgr; }
const MemRegionManager &getRegionManager() const { return MemMgr; }
+ const AnalyzerOptions &getAnalyzerOptions() const { return AnOpts; }
+
// Forwarding methods to SymbolManager.
const SymbolConjured* conjureSymbol(const Stmt *stmt,
@@ -246,6 +223,15 @@ public:
const LocationContext *LCtx,
QualType type, unsigned Count);
+ /// Create an SVal representing the result of an alloca()-like call, that is,
+ /// an AllocaRegion on the stack.
+ ///
+ /// After calling this function, it's a good idea to set the extent of the
+ /// returned AllocaRegion.
+ loc::MemRegionVal getAllocaRegionVal(const Expr *E,
+ const LocationContext *LCtx,
+ unsigned Count);
+
DefinedOrUnknownSVal getDerivedRegionValueSymbolVal(
SymbolRef parentSymbol, const TypedValueRegion *region);
@@ -266,8 +252,8 @@ public:
/// Returns the value of \p E, if it can be determined in a non-path-sensitive
/// manner.
///
- /// If \p E is not a constant or cannot be modeled, returns \c None.
- Optional<SVal> getConstantVal(const Expr *E);
+ /// If \p E is not a constant or cannot be modeled, returns \c std::nullopt.
+ std::optional<SVal> getConstantVal(const Expr *E);
NonLoc makeCompoundVal(QualType type, llvm::ImmutableList<SVal> vals) {
return nonloc::CompoundVal(BasicVals.getCompoundValData(type, vals));
@@ -332,26 +318,30 @@ public:
return nonloc::ConcreteInt(BasicVals.getIntValue(integer, isUnsigned));
}
- NonLoc makeIntValWithPtrWidth(uint64_t integer, bool isUnsigned) {
- return nonloc::ConcreteInt(
- BasicVals.getIntWithPtrWidth(integer, isUnsigned));
+ NonLoc makeIntValWithWidth(QualType ptrType, uint64_t integer) {
+ return nonloc::ConcreteInt(BasicVals.getValue(integer, ptrType));
}
NonLoc makeLocAsInteger(Loc loc, unsigned bits) {
return nonloc::LocAsInteger(BasicVals.getPersistentSValWithData(loc, bits));
}
- NonLoc makeNonLoc(const SymExpr *lhs, BinaryOperator::Opcode op,
- const llvm::APSInt& rhs, QualType type);
+ nonloc::SymbolVal makeNonLoc(const SymExpr *lhs, BinaryOperator::Opcode op,
+ const llvm::APSInt &rhs, QualType type);
+
+ nonloc::SymbolVal makeNonLoc(const llvm::APSInt &rhs,
+ BinaryOperator::Opcode op, const SymExpr *lhs,
+ QualType type);
- NonLoc makeNonLoc(const llvm::APSInt& rhs, BinaryOperator::Opcode op,
- const SymExpr *lhs, QualType type);
+ nonloc::SymbolVal makeNonLoc(const SymExpr *lhs, BinaryOperator::Opcode op,
+ const SymExpr *rhs, QualType type);
- NonLoc makeNonLoc(const SymExpr *lhs, BinaryOperator::Opcode op,
- const SymExpr *rhs, QualType type);
+ NonLoc makeNonLoc(const SymExpr *operand, UnaryOperator::Opcode op,
+ QualType type);
/// Create a NonLoc value for cast.
- NonLoc makeNonLoc(const SymExpr *operand, QualType fromTy, QualType toTy);
+ nonloc::SymbolVal makeNonLoc(const SymExpr *operand, QualType fromTy,
+ QualType toTy);
nonloc::ConcreteInt makeTruthVal(bool b, QualType type) {
return nonloc::ConcreteInt(BasicVals.getTruthValue(b, type));
@@ -364,38 +354,46 @@ public:
/// Create NULL pointer, with proper pointer bit-width for given address
/// space.
/// \param type pointer type.
- Loc makeNullWithType(QualType type) {
+ loc::ConcreteInt makeNullWithType(QualType type) {
+ // We cannot use the `isAnyPointerType()`.
+ assert((type->isPointerType() || type->isObjCObjectPointerType() ||
+ type->isBlockPointerType() || type->isNullPtrType() ||
+ type->isReferenceType()) &&
+ "makeNullWithType must use pointer type");
+
+ // The `sizeof(T&)` is `sizeof(T)`, thus we replace the reference with a
+ // pointer. Here we assume that references are actually implemented by
+ // pointers under-the-hood.
+ type = type->isReferenceType()
+ ? Context.getPointerType(type->getPointeeType())
+ : type;
return loc::ConcreteInt(BasicVals.getZeroWithTypeSize(type));
}
- Loc makeNull() {
- return loc::ConcreteInt(BasicVals.getZeroWithPtrWidth());
- }
-
- Loc makeLoc(SymbolRef sym) {
+ loc::MemRegionVal makeLoc(SymbolRef sym) {
return loc::MemRegionVal(MemMgr.getSymbolicRegion(sym));
}
- Loc makeLoc(const MemRegion* region) {
+ loc::MemRegionVal makeLoc(const MemRegion *region) {
return loc::MemRegionVal(region);
}
- Loc makeLoc(const AddrLabelExpr *expr) {
+ loc::GotoLabel makeLoc(const AddrLabelExpr *expr) {
return loc::GotoLabel(expr->getLabel());
}
- Loc makeLoc(const llvm::APSInt& integer) {
+ loc::ConcreteInt makeLoc(const llvm::APSInt &integer) {
return loc::ConcreteInt(BasicVals.getValue(integer));
}
- /// Return MemRegionVal on success cast, otherwise return None.
- Optional<loc::MemRegionVal> getCastedMemRegionVal(const MemRegion *region,
- QualType type);
+ /// Return MemRegionVal on success cast, otherwise return std::nullopt.
+ std::optional<loc::MemRegionVal>
+ getCastedMemRegionVal(const MemRegion *region, QualType type);
/// Make an SVal that represents the given symbol. This follows the convention
/// of representing Loc-type symbols (symbolic pointers and references)
/// as Loc values wrapping the symbol rather than as plain symbol values.
- SVal makeSymbolVal(SymbolRef Sym) {
+ DefinedSVal makeSymbolVal(SymbolRef Sym) {
if (Loc::isLocType(Sym->getType()))
return makeLoc(Sym);
return nonloc::SymbolVal(Sym);
diff --git a/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SValVisitor.h b/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SValVisitor.h
index fc83e26183b3..b10f416f4435 100644
--- a/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SValVisitor.h
+++ b/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SValVisitor.h
@@ -14,9 +14,9 @@
#ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_SVALVISITOR_H
#define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_SVALVISITOR_H
+#include "clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h"
-#include "clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h"
namespace clang {
@@ -25,49 +25,40 @@ namespace ento {
/// SValVisitor - this class implements a simple visitor for SVal
/// subclasses.
template <typename ImplClass, typename RetTy = void> class SValVisitor {
-public:
-
-#define DISPATCH(NAME, CLASS) \
- return static_cast<ImplClass *>(this)->Visit ## NAME(V.castAs<CLASS>())
+ ImplClass &derived() { return *static_cast<ImplClass *>(this); }
+public:
RetTy Visit(SVal V) {
// Dispatch to VisitFooVal for each FooVal.
- // Take namespaces (loc:: and nonloc::) into account.
- switch (V.getBaseKind()) {
-#define BASIC_SVAL(Id, Parent) case SVal::Id ## Kind: DISPATCH(Id, Id);
+ switch (V.getKind()) {
+#define BASIC_SVAL(Id, Parent) \
+ case SVal::Id##Kind: \
+ return derived().Visit##Id(V.castAs<Id>());
+#define LOC_SVAL(Id, Parent) \
+ case SVal::Loc##Id##Kind: \
+ return derived().Visit##Id(V.castAs<loc::Id>());
+#define NONLOC_SVAL(Id, Parent) \
+ case SVal::NonLoc##Id##Kind: \
+ return derived().Visit##Id(V.castAs<nonloc::Id>());
#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.def"
- case SVal::LocKind:
- switch (V.getSubKind()) {
-#define LOC_SVAL(Id, Parent) \
- case loc::Id ## Kind: DISPATCH(Loc ## Id, loc :: Id);
-#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.def"
- }
- llvm_unreachable("Unknown Loc sub-kind!");
- case SVal::NonLocKind:
- switch (V.getSubKind()) {
-#define NONLOC_SVAL(Id, Parent) \
- case nonloc::Id ## Kind: DISPATCH(NonLoc ## Id, nonloc :: Id);
-#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.def"
- }
- llvm_unreachable("Unknown NonLoc sub-kind!");
}
llvm_unreachable("Unknown SVal kind!");
}
-#define BASIC_SVAL(Id, Parent) \
- RetTy Visit ## Id(Id V) { DISPATCH(Parent, Id); }
-#define ABSTRACT_SVAL(Id, Parent) \
- BASIC_SVAL(Id, Parent)
-#define LOC_SVAL(Id, Parent) \
- RetTy VisitLoc ## Id(loc::Id V) { DISPATCH(Parent, Parent); }
-#define NONLOC_SVAL(Id, Parent) \
- RetTy VisitNonLoc ## Id(nonloc::Id V) { DISPATCH(Parent, Parent); }
+ // Dispatch to the more generic handler as a default implementation.
+#define BASIC_SVAL(Id, Parent) \
+ RetTy Visit##Id(Id V) { return derived().Visit##Parent(V.castAs<Id>()); }
+#define ABSTRACT_SVAL(Id, Parent) BASIC_SVAL(Id, Parent)
+#define LOC_SVAL(Id, Parent) \
+ RetTy Visit##Id(loc::Id V) { return derived().VisitLoc(V.castAs<Loc>()); }
+#define NONLOC_SVAL(Id, Parent) \
+ RetTy Visit##Id(nonloc::Id V) { \
+ return derived().VisitNonLoc(V.castAs<NonLoc>()); \
+ }
#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.def"
// Base case, ignore it. :)
RetTy VisitSVal(SVal V) { return RetTy(); }
-
-#undef DISPATCH
};
/// SymExprVisitor - this class implements a simple visitor for SymExpr
diff --git a/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.def b/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.def
index eb05de6d9933..36d2425d155a 100644
--- a/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.def
+++ b/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.def
@@ -6,28 +6,24 @@
//
//===----------------------------------------------------------------------===//
//
-// The list of symbolic values (SVal kinds and sub-kinds) used in the Static
-// Analyzer. The distinction between loc:: and nonloc:: SVal namespaces is
+// The list of symbolic values (SVal kinds) used in the Static Analyzer.
+// The distinction between `loc::` and `nonloc::` SVal namespaces is
// currently hardcoded, because it is too peculiar and explicit to be handled
// uniformly. In order to use this information, users of this file must define
// one or more of the following macros:
//
-// BASIC_SVAL(Id, Parent) - for specific SVal sub-kinds, which are
-// neither in loc:: nor in nonloc:: namespace; these classes occupy
-// their own base kind IdKind.
+// BASIC_SVAL(Id, Parent) - for specific SVal kinds, which are
+// neither in `loc::` nor in `nonloc::` namespace.
//
// ABSTRACT_SVAL(Id, Parent) - for abstract SVal classes which are
-// neither in loc:: nor in nonloc:: namespace,
+// neither in `loc::` nor in `nonloc::` namespace,
//
-// ABSTRACT_SVAL_WITH_KIND(Id, Parent) - for SVal classes which are also
-// neither in loc:: nor in nonloc:: namespace, but occupy a whole base kind
-// identifier IdKind, much like BASIC_SVALs.
+// LOC_SVAL(Id, Parent) - for values in `loc::` namespace.
//
-// LOC_SVAL(Id, Parent) - for values in loc:: namespace, which occupy a sub-kind
-// loc::IdKind.
+// NONLOC_SVAL(Id, Parent) - for values in `nonloc::` namespace.
//
-// NONLOC_SVAL(Id, Parent) - for values in nonloc:: namespace, which occupy a
-// sub-kind nonloc::IdKind.
+// SVAL_RANGE(Id, First, Last) - for defining range of subtypes of
+// the abstract class `Id`.
//
//===----------------------------------------------------------------------===//
@@ -39,10 +35,6 @@
#define ABSTRACT_SVAL(Id, Parent)
#endif
-#ifndef ABSTRACT_SVAL_WITH_KIND
-#define ABSTRACT_SVAL_WITH_KIND(Id, Parent) ABSTRACT_SVAL(Id, Parent)
-#endif
-
#ifndef LOC_SVAL
#define LOC_SVAL(Id, Parent)
#endif
@@ -51,24 +43,30 @@
#define NONLOC_SVAL(Id, Parent)
#endif
+#ifndef SVAL_RANGE
+#define SVAL_RANGE(Id, First, Last)
+#endif
+
BASIC_SVAL(UndefinedVal, SVal)
ABSTRACT_SVAL(DefinedOrUnknownSVal, SVal)
BASIC_SVAL(UnknownVal, DefinedOrUnknownSVal)
ABSTRACT_SVAL(DefinedSVal, DefinedOrUnknownSVal)
- ABSTRACT_SVAL_WITH_KIND(Loc, DefinedSVal)
+ ABSTRACT_SVAL(Loc, DefinedSVal)
LOC_SVAL(ConcreteInt, Loc)
LOC_SVAL(GotoLabel, Loc)
LOC_SVAL(MemRegionVal, Loc)
- ABSTRACT_SVAL_WITH_KIND(NonLoc, DefinedSVal)
+ SVAL_RANGE(Loc, ConcreteInt, MemRegionVal)
+ ABSTRACT_SVAL(NonLoc, DefinedSVal)
NONLOC_SVAL(CompoundVal, NonLoc)
NONLOC_SVAL(ConcreteInt, NonLoc)
NONLOC_SVAL(LazyCompoundVal, NonLoc)
NONLOC_SVAL(LocAsInteger, NonLoc)
NONLOC_SVAL(SymbolVal, NonLoc)
NONLOC_SVAL(PointerToMember, NonLoc)
+ SVAL_RANGE(NonLoc, CompoundVal, PointerToMember)
+#undef SVAL_RANGE
#undef NONLOC_SVAL
#undef LOC_SVAL
-#undef ABSTRACT_SVAL_WITH_KIND
#undef ABSTRACT_SVAL
#undef BASIC_SVAL
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..c60528b7685f 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
@@ -18,14 +18,16 @@
#include "clang/AST/Type.h"
#include "clang/Basic/LLVM.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/SymExpr.h"
+#include "llvm/ADT/APSInt.h"
#include "llvm/ADT/FoldingSet.h"
#include "llvm/ADT/ImmutableList.h"
-#include "llvm/ADT/None.h"
-#include "llvm/ADT/Optional.h"
#include "llvm/ADT/PointerUnion.h"
+#include "llvm/ADT/STLForwardCompat.h"
+#include "llvm/ADT/iterator_range.h"
#include "llvm/Support/Casting.h"
#include <cassert>
#include <cstdint>
+#include <optional>
#include <utility>
//==------------------------------------------------------------------------==//
@@ -35,13 +37,11 @@
namespace clang {
class CXXBaseSpecifier;
-class DeclaratorDecl;
class FunctionDecl;
class LabelDecl;
namespace ento {
-class BasicValueFactory;
class CompoundValData;
class LazyCompoundValData;
class MemRegion;
@@ -49,105 +49,63 @@ class PointerToMemberData;
class SValBuilder;
class TypedValueRegion;
-namespace nonloc {
-
-/// Sub-kinds for NonLoc values.
-enum Kind {
-#define NONLOC_SVAL(Id, Parent) Id ## Kind,
-#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.def"
-};
-
-} // namespace nonloc
-
-namespace loc {
-
-/// Sub-kinds for Loc values.
-enum Kind {
-#define LOC_SVAL(Id, Parent) Id ## Kind,
-#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.def"
-};
-
-} // namespace loc
-
/// SVal - This represents a symbolic expression, which can be either
/// an L-value or an R-value.
///
class SVal {
public:
- enum BaseKind {
- // The enumerators must be representable using 2 bits.
-#define BASIC_SVAL(Id, Parent) Id ## Kind,
-#define ABSTRACT_SVAL_WITH_KIND(Id, Parent) Id ## Kind,
+ enum SValKind : unsigned char {
+#define BASIC_SVAL(Id, Parent) Id##Kind,
+#define LOC_SVAL(Id, Parent) Loc##Id##Kind,
+#define NONLOC_SVAL(Id, Parent) NonLoc##Id##Kind,
+#define SVAL_RANGE(Id, First, Last) \
+ BEGIN_##Id = Id##First##Kind, END_##Id = Id##Last##Kind,
#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.def"
};
- enum { BaseBits = 2, BaseMask = 0b11 };
protected:
const void *Data = nullptr;
+ SValKind Kind = UndefinedValKind;
- /// The lowest 2 bits are a BaseKind (0 -- 3).
- /// The higher bits are an unsigned "kind" value.
- unsigned Kind = 0;
+ explicit SVal(SValKind Kind, const void *Data = nullptr)
+ : Data(Data), Kind(Kind) {}
- explicit SVal(const void *d, bool isLoc, unsigned ValKind)
- : Data(d), Kind((isLoc ? LocKind : NonLocKind) | (ValKind << BaseBits)) {}
-
- explicit SVal(BaseKind k, const void *D = nullptr) : Data(D), Kind(k) {}
+ template <typename T> const T *castDataAs() const {
+ return static_cast<const T *>(Data);
+ }
public:
explicit SVal() = default;
/// Convert to the specified SVal type, asserting that this SVal is of
/// the desired type.
- template<typename T>
- T castAs() const {
- assert(T::isKind(*this));
- return *static_cast<const T *>(this);
- }
+ template <typename T> T castAs() const { return llvm::cast<T>(*this); }
- /// Convert to the specified SVal type, returning None if this SVal is
+ /// Convert to the specified SVal type, returning std::nullopt if this SVal is
/// not of the desired type.
- template<typename T>
- Optional<T> getAs() const {
- if (!T::isKind(*this))
- return None;
- return *static_cast<const T *>(this);
+ template <typename T> std::optional<T> getAs() const {
+ return llvm::dyn_cast<T>(*this);
}
- unsigned getRawKind() const { return Kind; }
- BaseKind getBaseKind() const { return (BaseKind) (Kind & BaseMask); }
- unsigned getSubKind() const { return Kind >> BaseBits; }
+ SValKind getKind() const { return Kind; }
// This method is required for using SVal in a FoldingSetNode. It
// extracts a unique signature for this SVal object.
void Profile(llvm::FoldingSetNodeID &ID) const {
- ID.AddInteger((unsigned) getRawKind());
ID.AddPointer(Data);
+ ID.AddInteger(llvm::to_underlying(getKind()));
}
- bool operator==(const SVal &R) const {
- return getRawKind() == R.getRawKind() && Data == R.Data;
- }
+ bool operator==(SVal R) const { return Kind == R.Kind && Data == R.Data; }
+ bool operator!=(SVal R) const { return !(*this == R); }
- bool operator!=(const SVal &R) const {
- return !(*this == R);
- }
+ bool isUnknown() const { return getKind() == UnknownValKind; }
- bool isUnknown() const {
- return getRawKind() == UnknownValKind;
- }
+ bool isUndef() const { return getKind() == UndefinedValKind; }
- bool isUndef() const {
- return getRawKind() == UndefinedValKind;
- }
+ bool isUnknownOrUndef() const { return isUnknown() || isUndef(); }
- bool isUnknownOrUndef() const {
- return getRawKind() <= UnknownValKind;
- }
-
- bool isValid() const {
- return getRawKind() > UnknownValKind;
- }
+ bool isValid() const { return !isUnknownOrUndef(); }
bool isConstant() const;
@@ -155,9 +113,6 @@ public:
bool isZeroConstant() const;
- /// hasConjuredSymbol - If this SVal wraps a conjured symbol, return true;
- bool hasConjuredSymbol() const;
-
/// getAsFunctionDecl - If this SVal is a MemRegionVal and wraps a
/// CodeTextRegion wrapping a FunctionDecl, return that FunctionDecl.
/// Otherwise return 0.
@@ -182,6 +137,11 @@ public:
/// should continue to the base regions if the region is not symbolic.
SymbolRef getAsSymbol(bool IncludeBaseRegions = false) const;
+ /// If this SVal is loc::ConcreteInt or nonloc::ConcreteInt,
+ /// return a pointer to APSInt which is held in it.
+ /// Otherwise, return nullptr.
+ const llvm::APSInt *getAsInteger() const;
+
const MemRegion *getAsRegion() const;
/// printJson - Pretty-prints in JSON format.
@@ -190,16 +150,11 @@ public:
void dumpToStream(raw_ostream &OS) const;
void dump() const;
- SymExpr::symbol_iterator symbol_begin() const {
- const SymExpr *SE = getAsSymbol(/*IncludeBaseRegions=*/true);
- if (SE)
- return SE->symbol_begin();
- else
- return SymExpr::symbol_iterator();
- }
-
- SymExpr::symbol_iterator symbol_end() const {
- return SymExpr::symbol_end();
+ llvm::iterator_range<SymExpr::symbol_iterator> symbols() const {
+ if (const SymExpr *SE = getAsSymbol(/*IncludeBaseRegions=*/true))
+ return SE->symbols();
+ SymExpr::symbol_iterator end{};
+ return llvm::make_range(end, end);
}
/// Try to get a reasonable type for the given value.
@@ -221,16 +176,24 @@ inline raw_ostream &operator<<(raw_ostream &os, clang::ento::SVal V) {
return os;
}
+namespace nonloc {
+/// Sub-kinds for NonLoc values.
+#define NONLOC_SVAL(Id, Parent) \
+ inline constexpr auto Id##Kind = SVal::SValKind::NonLoc##Id##Kind;
+#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.def"
+} // namespace nonloc
+
+namespace loc {
+/// Sub-kinds for Loc values.
+#define LOC_SVAL(Id, Parent) \
+ inline constexpr auto Id##Kind = SVal::SValKind::Loc##Id##Kind;
+#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.def"
+} // namespace loc
+
class UndefinedVal : public SVal {
public:
UndefinedVal() : SVal(UndefinedValKind) {}
-
-private:
- friend class SVal;
-
- static bool isKind(const SVal& V) {
- return V.getBaseKind() == UndefinedValKind;
- }
+ static bool classof(SVal V) { return V.getKind() == UndefinedValKind; }
};
class DefinedOrUnknownSVal : public SVal {
@@ -240,30 +203,18 @@ public:
bool isUndef() const = delete;
bool isValid() const = delete;
-protected:
- DefinedOrUnknownSVal() = default;
- explicit DefinedOrUnknownSVal(const void *d, bool isLoc, unsigned ValKind)
- : SVal(d, isLoc, ValKind) {}
- explicit DefinedOrUnknownSVal(BaseKind k, void *D = nullptr) : SVal(k, D) {}
-
-private:
- friend class SVal;
+ static bool classof(SVal V) { return !V.isUndef(); }
- static bool isKind(const SVal& V) {
- return !V.isUndef();
- }
+protected:
+ explicit DefinedOrUnknownSVal(SValKind Kind, const void *Data = nullptr)
+ : SVal(Kind, Data) {}
};
class UnknownVal : public DefinedOrUnknownSVal {
public:
explicit UnknownVal() : DefinedOrUnknownSVal(UnknownValKind) {}
-private:
- friend class SVal;
-
- static bool isKind(const SVal &V) {
- return V.getBaseKind() == UnknownValKind;
- }
+ static bool classof(SVal V) { return V.getKind() == UnknownValKind; }
};
class DefinedSVal : public DefinedOrUnknownSVal {
@@ -274,39 +225,24 @@ public:
bool isUnknownOrUndef() const = delete;
bool isValid() const = delete;
-protected:
- DefinedSVal() = default;
- explicit DefinedSVal(const void *d, bool isLoc, unsigned ValKind)
- : DefinedOrUnknownSVal(d, isLoc, ValKind) {}
-
-private:
- friend class SVal;
+ static bool classof(SVal V) { return !V.isUnknownOrUndef(); }
- static bool isKind(const SVal& V) {
- return !V.isUnknownOrUndef();
- }
+protected:
+ explicit DefinedSVal(SValKind Kind, const void *Data)
+ : DefinedOrUnknownSVal(Kind, Data) {}
};
/// Represents an SVal that is guaranteed to not be UnknownVal.
class KnownSVal : public SVal {
- friend class SVal;
-
- KnownSVal() = default;
-
- static bool isKind(const SVal &V) {
- return !V.isUnknown();
- }
-
public:
- KnownSVal(const DefinedSVal &V) : SVal(V) {}
- KnownSVal(const UndefinedVal &V) : SVal(V) {}
+ /*implicit*/ KnownSVal(DefinedSVal V) : SVal(V) {}
+ /*implicit*/ KnownSVal(UndefinedVal V) : SVal(V) {}
+ static bool classof(SVal V) { return !V.isUnknown(); }
};
class NonLoc : public DefinedSVal {
protected:
- NonLoc() = default;
- explicit NonLoc(unsigned SubKind, const void *d)
- : DefinedSVal(d, false, SubKind) {}
+ NonLoc(SValKind Kind, const void *Data) : DefinedSVal(Kind, Data) {}
public:
void dumpToStream(raw_ostream &Out) const;
@@ -316,19 +252,14 @@ public:
T->isAnyComplexType() || T->isVectorType();
}
-private:
- friend class SVal;
-
- static bool isKind(const SVal& V) {
- return V.getBaseKind() == NonLocKind;
+ static bool classof(SVal V) {
+ return BEGIN_NonLoc <= V.getKind() && V.getKind() <= END_NonLoc;
}
};
class Loc : public DefinedSVal {
protected:
- Loc() = default;
- explicit Loc(unsigned SubKind, const void *D)
- : DefinedSVal(const_cast<void *>(D), true, SubKind) {}
+ Loc(SValKind Kind, const void *Data) : DefinedSVal(Kind, Data) {}
public:
void dumpToStream(raw_ostream &Out) const;
@@ -338,11 +269,8 @@ public:
T->isReferenceType() || T->isNullPtrType();
}
-private:
- friend class SVal;
-
- static bool isKind(const SVal& V) {
- return V.getBaseKind() == LocKind;
+ static bool classof(SVal V) {
+ return BEGIN_Loc <= V.getKind() && V.getKind() <= END_Loc;
}
};
@@ -356,11 +284,12 @@ namespace nonloc {
class SymbolVal : public NonLoc {
public:
SymbolVal() = delete;
- SymbolVal(SymbolRef sym) : NonLoc(SymbolValKind, sym) {
- assert(sym);
- assert(!Loc::isLocType(sym->getType()));
+ explicit SymbolVal(SymbolRef Sym) : NonLoc(SymbolValKind, Sym) {
+ assert(Sym);
+ assert(!Loc::isLocType(Sym->getType()));
}
+ LLVM_ATTRIBUTE_RETURNS_NONNULL
SymbolRef getSymbol() const {
return (const SymExpr *) Data;
}
@@ -369,49 +298,17 @@ public:
return !isa<SymbolData>(getSymbol());
}
-private:
- friend class SVal;
-
- static bool isKind(const SVal& V) {
- return V.getBaseKind() == NonLocKind &&
- V.getSubKind() == SymbolValKind;
- }
-
- static bool isKind(const NonLoc& V) {
- return V.getSubKind() == SymbolValKind;
- }
+ static bool classof(SVal V) { return V.getKind() == SymbolValKind; }
};
/// Value representing integer constant.
class ConcreteInt : public NonLoc {
public:
- explicit ConcreteInt(const llvm::APSInt& V) : NonLoc(ConcreteIntKind, &V) {}
-
- const llvm::APSInt& getValue() const {
- return *static_cast<const llvm::APSInt *>(Data);
- }
-
- // Transfer functions for binary/unary operations on ConcreteInts.
- SVal evalBinOp(SValBuilder &svalBuilder, BinaryOperator::Opcode Op,
- const ConcreteInt& R) const;
-
- ConcreteInt evalComplement(SValBuilder &svalBuilder) const;
+ explicit ConcreteInt(const llvm::APSInt &V) : NonLoc(ConcreteIntKind, &V) {}
- ConcreteInt evalMinus(SValBuilder &svalBuilder) const;
+ const llvm::APSInt &getValue() const { return *castDataAs<llvm::APSInt>(); }
-private:
- friend class SVal;
-
- ConcreteInt() = default;
-
- static bool isKind(const SVal& V) {
- return V.getBaseKind() == NonLocKind &&
- V.getSubKind() == ConcreteIntKind;
- }
-
- static bool isKind(const NonLoc& V) {
- return V.getSubKind() == ConcreteIntKind;
- }
+ static bool classof(SVal V) { return V.getKind() == ConcreteIntKind; }
};
class LocAsInteger : public NonLoc {
@@ -421,102 +318,63 @@ class LocAsInteger : public NonLoc {
: NonLoc(LocAsIntegerKind, &data) {
// We do not need to represent loc::ConcreteInt as LocAsInteger,
// as it'd collapse into a nonloc::ConcreteInt instead.
- assert(data.first.getBaseKind() == LocKind &&
- (data.first.getSubKind() == loc::MemRegionValKind ||
- data.first.getSubKind() == loc::GotoLabelKind));
+ [[maybe_unused]] SValKind K = data.first.getKind();
+ assert(K == loc::MemRegionValKind || K == loc::GotoLabelKind);
}
public:
Loc getLoc() const {
- const std::pair<SVal, uintptr_t> *D =
- static_cast<const std::pair<SVal, uintptr_t> *>(Data);
- return D->first.castAs<Loc>();
- }
-
- Loc getPersistentLoc() const {
- const std::pair<SVal, uintptr_t> *D =
- static_cast<const std::pair<SVal, uintptr_t> *>(Data);
- const SVal& V = D->first;
- return V.castAs<Loc>();
+ return castDataAs<std::pair<SVal, uintptr_t>>()->first.castAs<Loc>();
}
unsigned getNumBits() const {
- const std::pair<SVal, uintptr_t> *D =
- static_cast<const std::pair<SVal, uintptr_t> *>(Data);
- return D->second;
- }
-
-private:
- friend class SVal;
-
- LocAsInteger() = default;
-
- static bool isKind(const SVal& V) {
- return V.getBaseKind() == NonLocKind &&
- V.getSubKind() == LocAsIntegerKind;
+ return castDataAs<std::pair<SVal, uintptr_t>>()->second;
}
- static bool isKind(const NonLoc& V) {
- return V.getSubKind() == LocAsIntegerKind;
- }
+ static bool classof(SVal V) { return V.getKind() == LocAsIntegerKind; }
};
class CompoundVal : public NonLoc {
friend class ento::SValBuilder;
- explicit CompoundVal(const CompoundValData* D) : NonLoc(CompoundValKind, D) {}
+ explicit CompoundVal(const CompoundValData *D) : NonLoc(CompoundValKind, D) {
+ assert(D);
+ }
public:
+ LLVM_ATTRIBUTE_RETURNS_NONNULL
const CompoundValData* getValue() const {
- return static_cast<const CompoundValData *>(Data);
+ return castDataAs<CompoundValData>();
}
using iterator = llvm::ImmutableList<SVal>::iterator;
-
iterator begin() const;
iterator end() const;
-private:
- friend class SVal;
-
- CompoundVal() = default;
-
- static bool isKind(const SVal& V) {
- return V.getBaseKind() == NonLocKind && V.getSubKind() == CompoundValKind;
- }
-
- static bool isKind(const NonLoc& V) {
- return V.getSubKind() == CompoundValKind;
- }
+ static bool classof(SVal V) { return V.getKind() == CompoundValKind; }
};
class LazyCompoundVal : public NonLoc {
friend class ento::SValBuilder;
explicit LazyCompoundVal(const LazyCompoundValData *D)
- : NonLoc(LazyCompoundValKind, D) {}
+ : NonLoc(LazyCompoundValKind, D) {
+ assert(D);
+ }
public:
+ LLVM_ATTRIBUTE_RETURNS_NONNULL
const LazyCompoundValData *getCVData() const {
- return static_cast<const LazyCompoundValData *>(Data);
+ return castDataAs<LazyCompoundValData>();
}
+ /// It might return null.
const void *getStore() const;
- const TypedValueRegion *getRegion() const;
-
-private:
- friend class SVal;
-
- LazyCompoundVal() = default;
- static bool isKind(const SVal& V) {
- return V.getBaseKind() == NonLocKind &&
- V.getSubKind() == LazyCompoundValKind;
- }
+ LLVM_ATTRIBUTE_RETURNS_NONNULL
+ const TypedValueRegion *getRegion() const;
- static bool isKind(const NonLoc& V) {
- return V.getSubKind() == LazyCompoundValKind;
- }
+ static bool classof(SVal V) { return V.getKind() == LazyCompoundValKind; }
};
/// Value representing pointer-to-member.
@@ -554,21 +412,11 @@ public:
iterator begin() const;
iterator end() const;
-private:
- friend class SVal;
+ static bool classof(SVal V) { return V.getKind() == PointerToMemberKind; }
- PointerToMember() = default;
+private:
explicit PointerToMember(const PTMDataType D)
: NonLoc(PointerToMemberKind, D.getOpaqueValue()) {}
-
- static bool isKind(const SVal& V) {
- return V.getBaseKind() == NonLocKind &&
- V.getSubKind() == PointerToMemberKind;
- }
-
- static bool isKind(const NonLoc& V) {
- return V.getSubKind() == PointerToMemberKind;
- }
};
} // namespace nonloc
@@ -585,36 +433,23 @@ public:
assert(Label);
}
- const LabelDecl *getLabel() const {
- return static_cast<const LabelDecl *>(Data);
- }
+ const LabelDecl *getLabel() const { return castDataAs<LabelDecl>(); }
-private:
- friend class SVal;
-
- GotoLabel() = default;
-
- static bool isKind(const SVal& V) {
- return V.getBaseKind() == LocKind && V.getSubKind() == GotoLabelKind;
- }
-
- static bool isKind(const Loc& V) {
- return V.getSubKind() == GotoLabelKind;
- }
+ static bool classof(SVal V) { return V.getKind() == GotoLabelKind; }
};
class MemRegionVal : public Loc {
public:
- explicit MemRegionVal(const MemRegion* r) : Loc(MemRegionValKind, r) {
+ explicit MemRegionVal(const MemRegion *r) : Loc(MemRegionValKind, r) {
assert(r);
}
/// Get the underlining region.
- const MemRegion *getRegion() const {
- return static_cast<const MemRegion *>(Data);
- }
+ LLVM_ATTRIBUTE_RETURNS_NONNULL
+ const MemRegion *getRegion() const { return castDataAs<MemRegion>(); }
/// Get the underlining region and strip casts.
+ LLVM_ATTRIBUTE_RETURNS_NONNULL
const MemRegion* stripCasts(bool StripBaseCasts = true) const;
template <typename REGION>
@@ -630,52 +465,44 @@ public:
return getRegion() != R.getRegion();
}
-private:
- friend class SVal;
-
- MemRegionVal() = default;
-
- static bool isKind(const SVal& V) {
- return V.getBaseKind() == LocKind &&
- V.getSubKind() == MemRegionValKind;
- }
-
- static bool isKind(const Loc& V) {
- return V.getSubKind() == MemRegionValKind;
- }
+ static bool classof(SVal V) { return V.getKind() == MemRegionValKind; }
};
class ConcreteInt : public Loc {
public:
- explicit ConcreteInt(const llvm::APSInt& V) : Loc(ConcreteIntKind, &V) {}
-
- const llvm::APSInt &getValue() const {
- return *static_cast<const llvm::APSInt *>(Data);
- }
-
- // Transfer functions for binary/unary operations on ConcreteInts.
- SVal evalBinOp(BasicValueFactory& BasicVals, BinaryOperator::Opcode Op,
- const ConcreteInt& R) const;
-
-private:
- friend class SVal;
+ explicit ConcreteInt(const llvm::APSInt &V) : Loc(ConcreteIntKind, &V) {}
- ConcreteInt() = default;
+ const llvm::APSInt &getValue() const { return *castDataAs<llvm::APSInt>(); }
- static bool isKind(const SVal& V) {
- return V.getBaseKind() == LocKind &&
- V.getSubKind() == ConcreteIntKind;
- }
-
- static bool isKind(const Loc& V) {
- return V.getSubKind() == ConcreteIntKind;
- }
+ static bool classof(SVal V) { return V.getKind() == ConcreteIntKind; }
};
} // namespace loc
-
} // namespace ento
-
} // namespace clang
+namespace llvm {
+template <typename To, typename From>
+struct CastInfo<
+ To, From,
+ std::enable_if_t<std::is_base_of<::clang::ento::SVal, From>::value>>
+ : public CastIsPossible<To, ::clang::ento::SVal> {
+ using Self = CastInfo<
+ To, From,
+ std::enable_if_t<std::is_base_of<::clang::ento::SVal, From>::value>>;
+ static bool isPossible(const From &V) {
+ return To::classof(*static_cast<const ::clang::ento::SVal *>(&V));
+ }
+ static std::optional<To> castFailed() { return std::optional<To>{}; }
+ static To doCast(const From &f) {
+ return *static_cast<const To *>(cast<::clang::ento::SVal>(&f));
+ }
+ static std::optional<To> doCastIfPossible(const From &f) {
+ if (!Self::isPossible(f))
+ return Self::castFailed();
+ return doCast(f);
+ }
+};
+} // namespace llvm
+
#endif // LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_SVALS_H
diff --git a/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SimpleConstraintManager.h b/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SimpleConstraintManager.h
index 87e927f5b480..725140e073c6 100644
--- a/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SimpleConstraintManager.h
+++ b/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SimpleConstraintManager.h
@@ -34,16 +34,6 @@ public:
// Implementation for interface from ConstraintManager.
//===------------------------------------------------------------------===//
- /// Ensures that the DefinedSVal conditional is expressed as a NonLoc by
- /// creating boolean casts to handle Loc's.
- ProgramStateRef assume(ProgramStateRef State, DefinedSVal Cond,
- bool Assumption) override;
-
- ProgramStateRef assumeInclusiveRange(ProgramStateRef State, NonLoc Value,
- const llvm::APSInt &From,
- const llvm::APSInt &To,
- bool InRange) override;
-
protected:
//===------------------------------------------------------------------===//
// Interface that subclasses must implement.
@@ -74,6 +64,17 @@ protected:
// Internal implementation.
//===------------------------------------------------------------------===//
+ /// Ensures that the DefinedSVal conditional is expressed as a NonLoc by
+ /// creating boolean casts to handle Loc's.
+ ProgramStateRef assumeInternal(ProgramStateRef State, DefinedSVal Cond,
+ bool Assumption) override;
+
+ ProgramStateRef assumeInclusiveRangeInternal(ProgramStateRef State,
+ NonLoc Value,
+ const llvm::APSInt &From,
+ const llvm::APSInt &To,
+ bool InRange) override;
+
SValBuilder &getSValBuilder() const { return SVB; }
BasicValueFactory &getBasicVals() const { return SVB.getBasicValueFactory(); }
SymbolManager &getSymbolManager() const { return SVB.getSymbolManager(); }
diff --git a/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h b/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h
index d2461705d128..fac0c04ae2ca 100644
--- a/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h
+++ b/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h
@@ -23,11 +23,11 @@
#include "clang/Basic/LLVM.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseSet.h"
-#include "llvm/ADT/Optional.h"
#include "llvm/ADT/SmallVector.h"
#include <cassert>
#include <cstdint>
#include <memory>
+#include <optional>
namespace clang {
@@ -83,7 +83,8 @@ public:
/// \param[in] R The region to find the default binding for.
/// \return The default value bound to the region in the store, if a default
/// binding exists.
- virtual Optional<SVal> getDefaultBinding(Store store, const MemRegion *R) = 0;
+ virtual std::optional<SVal> getDefaultBinding(Store store,
+ const MemRegion *R) = 0;
/// Return the default value bound to a LazyCompoundVal. The default binding
/// is used to represent the value of any fields or elements within the
@@ -93,7 +94,7 @@ public:
/// \param[in] lcv The lazy compound value.
/// \return The default value bound to the LazyCompoundVal \c lcv, if a
/// default binding exists.
- Optional<SVal> getDefaultBinding(nonloc::LazyCompoundVal lcv) {
+ std::optional<SVal> getDefaultBinding(nonloc::LazyCompoundVal lcv) {
return getDefaultBinding(lcv.getStore(), lcv.getRegion());
}
@@ -172,17 +173,17 @@ public:
/// dynamic_cast.
/// - We don't know (base is a symbolic region and we don't have
/// enough info to determine if the cast will succeed at run time).
- /// The function returns an SVal representing the derived class; it's
- /// valid only if Failed flag is set to false.
- SVal attemptDownCast(SVal Base, QualType DerivedPtrType, bool &Failed);
+ /// The function returns an optional with SVal representing the derived class
+ /// in case of a successful cast and `std::nullopt` otherwise.
+ std::optional<SVal> evalBaseToDerived(SVal Base, QualType DerivedPtrType);
const ElementRegion *GetElementZeroRegion(const SubRegion *R, QualType T);
/// castRegion - Used by ExprEngine::VisitCast to handle casts from
/// a MemRegion* to a specific location type. 'R' is the region being
/// casted and 'CastToTy' the result type of the cast.
- Optional<const MemRegion *> castRegion(const MemRegion *region,
- QualType CastToTy);
+ std::optional<const MemRegion *> castRegion(const MemRegion *region,
+ QualType CastToTy);
virtual StoreRef removeDeadBindings(Store store, const StackFrameContext *LCtx,
SymbolReaper &SymReaper) = 0;
@@ -316,8 +317,6 @@ inline StoreRef &StoreRef::operator=(StoreRef const &newStore) {
// FIXME: Do we need to pass ProgramStateManager anymore?
std::unique_ptr<StoreManager>
CreateRegionStoreManager(ProgramStateManager &StMgr);
-std::unique_ptr<StoreManager>
-CreateFieldsOnlyRegionStoreManager(ProgramStateManager &StMgr);
} // namespace ento
diff --git a/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SymExpr.h b/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SymExpr.h
index 2f4ac6ba5f97..862a30c0e736 100644
--- a/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SymExpr.h
+++ b/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SymExpr.h
@@ -17,6 +17,7 @@
#include "clang/Basic/LLVM.h"
#include "llvm/ADT/FoldingSet.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/iterator_range.h"
#include <cassert>
namespace clang {
@@ -83,8 +84,9 @@ public:
bool operator!=(const symbol_iterator &X) const;
};
- symbol_iterator symbol_begin() const { return symbol_iterator(this); }
- static symbol_iterator symbol_end() { return symbol_iterator(); }
+ llvm::iterator_range<symbol_iterator> symbols() const {
+ return llvm::make_range(symbol_iterator(this), symbol_iterator());
+ }
virtual unsigned computeComplexity() const = 0;
@@ -98,6 +100,7 @@ public:
/// the beginning of the analysis, and SymbolDerived which denotes the value
/// of a certain memory region after its super region (a memory space or
/// a larger record region) is default-bound with a certain symbol.
+ /// It might return null.
virtual const MemRegion *getOriginRegion() const { return nullptr; }
};
diff --git a/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h b/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h
index c71cb88f5574..3b64d38ee2b2 100644
--- a/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h
+++ b/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h
@@ -24,6 +24,7 @@
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/FoldingSet.h"
+#include "llvm/ADT/iterator_range.h"
#include "llvm/Support/Allocator.h"
#include <cassert>
@@ -48,6 +49,7 @@ public:
assert(isValidTypeForSymbol(r->getValueType()));
}
+ LLVM_ATTRIBUTE_RETURNS_NONNULL
const TypedValueRegion* getRegion() const { return R; }
static void Profile(llvm::FoldingSetNodeID& profile, const TypedValueRegion* R) {
@@ -95,8 +97,10 @@ public:
assert(isValidTypeForSymbol(t));
}
+ /// It might return null.
const Stmt *getStmt() const { return S; }
unsigned getCount() const { return Count; }
+ /// It might return null.
const void *getTag() const { return SymbolTag; }
QualType getType() const override;
@@ -140,7 +144,9 @@ public:
assert(isValidTypeForSymbol(r->getValueType()));
}
+ LLVM_ATTRIBUTE_RETURNS_NONNULL
SymbolRef getParentSymbol() const { return parentSymbol; }
+ LLVM_ATTRIBUTE_RETURNS_NONNULL
const TypedValueRegion *getRegion() const { return R; }
QualType getType() const override;
@@ -179,6 +185,7 @@ public:
assert(r);
}
+ LLVM_ATTRIBUTE_RETURNS_NONNULL
const SubRegion *getRegion() const { return R; }
QualType getType() const override;
@@ -226,29 +233,37 @@ public:
assert(tag);
}
- const MemRegion *getRegion() const { return R; }
- const Stmt *getStmt() const { return S; }
- const LocationContext *getLocationContext() const { return LCtx; }
- unsigned getCount() const { return Count; }
- const void *getTag() const { return Tag; }
+ LLVM_ATTRIBUTE_RETURNS_NONNULL
+ const MemRegion *getRegion() const { return R; }
- QualType getType() const override;
+ LLVM_ATTRIBUTE_RETURNS_NONNULL
+ const Stmt *getStmt() const { return S; }
- StringRef getKindStr() const override;
+ LLVM_ATTRIBUTE_RETURNS_NONNULL
+ const LocationContext *getLocationContext() const { return LCtx; }
- void dumpToStream(raw_ostream &os) const override;
+ unsigned getCount() const { return Count; }
- static void Profile(llvm::FoldingSetNodeID& profile, const MemRegion *R,
- const Stmt *S, QualType T, const LocationContext *LCtx,
- unsigned Count, const void *Tag) {
- profile.AddInteger((unsigned) SymbolMetadataKind);
- profile.AddPointer(R);
- profile.AddPointer(S);
- profile.Add(T);
- profile.AddPointer(LCtx);
- profile.AddInteger(Count);
- profile.AddPointer(Tag);
- }
+ LLVM_ATTRIBUTE_RETURNS_NONNULL
+ const void *getTag() const { return Tag; }
+
+ QualType getType() const override;
+
+ StringRef getKindStr() const override;
+
+ void dumpToStream(raw_ostream &os) const override;
+
+ static void Profile(llvm::FoldingSetNodeID &profile, const MemRegion *R,
+ const Stmt *S, QualType T, const LocationContext *LCtx,
+ unsigned Count, const void *Tag) {
+ profile.AddInteger((unsigned)SymbolMetadataKind);
+ profile.AddPointer(R);
+ profile.AddPointer(S);
+ profile.Add(T);
+ profile.AddPointer(LCtx);
+ profile.AddInteger(Count);
+ profile.AddPointer(Tag);
+ }
void Profile(llvm::FoldingSetNodeID& profile) override {
Profile(profile, R, S, T, LCtx, Count, Tag);
@@ -287,6 +302,7 @@ public:
QualType getType() const override { return ToTy; }
+ LLVM_ATTRIBUTE_RETURNS_NONNULL
const SymExpr *getOperand() const { return Operand; }
void dumpToStream(raw_ostream &os) const override;
@@ -309,6 +325,55 @@ public:
}
};
+/// Represents a symbolic expression involving a unary operator.
+class UnarySymExpr : public SymExpr {
+ const SymExpr *Operand;
+ UnaryOperator::Opcode Op;
+ QualType T;
+
+public:
+ UnarySymExpr(const SymExpr *In, UnaryOperator::Opcode Op, QualType T)
+ : SymExpr(UnarySymExprKind), Operand(In), Op(Op), T(T) {
+ // Note, some unary operators are modeled as a binary operator. E.g. ++x is
+ // modeled as x + 1.
+ assert((Op == UO_Minus || Op == UO_Not) && "non-supported unary expression");
+ // Unary expressions are results of arithmetic. Pointer arithmetic is not
+ // handled by unary expressions, but it is instead handled by applying
+ // sub-regions to regions.
+ assert(isValidTypeForSymbol(T) && "non-valid type for unary symbol");
+ assert(!Loc::isLocType(T) && "unary symbol should be nonloc");
+ }
+
+ unsigned computeComplexity() const override {
+ if (Complexity == 0)
+ Complexity = 1 + Operand->computeComplexity();
+ return Complexity;
+ }
+
+ const SymExpr *getOperand() const { return Operand; }
+ UnaryOperator::Opcode getOpcode() const { return Op; }
+ QualType getType() const override { return T; }
+
+ void dumpToStream(raw_ostream &os) const override;
+
+ static void Profile(llvm::FoldingSetNodeID &ID, const SymExpr *In,
+ UnaryOperator::Opcode Op, QualType T) {
+ ID.AddInteger((unsigned)UnarySymExprKind);
+ ID.AddPointer(In);
+ ID.AddInteger(Op);
+ ID.Add(T);
+ }
+
+ void Profile(llvm::FoldingSetNodeID &ID) override {
+ Profile(ID, Operand, Op, T);
+ }
+
+ // Implement isa<T> support.
+ static bool classof(const SymExpr *SE) {
+ return SE->getKind() == UnarySymExprKind;
+ }
+};
+
/// Represents a symbolic expression involving a binary operator
class BinarySymExpr : public SymExpr {
BinaryOperator::Opcode Op;
@@ -486,6 +551,9 @@ public:
const SymSymExpr *getSymSymExpr(const SymExpr *lhs, BinaryOperator::Opcode op,
const SymExpr *rhs, QualType t);
+ const UnarySymExpr *getUnarySymExpr(const SymExpr *operand,
+ UnaryOperator::Opcode op, QualType t);
+
QualType getType(const SymExpr *SE) const {
return SE->getType();
}
@@ -515,7 +583,12 @@ class SymbolReaper {
SymbolMapTy TheLiving;
SymbolSetTy MetadataInUse;
- RegionSetTy RegionRoots;
+ RegionSetTy LiveRegionRoots;
+ // The lazily copied regions are locations for which a program
+ // can access the value stored at that location, but not its address.
+ // These regions are constructed as a set of regions referred to by
+ // lazyCompoundVal.
+ RegionSetTy LazilyCopiedRegionRoots;
const StackFrameContext *LCtx;
const Stmt *Loc;
@@ -535,6 +608,7 @@ public:
SymbolManager &symmgr, StoreManager &storeMgr)
: LCtx(Ctx), Loc(s), SymMgr(symmgr), reapedStore(nullptr, storeMgr) {}
+ /// It might return null.
const LocationContext *getLocationContext() const { return LCtx; }
bool isLive(SymbolRef sym);
@@ -558,10 +632,9 @@ public:
/// symbol marking has occurred, i.e. in the MarkLiveSymbols callback.
void markInUse(SymbolRef sym);
- using region_iterator = RegionSetTy::const_iterator;
-
- region_iterator region_begin() const { return RegionRoots.begin(); }
- region_iterator region_end() const { return RegionRoots.end(); }
+ llvm::iterator_range<RegionSetTy::const_iterator> regions() const {
+ return LiveRegionRoots;
+ }
/// Returns whether or not a symbol has been confirmed dead.
///
@@ -572,6 +645,7 @@ public:
}
void markLive(const MemRegion *region);
+ void markLazilyCopied(const MemRegion *region);
void markElementIndicesLive(const MemRegion *region);
/// Set to the value of the symbolic store after
@@ -579,6 +653,12 @@ public:
void setReapedStore(StoreRef st) { reapedStore = st; }
private:
+ bool isLazilyCopiedRegion(const MemRegion *region) const;
+ // A readable region is a region that live or lazily copied.
+ // Any symbols that refer to values in regions are alive if the region
+ // is readable.
+ bool isReadableRegion(const MemRegion *region);
+
/// Mark the symbols dependent on the input symbol as live.
void markDependentsLive(SymbolRef sym);
};
@@ -592,6 +672,11 @@ public:
SymbolVisitor(const SymbolVisitor &) = default;
SymbolVisitor(SymbolVisitor &&) {}
+ // The copy and move assignment operator is defined as deleted pending further
+ // motivation.
+ SymbolVisitor &operator=(const SymbolVisitor &) = delete;
+ SymbolVisitor &operator=(SymbolVisitor &&) = delete;
+
/// A visitor method invoked by ProgramStateManager::scanReachableSymbols.
///
/// The method returns \c true if symbols should continue be scanned and \c
diff --git a/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/Symbols.def b/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/Symbols.def
index 7163a16263ab..b93f8e250155 100644
--- a/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/Symbols.def
+++ b/contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/Symbols.def
@@ -33,6 +33,8 @@
#define SYMBOL_RANGE(Id, First, Last)
#endif
+SYMBOL(UnarySymExpr, SymExpr)
+
ABSTRACT_SYMBOL(BinarySymExpr, SymExpr)
SYMBOL(IntSymExpr, BinarySymExpr)
SYMBOL(SymIntExpr, BinarySymExpr)
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/Support/RISCVVIntrinsicUtils.h b/contrib/llvm-project/clang/include/clang/Support/RISCVVIntrinsicUtils.h
new file mode 100644
index 000000000000..05a5e02e1390
--- /dev/null
+++ b/contrib/llvm-project/clang/include/clang/Support/RISCVVIntrinsicUtils.h
@@ -0,0 +1,570 @@
+//===--- RISCVVIntrinsicUtils.h - RISC-V Vector Intrinsic Utils -*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef CLANG_SUPPORT_RISCVVINTRINSICUTILS_H
+#define CLANG_SUPPORT_RISCVVINTRINSICUTILS_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/BitmaskEnum.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
+#include <cstdint>
+#include <optional>
+#include <set>
+#include <string>
+#include <unordered_map>
+#include <vector>
+
+namespace llvm {
+class raw_ostream;
+} // end namespace llvm
+
+namespace clang {
+namespace RISCV {
+
+using VScaleVal = std::optional<unsigned>;
+
+// Modifier for vector type.
+enum class VectorTypeModifier : uint8_t {
+ NoModifier,
+ Widening2XVector,
+ Widening4XVector,
+ Widening8XVector,
+ MaskVector,
+ Log2EEW3,
+ Log2EEW4,
+ Log2EEW5,
+ Log2EEW6,
+ FixedSEW8,
+ FixedSEW16,
+ FixedSEW32,
+ FixedSEW64,
+ LFixedLog2LMULN3,
+ LFixedLog2LMULN2,
+ LFixedLog2LMULN1,
+ LFixedLog2LMUL0,
+ LFixedLog2LMUL1,
+ LFixedLog2LMUL2,
+ LFixedLog2LMUL3,
+ SFixedLog2LMULN3,
+ SFixedLog2LMULN2,
+ SFixedLog2LMULN1,
+ SFixedLog2LMUL0,
+ SFixedLog2LMUL1,
+ SFixedLog2LMUL2,
+ SFixedLog2LMUL3,
+ SEFixedLog2LMULN3,
+ SEFixedLog2LMULN2,
+ SEFixedLog2LMULN1,
+ SEFixedLog2LMUL0,
+ SEFixedLog2LMUL1,
+ SEFixedLog2LMUL2,
+ SEFixedLog2LMUL3,
+ Tuple2,
+ Tuple3,
+ Tuple4,
+ Tuple5,
+ Tuple6,
+ Tuple7,
+ Tuple8,
+};
+
+// Similar to basic type but used to describe what's kind of type related to
+// basic vector type, used to compute type info of arguments.
+enum class BaseTypeModifier : uint8_t {
+ Invalid,
+ Scalar,
+ Vector,
+ Void,
+ SizeT,
+ Ptrdiff,
+ UnsignedLong,
+ SignedLong,
+ Float32
+};
+
+// Modifier for type, used for both scalar and vector types.
+enum class TypeModifier : uint8_t {
+ NoModifier = 0,
+ Pointer = 1 << 0,
+ Const = 1 << 1,
+ Immediate = 1 << 2,
+ UnsignedInteger = 1 << 3,
+ SignedInteger = 1 << 4,
+ Float = 1 << 5,
+ BFloat = 1 << 6,
+ // LMUL1 should be kind of VectorTypeModifier, but that might come with
+ // Widening2XVector for widening reduction.
+ // However that might require VectorTypeModifier become bitmask rather than
+ // simple enum, so we decide keek LMUL1 in TypeModifier for code size
+ // optimization of clang binary size.
+ LMUL1 = 1 << 7,
+ MaxOffset = 7,
+ LLVM_MARK_AS_BITMASK_ENUM(LMUL1),
+};
+
+class Policy {
+public:
+ enum PolicyType {
+ Undisturbed,
+ Agnostic,
+ };
+
+private:
+ // The default assumption for an RVV instruction is TAMA, as an undisturbed
+ // policy generally will affect the performance of an out-of-order core.
+ const PolicyType TailPolicy = Agnostic;
+ const PolicyType MaskPolicy = Agnostic;
+
+public:
+ Policy() = default;
+ Policy(PolicyType TailPolicy) : TailPolicy(TailPolicy) {}
+ Policy(PolicyType TailPolicy, PolicyType MaskPolicy)
+ : TailPolicy(TailPolicy), MaskPolicy(MaskPolicy) {}
+
+ bool isTAMAPolicy() const {
+ return TailPolicy == Agnostic && MaskPolicy == Agnostic;
+ }
+
+ bool isTAMUPolicy() const {
+ return TailPolicy == Agnostic && MaskPolicy == Undisturbed;
+ }
+
+ bool isTUMAPolicy() const {
+ return TailPolicy == Undisturbed && MaskPolicy == Agnostic;
+ }
+
+ bool isTUMUPolicy() const {
+ return TailPolicy == Undisturbed && MaskPolicy == Undisturbed;
+ }
+
+ bool isTAPolicy() const { return TailPolicy == Agnostic; }
+
+ bool isTUPolicy() const { return TailPolicy == Undisturbed; }
+
+ bool isMAPolicy() const { return MaskPolicy == Agnostic; }
+
+ bool isMUPolicy() const { return MaskPolicy == Undisturbed; }
+
+ bool operator==(const Policy &Other) const {
+ return TailPolicy == Other.TailPolicy && MaskPolicy == Other.MaskPolicy;
+ }
+
+ bool operator!=(const Policy &Other) const { return !(*this == Other); }
+
+ bool operator<(const Policy &Other) const {
+ // Just for maintain the old order for quick test.
+ if (MaskPolicy != Other.MaskPolicy)
+ return Other.MaskPolicy < MaskPolicy;
+ return TailPolicy < Other.TailPolicy;
+ }
+};
+
+// PrototypeDescriptor is used to compute type info of arguments or return
+// value.
+struct PrototypeDescriptor {
+ constexpr PrototypeDescriptor() = default;
+ constexpr PrototypeDescriptor(
+ BaseTypeModifier PT,
+ VectorTypeModifier VTM = VectorTypeModifier::NoModifier,
+ TypeModifier TM = TypeModifier::NoModifier)
+ : PT(static_cast<uint8_t>(PT)), VTM(static_cast<uint8_t>(VTM)),
+ TM(static_cast<uint8_t>(TM)) {}
+ constexpr PrototypeDescriptor(uint8_t PT, uint8_t VTM, uint8_t TM)
+ : PT(PT), VTM(VTM), TM(TM) {}
+
+ uint8_t PT = static_cast<uint8_t>(BaseTypeModifier::Invalid);
+ uint8_t VTM = static_cast<uint8_t>(VectorTypeModifier::NoModifier);
+ uint8_t TM = static_cast<uint8_t>(TypeModifier::NoModifier);
+
+ bool operator!=(const PrototypeDescriptor &PD) const {
+ return !(*this == PD);
+ }
+ bool operator==(const PrototypeDescriptor &PD) const {
+ return PD.PT == PT && PD.VTM == VTM && PD.TM == TM;
+ }
+ bool operator<(const PrototypeDescriptor &PD) const {
+ return std::tie(PT, VTM, TM) < std::tie(PD.PT, PD.VTM, PD.TM);
+ }
+ static const PrototypeDescriptor Mask;
+ static const PrototypeDescriptor Vector;
+ static const PrototypeDescriptor VL;
+ static std::optional<PrototypeDescriptor>
+ parsePrototypeDescriptor(llvm::StringRef PrototypeStr);
+};
+
+llvm::SmallVector<PrototypeDescriptor>
+parsePrototypes(llvm::StringRef Prototypes);
+
+// Basic type of vector type.
+enum class BasicType : uint8_t {
+ Unknown = 0,
+ Int8 = 1 << 0,
+ Int16 = 1 << 1,
+ Int32 = 1 << 2,
+ Int64 = 1 << 3,
+ BFloat16 = 1 << 4,
+ Float16 = 1 << 5,
+ Float32 = 1 << 6,
+ Float64 = 1 << 7,
+ MaxOffset = 7,
+ LLVM_MARK_AS_BITMASK_ENUM(Float64),
+};
+
+// Type of vector type.
+enum ScalarTypeKind : uint8_t {
+ Void,
+ Size_t,
+ Ptrdiff_t,
+ UnsignedLong,
+ SignedLong,
+ Boolean,
+ SignedInteger,
+ UnsignedInteger,
+ Float,
+ BFloat,
+ Invalid,
+ Undefined,
+};
+
+// Exponential LMUL
+struct LMULType {
+ int Log2LMUL;
+ LMULType(int Log2LMUL);
+ // Return the C/C++ string representation of LMUL
+ std::string str() const;
+ std::optional<unsigned> getScale(unsigned ElementBitwidth) const;
+ void MulLog2LMUL(int Log2LMUL);
+};
+
+class RVVType;
+using RVVTypePtr = RVVType *;
+using RVVTypes = std::vector<RVVTypePtr>;
+class RVVTypeCache;
+
+// This class is compact representation of a valid and invalid RVVType.
+class RVVType {
+ friend class RVVTypeCache;
+
+ BasicType BT;
+ ScalarTypeKind ScalarType = Undefined;
+ LMULType LMUL;
+ bool IsPointer = false;
+ // IsConstant indices are "int", but have the constant expression.
+ bool IsImmediate = false;
+ // Const qualifier for pointer to const object or object of const type.
+ bool IsConstant = false;
+ unsigned ElementBitwidth = 0;
+ VScaleVal Scale = 0;
+ bool Valid;
+ bool IsTuple = false;
+ unsigned NF = 0;
+
+ std::string BuiltinStr;
+ std::string ClangBuiltinStr;
+ std::string Str;
+ std::string ShortStr;
+
+ enum class FixedLMULType { LargerThan, SmallerThan, SmallerOrEqual };
+
+ RVVType(BasicType BT, int Log2LMUL, const PrototypeDescriptor &Profile);
+
+public:
+ // Return the string representation of a type, which is an encoded string for
+ // passing to the BUILTIN() macro in Builtins.def.
+ const std::string &getBuiltinStr() const { return BuiltinStr; }
+
+ // Return the clang builtin type for RVV vector type which are used in the
+ // riscv_vector.h header file.
+ const std::string &getClangBuiltinStr() const { return ClangBuiltinStr; }
+
+ // Return the C/C++ string representation of a type for use in the
+ // riscv_vector.h header file.
+ const std::string &getTypeStr() const { return Str; }
+
+ // Return the short name of a type for C/C++ name suffix.
+ const std::string &getShortStr() {
+ // Not all types are used in short name, so compute the short name by
+ // demanded.
+ if (ShortStr.empty())
+ initShortStr();
+ return ShortStr;
+ }
+
+ bool isValid() const { return Valid; }
+ bool isScalar() const { return Scale && *Scale == 0; }
+ bool isVector() const { return Scale && *Scale != 0; }
+ bool isVector(unsigned Width) const {
+ return isVector() && ElementBitwidth == Width;
+ }
+ bool isFloat() const { return ScalarType == ScalarTypeKind::Float; }
+ bool isBFloat() const { return ScalarType == ScalarTypeKind::BFloat; }
+ bool isSignedInteger() const {
+ return ScalarType == ScalarTypeKind::SignedInteger;
+ }
+ bool isFloatVector(unsigned Width) const {
+ return isVector() && isFloat() && ElementBitwidth == Width;
+ }
+ bool isFloat(unsigned Width) const {
+ return isFloat() && ElementBitwidth == Width;
+ }
+ bool isConstant() const { return IsConstant; }
+ bool isPointer() const { return IsPointer; }
+ bool isTuple() const { return IsTuple; }
+ unsigned getElementBitwidth() const { return ElementBitwidth; }
+
+ ScalarTypeKind getScalarType() const { return ScalarType; }
+ VScaleVal getScale() const { return Scale; }
+ unsigned getNF() const {
+ assert(NF > 1 && NF <= 8 && "Only legal NF should be fetched");
+ return NF;
+ }
+
+private:
+ // Verify RVV vector type and set Valid.
+ bool verifyType() const;
+
+ // Creates a type based on basic types of TypeRange
+ void applyBasicType();
+
+ // Applies a prototype modifier to the current type. The result maybe an
+ // invalid type.
+ void applyModifier(const PrototypeDescriptor &prototype);
+
+ void applyLog2EEW(unsigned Log2EEW);
+ void applyFixedSEW(unsigned NewSEW);
+ void applyFixedLog2LMUL(int Log2LMUL, enum FixedLMULType Type);
+
+ // Compute and record a string for legal type.
+ void initBuiltinStr();
+ // Compute and record a builtin RVV vector type string.
+ void initClangBuiltinStr();
+ // Compute and record a type string for used in the header.
+ void initTypeStr();
+ // Compute and record a short name of a type for C/C++ name suffix.
+ void initShortStr();
+};
+
+// This class is used to manage RVVType, RVVType should only created by this
+// class, also provided thread-safe cache capability.
+class RVVTypeCache {
+private:
+ std::unordered_map<uint64_t, RVVType> LegalTypes;
+ std::set<uint64_t> IllegalTypes;
+
+public:
+ /// Compute output and input types by applying different config (basic type
+ /// and LMUL with type transformers). It also record result of type in legal
+ /// or illegal set to avoid compute the same config again. The result maybe
+ /// have illegal RVVType.
+ std::optional<RVVTypes>
+ computeTypes(BasicType BT, int Log2LMUL, unsigned NF,
+ llvm::ArrayRef<PrototypeDescriptor> Prototype);
+ std::optional<RVVTypePtr> computeType(BasicType BT, int Log2LMUL,
+ PrototypeDescriptor Proto);
+};
+
+enum PolicyScheme : uint8_t {
+ SchemeNone,
+ // Passthru operand is at first parameter in C builtin.
+ HasPassthruOperand,
+ HasPolicyOperand,
+};
+
+// TODO refactor RVVIntrinsic class design after support all intrinsic
+// combination. This represents an instantiation of an intrinsic with a
+// particular type and prototype
+class RVVIntrinsic {
+
+private:
+ std::string BuiltinName; // Builtin name
+ std::string Name; // C intrinsic name.
+ std::string OverloadedName;
+ std::string IRName;
+ bool IsMasked;
+ bool HasMaskedOffOperand;
+ bool HasVL;
+ PolicyScheme Scheme;
+ bool SupportOverloading;
+ bool HasBuiltinAlias;
+ std::string ManualCodegen;
+ RVVTypePtr OutputType; // Builtin output type
+ RVVTypes InputTypes; // Builtin input types
+ // 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;
+ unsigned NF = 1;
+ Policy PolicyAttrs;
+
+public:
+ RVVIntrinsic(llvm::StringRef Name, llvm::StringRef Suffix,
+ llvm::StringRef OverloadedName, llvm::StringRef OverloadedSuffix,
+ llvm::StringRef IRName, bool IsMasked, bool HasMaskedOffOperand,
+ bool HasVL, PolicyScheme Scheme, bool SupportOverloading,
+ bool HasBuiltinAlias, llvm::StringRef ManualCodegen,
+ const RVVTypes &Types,
+ const std::vector<int64_t> &IntrinsicTypes,
+ const std::vector<llvm::StringRef> &RequiredFeatures,
+ unsigned NF, Policy PolicyAttrs, bool HasFRMRoundModeOp);
+ ~RVVIntrinsic() = default;
+
+ RVVTypePtr getOutputType() const { return OutputType; }
+ const RVVTypes &getInputTypes() const { return InputTypes; }
+ llvm::StringRef getBuiltinName() const { return BuiltinName; }
+ llvm::StringRef getName() const { return Name; }
+ llvm::StringRef getOverloadedName() const { return OverloadedName; }
+ bool hasMaskedOffOperand() const { return HasMaskedOffOperand; }
+ bool hasVL() const { return HasVL; }
+ bool hasPolicy() const { return Scheme != PolicyScheme::SchemeNone; }
+ bool hasPassthruOperand() const {
+ return Scheme == PolicyScheme::HasPassthruOperand;
+ }
+ bool hasPolicyOperand() const {
+ return Scheme == PolicyScheme::HasPolicyOperand;
+ }
+ bool supportOverloading() const { return SupportOverloading; }
+ bool hasBuiltinAlias() const { return HasBuiltinAlias; }
+ bool hasManualCodegen() const { return !ManualCodegen.empty(); }
+ bool isMasked() const { return IsMasked; }
+ llvm::StringRef getIRName() const { return IRName; }
+ llvm::StringRef getManualCodegen() const { return ManualCodegen; }
+ PolicyScheme getPolicyScheme() const { return Scheme; }
+ unsigned getNF() const { return NF; }
+ const std::vector<int64_t> &getIntrinsicTypes() const {
+ return IntrinsicTypes;
+ }
+ Policy getPolicyAttrs() const {
+ return PolicyAttrs;
+ }
+ unsigned getPolicyAttrsBits() const {
+ // CGBuiltin.cpp
+ // The 0th bit simulates the `vta` of RVV
+ // The 1st bit simulates the `vma` of RVV
+ // int PolicyAttrs = 0;
+
+ if (PolicyAttrs.isTUMAPolicy())
+ return 2;
+ if (PolicyAttrs.isTAMAPolicy())
+ return 3;
+ if (PolicyAttrs.isTUMUPolicy())
+ return 0;
+ if (PolicyAttrs.isTAMUPolicy())
+ return 1;
+
+ llvm_unreachable("unsupport policy");
+ return 0;
+ }
+
+ // Return the type string for a BUILTIN() macro in Builtins.def.
+ std::string getBuiltinTypeStr() const;
+
+ static std::string
+ getSuffixStr(RVVTypeCache &TypeCache, BasicType Type, int Log2LMUL,
+ llvm::ArrayRef<PrototypeDescriptor> PrototypeDescriptors);
+
+ static llvm::SmallVector<PrototypeDescriptor>
+ computeBuiltinTypes(llvm::ArrayRef<PrototypeDescriptor> Prototype,
+ bool IsMasked, bool HasMaskedOffOperand, bool HasVL,
+ unsigned NF, PolicyScheme DefaultScheme,
+ Policy PolicyAttrs, bool IsTuple);
+
+ static llvm::SmallVector<Policy> getSupportedUnMaskedPolicies();
+ static llvm::SmallVector<Policy>
+ getSupportedMaskedPolicies(bool HasTailPolicy, bool HasMaskPolicy);
+
+ static void updateNamesAndPolicy(bool IsMasked, bool HasPolicy,
+ std::string &Name, std::string &BuiltinName,
+ std::string &OverloadedName,
+ Policy &PolicyAttrs, bool HasFRMRoundModeOp);
+};
+
+// RVVRequire should be sync'ed with target features, but only
+// required features used in riscv_vector.td.
+enum RVVRequire : uint32_t {
+ RVV_REQ_None = 0,
+ RVV_REQ_RV64 = 1 << 0,
+ RVV_REQ_Zvfhmin = 1 << 1,
+ RVV_REQ_Xsfvcp = 1 << 2,
+ RVV_REQ_Xsfvfnrclipxfqf = 1 << 3,
+ RVV_REQ_Xsfvfwmaccqqq = 1 << 4,
+ RVV_REQ_Xsfvqmaccdod = 1 << 5,
+ RVV_REQ_Xsfvqmaccqoq = 1 << 6,
+ RVV_REQ_Zvbb = 1 << 7,
+ RVV_REQ_Zvbc = 1 << 8,
+ RVV_REQ_Zvkb = 1 << 9,
+ RVV_REQ_Zvkg = 1 << 10,
+ RVV_REQ_Zvkned = 1 << 11,
+ RVV_REQ_Zvknha = 1 << 12,
+ RVV_REQ_Zvknhb = 1 << 13,
+ RVV_REQ_Zvksed = 1 << 14,
+ RVV_REQ_Zvksh = 1 << 15,
+ RVV_REQ_Experimental = 1 << 16,
+
+ LLVM_MARK_AS_BITMASK_ENUM(RVV_REQ_Experimental)
+};
+
+// Raw RVV intrinsic info, used to expand later.
+// This struct is highly compact for minimized code size.
+struct RVVIntrinsicRecord {
+ // Intrinsic name, e.g. vadd_vv
+ const char *Name;
+
+ // Overloaded intrinsic name, could be empty if it can be computed from Name.
+ // e.g. vadd
+ const char *OverloadedName;
+
+ // Prototype for this intrinsic, index of RVVSignatureTable.
+ uint16_t PrototypeIndex;
+
+ // Suffix of intrinsic name, index of RVVSignatureTable.
+ uint16_t SuffixIndex;
+
+ // Suffix of overloaded intrinsic name, index of RVVSignatureTable.
+ uint16_t OverloadedSuffixIndex;
+
+ // Length of the prototype.
+ uint8_t PrototypeLength;
+
+ // Length of intrinsic name suffix.
+ uint8_t SuffixLength;
+
+ // Length of overloaded intrinsic suffix.
+ uint8_t OverloadedSuffixSize;
+
+ // Required target features for this intrinsic.
+ uint32_t RequiredExtensions;
+
+ // Supported type, mask of BasicType.
+ uint8_t TypeRangeMask;
+
+ // Supported LMUL.
+ uint8_t Log2LMULMask;
+
+ // Number of fields, greater than 1 if it's segment load/store.
+ uint8_t NF;
+
+ bool HasMasked : 1;
+ bool HasVL : 1;
+ bool HasMaskedOffOperand : 1;
+ bool HasTailPolicy : 1;
+ bool HasMaskPolicy : 1;
+ bool HasFRMRoundModeOp : 1;
+ bool IsTuple : 1;
+ uint8_t UnMaskedPolicyScheme : 2;
+ uint8_t MaskedPolicyScheme : 2;
+};
+
+llvm::raw_ostream &operator<<(llvm::raw_ostream &OS,
+ const RVVIntrinsicRecord &RVVInstrRecord);
+
+LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE();
+} // end namespace RISCV
+
+} // end namespace clang
+
+#endif // CLANG_SUPPORT_RISCVVINTRINSICUTILS_H
diff --git a/contrib/llvm-project/clang/include/clang/Testing/CommandLineArgs.h b/contrib/llvm-project/clang/include/clang/Testing/CommandLineArgs.h
index 95979a2bfb80..4dd28718dfa6 100644
--- a/contrib/llvm-project/clang/include/clang/Testing/CommandLineArgs.h
+++ b/contrib/llvm-project/clang/include/clang/Testing/CommandLineArgs.h
@@ -29,13 +29,20 @@ enum TestLanguage {
Lang_CXX17,
Lang_CXX20,
Lang_OpenCL,
+ Lang_OBJC,
Lang_OBJCXX
};
std::vector<std::string> getCommandLineArgsForTesting(TestLanguage Lang);
+std::vector<std::string> getCC1ArgsForTesting(TestLanguage Lang);
StringRef getFilenameForTesting(TestLanguage Lang);
+/// Find a target name such that looking for it in TargetRegistry by that name
+/// returns the same target. We expect that there is at least one target
+/// configured with this property.
+std::string getAnyTargetForTesting();
+
} // end namespace clang
#endif
diff --git a/contrib/llvm-project/clang/include/clang/Testing/TestAST.h b/contrib/llvm-project/clang/include/clang/Testing/TestAST.h
new file mode 100644
index 000000000000..845e31f65438
--- /dev/null
+++ b/contrib/llvm-project/clang/include/clang/Testing/TestAST.h
@@ -0,0 +1,103 @@
+//===--- TestAST.h - Build clang ASTs for testing -------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+//
+// In normal operation of Clang, the FrontendAction's lifecycle both creates
+// and destroys the AST, and code should operate on it during callbacks in
+// between (e.g. via ASTConsumer).
+//
+// For tests it is often more convenient to parse an AST from code, and keep it
+// alive as a normal local object, with assertions as straight-line code.
+// TestAST provides such an interface.
+// (ASTUnit can be used for this purpose, but is a production library with
+// broad scope and complicated API).
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TESTING_TESTAST_H
+#define LLVM_CLANG_TESTING_TESTAST_H
+
+#include "clang/Basic/LLVM.h"
+#include "clang/Frontend/CompilerInstance.h"
+#include "clang/Testing/CommandLineArgs.h"
+#include "llvm/ADT/StringRef.h"
+#include <string>
+#include <vector>
+
+namespace clang {
+
+/// Specifies a virtual source file to be parsed as part of a test.
+struct TestInputs {
+ TestInputs() = default;
+ TestInputs(StringRef Code) : Code(Code) {}
+
+ /// The source code of the input file to be parsed.
+ std::string Code;
+
+ /// The language to parse as.
+ /// This affects the -x and -std flags used, and the filename.
+ TestLanguage Language = TestLanguage::Lang_OBJCXX;
+
+ /// Extra argv to pass to clang -cc1.
+ std::vector<std::string> ExtraArgs = {};
+
+ /// Extra virtual files that are available to be #included.
+ /// Keys are plain filenames ("foo.h"), values are file content.
+ llvm::StringMap<std::string> ExtraFiles = {};
+
+ /// Filename to use for translation unit. A default will be used when empty.
+ std::string FileName;
+
+ /// By default, error diagnostics during parsing are reported as gtest errors.
+ /// To suppress this, set ErrorOK or include "error-ok" in a comment in Code.
+ /// In either case, all diagnostics appear in TestAST::diagnostics().
+ bool ErrorOK = false;
+
+ /// The action used to parse the code.
+ /// By default, a SyntaxOnlyAction is used.
+ std::function<std::unique_ptr<FrontendAction>()> MakeAction;
+};
+
+/// The result of parsing a file specified by TestInputs.
+///
+/// The ASTContext, Sema etc are valid as long as this object is alive.
+class TestAST {
+public:
+ /// Constructing a TestAST parses the virtual file.
+ ///
+ /// To keep tests terse, critical errors (e.g. invalid flags) are reported as
+ /// unit test failures with ADD_FAILURE() and produce an empty ASTContext,
+ /// Sema etc. This frees the test code from handling these explicitly.
+ TestAST(const TestInputs &);
+ TestAST(StringRef Code) : TestAST(TestInputs(Code)) {}
+ TestAST(TestAST &&M);
+ TestAST &operator=(TestAST &&);
+ ~TestAST();
+
+ /// Provides access to the AST context and other parts of Clang.
+
+ ASTContext &context() { return Clang->getASTContext(); }
+ Sema &sema() { return Clang->getSema(); }
+ SourceManager &sourceManager() { return Clang->getSourceManager(); }
+ FileManager &fileManager() { return Clang->getFileManager(); }
+ Preprocessor &preprocessor() { return Clang->getPreprocessor(); }
+ FrontendAction &action() { return *Action; }
+
+ /// Returns diagnostics emitted during parsing.
+ /// (By default, errors cause test failures, see TestInputs::ErrorOK).
+ llvm::ArrayRef<StoredDiagnostic> diagnostics() { return Diagnostics; }
+
+private:
+ void clear();
+ std::unique_ptr<FrontendAction> Action;
+ std::unique_ptr<CompilerInstance> Clang;
+ std::vector<StoredDiagnostic> Diagnostics;
+};
+
+} // end namespace clang
+
+#endif
diff --git a/contrib/llvm-project/clang/include/clang/Testing/TestClangConfig.h b/contrib/llvm-project/clang/include/clang/Testing/TestClangConfig.h
index 5d6be4f65d0a..92d5cc3cff99 100644
--- a/contrib/llvm-project/clang/include/clang/Testing/TestClangConfig.h
+++ b/contrib/llvm-project/clang/include/clang/Testing/TestClangConfig.h
@@ -73,7 +73,7 @@ struct TestClangConfig {
std::string Result;
llvm::raw_string_ostream OS(Result);
OS << "{ Language=" << Language << ", Target=" << Target << " }";
- return OS.str();
+ return Result;
}
friend std::ostream &operator<<(std::ostream &OS,
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..6b351e25db20 100644
--- a/contrib/llvm-project/clang/include/clang/Tooling/ASTDiff/ASTDiff.h
+++ b/contrib/llvm-project/clang/include/clang/Tooling/ASTDiff/ASTDiff.h
@@ -20,6 +20,7 @@
#define LLVM_CLANG_TOOLING_ASTDIFF_ASTDIFF_H
#include "clang/Tooling/ASTDiff/ASTDiffInternal.h"
+#include <optional>
namespace clang {
namespace diff {
@@ -44,22 +45,8 @@ struct Node {
ASTNodeKind getType() const;
StringRef getTypeLabel() const;
bool isLeaf() const { return Children.empty(); }
- llvm::Optional<StringRef> getIdentifier() const;
- 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;
+ std::optional<StringRef> getIdentifier() const;
+ std::optional<std::string> getQualifiedIdentifier() const;
};
/// SyntaxTree objects represent subtrees of the AST.
@@ -120,6 +107,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/AllTUsExecution.h b/contrib/llvm-project/clang/include/clang/Tooling/AllTUsExecution.h
index 43f2792457e7..03cfc9c67f5c 100644
--- a/contrib/llvm-project/clang/include/clang/Tooling/AllTUsExecution.h
+++ b/contrib/llvm-project/clang/include/clang/Tooling/AllTUsExecution.h
@@ -16,6 +16,7 @@
#include "clang/Tooling/ArgumentsAdjusters.h"
#include "clang/Tooling/Execution.h"
+#include <optional>
namespace clang {
namespace tooling {
@@ -61,7 +62,7 @@ public:
private:
// Used to store the parser when the executor is initialized with parser.
- llvm::Optional<CommonOptionsParser> OptionsParser;
+ std::optional<CommonOptionsParser> OptionsParser;
const CompilationDatabase &Compilations;
std::unique_ptr<ToolResults> Results;
ExecutionContext Context;
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/Core/Replacement.h b/contrib/llvm-project/clang/include/clang/Tooling/Core/Replacement.h
index 09374c5b1c17..f9452111e147 100644
--- a/contrib/llvm-project/clang/include/clang/Tooling/Core/Replacement.h
+++ b/contrib/llvm-project/clang/include/clang/Tooling/Core/Replacement.h
@@ -20,12 +20,12 @@
#include "clang/Basic/LangOptions.h"
#include "clang/Basic/SourceLocation.h"
-#include "llvm/ADT/Optional.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/raw_ostream.h"
#include <map>
+#include <optional>
#include <set>
#include <string>
#include <system_error>
@@ -173,11 +173,11 @@ public:
static char ID;
- const llvm::Optional<Replacement> &getNewReplacement() const {
+ const std::optional<Replacement> &getNewReplacement() const {
return NewReplacement;
}
- const llvm::Optional<Replacement> &getExistingReplacement() const {
+ const std::optional<Replacement> &getExistingReplacement() const {
return ExistingReplacement;
}
@@ -191,10 +191,10 @@ private:
// A new replacement, which is to expected be added into a set of
// replacements, that is causing problem.
- llvm::Optional<Replacement> NewReplacement;
+ std::optional<Replacement> NewReplacement;
// An existing replacement in a replacements set that is causing problem.
- llvm::Optional<Replacement> ExistingReplacement;
+ std::optional<Replacement> ExistingReplacement;
};
/// Less-than operator between two Replacements.
@@ -202,6 +202,9 @@ bool operator<(const Replacement &LHS, const Replacement &RHS);
/// Equal-to operator between two Replacements.
bool operator==(const Replacement &LHS, const Replacement &RHS);
+inline bool operator!=(const Replacement &LHS, const Replacement &RHS) {
+ return !(LHS == RHS);
+}
/// Maintains a set of replacements that are conflict-free.
/// Two replacements are considered conflicts if they overlap or have the same
@@ -259,7 +262,7 @@ public:
/// Merges \p Replaces into the current replacements. \p Replaces
/// refers to code after applying the current replacements.
- LLVM_NODISCARD Replacements merge(const Replacements &Replaces) const;
+ [[nodiscard]] Replacements merge(const Replacements &Replaces) const;
// Returns the affected ranges in the changed code.
std::vector<Range> getAffectedRanges() const;
@@ -301,7 +304,7 @@ private:
// applied.
Replacements getCanonicalReplacements() const;
- // If `R` and all existing replacements are order-indepedent, then merge it
+ // If `R` and all existing replacements are order-independent, then merge it
// with `Replaces` and returns the merged replacements; otherwise, returns an
// error.
llvm::Expected<Replacements>
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 c52da3305f7c..9a2aea5d6efa 100644
--- a/contrib/llvm-project/clang/include/clang/Tooling/DependencyScanning/DependencyScanningFilesystem.h
+++ b/contrib/llvm-project/clang/include/clang/Tooling/DependencyScanning/DependencyScanningFilesystem.h
@@ -6,176 +6,274 @@
//
//===----------------------------------------------------------------------===//
-#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 "clang/Lex/DependencyDirectivesScanner.h"
+#include "llvm/ADT/DenseMap.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"
#include <mutex>
+#include <optional>
namespace clang {
namespace tooling {
namespace dependencies {
+using DependencyDirectivesTy =
+ SmallVector<dependency_directives_scan::Directive, 20>;
+
+/// Contents and directive tokens of a cached file entry. Single instance can
+/// be shared between multiple entries.
+struct CachedFileContents {
+ CachedFileContents(std::unique_ptr<llvm::MemoryBuffer> Contents)
+ : Original(std::move(Contents)), DepDirectives(nullptr) {}
+
+ /// Owning storage for the original contents.
+ std::unique_ptr<llvm::MemoryBuffer> Original;
+
+ /// The mutex that must be locked before mutating directive tokens.
+ std::mutex ValueLock;
+ SmallVector<dependency_directives_scan::Token, 10> DepDirectiveTokens;
+ /// Accessor to the directive tokens that's atomic to avoid data races.
+ /// \p CachedFileContents has ownership of the pointer.
+ std::atomic<const std::optional<DependencyDirectivesTy> *> DepDirectives;
+
+ ~CachedFileContents() { delete DepDirectives.load(); }
+};
+
/// An in-memory representation of a file system entity that is of interest to
/// the dependency scanning filesystem.
///
/// It represents one of the following:
-/// - an opened source file with minimized contents and a stat value.
-/// - an opened source file with original contents and a stat value.
-/// - a directory entry with its stat value.
-/// - an error value to represent a file system error.
-/// - a placeholder with an invalid stat indicating a not yet initialized entry.
+/// - opened file with contents and a stat value,
+/// - opened file with contents, directive tokens and a stat value,
+/// - directory entry with its stat value,
+/// - 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:
- /// Default constructor creates an entry with an invalid stat.
- CachedFileSystemEntry() : MaybeStat(llvm::vfs::Status()) {}
+ /// 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();
+ }
+
+ /// 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();
+ }
- CachedFileSystemEntry(std::error_code Error) : MaybeStat(std::move(Error)) {}
+ /// \returns True if the entry is a filesystem error.
+ bool isError() const { return !MaybeStat; }
- /// Create an entry that represents an opened source 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. If file is not minimized, the full file is
- /// read and copied into memory to ensure that it's not memory mapped to avoid
- /// running out of file descriptors.
- static CachedFileSystemEntry createFileEntry(StringRef Filename,
- llvm::vfs::FileSystem &FS,
- bool Minimize = true);
-
- /// Create an entry that represents a directory on the filesystem.
- static CachedFileSystemEntry createDirectoryEntry(llvm::vfs::Status &&Stat);
-
- /// \returns True if the entry is valid.
- bool isValid() const { return !MaybeStat || MaybeStat->isStatusKnown(); }
-
- /// \returns True if the current entry points to a directory.
- bool isDirectory() const { return MaybeStat && MaybeStat->isDirectory(); }
-
- /// \returns The error or the file's contents.
- llvm::ErrorOr<StringRef> getContents() const {
- if (!MaybeStat)
- return MaybeStat.getError();
+ /// \returns True if the current entry represents a directory.
+ bool isDirectory() const { return !isError() && MaybeStat->isDirectory(); }
+
+ /// \returns Original contents of the file.
+ StringRef getOriginalContents() const {
+ assert(!isError() && "error");
assert(!MaybeStat->isDirectory() && "not a file");
- assert(isValid() && "not initialized");
- return Contents.str();
+ assert(Contents && "contents not initialized");
+ return Contents->Original->getBuffer();
}
- /// \returns The error or the status of the entry.
- llvm::ErrorOr<llvm::vfs::Status> getStatus() const {
- assert(isValid() && "not initialized");
- return MaybeStat;
+ /// \returns The scanned preprocessor directive tokens of the file that are
+ /// used to speed up preprocessing, if available.
+ std::optional<ArrayRef<dependency_directives_scan::Directive>>
+ getDirectiveTokens() const {
+ assert(!isError() && "error");
+ assert(!isDirectory() && "not a file");
+ assert(Contents && "contents not initialized");
+ if (auto *Directives = Contents->DepDirectives.load()) {
+ if (Directives->has_value())
+ return ArrayRef<dependency_directives_scan::Directive>(**Directives);
+ }
+ return std::nullopt;
}
- /// \returns the name of the file.
- StringRef getName() const {
- assert(isValid() && "not initialized");
- return MaybeStat->getName();
- }
+ /// \returns The error.
+ std::error_code getError() const { return MaybeStat.getError(); }
- /// Return the mapping between location -> distance that is used to speed up
- /// the block skipping in the preprocessor.
- const PreprocessorSkippedRangeMapping &getPPSkippedRangeMapping() const {
- return PPSkippedRangeMapping;
+ /// \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;
}
- CachedFileSystemEntry(CachedFileSystemEntry &&) = default;
- CachedFileSystemEntry &operator=(CachedFileSystemEntry &&) = default;
+ /// \returns The unique ID of the entry.
+ llvm::sys::fs::UniqueID getUniqueID() const {
+ assert(!isError() && "error");
+ return MaybeStat->getUniqueID();
+ }
- CachedFileSystemEntry(const CachedFileSystemEntry &) = delete;
- CachedFileSystemEntry &operator=(const CachedFileSystemEntry &) = delete;
+ /// \returns The data structure holding both contents and directive tokens.
+ CachedFileContents *getCachedContents() const {
+ assert(!isError() && "error");
+ assert(!isDirectory() && "not a file");
+ return Contents;
+ }
private:
+ void clearStatName() {
+ if (MaybeStat)
+ MaybeStat = llvm::vfs::Status::copyWithNewName(*MaybeStat, "");
+ }
+
+ /// 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;
- // Store the contents in a small string to allow a
- // move from the small string for the minimized contents.
- // Note: small size of 1 allows us to store an empty string with an implicit
- // null terminator without any allocations.
- llvm::SmallString<1> Contents;
- 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
-/// underlying real file system. It distinguishes between minimized and original
+/// underlying real file system, and the scanned preprocessor directives of
/// files.
///
/// It is sharded based on the hash of the key to reduce the lock contention for
/// 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);
};
- /// 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, bool Minimized);
+ DependencyScanningFilesystemSharedCache();
-private:
- class SingleCache {
- public:
- SingleCache();
-
- SharedFileSystemEntry &get(StringRef Key);
-
- private:
- struct CacheShard {
- std::mutex CacheLock;
- llvm::StringMap<SharedFileSystemEntry, llvm::BumpPtrAllocator> Cache;
- };
- std::unique_ptr<CacheShard[]> CacheShards;
- unsigned NumShards;
- };
+ /// Returns shard for the given key.
+ CacheShard &getShardForFilename(StringRef Filename) const;
+ CacheShard &getShardForUID(llvm::sys::fs::UniqueID UID) const;
- SingleCache CacheMinimized;
- SingleCache CacheOriginal;
+private:
+ std::unique_ptr<CacheShard[]> CacheShards;
+ unsigned NumShards;
};
/// This class is a local cache, that caches the 'stat' and 'open' calls to the
-/// underlying real file system. It distinguishes between minimized and original
-/// files.
+/// underlying real file system.
class DependencyScanningFilesystemLocalCache {
-private:
- using SingleCache =
- llvm::StringMap<const CachedFileSystemEntry *, llvm::BumpPtrAllocator>;
+ llvm::StringMap<const CachedFileSystemEntry *, llvm::BumpPtrAllocator> Cache;
- SingleCache CacheMinimized;
- SingleCache CacheOriginal;
+public:
+ /// Returns entry associated with the filename or nullptr if none is found.
+ const CachedFileSystemEntry *findEntryByFilename(StringRef Filename) const {
+ assert(llvm::sys::path::is_absolute_gnu(Filename));
+ auto It = Cache.find(Filename);
+ return It == Cache.end() ? nullptr : It->getValue();
+ }
- SingleCache &selectCache(bool Minimized) {
- return Minimized ? CacheMinimized : CacheOriginal;
+ /// Associates the given entry with the filename and returns the given entry
+ /// pointer (for convenience).
+ const CachedFileSystemEntry &
+ insertEntryForFilename(StringRef Filename,
+ const CachedFileSystemEntry &Entry) {
+ assert(llvm::sys::path::is_absolute_gnu(Filename));
+ const auto *InsertedEntry = Cache.insert({Filename, &Entry}).first->second;
+ assert(InsertedEntry == &Entry && "entry already present");
+ return *InsertedEntry;
}
+};
+
+/// Reference to a CachedFileSystemEntry.
+/// If the underlying entry is an opened file, this wrapper returns the file
+/// contents and the scanned preprocessor directives.
+class EntryRef {
+ /// The filename used to access this entry.
+ std::string Filename;
+
+ /// The underlying cached entry.
+ const CachedFileSystemEntry &Entry;
public:
- void setCachedEntry(StringRef Filename, bool Minimized,
- const CachedFileSystemEntry *Entry) {
- SingleCache &Cache = selectCache(Minimized);
- bool IsInserted = Cache.try_emplace(Filename, Entry).second;
- (void)IsInserted;
- assert(IsInserted && "local cache is updated more than once");
+ EntryRef(StringRef Name, const CachedFileSystemEntry &Entry)
+ : 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);
}
- const CachedFileSystemEntry *getCachedEntry(StringRef Filename,
- bool Minimized) {
- SingleCache &Cache = selectCache(Minimized);
- auto It = Cache.find(Filename);
- return It == Cache.end() ? nullptr : It->getValue();
+ bool isError() const { return Entry.isError(); }
+ bool isDirectory() const { return Entry.isDirectory(); }
+
+ /// If the cached entry represents an error, promotes it into `ErrorOr`.
+ llvm::ErrorOr<EntryRef> unwrapError() const {
+ if (isError())
+ return Entry.getError();
+ return *this;
+ }
+
+ StringRef getContents() const { return Entry.getOriginalContents(); }
+
+ std::optional<ArrayRef<dependency_directives_scan::Directive>>
+ getDirectiveTokens() const {
+ return Entry.getDirectiveTokens();
}
};
/// A virtual file system optimized for the dependency discovery.
///
-/// It is primarily designed to work with source files whose contents was was
+/// It is primarily designed to work with source files whose contents was
/// preprocessed to remove any tokens that are unlikely to affect the dependency
/// computation.
///
@@ -186,39 +284,126 @@ class DependencyScanningWorkerFilesystem : public llvm::vfs::ProxyFileSystem {
public:
DependencyScanningWorkerFilesystem(
DependencyScanningFilesystemSharedCache &SharedCache,
- IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS,
- ExcludedPreprocessorDirectiveSkipMapping *PPSkipMappings)
- : ProxyFileSystem(std::move(FS)), SharedCache(SharedCache),
- PPSkipMappings(PPSkipMappings) {}
+ IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS);
llvm::ErrorOr<llvm::vfs::Status> status(const Twine &Path) override;
llvm::ErrorOr<std::unique_ptr<llvm::vfs::File>>
openFileForRead(const Twine &Path) override;
- void clearIgnoredFiles() { IgnoredFiles.clear(); }
- void ignoreFile(StringRef Filename);
+ std::error_code setCurrentWorkingDirectory(const Twine &Path) override;
+
+ /// 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 DisableDirectivesScanning = false);
private:
- bool shouldIgnoreFile(StringRef Filename);
+ /// Check whether the file should be scanned for preprocessor directives.
+ bool shouldScanForDirectives(StringRef Filename);
+
+ /// 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.
+ /// \p FilenameForLookup will always be an absolute path, and different than
+ /// \p OriginalFilename if \p OriginalFilename is relative.
+ llvm::ErrorOr<const CachedFileSystemEntry &>
+ computeAndStoreResult(StringRef OriginalFilename,
+ StringRef FilenameForLookup);
+
+ /// Scan for preprocessor directives for the given entry if necessary and
+ /// returns a wrapper object with reference semantics.
+ EntryRef scanForDirectivesIfNecessary(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<const CachedFileSystemEntry *>
- getOrCreateFileSystemEntry(const 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);
+ }
+
+ void printImpl(raw_ostream &OS, PrintType Type,
+ unsigned IndentLevel) const override {
+ printIndent(OS, IndentLevel);
+ OS << "DependencyScanningFilesystem\n";
+ getUnderlyingFS().print(OS, Type, IndentLevel + 1);
+ }
/// The global cache shared between worker threads.
DependencyScanningFilesystemSharedCache &SharedCache;
/// The local cache is used by the worker thread to cache file system queries
/// locally instead of querying the global cache every time.
- DependencyScanningFilesystemLocalCache Cache;
- /// The optional mapping structure which records information about the
- /// excluded conditional directive skip mappings that are used by the
- /// currently active preprocessor.
- ExcludedPreprocessorDirectiveSkipMapping *PPSkipMappings;
- /// The set of files that should not be minimized.
- llvm::StringSet<> IgnoredFiles;
+ DependencyScanningFilesystemLocalCache LocalCache;
+
+ /// The working directory to use for making relative paths absolute before
+ /// using them for cache lookups.
+ llvm::ErrorOr<std::string> WorkingDirForCacheLookup;
+
+ void updateWorkingDirForCacheLookup();
};
} // 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 76edf150dbee..dcdf1c171f6d 100644
--- a/contrib/llvm-project/clang/include/clang/Tooling/DependencyScanning/DependencyScanningService.h
+++ b/contrib/llvm-project/clang/include/clang/Tooling/DependencyScanning/DependencyScanningService.h
@@ -6,10 +6,11 @@
//
//===----------------------------------------------------------------------===//
-#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"
+#include "llvm/ADT/BitmaskEnum.h"
namespace clang {
namespace tooling {
@@ -19,15 +20,13 @@ namespace dependencies {
/// dependencies.
enum class ScanningMode {
/// This mode is used to compute the dependencies by running the preprocessor
- /// over
- /// the unmodified source files.
+ /// over the source files.
CanonicalPreprocessing,
/// This mode is used to compute the dependencies by running the preprocessor
- /// over
- /// the source files that have been minimized to contents that might affect
- /// the dependencies.
- MinimizedSourcePreprocessing
+ /// with special kind of lexing after scanning header and source files to get
+ /// the minimum necessary preprocessor directives for evaluating includes.
+ DependencyDirectivesScan,
};
/// The format that is output by the dependency scanner.
@@ -37,26 +36,45 @@ enum class ScanningOutputFormat {
/// intermodule dependency information.
Make,
- /// This outputs the full module dependency graph suitable for use for
+ /// This outputs the full clang module dependency graph suitable for use for
/// explicitly building modules.
Full,
+
+ /// This outputs the dependency graph for standard c++ modules in P1689R5
+ /// format.
+ P1689,
+};
+
+enum class ScanningOptimizations {
+ None = 0,
+
+ /// Remove unused header search paths including header maps.
+ HeaderSearch = 1,
+
+ /// Remove warnings from system modules.
+ SystemWarnings = 2,
+
+ LLVM_MARK_AS_BITMASK_ENUM(SystemWarnings),
+ All = HeaderSearch | SystemWarnings,
+ Default = All
};
-/// The dependency scanning service contains the shared state that is used by
-/// the invidual dependency scanning workers.
+/// The dependency scanning service contains shared configuration and state that
+/// is used by the individual dependency scanning workers.
class DependencyScanningService {
public:
- DependencyScanningService(ScanningMode Mode, ScanningOutputFormat Format,
- bool ReuseFileManager = true,
- bool SkipExcludedPPRanges = true);
+ DependencyScanningService(
+ ScanningMode Mode, ScanningOutputFormat Format,
+ ScanningOptimizations OptimizeArgs = ScanningOptimizations::Default,
+ bool EagerLoadModules = false);
ScanningMode getMode() const { return Mode; }
ScanningOutputFormat getFormat() const { return Format; }
- bool canReuseFileManager() const { return ReuseFileManager; }
+ ScanningOptimizations getOptimizeArgs() const { return OptimizeArgs; }
- bool canSkipExcludedPPRanges() const { return SkipExcludedPPRanges; }
+ bool shouldEagerLoadModules() const { return EagerLoadModules; }
DependencyScanningFilesystemSharedCache &getSharedCache() {
return SharedCache;
@@ -65,11 +83,10 @@ public:
private:
const ScanningMode Mode;
const ScanningOutputFormat Format;
- const bool ReuseFileManager;
- /// Set to true to use the preprocessor optimization that skips excluded PP
- /// ranges by bumping the buffer pointer in the lexer instead of lexing the
- /// tokens in the range until reaching the corresponding directive.
- const bool SkipExcludedPPRanges;
+ /// Whether to optimize the modules' command-line arguments.
+ const ScanningOptimizations OptimizeArgs;
+ /// Whether to set up command-lines to load PCM files eagerly.
+ const bool EagerLoadModules;
/// The global file system cache.
DependencyScanningFilesystemSharedCache SharedCache;
};
@@ -78,4 +95,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 f88dc472c80b..cb9476d1550d 100644
--- a/contrib/llvm-project/clang/include/clang/Tooling/DependencyScanning/DependencyScanningTool.h
+++ b/contrib/llvm-project/clang/include/clang/Tooling/DependencyScanning/DependencyScanningTool.h
@@ -6,22 +6,35 @@
//
//===----------------------------------------------------------------------===//
-#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"
#include "clang/Tooling/DependencyScanning/ModuleDepCollector.h"
#include "clang/Tooling/JSONCompilationDatabase.h"
-#include "llvm/ADT/StringSet.h"
+#include "llvm/ADT/DenseSet.h"
+#include "llvm/ADT/MapVector.h"
+#include <optional>
#include <string>
+#include <vector>
-namespace clang{
-namespace tooling{
-namespace dependencies{
+namespace clang {
+namespace tooling {
+namespace dependencies {
+
+/// A callback to lookup module outputs for "-fmodule-file=", "-o" etc.
+using LookupModuleOutputCallback =
+ llvm::function_ref<std::string(const ModuleID &, ModuleOutputKind)>;
+
+/// Graph of modular dependencies.
+using ModuleDepsGraph = std::vector<ModuleDeps>;
/// The full dependencies and module graph for a specific input.
-struct FullDependencies {
+struct TranslationUnitDeps {
+ /// The graph of direct and transitive modular dependencies.
+ ModuleDepsGraph ModuleGraph;
+
/// The identifier of the C++20 module this translation unit exports.
///
/// If the translation unit is not a module then \c ID.ModuleName is empty.
@@ -42,30 +55,22 @@ struct FullDependencies {
/// determined that the differences are benign for this compilation.
std::vector<ModuleID> ClangModuleDeps;
- /// Get additional arguments suitable for appending to the original Clang
- /// command line.
+ /// The sequence of commands required to build the translation unit. Commands
+ /// should be executed in order.
///
- /// \param LookupPCMPath This function is called to fill in "-fmodule-file="
- /// arguments and the "-o" argument. It needs to return
- /// a path for where the PCM for the given module is to
- /// be located.
- /// \param LookupModuleDeps This function is called to collect the full
- /// transitive set of dependencies for this
- /// compilation and fill in "-fmodule-map-file="
- /// arguments.
- std::vector<std::string> getAdditionalArgs(
- std::function<StringRef(ModuleID)> LookupPCMPath,
- std::function<const ModuleDeps &(ModuleID)> LookupModuleDeps) const;
-
- /// Get additional arguments suitable for appending to the original Clang
- /// command line, excluding arguments containing modules-related paths:
- /// "-fmodule-file=", "-fmodule-map-file=".
- std::vector<std::string> getAdditionalArgsWithoutModulePaths() const;
+ /// FIXME: If we add support for multi-arch builds in clang-scan-deps, we
+ /// should make the dependencies between commands explicit to enable parallel
+ /// builds of each architecture.
+ std::vector<Command> Commands;
+
+ /// Deprecated driver command-line. This will be removed in a future version.
+ std::vector<std::string> DriverCommandLine;
};
-struct FullDependenciesResult {
- FullDependencies FullDeps;
- std::vector<ModuleDeps> DiscoveredModules;
+struct P1689Rule {
+ std::string PrimaryOutput;
+ std::optional<P1689ModuleInfo> Provides;
+ std::vector<P1689ModuleInfo> Requires;
};
/// The high-level implementation of the dependency discovery tool that runs on
@@ -73,7 +78,9 @@ struct FullDependenciesResult {
class DependencyScanningTool {
public:
/// Construct a dependency scanning tool.
- DependencyScanningTool(DependencyScanningService &Service);
+ DependencyScanningTool(DependencyScanningService &Service,
+ llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS =
+ llvm::vfs::createPhysicalFileSystem());
/// Print out the dependency information into a string using the dependency
/// file format that is specified in the options (-MD is the default) and
@@ -82,30 +89,137 @@ public:
/// \returns A \c StringError with the diagnostic output if clang errors
/// occurred, dependency file contents otherwise.
llvm::Expected<std::string>
- getDependencyFile(const tooling::CompilationDatabase &Compilations,
- StringRef CWD);
+ getDependencyFile(const std::vector<std::string> &CommandLine, StringRef CWD);
- /// Collect the full module dependency graph for the input, ignoring any
- /// modules which have already been seen.
+ /// Collect the module dependency in P1689 format for C++20 named modules.
+ ///
+ /// \param MakeformatOutput The output parameter for dependency information
+ /// in make format if the command line requires to generate make-format
+ /// dependency information by `-MD -MF <dep_file>`.
+ ///
+ /// \param MakeformatOutputPath The output parameter for the path to
+ /// \param MakeformatOutput.
+ ///
+ /// \returns A \c StringError with the diagnostic output if clang errors
+ /// occurred, P1689 dependency format rules otherwise.
+ llvm::Expected<P1689Rule>
+ getP1689ModuleDependencyFile(const clang::tooling::CompileCommand &Command,
+ StringRef CWD, std::string &MakeformatOutput,
+ std::string &MakeformatOutputPath);
+ llvm::Expected<P1689Rule>
+ getP1689ModuleDependencyFile(const clang::tooling::CompileCommand &Command,
+ StringRef CWD) {
+ std::string MakeformatOutput;
+ std::string MakeformatOutputPath;
+
+ return getP1689ModuleDependencyFile(Command, CWD, MakeformatOutput,
+ MakeformatOutputPath);
+ }
+
+ /// Given a Clang driver command-line for a translation unit, gather the
+ /// modular dependencies and return the information needed for explicit build.
///
/// \param AlreadySeen This stores modules which have previously been
/// reported. Use the same instance for all calls to this
/// function for a single \c DependencyScanningTool in a
/// single build. Use a different one for different tools,
/// and clear it between builds.
+ /// \param LookupModuleOutput This function is called to fill in
+ /// "-fmodule-file=", "-o" and other output
+ /// arguments for dependencies.
///
/// \returns a \c StringError with the diagnostic output if clang errors
- /// occurred, \c FullDependencies otherwise.
- llvm::Expected<FullDependenciesResult>
- getFullDependencies(const tooling::CompilationDatabase &Compilations,
- StringRef CWD, const llvm::StringSet<> &AlreadySeen);
+ /// occurred, \c TranslationUnitDeps otherwise.
+ llvm::Expected<TranslationUnitDeps>
+ getTranslationUnitDependencies(const std::vector<std::string> &CommandLine,
+ StringRef CWD,
+ const llvm::DenseSet<ModuleID> &AlreadySeen,
+ LookupModuleOutputCallback LookupModuleOutput);
+
+ /// Given a compilation context specified via the Clang driver command-line,
+ /// gather modular dependencies of module with the given name, and return the
+ /// information needed for explicit build.
+ llvm::Expected<ModuleDepsGraph> getModuleDependencies(
+ StringRef ModuleName, const std::vector<std::string> &CommandLine,
+ StringRef CWD, const llvm::DenseSet<ModuleID> &AlreadySeen,
+ LookupModuleOutputCallback LookupModuleOutput);
private:
DependencyScanningWorker Worker;
};
+class FullDependencyConsumer : public DependencyConsumer {
+public:
+ FullDependencyConsumer(const llvm::DenseSet<ModuleID> &AlreadySeen)
+ : AlreadySeen(AlreadySeen) {}
+
+ void handleBuildCommand(Command Cmd) override {
+ Commands.push_back(std::move(Cmd));
+ }
+
+ void handleDependencyOutputOpts(const DependencyOutputOptions &) override {}
+
+ void handleFileDependency(StringRef File) override {
+ Dependencies.push_back(std::string(File));
+ }
+
+ void handlePrebuiltModuleDependency(PrebuiltModuleDep PMD) override {
+ PrebuiltModuleDeps.emplace_back(std::move(PMD));
+ }
+
+ void handleModuleDependency(ModuleDeps MD) override {
+ ClangModuleDeps[MD.ID] = std::move(MD);
+ }
+
+ void handleDirectModuleDependency(ModuleID ID) override {
+ DirectModuleDeps.push_back(ID);
+ }
+
+ void handleContextHash(std::string Hash) override {
+ ContextHash = std::move(Hash);
+ }
+
+ TranslationUnitDeps takeTranslationUnitDeps();
+ ModuleDepsGraph takeModuleGraphDeps();
+
+private:
+ std::vector<std::string> Dependencies;
+ std::vector<PrebuiltModuleDep> PrebuiltModuleDeps;
+ llvm::MapVector<ModuleID, ModuleDeps> ClangModuleDeps;
+ std::vector<ModuleID> DirectModuleDeps;
+ std::vector<Command> Commands;
+ std::string ContextHash;
+ std::vector<std::string> OutputPaths;
+ const llvm::DenseSet<ModuleID> &AlreadySeen;
+};
+
+/// A simple dependency action controller that uses a callback. If no callback
+/// is provided, it is assumed that looking up module outputs is unreachable.
+class CallbackActionController : public DependencyActionController {
+public:
+ virtual ~CallbackActionController();
+
+ CallbackActionController(LookupModuleOutputCallback LMO)
+ : LookupModuleOutput(std::move(LMO)) {
+ if (!LookupModuleOutput) {
+ LookupModuleOutput = [](const ModuleID &,
+ ModuleOutputKind) -> std::string {
+ llvm::report_fatal_error("unexpected call to lookupModuleOutput");
+ };
+ }
+ }
+
+ std::string lookupModuleOutput(const ModuleID &ID,
+ ModuleOutputKind Kind) override {
+ return LookupModuleOutput(ID, Kind);
+ }
+
+private:
+ LookupModuleOutputCallback LookupModuleOutput;
+};
+
} // end namespace dependencies
} // 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 5903ad13c1d8..0f607862194b 100644
--- a/contrib/llvm-project/clang/include/clang/Tooling/DependencyScanning/DependencyScanningWorker.h
+++ b/contrib/llvm-project/clang/include/clang/Tooling/DependencyScanning/DependencyScanningWorker.h
@@ -6,19 +6,18 @@
//
//===----------------------------------------------------------------------===//
-#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"
#include "clang/Basic/LLVM.h"
#include "clang/Frontend/PCHContainerOperations.h"
-#include "clang/Lex/PreprocessorExcludedConditionalDirectiveSkipMapping.h"
-#include "clang/Tooling/CompilationDatabase.h"
#include "clang/Tooling/DependencyScanning/DependencyScanningService.h"
#include "clang/Tooling/DependencyScanning/ModuleDepCollector.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/FileSystem.h"
+#include <optional>
#include <string>
namespace clang {
@@ -30,10 +29,24 @@ namespace dependencies {
class DependencyScanningWorkerFilesystem;
+/// A command-line tool invocation that is part of building a TU.
+///
+/// \see TranslationUnitDeps::Commands.
+struct Command {
+ std::string Executable;
+ std::vector<std::string> Arguments;
+};
+
class DependencyConsumer {
public:
virtual ~DependencyConsumer() {}
+ virtual void handleProvidedAndRequiredStdCXXModules(
+ std::optional<P1689ModuleInfo> Provided,
+ std::vector<P1689ModuleInfo> Requires) {}
+
+ virtual void handleBuildCommand(Command Cmd) {}
+
virtual void
handleDependencyOutputOpts(const DependencyOutputOptions &Opts) = 0;
@@ -43,9 +56,21 @@ public:
virtual void handleModuleDependency(ModuleDeps MD) = 0;
+ virtual void handleDirectModuleDependency(ModuleID MD) = 0;
+
virtual void handleContextHash(std::string Hash) = 0;
};
+/// Dependency scanner callbacks that are used during scanning to influence the
+/// behaviour of the scan - for example, to customize the scanned invocations.
+class DependencyActionController {
+public:
+ virtual ~DependencyActionController();
+
+ virtual std::string lookupModuleOutput(const ModuleID &ID,
+ ModuleOutputKind Kind) = 0;
+};
+
/// An individual dependency scanning worker that is able to run on its own
/// thread.
///
@@ -54,37 +79,50 @@ public:
/// using the regular processing run.
class DependencyScanningWorker {
public:
- DependencyScanningWorker(DependencyScanningService &Service);
+ DependencyScanningWorker(DependencyScanningService &Service,
+ llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS);
- /// Run the dependency scanning tool for a given clang driver invocation (as
- /// specified for the given Input in the CDB), and report the discovered
- /// dependencies to the provided consumer.
+ /// Run the dependency scanning tool for a given clang driver command-line,
+ /// and report the discovered dependencies to the provided consumer. If \p
+ /// ModuleName isn't empty, this function reports the dependencies of module
+ /// \p ModuleName.
///
+ /// \returns false if clang errors occurred (with diagnostics reported to
+ /// \c DiagConsumer), true otherwise.
+ bool computeDependencies(StringRef WorkingDirectory,
+ const std::vector<std::string> &CommandLine,
+ DependencyConsumer &DepConsumer,
+ DependencyActionController &Controller,
+ DiagnosticConsumer &DiagConsumer,
+ std::optional<StringRef> ModuleName = std::nullopt);
/// \returns A \c StringError with the diagnostic output if clang errors
/// occurred, success otherwise.
- llvm::Error computeDependencies(const std::string &Input,
- StringRef WorkingDirectory,
- const CompilationDatabase &CDB,
- DependencyConsumer &Consumer);
+ llvm::Error computeDependencies(
+ StringRef WorkingDirectory, const std::vector<std::string> &CommandLine,
+ DependencyConsumer &Consumer, DependencyActionController &Controller,
+ std::optional<StringRef> ModuleName = std::nullopt);
+
+ bool shouldEagerLoadModules() const { return EagerLoadModules; }
private:
- IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts;
std::shared_ptr<PCHContainerOperations> PCHContainerOps;
- std::unique_ptr<ExcludedPreprocessorDirectiveSkipMapping> PPSkipMappings;
-
- llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> RealFS;
- /// The file system that is used by each worker when scanning for
- /// dependencies. This filesystem persists accross multiple compiler
- /// invocations.
+ /// The file system to be used during the scan.
+ /// This is either \c FS passed in the constructor (when performing canonical
+ /// preprocessing), or \c DepFS (when performing dependency directives scan).
+ llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> BaseFS;
+ /// When performing dependency directives scan, this is the caching (and
+ /// dependency-directives-extracting) filesystem overlaid on top of \c FS
+ /// (passed in the constructor).
llvm::IntrusiveRefCntPtr<DependencyScanningWorkerFilesystem> DepFS;
- /// The file manager that is reused accross multiple invocations by this
- /// worker. If null, the file manager will not be reused.
- llvm::IntrusiveRefCntPtr<FileManager> Files;
ScanningOutputFormat Format;
+ /// Whether to optimize the modules' command-line arguments.
+ ScanningOptimizations OptimizeArgs;
+ /// Whether to set up command-lines to load PCM files eagerly.
+ bool EagerLoadModules;
};
} // end namespace dependencies
} // 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 a9f2b4d0c6fc..051363b075de 100644
--- a/contrib/llvm-project/clang/include/clang/Tooling/DependencyScanning/ModuleDepCollector.h
+++ b/contrib/llvm-project/clang/include/clang/Tooling/DependencyScanning/ModuleDepCollector.h
@@ -1,14 +1,13 @@
//===- ModuleDepCollector.h - Callbacks to collect deps ---------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_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"
@@ -17,16 +16,21 @@
#include "clang/Lex/HeaderSearch.h"
#include "clang/Lex/PPCallbacks.h"
#include "clang/Serialization/ASTReader.h"
+#include "clang/Tooling/DependencyScanning/DependencyScanningService.h"
#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/Hashing.h"
#include "llvm/ADT/StringSet.h"
#include "llvm/Support/raw_ostream.h"
+#include <optional>
#include <string>
#include <unordered_map>
+#include <variant>
namespace clang {
namespace tooling {
namespace dependencies {
+class DependencyActionController;
class DependencyConsumer;
/// Modular dependency that has already been built prior to the dependency scan.
@@ -47,25 +51,61 @@ struct ModuleID {
/// or a header-name for C++20 header units.
std::string ModuleName;
- /// The context hash of a module represents the set of compiler options that
- /// may make one version of a module incompatible with another. This includes
- /// things like language mode, predefined macros, header search paths, etc...
+ /// The context hash of a module represents the compiler options that affect
+ /// the resulting command-line invocation.
+ ///
+ /// Modules with the same name and ContextHash but different invocations could
+ /// cause non-deterministic build results.
///
/// Modules with the same name but a different \c ContextHash should be
/// treated as separate modules for the purpose of a build.
std::string ContextHash;
bool operator==(const ModuleID &Other) const {
- return ModuleName == Other.ModuleName && ContextHash == Other.ContextHash;
+ return std::tie(ModuleName, ContextHash) ==
+ std::tie(Other.ModuleName, Other.ContextHash);
}
-};
-struct ModuleIDHasher {
- std::size_t operator()(const ModuleID &MID) const {
- return llvm::hash_combine(MID.ModuleName, MID.ContextHash);
+ bool operator<(const ModuleID& Other) const {
+ return std::tie(ModuleName, ContextHash) <
+ std::tie(Other.ModuleName, Other.ContextHash);
}
};
+/// P1689ModuleInfo - Represents the needed information of standard C++20
+/// modules for P1689 format.
+struct P1689ModuleInfo {
+ /// The name of the module. This may include `:` for partitions.
+ std::string ModuleName;
+
+ /// Optional. The source path to the module.
+ std::string SourcePath;
+
+ /// If this module is a standard c++ interface unit.
+ bool IsStdCXXModuleInterface = true;
+
+ enum class ModuleType {
+ NamedCXXModule
+ // To be supported
+ // AngleHeaderUnit,
+ // QuoteHeaderUnit
+ };
+ ModuleType Type = ModuleType::NamedCXXModule;
+};
+
+/// An output from a module compilation, such as the path of the module file.
+enum class ModuleOutputKind {
+ /// The module file (.pcm). Required.
+ ModuleFile,
+ /// The path of the dependency file (.d), if any.
+ DependencyFile,
+ /// The null-separated list of names to use as the targets in the dependency
+ /// file, if any. Defaults to the value of \c ModuleFile, as in the driver.
+ DependencyTargets,
+ /// The path of the serialized diagnostic file (.dia), if any.
+ DiagnosticSerializationFile,
+};
+
struct ModuleDeps {
/// The identifier of the module.
ModuleID ID;
@@ -79,13 +119,14 @@ struct ModuleDeps {
/// additionally appear in \c FileDeps as a dependency.
std::string ClangModuleMapFile;
- /// The path to where an implicit build would put the PCM for this module.
- std::string ImplicitModulePCMPath;
-
/// A collection of absolute paths to files that this module directly depends
/// on, not including transitive dependencies.
llvm::StringSet<> FileDeps;
+ /// A collection of absolute paths to module map files that this module needs
+ /// to know about. The ordering is significant.
+ std::vector<std::string> ModuleMapFileDeps;
+
/// A collection of prebuilt modular dependencies this module directly depends
/// on, not including transitive dependencies.
std::vector<PrebuiltModuleDep> PrebuiltModuleDeps;
@@ -97,43 +138,17 @@ struct ModuleDeps {
/// determined that the differences are benign for this compilation.
std::vector<ModuleID> ClangModuleDeps;
- // Used to track which modules that were discovered were directly imported by
- // the primary TU.
- bool ImportedByMainFile = false;
+ /// Get (or compute) the compiler invocation that can be used to build this
+ /// module. Does not include argv[0].
+ const std::vector<std::string> &getBuildArguments();
- /// Compiler invocation that can be used to build this module (without paths).
- CompilerInvocation Invocation;
+private:
+ friend class ModuleDepCollectorPP;
- /// Gets the canonical command line suitable for passing to clang.
- ///
- /// \param LookupPCMPath This function is called to fill in "-fmodule-file="
- /// arguments and the "-o" argument. It needs to return
- /// a path for where the PCM for the given module is to
- /// be located.
- /// \param LookupModuleDeps This function is called to collect the full
- /// transitive set of dependencies for this
- /// compilation and fill in "-fmodule-map-file="
- /// arguments.
- std::vector<std::string> getCanonicalCommandLine(
- std::function<StringRef(ModuleID)> LookupPCMPath,
- std::function<const ModuleDeps &(ModuleID)> LookupModuleDeps) const;
-
- /// Gets the canonical command line suitable for passing to clang, excluding
- /// arguments containing modules-related paths: "-fmodule-file=", "-o",
- /// "-fmodule-map-file=".
- std::vector<std::string> getCanonicalCommandLineWithoutModulePaths() const;
+ std::variant<std::monostate, CowCompilerInvocation, std::vector<std::string>>
+ BuildInfo;
};
-namespace detail {
-/// Collect the paths of PCM and module map files for the modules in \c Modules
-/// transitively.
-void collectPCMAndModuleMapPaths(
- llvm::ArrayRef<ModuleID> Modules,
- std::function<StringRef(ModuleID)> LookupPCMPath,
- std::function<const ModuleDeps &(ModuleID)> LookupModuleDeps,
- std::vector<std::string> &PCMPaths, std::vector<std::string> &ModMapPaths);
-} // namespace detail
-
class ModuleDepCollector;
/// Callback that records textual includes and direct modular includes/imports
@@ -142,17 +157,16 @@ class ModuleDepCollector;
/// \c DependencyConsumer of the parent \c ModuleDepCollector.
class ModuleDepCollectorPP final : public PPCallbacks {
public:
- ModuleDepCollectorPP(CompilerInstance &I, ModuleDepCollector &MDC)
- : Instance(I), MDC(MDC) {}
+ ModuleDepCollectorPP(ModuleDepCollector &MDC) : MDC(MDC) {}
- void FileChanged(SourceLocation Loc, FileChangeReason Reason,
- SrcMgr::CharacteristicKind FileType,
- FileID PrevFID) override;
+ void LexedFileChanged(FileID FID, LexedFileChangeReason Reason,
+ SrcMgr::CharacteristicKind FileType, FileID PrevFID,
+ SourceLocation Loc) override;
void InclusionDirective(SourceLocation HashLoc, const Token &IncludeTok,
StringRef FileName, bool IsAngled,
- CharSourceRange FilenameRange, const FileEntry *File,
- StringRef SearchPath, StringRef RelativePath,
- const Module *Imported,
+ CharSourceRange FilenameRange,
+ OptionalFileEntryRef File, StringRef SearchPath,
+ StringRef RelativePath, const Module *Imported,
SrcMgr::CharacteristicKind FileType) override;
void moduleImport(SourceLocation ImportLoc, ModuleIdPath Path,
const Module *Imported) override;
@@ -160,29 +174,35 @@ public:
void EndOfMainFile() override;
private:
- /// The compiler instance for the current translation unit.
- CompilerInstance &Instance;
/// The parent dependency collector.
ModuleDepCollector &MDC;
- /// Working set of direct modular dependencies.
- llvm::DenseSet<const Module *> DirectModularDeps;
- /// Working set of direct modular dependencies that have already been built.
- llvm::DenseSet<const Module *> DirectPrebuiltModularDeps;
void handleImport(const Module *Imported);
/// Adds direct modular dependencies that have already been built to the
/// ModuleDeps instance.
- void addDirectPrebuiltModuleDeps(const Module *M, ModuleDeps &MD);
+ void
+ addAllSubmodulePrebuiltDeps(const Module *M, ModuleDeps &MD,
+ llvm::DenseSet<const Module *> &SeenSubmodules);
+ void addModulePrebuiltDeps(const Module *M, ModuleDeps &MD,
+ llvm::DenseSet<const Module *> &SeenSubmodules);
/// Traverses the previously collected direct modular dependencies to discover
/// transitive modular dependencies and fills the parent \c ModuleDepCollector
/// with both.
- ModuleID handleTopLevelModule(const Module *M);
+ /// Returns the ID or nothing if the dependency is spurious and is ignored.
+ std::optional<ModuleID> handleTopLevelModule(const Module *M);
void addAllSubmoduleDeps(const Module *M, ModuleDeps &MD,
llvm::DenseSet<const Module *> &AddedModules);
void addModuleDep(const Module *M, ModuleDeps &MD,
llvm::DenseSet<const Module *> &AddedModules);
+
+ /// Traverses the affecting modules and updates \c MD with references to the
+ /// parent \c ModuleDepCollector info.
+ void addAllAffectingClangModules(const Module *M, ModuleDeps &MD,
+ llvm::DenseSet<const Module *> &AddedModules);
+ void addAffectingClangModule(const Module *M, ModuleDeps &MD,
+ llvm::DenseSet<const Module *> &AddedModules);
};
/// Collects modular and non-modular dependencies of the main file by attaching
@@ -190,19 +210,28 @@ private:
class ModuleDepCollector final : public DependencyCollector {
public:
ModuleDepCollector(std::unique_ptr<DependencyOutputOptions> Opts,
- CompilerInstance &I, DependencyConsumer &C,
- CompilerInvocation &&OriginalCI);
+ CompilerInstance &ScanInstance, DependencyConsumer &C,
+ DependencyActionController &Controller,
+ CompilerInvocation OriginalCI,
+ ScanningOptimizations OptimizeArgs, bool EagerLoadModules,
+ bool IsStdModuleP1689Format);
void attachToPreprocessor(Preprocessor &PP) override;
void attachToASTReader(ASTReader &R) override;
+ /// Apply any changes implied by the discovered dependencies to the given
+ /// invocation, (e.g. disable implicit modules, add explicit module paths).
+ void applyDiscoveredDependencies(CompilerInvocation &CI);
+
private:
friend ModuleDepCollectorPP;
- /// The compiler instance for the current translation unit.
- CompilerInstance &Instance;
+ /// The compiler instance for scanning the current translation unit.
+ CompilerInstance &ScanInstance;
/// The consumer of collected dependency information.
DependencyConsumer &Consumer;
+ /// Callbacks for computing dependency information.
+ DependencyActionController &Controller;
/// Path to the main source file.
std::string MainFile;
/// Hash identifying the compilation conditions of the current TU.
@@ -211,24 +240,88 @@ private:
/// textually included header files.
std::vector<std::string> FileDeps;
/// Direct and transitive modular dependencies of the main source file.
- std::unordered_map<const Module *, ModuleDeps> ModularDeps;
+ llvm::MapVector<const Module *, std::unique_ptr<ModuleDeps>> ModularDeps;
+ /// Secondary mapping for \c ModularDeps allowing lookup by ModuleID without
+ /// a preprocessor. Storage owned by \c ModularDeps.
+ llvm::DenseMap<ModuleID, ModuleDeps *> ModuleDepsByID;
+ /// Direct modular dependencies that have already been built.
+ llvm::MapVector<const Module *, PrebuiltModuleDep> DirectPrebuiltModularDeps;
+ /// Working set of direct modular dependencies.
+ llvm::SetVector<const Module *> DirectModularDeps;
/// Options that control the dependency output generation.
std::unique_ptr<DependencyOutputOptions> Opts;
- /// The original Clang invocation passed to dependency scanner.
- CompilerInvocation OriginalInvocation;
+ /// A Clang invocation that's based on the original TU invocation and that has
+ /// been partially transformed into one that can perform explicit build of
+ /// a discovered modular dependency. Note that this still needs to be adjusted
+ /// for each individual module.
+ CowCompilerInvocation CommonInvocation;
+ /// Whether to optimize the modules' command-line arguments.
+ ScanningOptimizations OptimizeArgs;
+ /// Whether to set up command-lines to load PCM files eagerly.
+ bool EagerLoadModules;
+ /// If we're generating dependency output in P1689 format
+ /// for standard C++ modules.
+ bool IsStdModuleP1689Format;
+
+ std::optional<P1689ModuleInfo> ProvidedStdCXXModule;
+ std::vector<P1689ModuleInfo> RequiredStdCXXModules;
/// Checks whether the module is known as being prebuilt.
bool isPrebuiltModule(const Module *M);
- /// Constructs a CompilerInvocation that can be used to build the given
- /// module, excluding paths to discovered modular dependencies that are yet to
- /// be built.
- CompilerInvocation
- makeInvocationForModuleBuildWithoutPaths(const ModuleDeps &Deps) const;
+ /// Adds \p Path to \c FileDeps, making it absolute if necessary.
+ void addFileDep(StringRef Path);
+ /// Adds \p Path to \c MD.FileDeps, making it absolute if necessary.
+ void addFileDep(ModuleDeps &MD, StringRef Path);
+
+ /// Get a Clang invocation adjusted to build the given modular dependency.
+ /// This excludes paths that are yet-to-be-provided by the build system.
+ CowCompilerInvocation getInvocationAdjustedForModuleBuildWithoutOutputs(
+ const ModuleDeps &Deps,
+ llvm::function_ref<void(CowCompilerInvocation &)> Optimize) const;
+
+ /// Collect module map files for given modules.
+ llvm::DenseSet<const FileEntry *>
+ collectModuleMapFiles(ArrayRef<ModuleID> ClangModuleDeps) const;
+
+ /// Add module map files to the invocation, if needed.
+ void addModuleMapFiles(CompilerInvocation &CI,
+ ArrayRef<ModuleID> ClangModuleDeps) const;
+ /// Add module files (pcm) to the invocation, if needed.
+ void addModuleFiles(CompilerInvocation &CI,
+ ArrayRef<ModuleID> ClangModuleDeps) const;
+ void addModuleFiles(CowCompilerInvocation &CI,
+ ArrayRef<ModuleID> ClangModuleDeps) const;
+
+ /// Add paths that require looking up outputs to the given dependencies.
+ void addOutputPaths(CowCompilerInvocation &CI, ModuleDeps &Deps);
+
+ /// Compute the context hash for \p Deps, and create the mapping
+ /// \c ModuleDepsByID[Deps.ID] = &Deps.
+ void associateWithContextHash(const CowCompilerInvocation &CI,
+ ModuleDeps &Deps);
};
} // end namespace dependencies
} // end namespace tooling
} // end namespace clang
-#endif // LLVM_CLANG_TOOLING_DEPENDENCY_SCANNING_MODULE_DEP_COLLECTOR_H
+namespace llvm {
+inline hash_code hash_value(const clang::tooling::dependencies::ModuleID &ID) {
+ return hash_combine(ID.ModuleName, ID.ContextHash);
+}
+
+template <> struct DenseMapInfo<clang::tooling::dependencies::ModuleID> {
+ using ModuleID = clang::tooling::dependencies::ModuleID;
+ static inline ModuleID getEmptyKey() { return ModuleID{"", ""}; }
+ static inline ModuleID getTombstoneKey() {
+ return ModuleID{"~", "~"}; // ~ is not a valid module name or context hash
+ }
+ static unsigned getHashValue(const ModuleID &ID) { return hash_value(ID); }
+ static bool isEqual(const ModuleID &LHS, const ModuleID &RHS) {
+ return LHS == RHS;
+ }
+};
+} // namespace llvm
+
+#endif // LLVM_CLANG_TOOLING_DEPENDENCYSCANNING_MODULEDEPCOLLECTOR_H
diff --git a/contrib/llvm-project/clang/include/clang/Tooling/DiagnosticsYaml.h b/contrib/llvm-project/clang/include/clang/Tooling/DiagnosticsYaml.h
index 3f257d84f813..88f81e1f6299 100644
--- a/contrib/llvm-project/clang/include/clang/Tooling/DiagnosticsYaml.h
+++ b/contrib/llvm-project/clang/include/clang/Tooling/DiagnosticsYaml.h
@@ -42,8 +42,7 @@ template <> struct MappingTraits<clang::tooling::DiagnosticMessage> {
Io.mapOptional("FileOffset", M.FileOffset);
std::vector<clang::tooling::Replacement> Fixes;
for (auto &Replacements : M.Fix) {
- for (auto &Replacement : Replacements.second)
- Fixes.push_back(Replacement);
+ llvm::append_range(Fixes, Replacements.second);
}
Io.mapRequired("Replacements", Fixes);
for (auto &Fix : Fixes) {
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/Inclusions/HeaderAnalysis.h b/contrib/llvm-project/clang/include/clang/Tooling/Inclusions/HeaderAnalysis.h
new file mode 100644
index 000000000000..34ec2d80d06a
--- /dev/null
+++ b/contrib/llvm-project/clang/include/clang/Tooling/Inclusions/HeaderAnalysis.h
@@ -0,0 +1,46 @@
+//===--- HeaderAnalysis.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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TOOLING_INCLUSIONS_HEADER_ANALYSIS_H
+#define LLVM_CLANG_TOOLING_INCLUSIONS_HEADER_ANALYSIS_H
+
+#include "clang/Basic/FileEntry.h"
+#include "llvm/ADT/StringRef.h"
+#include <optional>
+
+namespace clang {
+class SourceManager;
+class HeaderSearch;
+
+namespace tooling {
+
+/// Returns true if the given physical file is a self-contained header.
+///
+/// A header is considered self-contained if
+// - it has a proper header guard or has been #imported or contains #import(s)
+// - *and* it doesn't have a dont-include-me pattern.
+///
+/// This function can be expensive as it may scan the source code to find out
+/// dont-include-me pattern heuristically.
+bool isSelfContainedHeader(FileEntryRef FE, const SourceManager &SM,
+ const HeaderSearch &HeaderInfo);
+
+/// This scans the given source code to see if it contains #import(s).
+bool codeContainsImports(llvm::StringRef Code);
+
+/// If Text begins an Include-What-You-Use directive, returns it.
+/// Given "// IWYU pragma: keep", returns "keep".
+/// Input is a null-terminated char* as provided by SM.getCharacterData().
+/// (This should not be StringRef as we do *not* want to scan for its length).
+/// For multi-line comments, we return only the first line.
+std::optional<llvm::StringRef> parseIWYUPragma(const char *Text);
+
+} // namespace tooling
+} // namespace clang
+
+#endif // LLVM_CLANG_TOOLING_INCLUSIONS_HEADER_ANALYSIS_H
diff --git a/contrib/llvm-project/clang/include/clang/Tooling/Inclusions/HeaderIncludes.h b/contrib/llvm-project/clang/include/clang/Tooling/Inclusions/HeaderIncludes.h
index 02fb2875671a..d5439dd2c84e 100644
--- a/contrib/llvm-project/clang/include/clang/Tooling/Inclusions/HeaderIncludes.h
+++ b/contrib/llvm-project/clang/include/clang/Tooling/Inclusions/HeaderIncludes.h
@@ -14,6 +14,8 @@
#include "clang/Tooling/Inclusions/IncludeStyle.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/Regex.h"
+#include <list>
+#include <optional>
#include <unordered_map>
namespace clang {
@@ -43,6 +45,8 @@ private:
SmallVector<llvm::Regex, 4> CategoryRegexs;
};
+enum class IncludeDirective { Include, Import };
+
/// Generates replacements for inserting or deleting #include directives in a
/// file.
class HeaderIncludes {
@@ -50,9 +54,9 @@ public:
HeaderIncludes(llvm::StringRef FileName, llvm::StringRef Code,
const IncludeStyle &Style);
- /// Inserts an #include directive of \p Header into the code. If \p IsAngled
- /// is true, \p Header will be quoted with <> in the directive; otherwise, it
- /// will be quoted with "".
+ /// Inserts an #include or #import directive of \p Header into the code.
+ /// If \p IsAngled is true, \p Header will be quoted with <> in the directive;
+ /// otherwise, it will be quoted with "".
///
/// When searching for points to insert new header, this ignores #include's
/// after the #include block(s) in the beginning of a file to avoid inserting
@@ -68,25 +72,32 @@ public:
/// this will simply insert the #include in front of the first #include of the
/// same category in the code that should be sorted after \p IncludeName. If
/// \p IncludeName already exists (with exactly the same spelling), this
- /// returns None.
- llvm::Optional<tooling::Replacement> insert(llvm::StringRef Header,
- bool IsAngled) const;
-
- /// Removes all existing #includes of \p Header quoted with <> if \p IsAngled
- /// is true or "" if \p IsAngled is false.
- /// This doesn't resolve the header file path; it only deletes #includes with
- /// exactly the same spelling.
+ /// returns std::nullopt.
+ std::optional<tooling::Replacement> insert(llvm::StringRef Header,
+ bool IsAngled,
+ IncludeDirective Directive) const;
+
+ /// Removes all existing #includes and #imports of \p Header quoted with <> if
+ /// \p IsAngled is true or "" if \p IsAngled is false.
+ /// This doesn't resolve the header file path; it only deletes #includes and
+ /// #imports with exactly the same spelling.
tooling::Replacements remove(llvm::StringRef Header, bool IsAngled) const;
+ // Matches a whole #include directive.
+ static const llvm::Regex IncludeRegex;
+
private:
struct Include {
- Include(StringRef Name, tooling::Range R) : Name(Name), R(R) {}
+ Include(StringRef Name, tooling::Range R, IncludeDirective D)
+ : Name(Name), R(R), Directive(D) {}
// An include header quoted with either <> or "".
std::string Name;
- // The range of the whole line of include directive including any eading
+ // The range of the whole line of include directive including any leading
// whitespaces and trailing comment.
tooling::Range R;
+ // Either #include or #import.
+ IncludeDirective Directive;
};
void addExistingInclude(Include IncludeToAdd, unsigned NextLineOffset);
@@ -97,7 +108,8 @@ private:
// Map from include name (quotation trimmed) to a list of existing includes
// (in case there are more than one) with the name in the current file. <x>
// and "x" will be treated as the same header when deleting #includes.
- llvm::StringMap<llvm::SmallVector<Include, 1>> ExistingIncludes;
+ // std::list is used for pointers stability (see IncludesByPriority)
+ llvm::StringMap<std::list<Include>> ExistingIncludes;
/// Map from priorities of #include categories to all #includes in the same
/// category. This is used to find #includes of the same category when
@@ -116,18 +128,16 @@ private:
// inserting new #includes into the actual code section (e.g. after a
// declaration).
unsigned MaxInsertOffset;
+ // True if we find the main-file header in the Code.
+ bool MainIncludeFound;
IncludeCategoryManager Categories;
// Record the offset of the end of the last include in each category.
std::unordered_map<int, int> CategoryEndOffsets;
// All possible priorities.
std::set<int> Priorities;
-
- // Matches a whole #include directive.
- llvm::Regex IncludeRegex;
};
-
} // namespace tooling
} // namespace clang
diff --git a/contrib/llvm-project/clang/include/clang/Tooling/Inclusions/IncludeStyle.h b/contrib/llvm-project/clang/include/clang/Tooling/Inclusions/IncludeStyle.h
index 4caaf4121f15..d6b2b0192477 100644
--- a/contrib/llvm-project/clang/include/clang/Tooling/Inclusions/IncludeStyle.h
+++ b/contrib/llvm-project/clang/include/clang/Tooling/Inclusions/IncludeStyle.h
@@ -50,6 +50,7 @@ struct IncludeStyle {
/// Dependent on the value, multiple ``#include`` blocks can be sorted
/// as one and divided based on category.
+ /// \version 6
IncludeBlocksStyle IncludeBlocks;
/// See documentation of ``IncludeCategories``.
@@ -105,7 +106,7 @@ struct IncludeStyle {
/// Priority: 2
/// SortPriority: 2
/// CaseSensitive: true
- /// - Regex: '^(<|"(gtest|gmock|isl|json)/)'
+ /// - Regex: '^((<|")(gtest|gmock|isl|json)/)'
/// Priority: 3
/// - Regex: '<[[:alnum:].]+>'
/// Priority: 4
@@ -113,6 +114,7 @@ struct IncludeStyle {
/// Priority: 1
/// SortPriority: 0
/// \endcode
+ /// \version 3.8
std::vector<IncludeCategory> IncludeCategories;
/// Specify a regular expression of suffixes that are allowed in the
@@ -126,6 +128,7 @@ struct IncludeStyle {
///
/// For example, if configured to "(_test)?$", then a header a.h would be seen
/// as the "main" include in both a.cc and a_test.cc.
+ /// \version 3.9
std::string IncludeIsMainRegex;
/// Specify a regular expression for files being formatted
@@ -146,6 +149,7 @@ struct IncludeStyle {
/// also being respected in later phase). Without this option set,
/// ``ClassImpl.hpp`` would not have the main include file put on top
/// before any other include.
+ /// \version 10
std::string IncludeIsMainSourceRegex;
};
diff --git a/contrib/llvm-project/clang/include/clang/Tooling/Inclusions/StandardLibrary.h b/contrib/llvm-project/clang/include/clang/Tooling/Inclusions/StandardLibrary.h
new file mode 100644
index 000000000000..a39ceb520dcf
--- /dev/null
+++ b/contrib/llvm-project/clang/include/clang/Tooling/Inclusions/StandardLibrary.h
@@ -0,0 +1,158 @@
+//===--- StandardLibrary.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
+/// Provides an interface for querying information about C and C++ Standard
+/// Library headers and symbols.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TOOLING_INCLUSIONS_STANDARDLIBRARY_H
+#define LLVM_CLANG_TOOLING_INCLUSIONS_STANDARDLIBRARY_H
+
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/Hashing.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/raw_ostream.h"
+#include <optional>
+#include <string>
+
+namespace clang {
+class Decl;
+class NamespaceDecl;
+class DeclContext;
+namespace tooling {
+namespace stdlib {
+
+class Symbol;
+enum class Lang { C = 0, CXX, LastValue = CXX };
+
+// A standard library header, such as <iostream>
+// Lightweight class, in fact just an index into a table.
+// C++ and C Library compatibility headers are considered different: e.g.
+// "<cstdio>" and "<stdio.h>" (and their symbols) are treated differently.
+class Header {
+public:
+ static std::vector<Header> all(Lang L = Lang::CXX);
+ // Name should contain the angle brackets, e.g. "<vector>".
+ static std::optional<Header> named(llvm::StringRef Name,
+ Lang Language = Lang::CXX);
+
+ friend llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const Header &H) {
+ return OS << H.name();
+ }
+ llvm::StringRef name() const;
+
+private:
+ Header(unsigned ID, Lang Language) : ID(ID), Language(Language) {}
+ unsigned ID;
+ Lang Language;
+
+ friend Symbol;
+ friend llvm::DenseMapInfo<Header>;
+ friend bool operator==(const Header &L, const Header &R) {
+ return L.ID == R.ID;
+ }
+};
+
+// A top-level standard library symbol, such as std::vector
+// Lightweight class, in fact just an index into a table.
+// C++ and C Standard Library symbols are considered distinct: e.g. std::printf
+// and ::printf are not treated as the same symbol.
+// The symbols do not contain macros right now, we don't have a reliable index
+// for them.
+class Symbol {
+public:
+ static std::vector<Symbol> all(Lang L = Lang::CXX);
+ /// \p Scope should have the trailing "::", for example:
+ /// named("std::chrono::", "system_clock")
+ static std::optional<Symbol>
+ named(llvm::StringRef Scope, llvm::StringRef Name, Lang Language = Lang::CXX);
+
+ friend llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const Symbol &S) {
+ return OS << S.qualifiedName();
+ }
+ llvm::StringRef scope() const;
+ llvm::StringRef name() const;
+ llvm::StringRef qualifiedName() const;
+ // The preferred header for this symbol (e.g. the suggested insertion).
+ std::optional<Header> header() const;
+ // Some symbols may be provided by multiple headers.
+ llvm::SmallVector<Header> headers() const;
+
+private:
+ Symbol(unsigned ID, Lang Language) : ID(ID), Language(Language) {}
+ unsigned ID;
+ Lang Language;
+
+ friend class Recognizer;
+ friend llvm::DenseMapInfo<Symbol>;
+ friend bool operator==(const Symbol &L, const Symbol &R) {
+ return L.ID == R.ID;
+ }
+};
+
+// A functor to find the stdlib::Symbol associated with a decl.
+//
+// For non-top-level decls (std::vector<int>::iterator), returns the top-level
+// symbol (std::vector).
+class Recognizer {
+public:
+ Recognizer();
+ std::optional<Symbol> operator()(const Decl *D);
+
+private:
+ using NSSymbolMap = llvm::DenseMap<llvm::StringRef, unsigned>;
+ NSSymbolMap *namespaceSymbols(const DeclContext *DC, Lang L);
+ llvm::DenseMap<const DeclContext *, NSSymbolMap *> NamespaceCache;
+};
+
+} // namespace stdlib
+} // namespace tooling
+} // namespace clang
+
+namespace llvm {
+
+template <> struct DenseMapInfo<clang::tooling::stdlib::Header> {
+ static inline clang::tooling::stdlib::Header getEmptyKey() {
+ return clang::tooling::stdlib::Header(-1,
+ clang::tooling::stdlib::Lang::CXX);
+ }
+ static inline clang::tooling::stdlib::Header getTombstoneKey() {
+ return clang::tooling::stdlib::Header(-2,
+ clang::tooling::stdlib::Lang::CXX);
+ }
+ static unsigned getHashValue(const clang::tooling::stdlib::Header &H) {
+ return hash_value(H.ID);
+ }
+ static bool isEqual(const clang::tooling::stdlib::Header &LHS,
+ const clang::tooling::stdlib::Header &RHS) {
+ return LHS == RHS;
+ }
+};
+
+template <> struct DenseMapInfo<clang::tooling::stdlib::Symbol> {
+ static inline clang::tooling::stdlib::Symbol getEmptyKey() {
+ return clang::tooling::stdlib::Symbol(-1,
+ clang::tooling::stdlib::Lang::CXX);
+ }
+ static inline clang::tooling::stdlib::Symbol getTombstoneKey() {
+ return clang::tooling::stdlib::Symbol(-2,
+ clang::tooling::stdlib::Lang::CXX);
+ }
+ static unsigned getHashValue(const clang::tooling::stdlib::Symbol &S) {
+ return hash_value(S.ID);
+ }
+ static bool isEqual(const clang::tooling::stdlib::Symbol &LHS,
+ const clang::tooling::stdlib::Symbol &RHS) {
+ return LHS == RHS;
+ }
+};
+} // namespace llvm
+
+#endif // LLVM_CLANG_TOOLING_INCLUSIONS_STANDARDLIBRARY_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..009437fde03f 100644
--- a/contrib/llvm-project/clang/include/clang/Tooling/Refactoring/ASTSelection.h
+++ b/contrib/llvm-project/clang/include/clang/Tooling/Refactoring/ASTSelection.h
@@ -6,14 +6,15 @@
//
//===----------------------------------------------------------------------===//
-#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"
#include "clang/Basic/LLVM.h"
#include "clang/Basic/SourceLocation.h"
#include "llvm/Support/raw_ostream.h"
+#include <optional>
#include <vector>
namespace clang {
@@ -65,10 +66,10 @@ struct SelectedASTNode {
/// Traverses the given ASTContext and creates a tree of selected AST nodes.
///
-/// \returns None if no nodes are selected in the AST, or a selected AST node
-/// that corresponds to the TranslationUnitDecl otherwise.
-Optional<SelectedASTNode> findSelectedASTNodes(const ASTContext &Context,
- SourceRange SelectionRange);
+/// \returns std::nullopt if no nodes are selected in the AST, or a selected AST
+/// node that corresponds to the TranslationUnitDecl otherwise.
+std::optional<SelectedASTNode> findSelectedASTNodes(const ASTContext &Context,
+ SourceRange SelectionRange);
/// An AST selection value that corresponds to a selection of a set of
/// statements that belong to one body of code (like one function).
@@ -130,7 +131,7 @@ public:
/// declaration doesn't exist.
const Decl *getFunctionLikeNearestParent() const;
- static Optional<CodeRangeASTSelection>
+ static std::optional<CodeRangeASTSelection>
create(SourceRange SelectionRange, const SelectedASTNode &ASTSelection);
private:
@@ -152,4 +153,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..92f322ef7d80 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"
@@ -116,6 +116,8 @@ public:
/// Returns a const reference to existing replacements.
const Replacements &getReplacements() const { return Replaces; }
+ Replacements &getReplacements() { return Replaces; }
+
llvm::ArrayRef<std::string> getInsertedHeaders() const {
return InsertedHeaders;
}
@@ -187,4 +189,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..695ca3879c10 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,11 +6,12 @@
//
//===----------------------------------------------------------------------===//
-#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"
+#include <optional>
namespace clang {
namespace tooling {
@@ -22,16 +23,17 @@ public:
/// Initiates the extract function refactoring operation.
///
/// \param Code The selected set of statements.
- /// \param DeclName The name name of the extract function. If None,
+ /// \param DeclName The name of the extract function. If None,
/// "extracted" is used.
- static Expected<ExtractFunction> initiate(RefactoringRuleContext &Context,
- CodeRangeASTSelection Code,
- Optional<std::string> DeclName);
+ static Expected<ExtractFunction>
+ initiate(RefactoringRuleContext &Context, CodeRangeASTSelection Code,
+ std::optional<std::string> DeclName);
static const RefactoringDescriptor &describe();
private:
- ExtractFunction(CodeRangeASTSelection Code, Optional<std::string> DeclName)
+ ExtractFunction(CodeRangeASTSelection Code,
+ std::optional<std::string> DeclName)
: Code(std::move(Code)),
DeclName(DeclName ? std::move(*DeclName) : "extracted") {}
@@ -49,4 +51,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..015dbba26f68 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"
@@ -124,10 +124,11 @@ public:
bool VisitDesignatedInitExpr(const DesignatedInitExpr *E) {
for (const DesignatedInitExpr::Designator &D : E->designators()) {
- if (D.isFieldDesignator() && D.getField()) {
- const FieldDecl *Decl = D.getField();
- if (!visit(Decl, D.getFieldLoc(), D.getFieldLoc()))
- return false;
+ if (D.isFieldDesignator()) {
+ if (const FieldDecl *Decl = D.getFieldDecl()) {
+ if (!visit(Decl, D.getFieldLoc(), D.getFieldLoc()))
+ return false;
+ }
}
}
return true;
@@ -150,4 +151,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..c6a6c4f6093a 100644
--- a/contrib/llvm-project/clang/include/clang/Tooling/Refactoring/RefactoringActionRule.h
+++ b/contrib/llvm-project/clang/include/clang/Tooling/Refactoring/RefactoringActionRule.h
@@ -6,11 +6,10 @@
//
//===----------------------------------------------------------------------===//
-#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"
#include "llvm/ADT/StringRef.h"
namespace clang {
@@ -69,4 +68,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..1a318da3acca 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"
@@ -98,7 +98,7 @@ public:
OptionRequirement() : Opt(createRefactoringOption<OptionType>()) {}
ArrayRef<std::shared_ptr<RefactoringOption>>
- getRefactoringOptions() const final override {
+ getRefactoringOptions() const final {
return Opt;
}
@@ -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..5cb051d53433 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"
@@ -52,7 +52,7 @@ using RefactoringActionRules =
class SourceChangeRefactoringRule : public RefactoringActionRuleBase {
public:
void invoke(RefactoringResultConsumer &Consumer,
- RefactoringRuleContext &Context) final override {
+ RefactoringRuleContext &Context) final {
Expected<AtomicChanges> Changes = createSourceReplacements(Context);
if (!Changes)
Consumer.handleError(Changes.takeError());
@@ -74,7 +74,7 @@ private:
class FindSymbolOccurrencesRefactoringRule : public RefactoringActionRuleBase {
public:
void invoke(RefactoringResultConsumer &Consumer,
- RefactoringRuleContext &Context) final override {
+ RefactoringRuleContext &Context) final {
Expected<SymbolOccurrences> Occurrences = findSymbolOccurrences(Context);
if (!Occurrences)
Consumer.handleError(Occurrences.takeError());
@@ -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..33194c401ea1 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"
@@ -94,9 +94,9 @@ void visitRefactoringOptions(
/// A type trait that returns true when the given type list has at least one
/// type whose base is the given base type.
template <typename Base, typename First, typename... Rest>
-struct HasBaseOf : std::conditional<HasBaseOf<Base, First>::value ||
- HasBaseOf<Base, Rest...>::value,
- std::true_type, std::false_type>::type {};
+struct HasBaseOf : std::conditional_t<HasBaseOf<Base, First>::value ||
+ HasBaseOf<Base, Rest...>::value,
+ std::true_type, std::false_type> {};
template <typename Base, typename T>
struct HasBaseOf<Base, T> : std::is_base_of<Base, T> {};
@@ -104,9 +104,9 @@ struct HasBaseOf<Base, T> : std::is_base_of<Base, T> {};
/// A type trait that returns true when the given type list contains types that
/// derive from Base.
template <typename Base, typename First, typename... Rest>
-struct AreBaseOf : std::conditional<AreBaseOf<Base, First>::value &&
- AreBaseOf<Base, Rest...>::value,
- std::true_type, std::false_type>::type {};
+struct AreBaseOf : std::conditional_t<AreBaseOf<Base, First>::value &&
+ AreBaseOf<Base, Rest...>::value,
+ std::true_type, std::false_type> {};
template <typename Base, typename T>
struct AreBaseOf<Base, T> : std::is_base_of<Base, T> {};
@@ -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..3234b0976a8e 100644
--- a/contrib/llvm-project/clang/include/clang/Tooling/Refactoring/RefactoringOptionVisitor.h
+++ b/contrib/llvm-project/clang/include/clang/Tooling/Refactoring/RefactoringOptionVisitor.h
@@ -6,10 +6,11 @@
//
//===----------------------------------------------------------------------===//
-#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 <optional>
#include <type_traits>
namespace clang {
@@ -27,7 +28,7 @@ public:
virtual ~RefactoringOptionVisitor() {}
virtual void visit(const RefactoringOption &Opt,
- Optional<std::string> &Value) = 0;
+ std::optional<std::string> &Value) = 0;
};
namespace traits {
@@ -38,7 +39,8 @@ private:
template <typename ClassT>
static auto check(ClassT *) -> typename std::is_same<
decltype(std::declval<RefactoringOptionVisitor>().visit(
- std::declval<RefactoringOption>(), *std::declval<Optional<T> *>())),
+ std::declval<RefactoringOption>(),
+ *std::declval<std::optional<T> *>())),
void>::type;
template <typename> static std::false_type check(...);
@@ -58,4 +60,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..62c01e75b1c7 100644
--- a/contrib/llvm-project/clang/include/clang/Tooling/Refactoring/RefactoringOptions.h
+++ b/contrib/llvm-project/clang/include/clang/Tooling/Refactoring/RefactoringOptions.h
@@ -6,14 +6,15 @@
//
//===----------------------------------------------------------------------===//
-#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"
#include "clang/Tooling/Refactoring/RefactoringOption.h"
#include "clang/Tooling/Refactoring/RefactoringOptionVisitor.h"
#include "llvm/Support/Error.h"
+#include <optional>
#include <type_traits>
namespace clang {
@@ -24,18 +25,18 @@ template <typename T,
typename = std::enable_if_t<traits::IsValidOptionType<T>::value>>
class OptionalRefactoringOption : public RefactoringOption {
public:
- void passToVisitor(RefactoringOptionVisitor &Visitor) final override {
+ void passToVisitor(RefactoringOptionVisitor &Visitor) final {
Visitor.visit(*this, Value);
}
bool isRequired() const override { return false; }
- using ValueType = Optional<T>;
+ using ValueType = std::optional<T>;
const ValueType &getValue() const { return Value; }
protected:
- Optional<T> Value;
+ std::optional<T> Value;
};
/// A required refactoring option that stores a value of type \c T.
@@ -48,10 +49,10 @@ public:
const ValueType &getValue() const {
return *OptionalRefactoringOption<T>::Value;
}
- bool isRequired() const final override { return true; }
+ bool isRequired() const final { return true; }
};
} // 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..aff965edb07c 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"
@@ -70,7 +70,7 @@ public:
ArrayRef<SourceRange> getNameRanges() const {
if (MultipleRanges)
- return llvm::makeArrayRef(MultipleRanges.get(), NumRanges);
+ return llvm::ArrayRef(MultipleRanges.get(), NumRanges);
return SingleRange;
}
@@ -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/StandaloneExecution.h b/contrib/llvm-project/clang/include/clang/Tooling/StandaloneExecution.h
index 8db6229acf7f..cdbe65a95b9d 100644
--- a/contrib/llvm-project/clang/include/clang/Tooling/StandaloneExecution.h
+++ b/contrib/llvm-project/clang/include/clang/Tooling/StandaloneExecution.h
@@ -15,6 +15,7 @@
#include "clang/Tooling/ArgumentsAdjusters.h"
#include "clang/Tooling/Execution.h"
+#include <optional>
namespace clang {
namespace tooling {
@@ -83,7 +84,7 @@ public:
private:
// Used to store the parser when the executor is initialized with parser.
- llvm::Optional<CommonOptionsParser> OptionsParser;
+ std::optional<CommonOptionsParser> OptionsParser;
// FIXME: The standalone executor is currently just a wrapper of `ClangTool`.
// Merge `ClangTool` implementation into the this.
ClangTool Tool;
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..273d03ddc233 100644
--- a/contrib/llvm-project/clang/include/clang/Tooling/Syntax/BuildTree.h
+++ b/contrib/llvm-project/clang/include/clang/Tooling/Syntax/BuildTree.h
@@ -7,12 +7,13 @@
//===----------------------------------------------------------------------===//
// 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"
#include "clang/Tooling/Syntax/Nodes.h"
+#include "clang/Tooling/Syntax/TokenBufferTokenManager.h"
#include "clang/Tooling/Syntax/Tree.h"
namespace clang {
@@ -21,19 +22,21 @@ namespace syntax {
/// Build a syntax tree for the main file.
/// This usually covers the whole TranslationUnitDecl, but can be restricted by
/// the ASTContext's traversal scope.
-syntax::TranslationUnit *buildSyntaxTree(Arena &A, ASTContext &Context);
+syntax::TranslationUnit *
+buildSyntaxTree(Arena &A, TokenBufferTokenManager &TBTM, ASTContext &Context);
// Create syntax trees from subtrees not backed by the source code.
// Synthesis of Leafs
/// Create `Leaf` from token with `Spelling` and assert it has the desired
/// `TokenKind`.
-syntax::Leaf *createLeaf(syntax::Arena &A, tok::TokenKind K,
- StringRef Spelling);
+syntax::Leaf *createLeaf(syntax::Arena &A, TokenBufferTokenManager &TBTM,
+ tok::TokenKind K, StringRef Spelling);
/// Infer the token spelling from its `TokenKind`, then create `Leaf` from
/// this token
-syntax::Leaf *createLeaf(syntax::Arena &A, tok::TokenKind K);
+syntax::Leaf *createLeaf(syntax::Arena &A, TokenBufferTokenManager &TBTM,
+ tok::TokenKind K);
// Synthesis of Trees
/// Creates the concrete syntax node according to the specified `NodeKind` `K`.
@@ -44,7 +47,8 @@ createTree(syntax::Arena &A,
syntax::NodeKind K);
// Synthesis of Syntax Nodes
-syntax::EmptyStatement *createEmptyStatement(syntax::Arena &A);
+syntax::EmptyStatement *createEmptyStatement(syntax::Arena &A,
+ TokenBufferTokenManager &TBTM);
/// Creates a completely independent copy of `N` with its macros expanded.
///
@@ -52,7 +56,9 @@ syntax::EmptyStatement *createEmptyStatement(syntax::Arena &A);
/// * Detached, i.e. `Parent == NextSibling == nullptr` and
/// `Role == Detached`.
/// * Synthesized, i.e. `Original == false`.
-syntax::Node *deepCopyExpandingMacros(syntax::Arena &A, const syntax::Node *N);
+syntax::Node *deepCopyExpandingMacros(syntax::Arena &A,
+ TokenBufferTokenManager &TBTM,
+ const syntax::Node *N);
} // namespace syntax
} // namespace clang
#endif
diff --git a/contrib/llvm-project/clang/include/clang/Tooling/Syntax/Mutations.h b/contrib/llvm-project/clang/include/clang/Tooling/Syntax/Mutations.h
index 8fd58ae34fff..6db9c88ca000 100644
--- a/contrib/llvm-project/clang/include/clang/Tooling/Syntax/Mutations.h
+++ b/contrib/llvm-project/clang/include/clang/Tooling/Syntax/Mutations.h
@@ -13,6 +13,7 @@
#include "clang/Tooling/Core/Replacement.h"
#include "clang/Tooling/Syntax/Nodes.h"
+#include "clang/Tooling/Syntax/TokenBufferTokenManager.h"
#include "clang/Tooling/Syntax/Tree.h"
namespace clang {
@@ -20,7 +21,7 @@ namespace syntax {
/// Computes textual replacements required to mimic the tree modifications made
/// to the syntax tree.
-tooling::Replacements computeReplacements(const Arena &A,
+tooling::Replacements computeReplacements(const TokenBufferTokenManager &TBTM,
const syntax::TranslationUnit &TU);
/// Removes a statement or replaces it with an empty statement where one is
@@ -29,7 +30,8 @@ tooling::Replacements computeReplacements(const Arena &A,
/// One can remove `foo();` completely and to remove `bar();` we would need to
/// replace it with an empty statement.
/// EXPECTS: S->canModify() == true
-void removeStatement(syntax::Arena &A, syntax::Statement *S);
+void removeStatement(syntax::Arena &A, TokenBufferTokenManager &TBTM,
+ syntax::Statement *S);
} // namespace syntax
} // namespace clang
diff --git a/contrib/llvm-project/clang/include/clang/Tooling/Syntax/Nodes.h b/contrib/llvm-project/clang/include/clang/Tooling/Syntax/Nodes.h
index edb6d4d4381d..c4f31900d0ce 100644
--- a/contrib/llvm-project/clang/include/clang/Tooling/Syntax/Nodes.h
+++ b/contrib/llvm-project/clang/include/clang/Tooling/Syntax/Nodes.h
@@ -21,13 +21,8 @@
#ifndef LLVM_CLANG_TOOLING_SYNTAX_NODES_H
#define LLVM_CLANG_TOOLING_SYNTAX_NODES_H
-#include "clang/Basic/TokenKinds.h"
-#include "clang/Lex/Token.h"
-#include "clang/Tooling/Syntax/Tokens.h"
+#include "clang/Basic/LLVM.h"
#include "clang/Tooling/Syntax/Tree.h"
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/StringRef.h"
-#include "llvm/Support/raw_ostream.h"
namespace clang {
namespace syntax {
diff --git a/contrib/llvm-project/clang/include/clang/Tooling/Syntax/TokenBufferTokenManager.h b/contrib/llvm-project/clang/include/clang/Tooling/Syntax/TokenBufferTokenManager.h
new file mode 100644
index 000000000000..6522af584e9a
--- /dev/null
+++ b/contrib/llvm-project/clang/include/clang/Tooling/Syntax/TokenBufferTokenManager.h
@@ -0,0 +1,70 @@
+//===- TokenBufferTokenManager.h -----------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TOOLING_SYNTAX_TOKEN_BUFFER_TOKEN_MANAGER_H
+#define LLVM_CLANG_TOOLING_SYNTAX_TOKEN_BUFFER_TOKEN_MANAGER_H
+
+#include "clang/Tooling/Syntax/TokenManager.h"
+#include "clang/Tooling/Syntax/Tokens.h"
+
+namespace clang {
+namespace syntax {
+
+/// A TokenBuffer-powered token manager.
+/// It tracks the underlying token buffers, source manager, etc.
+class TokenBufferTokenManager : public TokenManager {
+public:
+ TokenBufferTokenManager(const TokenBuffer &Tokens,
+ const LangOptions &LangOpts, SourceManager &SourceMgr)
+ : Tokens(Tokens), LangOpts(LangOpts), SM(SourceMgr) {}
+
+ static bool classof(const TokenManager *N) { return N->kind() == Kind; }
+ llvm::StringLiteral kind() const override { return Kind; }
+
+ llvm::StringRef getText(Key I) const override {
+ const auto *Token = getToken(I);
+ assert(Token);
+ // Handle 'eof' separately, calling text() on it produces an empty string.
+ // FIXME: this special logic is for syntax::Leaf dump, move it when we
+ // have a direct way to retrive token kind in the syntax::Leaf.
+ if (Token->kind() == tok::eof)
+ return "<eof>";
+ return Token->text(SM);
+ }
+
+ const syntax::Token *getToken(Key I) const {
+ return reinterpret_cast<const syntax::Token *>(I);
+ }
+ SourceManager &sourceManager() { return SM; }
+ const SourceManager &sourceManager() const { return SM; }
+ const TokenBuffer &tokenBuffer() const { return Tokens; }
+
+private:
+ // This manager is powered by the TokenBuffer.
+ static constexpr llvm::StringLiteral Kind = "TokenBuffer";
+
+ /// Add \p Buffer to the underlying source manager, tokenize it and store the
+ /// resulting tokens. Used exclusively in `FactoryImpl` to materialize tokens
+ /// that were not written in user code.
+ std::pair<FileID, ArrayRef<Token>>
+ lexBuffer(std::unique_ptr<llvm::MemoryBuffer> Buffer);
+ friend class FactoryImpl;
+
+ const TokenBuffer &Tokens;
+ const LangOptions &LangOpts;
+
+ /// The underlying source manager for the ExtraTokens.
+ SourceManager &SM;
+ /// IDs and storage for additional tokenized files.
+ llvm::DenseMap<FileID, std::vector<Token>> ExtraTokens;
+};
+
+} // namespace syntax
+} // namespace clang
+
+#endif // LLVM_CLANG_TOOLING_SYNTAX_TOKEN_BUFFER_TOKEN_MANAGER_H
diff --git a/contrib/llvm-project/clang/include/clang/Tooling/Syntax/TokenManager.h b/contrib/llvm-project/clang/include/clang/Tooling/Syntax/TokenManager.h
new file mode 100644
index 000000000000..6f0d11ce0d6b
--- /dev/null
+++ b/contrib/llvm-project/clang/include/clang/Tooling/Syntax/TokenManager.h
@@ -0,0 +1,47 @@
+//===- TokenManager.h - Manage Tokens for syntax-tree ------------*- 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
+//
+//===----------------------------------------------------------------------===//
+//
+// Defines Token interfaces for the clang syntax-tree. This is the level of
+// abstraction that the syntax-tree uses to operate on Token.
+//
+// TokenManager decouples the syntax-tree from a particular token
+// implementation. For example, a TokenBuffer captured from a clang parser may
+// track macro expansions and associate tokens with clang's SourceManager, while
+// a clang pseudoparser would use a flat array of raw-lexed tokens in memory.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TOOLING_SYNTAX_TOKEN_MANAGER_H
+#define LLVM_CLANG_TOOLING_SYNTAX_TOKEN_MANAGER_H
+
+#include "llvm/ADT/StringRef.h"
+#include <cstdint>
+
+namespace clang {
+namespace syntax {
+
+/// Defines interfaces for operating "Token" in the clang syntax-tree.
+class TokenManager {
+public:
+ virtual ~TokenManager() = default;
+
+ /// Describes what the exact class kind of the TokenManager is.
+ virtual llvm::StringLiteral kind() const = 0;
+
+ /// A key to identify a specific token. The token concept depends on the
+ /// underlying implementation -- it can be a spelled token from the original
+ /// source file or an expanded token.
+ /// The syntax-tree Leaf node holds a Key.
+ using Key = uintptr_t;
+ virtual llvm::StringRef getText(Key K) const = 0;
+};
+
+} // namespace syntax
+} // namespace clang
+
+#endif // LLVM_CLANG_TOOLING_SYNTAX_TOKEN_MANAGER_H
diff --git a/contrib/llvm-project/clang/include/clang/Tooling/Syntax/Tokens.h b/contrib/llvm-project/clang/include/clang/Tooling/Syntax/Tokens.h
index e4bc1553c2d6..b1bdefed7c97 100644
--- a/contrib/llvm-project/clang/include/clang/Tooling/Syntax/Tokens.h
+++ b/contrib/llvm-project/clang/include/clang/Tooling/Syntax/Tokens.h
@@ -27,7 +27,6 @@
#ifndef LLVM_CLANG_TOOLING_SYNTAX_TOKENS_H
#define LLVM_CLANG_TOOLING_SYNTAX_TOKENS_H
-#include "clang/Basic/FileManager.h"
#include "clang/Basic/LangOptions.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Basic/SourceManager.h"
@@ -35,7 +34,6 @@
#include "clang/Lex/Token.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/Optional.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/raw_ostream.h"
@@ -205,7 +203,7 @@ public:
/// Returns the subrange of spelled tokens corresponding to AST node spanning
/// \p Expanded. This is the text that should be replaced if a refactoring
/// were to rewrite the node. If \p Expanded is empty, the returned value is
- /// llvm::None.
+ /// std::nullopt.
///
/// Will fail if the expanded tokens do not correspond to a sequence of
/// spelled tokens. E.g. for the following example:
@@ -230,7 +228,7 @@ public:
///
/// EXPECTS: \p Expanded is a subrange of expandedTokens().
/// Complexity is logarithmic.
- llvm::Optional<llvm::ArrayRef<syntax::Token>>
+ std::optional<llvm::ArrayRef<syntax::Token>>
spelledForExpanded(llvm::ArrayRef<syntax::Token> Expanded) const;
/// Find the subranges of expanded tokens, corresponding to \p Spelled.
@@ -279,7 +277,7 @@ public:
/// If \p Spelled starts a mapping (e.g. if it's a macro name or '#' starting
/// a preprocessor directive) return the subrange of expanded tokens that the
/// macro expands to.
- llvm::Optional<Expansion>
+ std::optional<Expansion>
expansionStartingAt(const syntax::Token *Spelled) const;
/// Returns all expansions (partially) expanded from the specified tokens.
/// This is the expansions whose Spelled range intersects \p Spelled.
@@ -426,7 +424,7 @@ public:
/// Finalizes token collection. Should be called after preprocessing is
/// finished, i.e. after running Execute().
- LLVM_NODISCARD TokenBuffer consume() &&;
+ [[nodiscard]] TokenBuffer consume() &&;
private:
/// Maps from a start to an end spelling location of transformations
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..a80b7bf2a3de 100644
--- a/contrib/llvm-project/clang/include/clang/Tooling/Syntax/Tree.h
+++ b/contrib/llvm-project/clang/include/clang/Tooling/Syntax/Tree.h
@@ -6,11 +6,11 @@
//
//===----------------------------------------------------------------------===//
// Defines the basic structure of the syntax tree. There are two kinds of nodes:
-// - leaf nodes correspond to a token in the expanded token stream,
+// - leaf nodes correspond to tokens,
// - tree nodes correspond to language grammar constructs.
//
// The tree is initially built from an AST. Each node of a newly built tree
-// covers a continous subrange of expanded tokens (i.e. tokens after
+// covers a continuous subrange of expanded tokens (i.e. tokens after
// preprocessing), the specific tokens coverered are stored in the leaf nodes of
// a tree. A post-order traversal of a tree will visit leaf nodes in an order
// corresponding the original order of expanded tokens.
@@ -18,51 +18,25 @@
// 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"
-#include "clang/Basic/SourceManager.h"
#include "clang/Basic/TokenKinds.h"
-#include "clang/Tooling/Syntax/Tokens.h"
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/DenseMap.h"
+#include "clang/Tooling/Syntax/TokenManager.h"
#include "llvm/ADT/iterator.h"
#include "llvm/Support/Allocator.h"
#include <cstdint>
-#include <iterator>
+#include <vector>
namespace clang {
namespace syntax {
-/// A memory arena for syntax trees. Also tracks the underlying token buffers,
-/// source manager, etc.
+/// A memory arena for syntax trees.
+// FIXME: use BumpPtrAllocator directly.
class Arena {
public:
- Arena(SourceManager &SourceMgr, const LangOptions &LangOpts,
- const TokenBuffer &Tokens);
-
- const SourceManager &getSourceManager() const { return SourceMgr; }
- const LangOptions &getLangOptions() const { return LangOpts; }
-
- const TokenBuffer &getTokenBuffer() const;
llvm::BumpPtrAllocator &getAllocator() { return Allocator; }
-
private:
- /// Add \p Buffer to the underlying source manager, tokenize it and store the
- /// resulting tokens. Used exclusively in `FactoryImpl` to materialize tokens
- /// that were not written in user code.
- std::pair<FileID, ArrayRef<Token>>
- lexBuffer(std::unique_ptr<llvm::MemoryBuffer> Buffer);
- friend class FactoryImpl;
-
-private:
- SourceManager &SourceMgr;
- const LangOptions &LangOpts;
- const TokenBuffer &Tokens;
- /// IDs and storage for additional tokenized files.
- llvm::DenseMap<FileID, std::vector<Token>> ExtraTokens;
/// Keeps all the allocated nodes and their intermediate data structures.
llvm::BumpPtrAllocator Allocator;
};
@@ -122,9 +96,9 @@ public:
Node *getPreviousSibling() { return PreviousSibling; }
/// Dumps the structure of a subtree. For debugging and testing purposes.
- std::string dump(const SourceManager &SM) const;
+ std::string dump(const TokenManager &SM) const;
/// Dumps the tokens forming this subtree.
- std::string dumpTokens(const SourceManager &SM) const;
+ std::string dumpTokens(const TokenManager &SM) const;
/// Asserts invariants on this node of the tree and its immediate children.
/// Will not recurse into the subtree. No-op if NDEBUG is set.
@@ -153,16 +127,17 @@ private:
unsigned CanModify : 1;
};
-/// A leaf node points to a single token inside the expanded token stream.
+/// A leaf node points to a single token.
+// FIXME: add TokenKind field (borrow some bits from the Node::kind).
class Leaf final : public Node {
public:
- Leaf(const Token *T);
+ Leaf(TokenManager::Key K);
static bool classof(const Node *N);
- const Token *getToken() const { return Tok; }
+ TokenManager::Key getTokenKey() const { return K; }
private:
- const Token *Tok;
+ TokenManager::Key K;
};
/// A node that has children and represents a syntactic language construct.
@@ -181,7 +156,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 +247,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 73d09662562b..070706e8fa6d 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 {
@@ -115,7 +114,7 @@ public:
/// T must derive from clang::FrontendAction.
///
/// Example:
-/// FrontendActionFactory *Factory =
+/// std::unique_ptr<FrontendActionFactory> Factory =
/// newFrontendActionFactory<clang::SyntaxOnlyAction>();
template <typename T>
std::unique_ptr<FrontendActionFactory> newFrontendActionFactory();
@@ -145,7 +144,7 @@ public:
///
/// Example:
/// struct ProvidesASTConsumers {
-/// clang::ASTConsumer *newASTConsumer();
+/// std::unique_ptr<clang::ASTConsumer> newASTConsumer();
/// } Factory;
/// std::unique_ptr<FrontendActionFactory> FactoryAdapter(
/// newFrontendActionFactory(&Factory));
@@ -268,11 +267,20 @@ public:
~ToolInvocation();
- /// Set a \c DiagnosticConsumer to use during parsing.
+ ToolInvocation(const ToolInvocation &) = delete;
+ ToolInvocation &operator=(const ToolInvocation &) = delete;
+
+ /// Set a \c DiagnosticConsumer to use during driver command-line parsing and
+ /// the action invocation itself.
void setDiagnosticConsumer(DiagnosticConsumer *DiagConsumer) {
this->DiagConsumer = DiagConsumer;
}
+ /// Set a \c DiagnosticOptions to use during driver command-line parsing.
+ void setDiagnosticOptions(DiagnosticOptions *DiagOpts) {
+ this->DiagOpts = DiagOpts;
+ }
+
/// Run the clang invocation.
///
/// \returns True if there were no errors during execution.
@@ -290,6 +298,7 @@ public:
FileManager *Files;
std::shared_ptr<PCHContainerOperations> PCHContainerOps;
DiagnosticConsumer *DiagConsumer = nullptr;
+ DiagnosticOptions *DiagOpts = nullptr;
};
/// Utility to run a FrontendAction over a set of files.
@@ -355,11 +364,6 @@ public:
/// append them to ASTs.
int buildASTs(std::vector<std::unique_ptr<ASTUnit>> &ASTs);
- /// Sets whether working directory should be restored after calling run(). By
- /// default, working directory is restored. However, it could be useful to
- /// turn this off when running on multiple threads to avoid the raciness.
- void setRestoreWorkingDir(bool RestoreCWD);
-
/// Sets whether an error message should be printed out if an action fails. By
/// default, if an action fails, a message is printed out to stderr.
void setPrintErrorMessage(bool PrintErrorMessage);
@@ -389,7 +393,6 @@ private:
DiagnosticConsumer *DiagConsumer = nullptr;
- bool RestoreCWD = true;
bool PrintErrorMessage = true;
};
@@ -500,9 +503,15 @@ llvm::Expected<std::string> getAbsolutePath(llvm::vfs::FileSystem &FS,
void addTargetAndModeForProgramName(std::vector<std::string> &CommandLine,
StringRef InvokedAs);
+/// Helper function that expands response files in command line.
+void addExpandedResponseFiles(std::vector<std::string> &CommandLine,
+ llvm::StringRef WorkingDir,
+ llvm::cl::TokenizerCallback Tokenizer,
+ llvm::vfs::FileSystem &FS);
+
/// Creates a \c CompilerInvocation.
CompilerInvocation *newInvocation(DiagnosticsEngine *Diagnostics,
- const llvm::opt::ArgStringList &CC1Args,
+ ArrayRef<const char *> CC1Args,
const char *const BinaryName);
} // namespace tooling
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 8ff31f7a0342..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"
@@ -50,7 +50,7 @@ inline RangeSelector range(std::string BeginID, std::string EndID) {
/// Selects the (empty) range [B,B) when \p Selector selects the range [B,E).
RangeSelector before(RangeSelector Selector);
-/// Selects the the point immediately following \p Selector. That is, the
+/// Selects the point immediately following \p Selector. That is, the
/// (empty) range [E,E), when \p Selector selects either
/// * the CharRange [B,E) or
/// * the TokenRange [B,E'] where the token at E' spans the range [E',E).
@@ -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..50f460d65e7d 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"
@@ -46,6 +46,7 @@ struct Edit {
EditKind Kind = EditKind::Range;
CharSourceRange Range;
std::string Replacement;
+ std::string Note;
llvm::Any Metadata;
};
@@ -61,7 +62,9 @@ enum class IncludeFormat {
/// of `EditGenerator`.
using EditGenerator = MatchConsumer<llvm::SmallVector<Edit, 1>>;
-using TextGenerator = std::shared_ptr<MatchComputation<std::string>>;
+template <typename T> using Generator = std::shared_ptr<MatchComputation<T>>;
+
+using TextGenerator = Generator<std::string>;
using AnyGenerator = MatchConsumer<llvm::Any>;
@@ -136,6 +139,10 @@ inline EditGenerator noEdits() { return editList({}); }
/// diagnostic `Explanation` with the rule.
EditGenerator noopEdit(RangeSelector Anchor);
+/// Generates a single, no-op edit with the associated note anchored at the
+/// start location of the specified range.
+ASTEdit note(RangeSelector Anchor, TextGenerator Note);
+
/// Version of `ifBound` specialized to `ASTEdit`.
inline EditGenerator ifBound(std::string ID, ASTEdit TrueEdit,
ASTEdit FalseEdit) {
@@ -262,12 +269,9 @@ inline EditGenerator shrinkTo(RangeSelector outer, RangeSelector inner) {
//
// * Edits: a set of Edits to the source code, described with ASTEdits.
//
-// * Explanation: explanation of the rewrite. This will be displayed to the
-// user, where possible; for example, in clang-tidy diagnostics.
-//
// However, rules can also consist of (sub)rules, where the first that matches
-// is applied and the rest are ignored. So, the above components are gathered
-// as a `Case` and a rule is a list of cases.
+// is applied and the rest are ignored. So, the above components together form
+// a logical "case" and a rule is a sequence of cases.
//
// Rule cases have an additional, implicit, component: the parameters. These are
// portions of the pattern which are left unspecified, yet bound in the pattern
@@ -275,38 +279,83 @@ inline EditGenerator shrinkTo(RangeSelector outer, RangeSelector inner) {
//
// The \c Transformer class can be used to apply the rewrite rule and obtain the
// corresponding replacements.
-struct RewriteRule {
+struct RewriteRuleBase {
struct Case {
ast_matchers::internal::DynTypedMatcher Matcher;
EditGenerator Edits;
- TextGenerator Explanation;
};
// We expect RewriteRules will most commonly include only one case.
SmallVector<Case, 1> Cases;
+};
- /// DEPRECATED: use `::clang::transformer::RootID` instead.
- static const llvm::StringRef RootID;
+/// A source-code transformation with accompanying metadata.
+///
+/// When a case of the rule matches, the \c Transformer invokes the
+/// corresponding metadata generator and provides it alongside the edits.
+template <typename MetadataT> struct RewriteRuleWith : RewriteRuleBase {
+ SmallVector<Generator<MetadataT>, 1> Metadata;
};
-/// Constructs a simple \c RewriteRule.
+template <> struct RewriteRuleWith<void> : RewriteRuleBase {};
+
+using RewriteRule = RewriteRuleWith<void>;
+
+namespace detail {
+
RewriteRule makeRule(ast_matchers::internal::DynTypedMatcher M,
- EditGenerator Edits, TextGenerator Explanation = nullptr);
-
-/// Constructs a \c RewriteRule from multiple `ASTEdit`s.
-inline RewriteRule makeRule(ast_matchers::internal::DynTypedMatcher M,
- llvm::SmallVector<ASTEdit, 1> Edits,
- TextGenerator Explanation = nullptr) {
- return makeRule(std::move(M), editList(std::move(Edits)),
- std::move(Explanation));
+ EditGenerator Edits);
+
+template <typename MetadataT>
+RewriteRuleWith<MetadataT> makeRule(ast_matchers::internal::DynTypedMatcher M,
+ EditGenerator Edits,
+ Generator<MetadataT> Metadata) {
+ RewriteRuleWith<MetadataT> R;
+ R.Cases = {{std::move(M), std::move(Edits)}};
+ R.Metadata = {std::move(Metadata)};
+ return R;
}
-/// Overload of \c makeRule for common case of only one edit.
-inline RewriteRule makeRule(ast_matchers::internal::DynTypedMatcher M,
- ASTEdit Edit,
- TextGenerator Explanation = nullptr) {
- return makeRule(std::move(M), edit(std::move(Edit)), std::move(Explanation));
+inline EditGenerator makeEditGenerator(EditGenerator Edits) { return Edits; }
+EditGenerator makeEditGenerator(llvm::SmallVector<ASTEdit, 1> Edits);
+EditGenerator makeEditGenerator(ASTEdit Edit);
+
+} // namespace detail
+
+/// Constructs a simple \c RewriteRule. \c Edits can be an \c EditGenerator,
+/// multiple \c ASTEdits, or a single \c ASTEdit.
+/// @{
+template <int &..., typename EditsT>
+RewriteRule makeRule(ast_matchers::internal::DynTypedMatcher M,
+ EditsT &&Edits) {
+ return detail::makeRule(
+ std::move(M), detail::makeEditGenerator(std::forward<EditsT>(Edits)));
}
+RewriteRule makeRule(ast_matchers::internal::DynTypedMatcher M,
+ std::initializer_list<ASTEdit> Edits);
+/// @}
+
+/// Overloads of \c makeRule that also generate metadata when matching.
+/// @{
+template <typename MetadataT, int &..., typename EditsT>
+RewriteRuleWith<MetadataT> makeRule(ast_matchers::internal::DynTypedMatcher M,
+ EditsT &&Edits,
+ Generator<MetadataT> Metadata) {
+ return detail::makeRule(
+ std::move(M), detail::makeEditGenerator(std::forward<EditsT>(Edits)),
+ std::move(Metadata));
+}
+
+template <typename MetadataT>
+RewriteRuleWith<MetadataT> makeRule(ast_matchers::internal::DynTypedMatcher M,
+ std::initializer_list<ASTEdit> Edits,
+ Generator<MetadataT> Metadata) {
+ return detail::makeRule(std::move(M),
+ detail::makeEditGenerator(std::move(Edits)),
+ std::move(Metadata));
+}
+/// @}
+
/// For every case in Rule, adds an include directive for the given header. The
/// common use is assumed to be a rule with only one case. For example, to
/// replace a function call and add headers corresponding to the new code, one
@@ -317,7 +366,7 @@ inline RewriteRule makeRule(ast_matchers::internal::DynTypedMatcher M,
/// addInclude(R, "path/to/bar_header.h");
/// addInclude(R, "vector", IncludeFormat::Angled);
/// \endcode
-void addInclude(RewriteRule &Rule, llvm::StringRef Header,
+void addInclude(RewriteRuleBase &Rule, llvm::StringRef Header,
IncludeFormat Format = IncludeFormat::Quoted);
/// Applies the first rule whose pattern matches; other rules are ignored. If
@@ -359,7 +408,45 @@ void addInclude(RewriteRule &Rule, llvm::StringRef Header,
// makeRule(left_call, left_call_action),
// makeRule(right_call, right_call_action)});
// ```
-RewriteRule applyFirst(ArrayRef<RewriteRule> Rules);
+/// @{
+template <typename MetadataT>
+RewriteRuleWith<MetadataT>
+applyFirst(ArrayRef<RewriteRuleWith<MetadataT>> Rules) {
+ RewriteRuleWith<MetadataT> R;
+ for (auto &Rule : Rules) {
+ assert(Rule.Cases.size() == Rule.Metadata.size() &&
+ "mis-match in case and metadata array size");
+ R.Cases.append(Rule.Cases.begin(), Rule.Cases.end());
+ R.Metadata.append(Rule.Metadata.begin(), Rule.Metadata.end());
+ }
+ return R;
+}
+
+template <>
+RewriteRuleWith<void> applyFirst(ArrayRef<RewriteRuleWith<void>> Rules);
+
+template <typename MetadataT>
+RewriteRuleWith<MetadataT>
+applyFirst(const std::vector<RewriteRuleWith<MetadataT>> &Rules) {
+ return applyFirst(llvm::ArrayRef(Rules));
+}
+
+template <typename MetadataT>
+RewriteRuleWith<MetadataT>
+applyFirst(std::initializer_list<RewriteRuleWith<MetadataT>> Rules) {
+ return applyFirst(llvm::ArrayRef(Rules.begin(), Rules.end()));
+}
+/// @}
+
+/// Converts a \c RewriteRuleWith<T> to a \c RewriteRule by stripping off the
+/// metadata generators.
+template <int &..., typename MetadataT>
+std::enable_if_t<!std::is_same<MetadataT, void>::value, RewriteRule>
+stripMetadata(RewriteRuleWith<MetadataT> Rule) {
+ RewriteRule R;
+ R.Cases = std::move(Rule.Cases);
+ return R;
+}
/// Applies `Rule` to all descendants of the node bound to `NodeId`. `Rule` can
/// refer to nodes bound by the calling rule. `Rule` is not applied to the node
@@ -423,7 +510,8 @@ rewriteDescendants(const DynTypedNode &Node, RewriteRule Rule,
/// Only supports Rules whose cases' matchers share the same base "kind"
/// (`Stmt`, `Decl`, etc.) Deprecated: use `buildMatchers` instead, which
/// supports mixing matchers of different kinds.
-ast_matchers::internal::DynTypedMatcher buildMatcher(const RewriteRule &Rule);
+ast_matchers::internal::DynTypedMatcher
+buildMatcher(const RewriteRuleBase &Rule);
/// Builds a set of matchers that cover the rule.
///
@@ -433,7 +521,7 @@ ast_matchers::internal::DynTypedMatcher buildMatcher(const RewriteRule &Rule);
/// for rewriting. If any such matchers are included, will return an empty
/// vector.
std::vector<ast_matchers::internal::DynTypedMatcher>
-buildMatchers(const RewriteRule &Rule);
+buildMatchers(const RewriteRuleBase &Rule);
/// Gets the beginning location of the source matched by a rewrite rule. If the
/// match occurs within a macro expansion, returns the beginning of the
@@ -441,13 +529,12 @@ buildMatchers(const RewriteRule &Rule);
SourceLocation
getRuleMatchLoc(const ast_matchers::MatchFinder::MatchResult &Result);
-/// Returns the \c Case of \c Rule that was selected in the match result.
-/// Assumes a matcher built with \c buildMatcher.
-const RewriteRule::Case &
-findSelectedCase(const ast_matchers::MatchFinder::MatchResult &Result,
- const RewriteRule &Rule);
+/// Returns the index of the \c Case of \c Rule that was selected in the match
+/// result. Assumes a matcher built with \c buildMatcher.
+size_t findSelectedCase(const ast_matchers::MatchFinder::MatchResult &Result,
+ const RewriteRuleBase &Rule);
} // namespace detail
} // 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..004c614b0b9d 100644
--- a/contrib/llvm-project/clang/include/clang/Tooling/Transformer/SourceCode.h
+++ b/contrib/llvm-project/clang/include/clang/Tooling/Transformer/SourceCode.h
@@ -10,12 +10,13 @@
//
//===----------------------------------------------------------------------===//
-#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"
#include "clang/Basic/TokenKinds.h"
+#include <optional>
namespace clang {
namespace tooling {
@@ -41,6 +42,10 @@ CharSourceRange getExtendedRange(const T &Node, tok::TokenKind Next,
/// terminators. The returned range consists of file locations, if valid file
/// locations can be found for the associated content; otherwise, an invalid
/// range is returned.
+///
+/// Note that parsing comments is disabled by default. In order to select a
+/// range containing associated comments, you may need to invoke the tool with
+/// `-fparse-all-comments`.
CharSourceRange getAssociatedRange(const Decl &D, ASTContext &Context);
/// Returns the source-code text in the specified range.
@@ -86,18 +91,55 @@ StringRef getExtendedText(const T &Node, tok::TokenKind Next,
llvm::Error validateEditRange(const CharSourceRange &Range,
const SourceManager &SM);
+/// Determines whether \p Range is one that can be read from. If
+/// `AllowSystemHeaders` is false, a range that falls within a system header
+/// fails validation.
+llvm::Error validateRange(const CharSourceRange &Range, const SourceManager &SM,
+ bool AllowSystemHeaders);
+
/// Attempts to resolve the given range to one that can be edited by a rewrite;
-/// generally, one that starts and ends within a particular file. It supports a
-/// limited set of cases involving source locations in macro expansions. If a
-/// value is returned, it satisfies \c validateEditRange.
-llvm::Optional<CharSourceRange>
-getRangeForEdit(const CharSourceRange &EditRange, const SourceManager &SM,
- const LangOptions &LangOpts);
-inline llvm::Optional<CharSourceRange>
-getRangeForEdit(const CharSourceRange &EditRange, const ASTContext &Context) {
- return getRangeForEdit(EditRange, Context.getSourceManager(),
- Context.getLangOpts());
+/// generally, one that starts and ends within a particular file. If a value is
+/// returned, it satisfies \c validateEditRange.
+///
+/// If \c IncludeMacroExpansion is true, a limited set of cases involving source
+/// locations in macro expansions is supported. For example, if we're looking to
+/// rewrite the int literal 3 to 6, and we have the following definition:
+/// #define DO_NOTHING(x) x
+/// then
+/// foo(DO_NOTHING(3))
+/// will be rewritten to
+/// foo(6)
+std::optional<CharSourceRange>
+getFileRangeForEdit(const CharSourceRange &EditRange, const SourceManager &SM,
+ const LangOptions &LangOpts,
+ bool IncludeMacroExpansion = true);
+inline std::optional<CharSourceRange>
+getFileRangeForEdit(const CharSourceRange &EditRange, const ASTContext &Context,
+ bool IncludeMacroExpansion = true) {
+ return getFileRangeForEdit(EditRange, Context.getSourceManager(),
+ Context.getLangOpts(), IncludeMacroExpansion);
}
+
+/// Attempts to resolve the given range to one that starts and ends in a
+/// particular file.
+///
+/// If \c IncludeMacroExpansion is true, a limited set of cases involving source
+/// locations in macro expansions is supported. For example, if we're looking to
+/// get the range of the int literal 3, and we have the following definition:
+/// #define DO_NOTHING(x) x
+/// foo(DO_NOTHING(3))
+/// the returned range will hold the source text `DO_NOTHING(3)`.
+std::optional<CharSourceRange> getFileRange(const CharSourceRange &EditRange,
+ const SourceManager &SM,
+ const LangOptions &LangOpts,
+ bool IncludeMacroExpansion);
+inline std::optional<CharSourceRange>
+getFileRange(const CharSourceRange &EditRange, const ASTContext &Context,
+ bool IncludeMacroExpansion) {
+ return getFileRange(EditRange, Context.getSourceManager(),
+ Context.getLangOpts(), IncludeMacroExpansion);
+}
+
} // 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..22fc644dfac5 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.
@@ -50,18 +59,18 @@ bool needParensAfterUnaryOperator(const Expr &E);
/// Builds source for an expression, adding parens if needed for unambiguous
/// parsing.
-llvm::Optional<std::string> buildParens(const Expr &E,
- const ASTContext &Context);
+std::optional<std::string> buildParens(const Expr &E,
+ const ASTContext &Context);
/// Builds idiomatic source for the dereferencing of `E`: prefix with `*` but
/// simplify when it already begins with `&`. \returns empty string on failure.
-llvm::Optional<std::string> buildDereference(const Expr &E,
- const ASTContext &Context);
+std::optional<std::string> buildDereference(const Expr &E,
+ const ASTContext &Context);
/// Builds idiomatic source for taking the address of `E`: prefix with `&` but
/// simplify when it already begins with `*`. \returns empty string on failure.
-llvm::Optional<std::string> buildAddressOf(const Expr &E,
- const ASTContext &Context);
+std::optional<std::string> buildAddressOf(const Expr &E,
+ const ASTContext &Context);
/// Adds a dot to the end of the given expression, but adds parentheses when
/// needed by the syntax, and simplifies to `->` when possible, e.g.:
@@ -69,7 +78,9 @@ llvm::Optional<std::string> buildAddressOf(const Expr &E,
/// `x` becomes `x.`
/// `*a` becomes `a->`
/// `a+b` becomes `(a+b).`
-llvm::Optional<std::string> buildDot(const Expr &E, const ASTContext &Context);
+///
+/// DEPRECATED. Use `buildAccess`.
+std::optional<std::string> buildDot(const Expr &E, const ASTContext &Context);
/// Adds an arrow to the end of the given expression, but adds parentheses
/// when needed by the syntax, and simplifies to `.` when possible, e.g.:
@@ -77,10 +88,33 @@ llvm::Optional<std::string> buildDot(const Expr &E, const ASTContext &Context);
/// `x` becomes `x->`
/// `&a` becomes `a.`
/// `a+b` becomes `(a+b)->`
-llvm::Optional<std::string> buildArrow(const Expr &E,
- const ASTContext &Context);
+///
+/// DEPRECATED. Use `buildAccess`.
+std::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->`
+std::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/include/clang/Tooling/Transformer/Stencil.h b/contrib/llvm-project/clang/include/clang/Tooling/Transformer/Stencil.h
index 1b7495eb0262..249f95b7391d 100644
--- a/contrib/llvm-project/clang/include/clang/Tooling/Transformer/Stencil.h
+++ b/contrib/llvm-project/clang/include/clang/Tooling/Transformer/Stencil.h
@@ -117,6 +117,38 @@ inline Stencil ifBound(llvm::StringRef Id, llvm::StringRef TrueText,
detail::makeStencil(FalseText));
}
+/// Chooses between multiple stencils, based on the presence of bound nodes. \p
+/// CaseStencils takes a vector of (ID, \c Stencil) pairs and checks each ID in
+/// order to see if it's bound to a node. If so, the associated \c Stencil is
+/// run and all other cases are ignored. An optional \p DefaultStencil can be
+/// provided to be run if all cases are exhausted beacause none of the provided
+/// IDs are bound. If no default case is provided and all cases are exhausted,
+/// the stencil will fail with error `llvm::errc::result_out_of_range`.
+///
+/// For example, say one matches a statement's type with:
+/// anyOf(
+/// qualType(isInteger()).bind("int"),
+/// qualType(realFloatingPointType()).bind("float"),
+/// qualType(isAnyCharacter()).bind("char"),
+/// booleanType().bind("bool"))
+///
+/// Then, one can decide in a stencil how to construct a literal.
+/// cat("a = ",
+/// selectBound(
+/// {{"int", cat("0")},
+/// {"float", cat("0.0")},
+/// {"char", cat("'\\0'")},
+/// {"bool", cat("false")}}))
+///
+/// In addition, one could supply a default case for all other types:
+/// selectBound(
+/// {{"int", cat("0")},
+/// ...
+/// {"bool", cat("false")}},
+/// cat("{}"))
+Stencil selectBound(std::vector<std::pair<std::string, Stencil>> CaseStencils,
+ Stencil DefaultStencil = nullptr);
+
/// Wraps a \c MatchConsumer in a \c Stencil, so that it can be used in a \c
/// Stencil. This supports user-defined extensions to the \c Stencil language.
Stencil run(MatchConsumer<std::string> C);
diff --git a/contrib/llvm-project/clang/include/clang/Tooling/Transformer/Transformer.h b/contrib/llvm-project/clang/include/clang/Tooling/Transformer/Transformer.h
index 31feacba5e28..71b1fe81b951 100644
--- a/contrib/llvm-project/clang/include/clang/Tooling/Transformer/Transformer.h
+++ b/contrib/llvm-project/clang/include/clang/Tooling/Transformer/Transformer.h
@@ -18,20 +18,86 @@
namespace clang {
namespace tooling {
+
+namespace detail {
+/// Implementation details of \c Transformer with type erasure around
+/// \c RewriteRule<T> as well as the corresponding consumers.
+class TransformerImpl {
+public:
+ virtual ~TransformerImpl() = default;
+
+ void onMatch(const ast_matchers::MatchFinder::MatchResult &Result);
+
+ virtual std::vector<ast_matchers::internal::DynTypedMatcher>
+ buildMatchers() const = 0;
+
+protected:
+ /// Converts a set of \c Edit into a \c AtomicChange per file modified.
+ /// Returns an error if the edits fail to compose, e.g. overlapping edits.
+ static llvm::Expected<llvm::SmallVector<AtomicChange, 1>>
+ convertToAtomicChanges(const llvm::SmallVectorImpl<transformer::Edit> &Edits,
+ const ast_matchers::MatchFinder::MatchResult &Result);
+
+private:
+ virtual void
+ onMatchImpl(const ast_matchers::MatchFinder::MatchResult &Result) = 0;
+};
+
+// FIXME: Use std::type_identity or backport when available.
+template <class T> struct type_identity {
+ using type = T;
+};
+} // namespace detail
+
+template <typename T> struct TransformerResult {
+ llvm::MutableArrayRef<AtomicChange> Changes;
+ T Metadata;
+};
+
+template <> struct TransformerResult<void> {
+ llvm::MutableArrayRef<AtomicChange> Changes;
+};
+
/// Handles the matcher and callback registration for a single `RewriteRule`, as
/// defined by the arguments of the constructor.
class Transformer : public ast_matchers::MatchFinder::MatchCallback {
public:
- using ChangeConsumer =
- std::function<void(Expected<clang::tooling::AtomicChange> Change)>;
+ /// Provides the set of changes to the consumer. The callback is free to move
+ /// or destructively consume the changes as needed.
+ ///
+ /// We use \c MutableArrayRef as an abstraction to provide decoupling, and we
+ /// expect the majority of consumers to copy or move the individual values
+ /// into a separate data structure.
+ using ChangeSetConsumer = std::function<void(
+ Expected<llvm::MutableArrayRef<AtomicChange>> Changes)>;
- /// \param Consumer Receives each rewrite or error. Will not necessarily be
- /// called for each match; for example, if the rewrite is not applicable
- /// because of macros, but doesn't fail. Note that clients are responsible
+ /// \param Consumer receives all rewrites for a single match, or an error.
+ /// Will not necessarily be called for each match; for example, if the rule
+ /// generates no edits but does not fail. Note that clients are responsible
/// for handling the case that independent \c AtomicChanges conflict with each
/// other.
- Transformer(transformer::RewriteRule Rule, ChangeConsumer Consumer)
- : Rule(std::move(Rule)), Consumer(std::move(Consumer)) {}
+ explicit Transformer(transformer::RewriteRuleWith<void> Rule,
+ ChangeSetConsumer Consumer)
+ : Transformer(std::move(Rule),
+ [Consumer = std::move(Consumer)](
+ llvm::Expected<TransformerResult<void>> Result) {
+ if (Result)
+ Consumer(Result->Changes);
+ else
+ Consumer(Result.takeError());
+ }) {}
+
+ /// \param Consumer receives all rewrites and the associated metadata for a
+ /// single match, or an error. Will always be called for each match, even if
+ /// the rule generates no edits. Note that clients are responsible for
+ /// handling the case that independent \c AtomicChanges conflict with each
+ /// other.
+ template <typename MetadataT>
+ explicit Transformer(
+ transformer::RewriteRuleWith<MetadataT> Rule,
+ std::function<void(llvm::Expected<TransformerResult<
+ typename detail::type_identity<MetadataT>::type>>)>
+ Consumer);
/// N.B. Passes `this` pointer to `MatchFinder`. So, this object should not
/// be moved after this call.
@@ -42,10 +108,104 @@ public:
void run(const ast_matchers::MatchFinder::MatchResult &Result) override;
private:
- transformer::RewriteRule Rule;
- /// Receives each successful rewrites as an \c AtomicChange.
- ChangeConsumer Consumer;
+ std::unique_ptr<detail::TransformerImpl> Impl;
};
+
+namespace detail {
+/// Runs the metadata generator on \c Rule and stuffs it into \c Result.
+/// @{
+template <typename T>
+llvm::Error
+populateMetadata(const transformer::RewriteRuleWith<T> &Rule,
+ size_t SelectedCase,
+ const ast_matchers::MatchFinder::MatchResult &Match,
+ TransformerResult<T> &Result) {
+ // Silence a false positive GCC -Wunused-but-set-parameter warning in constexpr
+ // cases, by marking SelectedCase as used. See
+ // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85827 for details. The issue is
+ // fixed in GCC 10.
+ (void)SelectedCase;
+ if constexpr (!std::is_void_v<T>) {
+ auto Metadata = Rule.Metadata[SelectedCase]->eval(Match);
+ if (!Metadata)
+ return Metadata.takeError();
+ Result.Metadata = std::move(*Metadata);
+ }
+ return llvm::Error::success();
+}
+/// @}
+
+/// Implementation when metadata is generated as a part of the rewrite. This
+/// happens when we have a \c RewriteRuleWith<T>.
+template <typename T> class WithMetadataImpl final : public TransformerImpl {
+ transformer::RewriteRuleWith<T> Rule;
+ std::function<void(llvm::Expected<TransformerResult<T>>)> Consumer;
+
+public:
+ explicit WithMetadataImpl(
+ transformer::RewriteRuleWith<T> R,
+ std::function<void(llvm::Expected<TransformerResult<T>>)> Consumer)
+ : Rule(std::move(R)), Consumer(std::move(Consumer)) {
+ assert(llvm::all_of(Rule.Cases,
+ [](const transformer::RewriteRuleBase::Case &Case)
+ -> bool { return !!Case.Edits; }) &&
+ "edit generator must be provided for each rule");
+ if constexpr (!std::is_void_v<T>)
+ assert(llvm::all_of(Rule.Metadata,
+ [](const typename transformer::Generator<T> &Metadata)
+ -> bool { return !!Metadata; }) &&
+ "metadata generator must be provided for each rule");
+ }
+
+private:
+ void onMatchImpl(const ast_matchers::MatchFinder::MatchResult &Result) final {
+ size_t I = transformer::detail::findSelectedCase(Result, Rule);
+ auto Transformations = Rule.Cases[I].Edits(Result);
+ if (!Transformations) {
+ Consumer(Transformations.takeError());
+ return;
+ }
+
+ llvm::SmallVector<AtomicChange, 1> Changes;
+ if (!Transformations->empty()) {
+ auto C = convertToAtomicChanges(*Transformations, Result);
+ if (C) {
+ Changes = std::move(*C);
+ } else {
+ Consumer(C.takeError());
+ return;
+ }
+ } else if (std::is_void<T>::value) {
+ // If we don't have metadata and we don't have any edits, skip.
+ return;
+ }
+
+ TransformerResult<T> RewriteResult;
+ if (auto E = populateMetadata(Rule, I, Result, RewriteResult)) {
+ Consumer(std::move(E));
+ return;
+ }
+
+ RewriteResult.Changes = llvm::MutableArrayRef<AtomicChange>(Changes);
+ Consumer(std::move(RewriteResult));
+ }
+
+ std::vector<ast_matchers::internal::DynTypedMatcher>
+ buildMatchers() const final {
+ return transformer::detail::buildMatchers(Rule);
+ }
+};
+} // namespace detail
+
+template <typename MetadataT>
+Transformer::Transformer(
+ transformer::RewriteRuleWith<MetadataT> Rule,
+ std::function<void(llvm::Expected<TransformerResult<
+ typename detail::type_identity<MetadataT>::type>>)>
+ Consumer)
+ : Impl(std::make_unique<detail::WithMetadataImpl<MetadataT>>(
+ std::move(Rule), std::move(Consumer))) {}
+
} // namespace tooling
} // namespace clang
diff --git a/contrib/llvm-project/clang/include/clang/module.modulemap b/contrib/llvm-project/clang/include/clang/module.modulemap
deleted file mode 100644
index 33fcf9dc7576..000000000000
--- a/contrib/llvm-project/clang/include/clang/module.modulemap
+++ /dev/null
@@ -1,182 +0,0 @@
-module Clang_Analysis {
- requires cplusplus
- umbrella "Analysis"
-
- textual header "Analysis/Analyses/ThreadSafetyOps.def"
-
- module * { export * }
-
- // FIXME: Exclude these headers to avoid pulling all of the AST matchers
- // library into clang. Due to inline key functions in the headers,
- // importing the AST matchers library gives a link dependency on the AST
- // matchers (and thus the AST), which clang-format should not have.
- exclude header "Analysis/Analyses/ExprMutationAnalyzer.h"
-}
-
-module Clang_AST {
- requires cplusplus
- umbrella "AST"
-
- textual header "AST/BuiltinTypes.def"
- textual header "AST/CXXRecordDeclDefinitionBits.def"
- textual header "AST/OperationKinds.def"
- textual header "AST/TypeLocNodes.def"
-
- module * { export * }
-}
-
-module Clang_ASTMatchers { requires cplusplus umbrella "ASTMatchers" module * { export * } }
-
-module Clang_Basic {
- requires cplusplus
- umbrella "Basic"
-
- textual header "Basic/AArch64SVEACLETypes.def"
- textual header "Basic/BuiltinsAArch64.def"
- textual header "Basic/BuiltinsAMDGPU.def"
- textual header "Basic/BuiltinsARM.def"
- textual header "Basic/BuiltinsBPF.def"
- textual header "Basic/Builtins.def"
- textual header "Basic/BuiltinsHexagon.def"
- textual header "Basic/BuiltinsHexagonDep.def"
- textual header "Basic/BuiltinsHexagonMapCustomDep.def"
- textual header "Basic/BuiltinsMips.def"
- textual header "Basic/BuiltinsNEON.def"
- textual header "Basic/BuiltinsNVPTX.def"
- textual header "Basic/BuiltinsPPC.def"
- textual header "Basic/BuiltinsRISCV.def"
- textual header "Basic/BuiltinsSVE.def"
- textual header "Basic/BuiltinsSystemZ.def"
- textual header "Basic/BuiltinsWebAssembly.def"
- textual header "Basic/BuiltinsX86.def"
- textual header "Basic/BuiltinsX86_64.def"
- textual header "Basic/BuiltinsXCore.def"
- textual header "Basic/CodeGenOptions.def"
- textual header "Basic/DiagnosticOptions.def"
- textual header "Basic/Features.def"
- textual header "Basic/FPOptions.def"
- textual header "Basic/MSP430Target.def"
- textual header "Basic/LangOptions.def"
- textual header "Basic/OpenCLExtensions.def"
- textual header "Basic/OpenCLImageTypes.def"
- textual header "Basic/OpenCLExtensionTypes.def"
- textual header "Basic/OpenMPKinds.def"
- textual header "Basic/OperatorKinds.def"
- textual header "Basic/PPCTypes.def"
- textual header "Basic/RISCVVTypes.def"
- textual header "Basic/Sanitizers.def"
- textual header "Basic/TargetCXXABI.def"
- textual header "Basic/TokenKinds.def"
- textual header "Basic/X86Target.def"
-
- module * { export * }
-}
-
-module Clang_CodeGen { requires cplusplus umbrella "CodeGen" module * { export * } }
-module Clang_Config { requires cplusplus umbrella "Config" module * { export * } }
-
-// Files for diagnostic groups are spread all over the include/clang/ tree, but
-// logically form a single module.
-module Clang_Diagnostics {
- requires cplusplus
-
- module All { header "Basic/AllDiagnostics.h" export * }
- module Analysis { header "Analysis/AnalysisDiagnostic.h" export * }
- module AST { header "AST/ASTDiagnostic.h" export * }
- module Comment { header "AST/CommentDiagnostic.h" export * }
- module Driver { header "Driver/DriverDiagnostic.h" export * }
- module Frontend { header "Frontend/FrontendDiagnostic.h" export * }
- module Lex { header "Lex/LexDiagnostic.h" export * }
- module Parse { header "Parse/ParseDiagnostic.h" export * }
- module Sema { header "Sema/SemaDiagnostic.h" export * }
- module Serialization { header "Serialization/SerializationDiagnostic.h" export * }
- module Refactoring { header "Tooling/Refactoring/RefactoringDiagnostic.h" export * }
-}
-
-module Clang_Driver {
- requires cplusplus
- umbrella "Driver"
-
- textual header "Driver/Types.def"
-
- module * { export * }
-}
-
-module Clang_Edit { requires cplusplus umbrella "Edit" module * { export * } }
-module Clang_Format { requires cplusplus umbrella "Format" module * { export * } }
-
-module Clang_Frontend {
- requires cplusplus
- umbrella "Frontend"
-
- textual header "Basic/LangStandards.def"
-
- module * { export * }
-}
-
-module Clang_FrontendTool { requires cplusplus umbrella "FrontendTool" module * { export * } }
-module Clang_Index { requires cplusplus umbrella "Index" module * { export * } }
-module Clang_Lex { requires cplusplus umbrella "Lex" module * { export * } }
-module Clang_Parse { requires cplusplus umbrella "Parse" module * { export * } }
-module Clang_Rewrite { requires cplusplus umbrella "Rewrite/Core" module * { export * } }
-module Clang_RewriteFrontend { requires cplusplus umbrella "Rewrite/Frontend" module * { export * } }
-module Clang_Sema { requires cplusplus umbrella "Sema" module * { export * } }
-
-module Clang_Serialization {
- requires cplusplus
- umbrella "Serialization"
-
- textual header "Serialization/TypeBitCodes.def"
-
- module * { export * }
-}
-
-module Clang_StaticAnalyzer_Core {
- requires cplusplus
- umbrella "StaticAnalyzer/Core"
-
- textual header "StaticAnalyzer/Core/Analyses.def"
- textual header "StaticAnalyzer/Core/AnalyzerOptions.def"
- textual header "StaticAnalyzer/Core/PathSensitive/SVals.def"
- textual header "StaticAnalyzer/Core/PathSensitive/Symbols.def"
- textual header "StaticAnalyzer/Core/PathSensitive/Regions.def"
-
- module * { export * }
-}
-
-module Clang_StaticAnalyzer_Checkers {
- requires cplusplus
- umbrella "StaticAnalyzer/Checkers"
- module * { export * }
-}
-
-module Clang_StaticAnalyzer_Frontend {
- requires cplusplus
- umbrella "StaticAnalyzer/Frontend"
- module * { export * }
-}
-
-module Clang_Testing {
- requires cplusplus
- umbrella "Testing"
- module * { export * }
-}
-
-module Clang_Tooling {
- requires cplusplus umbrella "Tooling" module * { export * }
- // FIXME: Exclude these headers to avoid pulling all of the AST matchers
- // library into clang-format. Due to inline key functions in the headers,
- // importing the AST matchers library gives a link dependency on the AST
- // matchers (and thus the AST), which clang-format should not have.
- exclude header "Tooling/RefactoringCallbacks.h"
-}
-
-module Clang_ToolingCore {
- requires cplusplus
- umbrella "Tooling/Core" module * { export * }
-}
-
-module Clang_ToolingInclusions {
- requires cplusplus
- umbrella "Tooling/Inclusions" module * { export * }
-}